added 2 changesets to branch 'refs/remotes/xyzzy-github/x86_64' old head: a9ee7a51329c8a6c6e205e91907c2a753bb62495 new head: 9f90e8a9649d7b63607e2d90f94717bed2b072b5 ---------------------------------------------------------------------------- b28f734: Remove line copied from old vm86 code that shouldn't be there. 9f90e8a: Updated drivers to use BIOS module instead of vm86. [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 6 files changed, 315 insertions(+), 234 deletions(-) .../kernel/drivers/graphics/3dfx/driver.cpp | 1 - src/add-ons/kernel/drivers/graphics/ati/driver.cpp | 106 +++--- .../kernel/drivers/graphics/intel_810/driver.cpp | 74 ++-- src/add-ons/kernel/drivers/graphics/s3/driver.cpp | 77 ++-- src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp | 290 +++++++++------- src/add-ons/kernel/generic/bios/bios.cpp | 1 - ############################################################################ Commit: b28f734b1cd385194683bccf9f5c46a16a7644e7 Author: Alex Smith <alex@xxxxxxxxxxxxxxxx> Date: Fri Aug 3 15:18:49 2012 UTC Remove line copied from old vm86 code that shouldn't be there. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/generic/bios/bios.cpp b/src/add-ons/kernel/generic/bios/bios.cpp index 8ae2745..a887896 100644 --- a/src/add-ons/kernel/generic/bios/bios.cpp +++ b/src/add-ons/kernel/generic/bios/bios.cpp @@ -235,7 +235,6 @@ bios_prepare(bios_state** _state) (void*)state->mapped_address, kTotalSize); return status; } - *((uint32 *)state->mapped_address) = 0xdeadbeef; // Map the extended BIOS data area and VGA memory. void* address = (void*)(state->mapped_address + kEBDABase); ############################################################################ Commit: 9f90e8a9649d7b63607e2d90f94717bed2b072b5 Author: Alex Smith <alex@xxxxxxxxxxxxxxxx> Date: Fri Aug 3 15:28:20 2012 UTC Updated drivers to use BIOS module instead of vm86. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/drivers/graphics/3dfx/driver.cpp b/src/add-ons/kernel/drivers/graphics/3dfx/driver.cpp index 4bf33b7..70ca722 100644 --- a/src/add-ons/kernel/drivers/graphics/3dfx/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/3dfx/driver.cpp @@ -14,7 +14,6 @@ #include <graphic_driver.h> #ifdef __HAIKU__ #include <boot_item.h> -#include <arch/x86/vm86.h> #endif // __HAIKU__ #include "DriverInterface.h" diff --git a/src/add-ons/kernel/drivers/graphics/ati/driver.cpp b/src/add-ons/kernel/drivers/graphics/ati/driver.cpp index b8eca53..cc302c6 100644 --- a/src/add-ons/kernel/drivers/graphics/ati/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/ati/driver.cpp @@ -8,12 +8,12 @@ #include <KernelExport.h> #include <PCI.h> +#include <drivers/bios.h> #include <malloc.h> #include <stdio.h> #include <string.h> #include <graphic_driver.h> #include <boot_item.h> -#include <arch/x86/vm86.h> #include "DriverInterface.h" @@ -249,52 +249,60 @@ GetEdidFromBIOS(edid1_raw& edidRaw) #define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) #define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) - vm86_state vmState; + bios_module_info* biosModule; + status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule); + if (status != B_OK) { + TRACE("GetEdidFromBIOS(): failed to get BIOS module: 0x%" B_PRIx32 "\n", + status); + return status; + } - status_t status = vm86_prepare(&vmState, 0x2000); + bios_state* state; + status = biosModule->prepare(&state); if (status != B_OK) { - TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: 0x%lx\n", + TRACE("GetEdidFromBIOS(): bios_prepare() failed: 0x%" B_PRIx32 "\n", status); + put_module(B_BIOS_MODULE_NAME); return status; } - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 0; // 0 = report DDC service - vmState.regs.ecx = 0; - vmState.regs.es = 0; - vmState.regs.edi = 0; + bios_regs regs = {}; + regs.eax = 0x4f15; + regs.ebx = 0; // 0 = report DDC service + regs.ecx = 0; + regs.es = 0; + regs.edi = 0; - status = vm86_do_int(&vmState, 0x10); + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { // AH contains the error code, and AL determines whether or not the // function is supported. - if (vmState.regs.eax != 0x4f) + if (regs.eax != 0x4f) status = B_NOT_SUPPORTED; // Test if DDC is supported by the monitor. - if ((vmState.regs.ebx & 3) == 0) + if ((regs.ebx & 3) == 0) status = B_NOT_SUPPORTED; } if (status == B_OK) { - // According to the author of the vm86 functions, the address of any - // object to receive data must be >= 0x1000 and within the ram size - // specified in the second argument of the vm86_prepare() call above. - // Thus, the address of the struct to receive the EDID info is set to - // 0x1000. - - edid1_raw* edid = (edid1_raw*)0x1000; - - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 1; // 1 = read EDID - vmState.regs.ecx = 0; - vmState.regs.edx = 0; - vmState.regs.es = ADDRESS_SEGMENT(edid); - vmState.regs.edi = ADDRESS_OFFSET(edid); - - status = vm86_do_int(&vmState, 0x10); + edid1_raw* edid = (edid1_raw*)biosModule->allocate_mem(state, + sizeof(edid1_raw)); + if (edid == NULL) { + status = B_NO_MEMORY; + goto out; + } + + regs.eax = 0x4f15; + regs.ebx = 1; // 1 = read EDID + regs.ecx = 0; + regs.edx = 0; + regs.es = ADDRESS_SEGMENT(edid); + regs.edi = ADDRESS_OFFSET(edid); + + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { - if (vmState.regs.eax != 0x4f) { + if (regs.eax != 0x4f) { status = B_NOT_SUPPORTED; } else { // Copy the EDID info to the caller's location, and compute the @@ -322,8 +330,9 @@ GetEdidFromBIOS(edid1_raw& edidRaw) } } - vm86_cleanup(&vmState); - +out: + biosModule->finish(state); + put_module(B_BIOS_MODULE_NAME); return status; } @@ -336,31 +345,40 @@ SetVesaDisplayMode(uint16 mode) #define SET_MODE_MASK 0x01ff #define SET_MODE_LINEAR_BUFFER (1 << 14) - vm86_state vmState; + bios_module_info* biosModule; + status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule); + if (status != B_OK) { + TRACE("SetVesaDisplayMode(0x%x): failed to get BIOS module: 0x%" B_PRIx32 + "\n", mode, status); + return status; + } - status_t status = vm86_prepare(&vmState, 0x2000); + bios_state* state; + status = biosModule->prepare(&state); if (status != B_OK) { - TRACE("SetVesaDisplayMode(); vm86_prepare() failed, status: 0x%lx\n", - status); + TRACE("SetVesaDisplayMode(0x%x): bios_prepare() failed: 0x%" B_PRIx32 + "\n", mode, status); + put_module(B_BIOS_MODULE_NAME); return status; } - vmState.regs.eax = 0x4f02; - vmState.regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; + bios_regs regs = {}; + regs.eax = 0x4f02; + regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; - status = vm86_do_int(&vmState, 0x10); + status = biosModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - TRACE("SetVesaDisplayMode(0x%x): vm86_do_int failed\n", mode); + TRACE("SetVesaDisplayMode(0x%x): BIOS interrupt failed\n", mode); } - if (status == B_OK && (vmState.regs.eax & 0xffff) != 0x4f) { - TRACE("SetVesaDisplayMode(0x%x): BIOS returned 0x%04lx\n", mode, - vmState.regs.eax & 0xffff); + if (status == B_OK && (regs.eax & 0xffff) != 0x4f) { + TRACE("SetVesaDisplayMode(0x%x): BIOS returned 0x%04" B_PRIx32 "\n", + mode, regs.eax & 0xffff); status = B_ERROR; } - vm86_cleanup(&vmState); - + biosModule->finish(state); + put_module(B_BIOS_MODULE_NAME); return status; } diff --git a/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp index eddd81d..edb7b9e 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_810/driver.cpp @@ -10,12 +10,12 @@ #include <AGP.h> #include <KernelExport.h> #include <PCI.h> +#include <drivers/bios.h> #include <malloc.h> #include <stdio.h> #include <string.h> #include <graphic_driver.h> #include <boot_item.h> -#include <arch/x86/vm86.h> #include "DriverInterface.h" @@ -148,52 +148,60 @@ GetEdidFromBIOS(edid1_raw& edidRaw) #define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) #define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) - vm86_state vmState; + bios_module_info* biosModule; + status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule); + if (status != B_OK) { + TRACE("GetEdidFromBIOS(): failed to get BIOS module: 0x%" B_PRIx32 "\n", + status); + return status; + } - status_t status = vm86_prepare(&vmState, 0x2000); + bios_state* state; + status = biosModule->prepare(&state); if (status != B_OK) { - TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: 0x%lx\n", + TRACE("GetEdidFromBIOS(): bios_prepare() failed: 0x%" B_PRIx32 "\n", status); + put_module(B_BIOS_MODULE_NAME); return status; } - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 0; // 0 = report DDC service - vmState.regs.ecx = 0; - vmState.regs.es = 0; - vmState.regs.edi = 0; + bios_regs regs = {}; + regs.eax = 0x4f15; + regs.ebx = 0; // 0 = report DDC service + regs.ecx = 0; + regs.es = 0; + regs.edi = 0; - status = vm86_do_int(&vmState, 0x10); + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { - // AH contains the error code, and AL determines wether or not the + // AH contains the error code, and AL determines whether or not the // function is supported. - if (vmState.regs.eax != 0x4f) + if (regs.eax != 0x4f) status = B_NOT_SUPPORTED; // Test if DDC is supported by the monitor. - if ((vmState.regs.ebx & 3) == 0) + if ((regs.ebx & 3) == 0) status = B_NOT_SUPPORTED; } if (status == B_OK) { - // According to the author of the vm86 functions, the address of any - // object to receive data must be >= 0x1000 and within the ram size - // specified in the second argument of the vm86_prepare() call above. - // Thus, the address of the struct to receive the EDID info is set to - // 0x1000. - - edid1_raw* edid = (edid1_raw*)0x1000; - - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 1; // 1 = read EDID - vmState.regs.ecx = 0; - vmState.regs.edx = 0; - vmState.regs.es = ADDRESS_SEGMENT(edid); - vmState.regs.edi = ADDRESS_OFFSET(edid); - - status = vm86_do_int(&vmState, 0x10); + edid1_raw* edid = (edid1_raw*)biosModule->allocate_mem(state, + sizeof(edid1_raw)); + if (edid == NULL) { + status = B_NO_MEMORY; + goto out; + } + + regs.eax = 0x4f15; + regs.ebx = 1; // 1 = read EDID + regs.ecx = 0; + regs.edx = 0; + regs.es = ADDRESS_SEGMENT(edid); + regs.edi = ADDRESS_OFFSET(edid); + + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { - if (vmState.regs.eax != 0x4f) { + if (regs.eax != 0x4f) { status = B_NOT_SUPPORTED; } else { // Copy the EDID info to the caller's location, and compute the @@ -221,9 +229,11 @@ GetEdidFromBIOS(edid1_raw& edidRaw) } } - vm86_cleanup(&vmState); +out: + biosModule->finish(state); + put_module(B_BIOS_MODULE_NAME); - TRACE("GetEdidFromBIOS() status: 0x%lx\n", status); + TRACE("GetEdidFromBIOS() status: 0x%" B_PRIx32 "\n", status); return status; } diff --git a/src/add-ons/kernel/drivers/graphics/s3/driver.cpp b/src/add-ons/kernel/drivers/graphics/s3/driver.cpp index d57d894..d737fde 100644 --- a/src/add-ons/kernel/drivers/graphics/s3/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/s3/driver.cpp @@ -8,13 +8,13 @@ #include <KernelExport.h> #include <PCI.h> +#ifdef __HAIKU__ +#include <drivers/bios.h> +#endif // __HAIKU__ #include <malloc.h> #include <stdio.h> #include <string.h> #include <graphic_driver.h> -#ifdef __HAIKU__ -#include <arch/x86/vm86.h> -#endif // __HAIKU__ #include "DriverInterface.h" @@ -493,51 +493,60 @@ GetEdidFromBIOS(edid1_raw& edidRaw) #define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) #define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) - vm86_state vmState; + bios_module_info* biosModule; + status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule); + if (status != B_OK) { + TRACE("GetEdidFromBIOS(): failed to get BIOS module: 0x%" B_PRIx32 "\n", + status); + return status; + } - status_t status = vm86_prepare(&vmState, 0x2000); + bios_state* state; + status = biosModule->prepare(&state); if (status != B_OK) { - TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: %lx\n", status); + TRACE("GetEdidFromBIOS(): bios_prepare() failed: 0x%" B_PRIx32 "\n", + status); + put_module(B_BIOS_MODULE_NAME); return status; } - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 0; // 0 = report DDC service - vmState.regs.ecx = 0; - vmState.regs.es = 0; - vmState.regs.edi = 0; + bios_regs regs = {}; + regs.eax = 0x4f15; + regs.ebx = 0; // 0 = report DDC service + regs.ecx = 0; + regs.es = 0; + regs.edi = 0; - status = vm86_do_int(&vmState, 0x10); + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { // AH contains the error code, and AL determines whether or not the // function is supported. - if (vmState.regs.eax != 0x4f) + if (regs.eax != 0x4f) status = B_NOT_SUPPORTED; // Test if DDC is supported by the monitor. - if ((vmState.regs.ebx & 3) == 0) + if ((regs.ebx & 3) == 0) status = B_NOT_SUPPORTED; } if (status == B_OK) { - // According to the author of the vm86 functions, the address of any - // object to receive data must be >= 0x1000 and within the ram size - // specified in the second argument of the vm86_prepare() call above. - // Thus, the address of the struct to receive the EDID info is set to - // 0x1000. - - edid1_raw* edid = (edid1_raw*)0x1000; - - vmState.regs.eax = 0x4f15; - vmState.regs.ebx = 1; // 1 = read EDID - vmState.regs.ecx = 0; - vmState.regs.edx = 0; - vmState.regs.es = ADDRESS_SEGMENT(edid); - vmState.regs.edi = ADDRESS_OFFSET(edid); - - status = vm86_do_int(&vmState, 0x10); + edid1_raw* edid = (edid1_raw*)biosModule->allocate_mem(state, + sizeof(edid1_raw)); + if (edid == NULL) { + status = B_NO_MEMORY; + goto out; + } + + regs.eax = 0x4f15; + regs.ebx = 1; // 1 = read EDID + regs.ecx = 0; + regs.edx = 0; + regs.es = ADDRESS_SEGMENT(edid); + regs.edi = ADDRESS_OFFSET(edid); + + status = biosModule->interrupt(state, 0x10, ®s); if (status == B_OK) { - if (vmState.regs.eax != 0x4f) { + if (regs.eax != 0x4f) { status = B_NOT_SUPPORTED; } else { // Copy the EDID info to the caller's location, and compute the @@ -565,9 +574,11 @@ GetEdidFromBIOS(edid1_raw& edidRaw) } } - vm86_cleanup(&vmState); +out: + biosModule->finish(state); + put_module(B_BIOS_MODULE_NAME); - TRACE("GetEdidFromBIOS() status: 0x%lx\n", status); + TRACE("GetEdidFromBIOS() status: 0x%" B_PRIx32 "\n", status); return status; } diff --git a/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp b/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp index 6e31f6d..0a3dd14 100644 --- a/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp +++ b/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp @@ -9,10 +9,11 @@ #include <string.h> +#include <drivers/bios.h> + #include <boot_item.h> #include <frame_buffer_console.h> #include <util/kernel_cpp.h> -#include <arch/x86/vm86.h> #include <vm/vm.h> #include "driver.h" @@ -20,6 +21,43 @@ #include "vesa_info.h" +static bios_module_info* sBIOSModule; + + +/*! Loads the BIOS module and sets up a state for it. The BIOS module is only + loaded when we need it, as it is quite a large module. +*/ +static status_t +vbe_call_prepare(bios_state** state) +{ + status_t status; + + status = get_module(B_BIOS_MODULE_NAME, (module_info**)&sBIOSModule); + if (status != B_OK) { + dprintf(DEVICE_NAME ": failed to get BIOS module: %s\n", + strerror(status)); + return status; + } + + status = sBIOSModule->prepare(state); + if (status != B_OK) { + dprintf(DEVICE_NAME ": failed to prepare BIOS state: %s\n", + strerror(status)); + put_module(B_BIOS_MODULE_NAME); + } + + return status; +} + + +static void +vbe_call_finish(bios_state* state) +{ + sBIOSModule->finish(state); + put_module(B_BIOS_MODULE_NAME); +} + + static status_t find_graphics_card(addr_t frameBuffer, addr_t& base, size_t& size) { @@ -80,26 +118,31 @@ get_color_space_for_depth(uint32 depth) static status_t -vbe_get_mode_info(struct vm86_state& vmState, uint16 mode, - struct vbe_mode_info* modeInfo) +vbe_get_mode_info(bios_state* state, uint16 mode, struct vbe_mode_info* modeInfo) { - struct vbe_mode_info* vbeModeInfo = (struct vbe_mode_info*)0x1000; - + void* vbeModeInfo = sBIOSModule->allocate_mem(state, + sizeof(struct vbe_mode_info)); + if (vbeModeInfo == NULL) + return B_NO_MEMORY; memset(vbeModeInfo, 0, sizeof(vbe_mode_info)); - vmState.regs.eax = 0x4f01; - vmState.regs.ecx = mode; - vmState.regs.es = 0x1000 >> 4; - vmState.regs.edi = 0x0000; - status_t status = vm86_do_int(&vmState, 0x10); + uint32 physicalAddress = sBIOSModule->physical_address(state, vbeModeInfo); + bios_regs regs = {}; + regs.eax = 0x4f01; + regs.ecx = mode; + regs.es = physicalAddress >> 4; + regs.edi = physicalAddress - (regs.es << 4); + + status_t status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): vm86 failed\n", mode); + dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): BIOS failed: %s\n", mode, + strerror(status)); return status; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { - dprintf(DEVICE_NAME ": vbe_get_mode_info(): BIOS returned 0x%04lx\n", - vmState.regs.eax & 0xffff); + if ((regs.eax & 0xffff) != 0x4f) { + dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): BIOS returned " + "0x%04" B_PRIx32 "\n", mode, regs.eax & 0xffff); return B_ENTRY_NOT_FOUND; } @@ -109,20 +152,22 @@ vbe_get_mode_info(struct vm86_state& vmState, uint16 mode, static status_t -vbe_set_mode(struct vm86_state& vmState, uint16 mode) +vbe_set_mode(bios_state* state, uint16 mode) { - vmState.regs.eax = 0x4f02; - vmState.regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; + bios_regs regs = {}; + regs.eax = 0x4f02; + regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; - status_t status = vm86_do_int(&vmState, 0x10); + status_t status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vbe_set_mode(%u): vm86 failed\n", mode); + dprintf(DEVICE_NAME ": vbe_set_mode(%u): BIOS failed: %s\n", mode, + strerror(status)); return status; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { - dprintf(DEVICE_NAME ": vbe_set_mode(): BIOS returned 0x%04lx\n", - vmState.regs.eax & 0xffff); + if ((regs.eax & 0xffff) != 0x4f) { + dprintf(DEVICE_NAME ": vbe_set_mode(%u): BIOS returned 0x%04" B_PRIx32 + "\n", mode, regs.eax & 0xffff); return B_ERROR; } @@ -152,64 +197,64 @@ vbe_get_dpms_capabilities(uint32& vbeMode, uint32& 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)); + // Prepare BIOS environment + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; - } - vmState.regs.eax = 0x4f10; - vmState.regs.ebx = 0; - vmState.regs.esi = 0; - vmState.regs.edi = 0; + bios_regs regs = {}; + regs.eax = 0x4f10; + regs.ebx = 0; + regs.esi = 0; + regs.edi = 0; - status = vm86_do_int(&vmState, 0x10); + status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): vm86 failed\n"); + dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS failed: %s\n", + strerror(status)); goto out; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { + if ((regs.eax & 0xffff) != 0x4f) { dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS returned " - "0x%04lx\n", vmState.regs.eax & 0xffff); + "0x%04" B_PRIx32 "\n", regs.eax & 0xffff); status = B_ERROR; goto out; } - vbeMode = vmState.regs.ebx >> 8; + vbeMode = regs.ebx >> 8; mode = vbe_to_system_dpms(vbeMode); out: - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } static status_t -vbe_set_bits_per_gun(vm86_state& vmState, vesa_info& info, uint8 bits) +vbe_set_bits_per_gun(bios_state* state, vesa_info& info, uint8 bits) { info.bits_per_gun = 6; - vmState.regs.eax = 0x4f08; - vmState.regs.ebx = (bits << 8) | 1; + bios_regs regs = {}; + regs.eax = 0x4f08; + regs.ebx = (bits << 8) | 1; - status_t status = vm86_do_int(&vmState, 0x10); + status_t status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): vm86 failed: %s\n", + dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): BIOS failed: %s\n", strerror(status)); return status; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { - dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): BIOS returned 0x%04lx\n", - vmState.regs.eax & 0xffff); + if ((regs.eax & 0xffff) != 0x4f) { + dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): BIOS returned " + "0x%04" B_PRIx32 "\n", regs.eax & 0xffff); return B_ERROR; } - info.bits_per_gun = vmState.regs.ebx >> 8; + info.bits_per_gun = regs.ebx >> 8; return B_OK; } @@ -219,17 +264,14 @@ vbe_set_bits_per_gun(vesa_info& info, uint8 bits) { info.bits_per_gun = 6; - struct vm86_state vmState; - status_t status = vm86_prepare(&vmState, 0x20000); - if (status != B_OK) { - dprintf(DEVICE_NAME": vbe_set_bits_per_gun(): vm86_prepare failed: " - "%s\n", strerror(status)); + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; - } - status = vbe_set_bits_per_gun(vmState, info, bits); + status = vbe_set_bits_per_gun(state, info, bits); - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } @@ -386,31 +428,29 @@ vesa_set_display_mode(vesa_info& info, uint32 mode) if (mode >= info.shared_info->vesa_mode_count) return B_ENTRY_NOT_FOUND; - // Prepare vm86 mode environment - struct vm86_state vmState; - status_t status = vm86_prepare(&vmState, 0x20000); - if (status != B_OK) { - dprintf(DEVICE_NAME": vesa_set_display_mode(): vm86_prepare failed\n"); + // Prepare BIOS environment + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; - } // Get mode information struct vbe_mode_info modeInfo; - status = vbe_get_mode_info(vmState, info.modes[mode].mode, &modeInfo); + status = vbe_get_mode_info(state, info.modes[mode].mode, &modeInfo); if (status != B_OK) { dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot get mode info\n"); goto out; } // Set mode - status = vbe_set_mode(vmState, info.modes[mode].mode); + status = vbe_set_mode(state, info.modes[mode].mode); if (status != B_OK) { dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot set mode\n"); goto out; } if (info.modes[mode].bits_per_pixel <= 8) - vbe_set_bits_per_gun(vmState, info, 8); + vbe_set_bits_per_gun(state, info, 8); // Map new frame buffer if necessary @@ -426,7 +466,7 @@ vesa_set_display_mode(vesa_info& info, uint32 mode) } out: - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } @@ -437,38 +477,36 @@ 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)); + // Prepare BIOS environment + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; - } - vmState.regs.eax = 0x4f10; - vmState.regs.ebx = 2; - vmState.regs.esi = 0; - vmState.regs.edi = 0; + bios_regs regs = {}; + regs.eax = 0x4f10; + regs.ebx = 2; + regs.esi = 0; + regs.edi = 0; - status = vm86_do_int(&vmState, 0x10); + status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): vm86 failed: %s\n", + dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): BIOS 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); + if ((regs.eax & 0xffff) != 0x4f) { + dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): BIOS returned " + "0x%" B_PRIx32 "\n", regs.eax & 0xffff); status = B_ERROR; goto out; } - mode = vbe_to_system_dpms(vmState.regs.ebx >> 8); + mode = vbe_to_system_dpms(regs.ebx >> 8); out: - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } @@ -489,36 +527,34 @@ vesa_set_dpms_mode(vesa_info& info, uint32 mode) 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)); + // Prepare BIOS environment + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; - } - vmState.regs.eax = 0x4f10; - vmState.regs.ebx = (vbeMode << 8) | 1; - vmState.regs.esi = 0; - vmState.regs.edi = 0; + bios_regs regs = {}; + regs.eax = 0x4f10; + regs.ebx = (vbeMode << 8) | 1; + regs.esi = 0; + regs.edi = 0; - status = vm86_do_int(&vmState, 0x10); + status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): vm86 failed: %s\n", + dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): BIOS 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); + if ((regs.eax & 0xffff) != 0x4f) { + dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): BIOS returned " + "0x%04" B_PRIx32 "\n", regs.eax & 0xffff); status = B_ERROR; goto out; } out: - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; } @@ -527,26 +563,33 @@ status_t vesa_set_indexed_colors(vesa_info& info, uint8 first, uint8* colors, uint16 count) { + bios_regs regs = {}; + uint32 shift, physicalAddress; + if (first + count > 256) count = 256 - first; - // Prepare vm86 mode environment - struct vm86_state vmState; - status_t status = vm86_prepare(&vmState, 0x20000); - if (status != B_OK) { - dprintf(DEVICE_NAME": vesa_set_indexed_colors(): vm86_prepare failed: " - "%s\n", strerror(status)); + // Prepare BIOS environment + bios_state* state; + status_t status = vbe_call_prepare(&state); + if (status != B_OK) return status; + + uint8* palette = (uint8*)sBIOSModule->allocate_mem(state, 256 * 4); + if (palette == NULL) { + status = B_NO_MEMORY; + goto out; } - uint8* palette = (uint8*)0x1000; - uint32 shift = 8 - info.bits_per_gun; + shift = 8 - info.bits_per_gun; // convert colors to VESA palette for (int32 i = first; i < count; i++) { uint8 color[3]; - if (user_memcpy(color, &colors[i * 3], 3) < B_OK) - return B_BAD_ADDRESS; + if (user_memcpy(color, &colors[i * 3], 3) < B_OK) { + status = B_BAD_ADDRESS; + goto out; + } // order is BGR- palette[i * 4 + 0] = color[2] >> shift; @@ -556,27 +599,28 @@ vesa_set_indexed_colors(vesa_info& info, uint8 first, uint8* colors, } // set palette - vmState.regs.eax = 0x4f09; - vmState.regs.ebx = 0; - vmState.regs.ecx = count; - vmState.regs.edx = first; - vmState.regs.es = 0x1000 >> 4; - vmState.regs.edi = 0x0000; - - status = vm86_do_int(&vmState, 0x10); + physicalAddress = sBIOSModule->physical_address(state, palette); + regs.eax = 0x4f09; + regs.ebx = 0; + regs.ecx = count; + regs.edx = first; + regs.es = physicalAddress >> 4; + regs.edi = physicalAddress - (regs.es << 4); + + status = sBIOSModule->interrupt(state, 0x10, ®s); if (status != B_OK) { - dprintf(DEVICE_NAME ": vesa_set_indexed_colors(): vm86 failed: %s\n", + dprintf(DEVICE_NAME ": vesa_set_indexed_colors(): BIOS failed: %s\n", strerror(status)); goto out; } - if ((vmState.regs.eax & 0xffff) != 0x4f) { + if ((regs.eax & 0xffff) != 0x4f) { dprintf(DEVICE_NAME ": vesa_set_indexed_colors(): BIOS returned " - "0x%04lx\n", vmState.regs.eax & 0xffff); + "0x%04" B_PRIx32 "\n", regs.eax & 0xffff); status = B_ERROR; } out: - vm86_cleanup(&vmState); + vbe_call_finish(state); return status; }