* Added DPMS support to the VESA driver, in case the hardware/BIOS supports it.
* Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30974 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2008, Axel Dörfler, [email protected].
|
* Copyright 2004-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef VESA_H
|
#ifndef VESA_H
|
||||||
@@ -141,6 +141,15 @@ struct crtc_info_block {
|
|||||||
#define CRTC_NEGATIVE_VSYNC 0x08
|
#define CRTC_NEGATIVE_VSYNC 0x08
|
||||||
|
|
||||||
|
|
||||||
|
/* Power Management */
|
||||||
|
|
||||||
|
#define DPMS_ON 0x00
|
||||||
|
#define DPMS_STANDBY 0x01
|
||||||
|
#define DPMS_SUSPEND 0x02
|
||||||
|
#define DPMS_OFF 0x04
|
||||||
|
#define DPMS_REDUCED_ON 0x08
|
||||||
|
|
||||||
|
|
||||||
/* VBE 3.0 protected mode interface
|
/* VBE 3.0 protected mode interface
|
||||||
* The BIOS area can be scanned for the protected mode
|
* The BIOS area can be scanned for the protected mode
|
||||||
* signature that identifies the structure below.
|
* signature that identifies the structure below.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2008, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef VESA_INFO_H
|
#ifndef VESA_INFO_H
|
||||||
@@ -40,6 +40,7 @@ struct vesa_shared_info {
|
|||||||
|
|
||||||
edid1_info edid_info;
|
edid1_info edid_info;
|
||||||
bool has_edid;
|
bool has_edid;
|
||||||
|
uint32 dpms_capabilities;
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------- ioctl() interface ----------------
|
//----------------- ioctl() interface ----------------
|
||||||
@@ -49,6 +50,8 @@ enum {
|
|||||||
VESA_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
|
VESA_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
|
||||||
VESA_GET_DEVICE_NAME,
|
VESA_GET_DEVICE_NAME,
|
||||||
VESA_SET_DISPLAY_MODE,
|
VESA_SET_DISPLAY_MODE,
|
||||||
|
VESA_GET_DPMS_MODE,
|
||||||
|
VESA_SET_DPMS_MODE,
|
||||||
|
|
||||||
VGA_SET_INDEXED_COLORS,
|
VGA_SET_INDEXED_COLORS,
|
||||||
VGA_PLANAR_BLIT,
|
VGA_PLANAR_BLIT,
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "accelerant_protos.h"
|
#include "accelerant_protos.h"
|
||||||
#include "accelerant.h"
|
#include "accelerant.h"
|
||||||
|
|
||||||
@@ -11,20 +13,27 @@
|
|||||||
uint32
|
uint32
|
||||||
vesa_dpms_capabilities(void)
|
vesa_dpms_capabilities(void)
|
||||||
{
|
{
|
||||||
return B_DPMS_ON;
|
return gInfo->shared_info->dpms_capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
vesa_dpms_mode(void)
|
vesa_dpms_mode(void)
|
||||||
{
|
{
|
||||||
|
uint32 mode;
|
||||||
|
if (ioctl(gInfo->device, VESA_GET_DPMS_MODE, &mode, sizeof(mode)) != 0)
|
||||||
return B_DPMS_ON;
|
return B_DPMS_ON;
|
||||||
|
|
||||||
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
vesa_set_dpms_mode(uint32 dpms_flags)
|
vesa_set_dpms_mode(uint32 mode)
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
if (ioctl(gInfo->device, VESA_SET_DPMS_MODE, &mode, sizeof(mode)) != 0)
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2008, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <create_display_modes.h>
|
#include <create_display_modes.h>
|
||||||
@@ -138,7 +139,7 @@ vesa_set_display_mode(display_mode *_mode)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
vesa_mode* modes = gInfo->vesa_modes;
|
vesa_mode* modes = gInfo->vesa_modes;
|
||||||
for (unsigned int i = gInfo->shared_info->vesa_mode_count; i-- > 0;) {
|
for (uint32 i = gInfo->shared_info->vesa_mode_count; i-- > 0;) {
|
||||||
// search mode in VESA mode list
|
// search mode in VESA mode list
|
||||||
// TODO: list is ordered, we could use binary search
|
// TODO: list is ordered, we could use binary search
|
||||||
if (modes[i].width == mode.virtual_width
|
if (modes[i].width == mode.virtual_width
|
||||||
@@ -195,16 +196,17 @@ vesa_get_pixel_clock_limits(display_mode *mode, uint32 *low, uint32 *high)
|
|||||||
{
|
{
|
||||||
TRACE(("vesa_get_pixel_clock_limits()\n"));
|
TRACE(("vesa_get_pixel_clock_limits()\n"));
|
||||||
|
|
||||||
// ToDo: do some real stuff here (taken from radeon driver)
|
// TODO: do some real stuff here (taken from radeon driver)
|
||||||
uint32 total_pix = (uint32)mode->timing.h_total * (uint32)mode->timing.v_total;
|
uint32 totalPixel = (uint32)mode->timing.h_total
|
||||||
uint32 clock_limit = 2000000;
|
* (uint32)mode->timing.v_total;
|
||||||
|
uint32 clockLimit = 2000000;
|
||||||
|
|
||||||
/* lower limit of about 48Hz vertical refresh */
|
// lower limit of about 48Hz vertical refresh
|
||||||
*low = (total_pix * 48L) / 1000L;
|
*low = totalPixel * 48L / 1000L;
|
||||||
if (*low > clock_limit)
|
if (*low > clockLimit)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
*high = clock_limit;
|
*high = clockLimit;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +220,7 @@ vesa_move_display(uint16 h_display_start, uint16 v_display_start)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
vesa_get_timing_constraints(display_timing_constraints *dtc)
|
vesa_get_timing_constraints(display_timing_constraints* constraints)
|
||||||
{
|
{
|
||||||
TRACE(("vesa_get_timing_constraints()\n"));
|
TRACE(("vesa_get_timing_constraints()\n"));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2008, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -32,41 +32,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* device hooks prototypes */
|
|
||||||
|
|
||||||
static status_t device_open(const char *, uint32, void **);
|
|
||||||
static status_t device_close(void *);
|
|
||||||
static status_t device_free(void *);
|
|
||||||
static status_t device_ioctl(void *, uint32, void *, size_t);
|
|
||||||
static status_t device_read(void *, off_t, void *, size_t *);
|
|
||||||
static status_t device_write(void *, off_t, const void *, size_t *);
|
|
||||||
|
|
||||||
|
|
||||||
device_hooks gDeviceHooks = {
|
|
||||||
device_open,
|
|
||||||
device_close,
|
|
||||||
device_free,
|
|
||||||
device_ioctl,
|
|
||||||
device_read,
|
|
||||||
device_write,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
// the device will be accessed through the following functions (a.k.a. device hooks)
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
device_open(const char* name, uint32 flags, void** _cookie)
|
device_open(const char* name, uint32 flags, void** _cookie)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
// find accessed device
|
// find accessed device
|
||||||
{
|
|
||||||
char* thisName;
|
char* thisName;
|
||||||
|
|
||||||
// search for device name
|
// search for device name
|
||||||
@@ -74,9 +45,8 @@ device_open(const char *name, uint32 flags, void **_cookie)
|
|||||||
if (!strcmp(name, thisName))
|
if (!strcmp(name, thisName))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!thisName)
|
if (thisName == NULL)
|
||||||
return EINVAL;
|
return B_BAD_VALUE;
|
||||||
}
|
|
||||||
|
|
||||||
vesa_info* info = gDeviceInfo[id];
|
vesa_info* info = gDeviceInfo[id];
|
||||||
*_cookie = info;
|
*_cookie = info;
|
||||||
@@ -151,15 +121,41 @@ device_ioctl(void *cookie, uint32 msg, void *buffer, size_t bufferLength)
|
|||||||
|
|
||||||
case VESA_SET_DISPLAY_MODE:
|
case VESA_SET_DISPLAY_MODE:
|
||||||
{
|
{
|
||||||
unsigned int mode;
|
if (bufferLength != sizeof(uint32))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (bufferLength != sizeof(mode)
|
uint32 mode;
|
||||||
|| user_memcpy(&mode, buffer, sizeof(mode)) < B_OK)
|
if (user_memcpy(&mode, buffer, sizeof(uint32)) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
return vesa_set_display_mode(*info, mode);
|
return vesa_set_display_mode(*info, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case VESA_GET_DPMS_MODE:
|
||||||
|
{
|
||||||
|
if (bufferLength != sizeof(uint32))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
uint32 mode;
|
||||||
|
status_t status = vesa_get_dpms_mode(*info, mode);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return user_memcpy(buffer, &mode, sizeof(mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
case VESA_SET_DPMS_MODE:
|
||||||
|
{
|
||||||
|
if (bufferLength != sizeof(uint32))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
uint32 mode;
|
||||||
|
if (user_memcpy(&mode, buffer, sizeof(uint32)) < B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
return vesa_set_dpms_mode(*info, mode);
|
||||||
|
}
|
||||||
|
|
||||||
case VGA_SET_INDEXED_COLORS:
|
case VGA_SET_INDEXED_COLORS:
|
||||||
{
|
{
|
||||||
vga_set_indexed_colors_args args;
|
vga_set_indexed_colors_args args;
|
||||||
@@ -181,7 +177,9 @@ device_ioctl(void *cookie, uint32 msg, void *buffer, size_t bufferLength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
TRACE((DEVICE_NAME ": ioctl() unknown message %ld (length = %lu)\n", msg, bufferLength));
|
TRACE((DEVICE_NAME ": ioctl() unknown message %ld (length = %lu)\n",
|
||||||
|
msg, bufferLength));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_DEV_INVALID_IOCTL;
|
return B_DEV_INVALID_IOCTL;
|
||||||
@@ -197,9 +195,23 @@ device_read(void */*cookie*/, off_t /*pos*/, void */*buffer*/, size_t *_length)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
device_write(void */*cookie*/, off_t /*pos*/, const void */*buffer*/, size_t *_length)
|
device_write(void* /*cookie*/, off_t /*pos*/, const void* /*buffer*/,
|
||||||
|
size_t* _length)
|
||||||
{
|
{
|
||||||
*_length = 0;
|
*_length = 0;
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
device_hooks gDeviceHooks = {
|
||||||
|
device_open,
|
||||||
|
device_close,
|
||||||
|
device_free,
|
||||||
|
device_ioctl,
|
||||||
|
device_read,
|
||||||
|
device_write,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2008, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -44,26 +44,26 @@ get_color_space_for_depth(uint32 depth)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
vbe_get_mode_info(struct vm86_state *vmState, uint16 mode,
|
vbe_get_mode_info(struct vm86_state& vmState, uint16 mode,
|
||||||
struct vbe_mode_info* modeInfo)
|
struct vbe_mode_info* modeInfo)
|
||||||
{
|
{
|
||||||
struct vbe_mode_info* vbeModeInfo = (struct vbe_mode_info*)0x1000;
|
struct vbe_mode_info* vbeModeInfo = (struct vbe_mode_info*)0x1000;
|
||||||
|
|
||||||
memset(vbeModeInfo, 0, sizeof(vbe_mode_info));
|
memset(vbeModeInfo, 0, sizeof(vbe_mode_info));
|
||||||
vmState->regs.eax = 0x4f01;
|
vmState.regs.eax = 0x4f01;
|
||||||
vmState->regs.ecx = mode;
|
vmState.regs.ecx = mode;
|
||||||
vmState->regs.es = 0x1000 >> 4;
|
vmState.regs.es = 0x1000 >> 4;
|
||||||
vmState->regs.edi = 0x0000;
|
vmState.regs.edi = 0x0000;
|
||||||
|
|
||||||
status_t status = vm86_do_int(vmState, 0x10);
|
status_t status = vm86_do_int(&vmState, 0x10);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): vm86 failed\n", mode);
|
dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): vm86 failed\n", mode);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vmState->regs.eax & 0xffff) != 0x4f) {
|
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
||||||
dprintf(DEVICE_NAME ": vbe_get_mode_info(): BIOS returned 0x%04lx\n",
|
dprintf(DEVICE_NAME ": vbe_get_mode_info(): BIOS returned 0x%04lx\n",
|
||||||
vmState->regs.eax & 0xffff);
|
vmState.regs.eax & 0xffff);
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,20 +73,20 @@ vbe_get_mode_info(struct vm86_state *vmState, uint16 mode,
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
vbe_set_mode(struct vm86_state *vmState, uint16 mode)
|
vbe_set_mode(struct vm86_state& vmState, uint16 mode)
|
||||||
{
|
{
|
||||||
vmState->regs.eax = 0x4f02;
|
vmState.regs.eax = 0x4f02;
|
||||||
vmState->regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER;
|
vmState.regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER;
|
||||||
|
|
||||||
status_t status = vm86_do_int(vmState, 0x10);
|
status_t status = vm86_do_int(&vmState, 0x10);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME ": vbe_set_mode(%u): vm86 failed\n", mode);
|
dprintf(DEVICE_NAME ": vbe_set_mode(%u): vm86 failed\n", mode);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vmState->regs.eax & 0xffff) != 0x4f) {
|
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
||||||
dprintf(DEVICE_NAME ": vbe_set_mode(): BIOS returned 0x%04lx\n",
|
dprintf(DEVICE_NAME ": vbe_set_mode(): BIOS returned 0x%04lx\n",
|
||||||
vmState->regs.eax & 0xffff);
|
vmState.regs.eax & 0xffff);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +94,64 @@ vbe_set_mode(struct vm86_state *vmState, uint16 mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32
|
||||||
|
vbe_to_system_dpms(uint8 vbeMode)
|
||||||
|
{
|
||||||
|
uint32 mode = 0;
|
||||||
|
if ((vbeMode & (DPMS_OFF | DPMS_REDUCED_ON)) != 0)
|
||||||
|
mode |= B_DPMS_OFF;
|
||||||
|
if ((vbeMode & DPMS_STANDBY) != 0)
|
||||||
|
mode |= B_DPMS_STAND_BY;
|
||||||
|
if ((vbeMode & DPMS_SUSPEND) != 0)
|
||||||
|
mode |= B_DPMS_SUSPEND;
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
vbe_get_dpms_capabilities(uint32& vbeMode, uint32& mode)
|
||||||
|
{
|
||||||
|
// we always return a valid mode
|
||||||
|
vbeMode = 0;
|
||||||
|
mode = B_DPMS_ON;
|
||||||
|
|
||||||
|
// Prepare vm86 mode environment
|
||||||
|
struct vm86_state vmState;
|
||||||
|
status_t status = vm86_prepare(&vmState, 0x20000);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf(DEVICE_NAME": vbe_get_dpms_capabilities(): vm86_prepare "
|
||||||
|
"failed: %s\n", strerror(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
vmState.regs.eax = 0x4f10;
|
||||||
|
vmState.regs.ebx = 0;
|
||||||
|
vmState.regs.esi = 0;
|
||||||
|
vmState.regs.edi = 0;
|
||||||
|
|
||||||
|
status = vm86_do_int(&vmState, 0x10);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): vm86 failed\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
||||||
|
dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS returned "
|
||||||
|
"0x%04lx\n", vmState.regs.eax & 0xffff);
|
||||||
|
status = B_ERROR;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
vbeMode = vmState.regs.ebx >> 8;
|
||||||
|
mode = vbe_to_system_dpms(vbeMode);
|
||||||
|
|
||||||
|
out:
|
||||||
|
vm86_cleanup(&vmState);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -147,9 +205,11 @@ vesa_init(vesa_info &info)
|
|||||||
memcpy(&sharedInfo.edid_info, edidInfo, sizeof(edid1_info));
|
memcpy(&sharedInfo.edid_info, edidInfo, sizeof(edid1_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vbe_get_dpms_capabilities(info.vbe_dpms_capabilities,
|
||||||
|
sharedInfo.dpms_capabilities);
|
||||||
|
|
||||||
physical_entry mapping;
|
physical_entry mapping;
|
||||||
get_memory_map((void *)sharedInfo.frame_buffer, B_PAGE_SIZE,
|
get_memory_map((void*)sharedInfo.frame_buffer, B_PAGE_SIZE, &mapping, 1);
|
||||||
&mapping, 1);
|
|
||||||
sharedInfo.physical_frame_buffer = (uint8*)mapping.address;
|
sharedInfo.physical_frame_buffer = (uint8*)mapping.address;
|
||||||
|
|
||||||
dprintf(DEVICE_NAME ": vesa_init() completed successfully!\n");
|
dprintf(DEVICE_NAME ": vesa_init() completed successfully!\n");
|
||||||
@@ -168,7 +228,7 @@ vesa_uninit(vesa_info &info)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
vesa_set_display_mode(vesa_info &info, unsigned int mode)
|
vesa_set_display_mode(vesa_info& info, uint32 mode)
|
||||||
{
|
{
|
||||||
if (mode >= info.shared_info->vesa_mode_count)
|
if (mode >= info.shared_info->vesa_mode_count)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
@@ -181,41 +241,40 @@ vesa_set_display_mode(vesa_info &info, unsigned int mode)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
area_id newFBArea;
|
area_id frameBufferArea;
|
||||||
frame_buffer_boot_info* bufferInfo;
|
frame_buffer_boot_info* bufferInfo;
|
||||||
struct vbe_mode_info modeInfo;
|
struct vbe_mode_info modeInfo;
|
||||||
|
|
||||||
// Get mode information
|
// Get mode information
|
||||||
status = vbe_get_mode_info(&vmState, info.modes[mode].mode, &modeInfo);
|
status = vbe_get_mode_info(vmState, info.modes[mode].mode, &modeInfo);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot get mode info\n");
|
dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot get mode info\n");
|
||||||
goto error;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set mode
|
// Set mode
|
||||||
status = vbe_set_mode(&vmState, info.modes[mode].mode);
|
status = vbe_set_mode(vmState, info.modes[mode].mode);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot set mode\n");
|
dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot set mode\n");
|
||||||
goto error;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map new frame buffer
|
// Map new frame buffer
|
||||||
void* frameBuffer;
|
void* frameBuffer;
|
||||||
newFBArea = map_physical_memory("vesa_fb",
|
frameBufferArea = map_physical_memory("vesa_fb",
|
||||||
(void *)modeInfo.physical_base,
|
(void*)modeInfo.physical_base, modeInfo.bytes_per_row * modeInfo.height,
|
||||||
modeInfo.bytes_per_row * modeInfo.height, B_ANY_KERNEL_ADDRESS,
|
B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA, &frameBuffer);
|
||||||
B_READ_AREA | B_WRITE_AREA, &frameBuffer);
|
if (frameBufferArea < B_OK) {
|
||||||
if (newFBArea < B_OK) {
|
status = (status_t)frameBufferArea;
|
||||||
status = (status_t)newFBArea;
|
goto out;
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
delete_area(info.shared_info->frame_buffer_area);
|
delete_area(info.shared_info->frame_buffer_area);
|
||||||
|
|
||||||
// Turn on write combining for the area
|
// Turn on write combining for the area
|
||||||
vm_set_area_memory_type(newFBArea, modeInfo.physical_base, B_MTR_WC);
|
vm_set_area_memory_type(frameBufferArea, modeInfo.physical_base, B_MTR_WC);
|
||||||
|
|
||||||
// Update shared frame buffer information
|
// Update shared frame buffer information
|
||||||
info.shared_info->frame_buffer_area = newFBArea;
|
info.shared_info->frame_buffer_area = frameBufferArea;
|
||||||
info.shared_info->frame_buffer = (uint8*)frameBuffer;
|
info.shared_info->frame_buffer = (uint8*)frameBuffer;
|
||||||
info.shared_info->physical_frame_buffer = (uint8*)modeInfo.physical_base;
|
info.shared_info->physical_frame_buffer = (uint8*)modeInfo.physical_base;
|
||||||
info.shared_info->bytes_per_row = modeInfo.bytes_per_row;
|
info.shared_info->bytes_per_row = modeInfo.bytes_per_row;
|
||||||
@@ -227,15 +286,106 @@ vesa_set_display_mode(vesa_info &info, unsigned int mode)
|
|||||||
// Update boot item as it's used in vesa_init()
|
// Update boot item as it's used in vesa_init()
|
||||||
bufferInfo
|
bufferInfo
|
||||||
= (frame_buffer_boot_info*)get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL);
|
= (frame_buffer_boot_info*)get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL);
|
||||||
bufferInfo->area = newFBArea;
|
bufferInfo->area = frameBufferArea;
|
||||||
bufferInfo->frame_buffer = (addr_t)frameBuffer;
|
bufferInfo->frame_buffer = (addr_t)frameBuffer;
|
||||||
bufferInfo->width = modeInfo.width;
|
bufferInfo->width = modeInfo.width;
|
||||||
bufferInfo->height = modeInfo.height;
|
bufferInfo->height = modeInfo.height;
|
||||||
bufferInfo->depth = modeInfo.bits_per_pixel;
|
bufferInfo->depth = modeInfo.bits_per_pixel;
|
||||||
bufferInfo->bytes_per_row = modeInfo.bytes_per_row;
|
bufferInfo->bytes_per_row = modeInfo.bytes_per_row;
|
||||||
|
|
||||||
error:
|
out:
|
||||||
vm86_cleanup(&vmState);
|
vm86_cleanup(&vmState);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
vesa_get_dpms_mode(vesa_info& info, uint32& mode)
|
||||||
|
{
|
||||||
|
mode = B_DPMS_ON;
|
||||||
|
// we always return a valid mode
|
||||||
|
|
||||||
|
// Prepare vm86 mode environment
|
||||||
|
struct vm86_state vmState;
|
||||||
|
status_t status = vm86_prepare(&vmState, 0x20000);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf(DEVICE_NAME": vesa_get_dpms_mode(): vm86_prepare failed: %s\n",
|
||||||
|
strerror(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
vmState.regs.eax = 0x4f10;
|
||||||
|
vmState.regs.ebx = 2;
|
||||||
|
vmState.regs.esi = 0;
|
||||||
|
vmState.regs.edi = 0;
|
||||||
|
|
||||||
|
status = vm86_do_int(&vmState, 0x10);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): vm86 failed: %s\n",
|
||||||
|
strerror(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
||||||
|
dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): BIOS returned 0x%04lx\n",
|
||||||
|
vmState.regs.eax & 0xffff);
|
||||||
|
status = B_ERROR;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = vbe_to_system_dpms(vmState.regs.ebx >> 8);
|
||||||
|
|
||||||
|
out:
|
||||||
|
vm86_cleanup(&vmState);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
vesa_set_dpms_mode(vesa_info& info, uint32 mode)
|
||||||
|
{
|
||||||
|
// Only let supported modes through
|
||||||
|
mode &= info.shared_info->dpms_capabilities;
|
||||||
|
|
||||||
|
uint8 vbeMode = 0;
|
||||||
|
if ((mode & B_DPMS_OFF) != 0)
|
||||||
|
vbeMode |= DPMS_OFF | DPMS_REDUCED_ON;
|
||||||
|
if ((mode & B_DPMS_STAND_BY) != 0)
|
||||||
|
vbeMode |= DPMS_STANDBY;
|
||||||
|
if ((mode & B_DPMS_SUSPEND) != 0)
|
||||||
|
vbeMode |= DPMS_SUSPEND;
|
||||||
|
|
||||||
|
vbeMode &= info.vbe_dpms_capabilities;
|
||||||
|
|
||||||
|
// Prepare vm86 mode environment
|
||||||
|
struct vm86_state vmState;
|
||||||
|
status_t status = vm86_prepare(&vmState, 0x20000);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf(DEVICE_NAME": vesa_set_dpms_mode(): vm86_prepare failed: %s\n",
|
||||||
|
strerror(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
vmState.regs.eax = 0x4f10;
|
||||||
|
vmState.regs.ebx = (vbeMode << 8) | 1;
|
||||||
|
vmState.regs.esi = 0;
|
||||||
|
vmState.regs.edi = 0;
|
||||||
|
|
||||||
|
status = vm86_do_int(&vmState, 0x10);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): vm86 failed: %s\n",
|
||||||
|
strerror(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
||||||
|
dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): BIOS returned 0x%04lx\n",
|
||||||
|
vmState.regs.eax & 0xffff);
|
||||||
|
status = B_ERROR;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
vm86_cleanup(&vmState);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2008, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef VESA_PRIVATE_H
|
#ifndef VESA_PRIVATE_H
|
||||||
@@ -26,10 +26,13 @@ struct vesa_info {
|
|||||||
struct vesa_shared_info* shared_info;
|
struct vesa_shared_info* shared_info;
|
||||||
area_id shared_area;
|
area_id shared_area;
|
||||||
vesa_mode* modes;
|
vesa_mode* modes;
|
||||||
|
uint32 vbe_dpms_capabilities;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern status_t vesa_init(vesa_info& info);
|
extern status_t vesa_init(vesa_info& info);
|
||||||
extern void vesa_uninit(vesa_info& info);
|
extern void vesa_uninit(vesa_info& info);
|
||||||
extern status_t vesa_set_display_mode(vesa_info &info, unsigned int mode);
|
extern status_t vesa_set_display_mode(vesa_info& info, uint32 mode);
|
||||||
|
extern status_t vesa_get_dpms_mode(vesa_info& info, uint32& mode);
|
||||||
|
extern status_t vesa_set_dpms_mode(vesa_info& info, uint32 mode);
|
||||||
|
|
||||||
#endif /* VESA_PRIVATE_H */
|
#endif /* VESA_PRIVATE_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user