[haiku-commits] BRANCH xyzzy-github.x86_64 - in src/add-ons/kernel/drivers/graphics: vesa ati intel_810 s3

  • From: xyzzy-github.x86_64 <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 3 Aug 2012 17:49:15 +0200 (CEST)

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, &regs);
        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, &regs);
                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, &regs);
        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, &regs);
        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, &regs);
                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, &regs);
        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, &regs);
                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, &regs);
        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, &regs);
        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, &regs);
        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, &regs);
        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, &regs);
        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, &regs);
        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, &regs);
        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;
 }


Other related posts:

  • » [haiku-commits] BRANCH xyzzy-github.x86_64 - in src/add-ons/kernel/drivers/graphics: vesa ati intel_810 s3 - xyzzy-github . x86_64