summaryrefslogtreecommitdiffstats
path: root/sys/dev/dpms
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2009-09-09 09:50:31 +0000
committerdelphij <delphij@FreeBSD.org>2009-09-09 09:50:31 +0000
commit49000890a8d8e7ddc853db25ceb72d6c8dcc670b (patch)
tree7ca44f508d1d8e6e2d1eaa8e13908bbb1ecaedb5 /sys/dev/dpms
parent9d2fadbd2b45ba60a14fb37bd8671e217ded5386 (diff)
downloadFreeBSD-src-49000890a8d8e7ddc853db25ceb72d6c8dcc670b.zip
FreeBSD-src-49000890a8d8e7ddc853db25ceb72d6c8dcc670b.tar.gz
- Teach vesa(4) and dpms(4) about x86emu. [1]
- Add vesa kernel options for amd64. - Connect libvgl library and splash kernel modules to amd64 build. - Connect manual page dpms(4) to amd64 build. - Remove old vesa/dpms files. Submitted by: paradox <ddkprog yahoo com> [1], swell k at gmail.com (with some minor tweaks)
Diffstat (limited to 'sys/dev/dpms')
-rw-r--r--sys/dev/dpms/dpms.c106
1 files changed, 91 insertions, 15 deletions
diff --git a/sys/dev/dpms/dpms.c b/sys/dev/dpms/dpms.c
index 723a6c0..ac729f9 100644
--- a/sys/dev/dpms/dpms.c
+++ b/sys/dev/dpms/dpms.c
@@ -67,7 +67,11 @@ __FBSDID("$FreeBSD$");
#include <sys/libkern.h>
#include <sys/module.h>
-#include <machine/vm86.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <contrib/x86emu/x86emu.h>
+#include <contrib/x86emu/x86emu_regs.h>
/*
* VESA DPMS States
@@ -90,6 +94,9 @@ struct dpms_softc {
int dpms_initial_state;
};
+static struct x86emu vesa_emu;
+static unsigned char *emumem = NULL;
+
static int dpms_attach(device_t);
static int dpms_detach(device_t);
static int dpms_get_supported_states(int *);
@@ -119,6 +126,59 @@ static driver_t dpms_driver = {
static devclass_t dpms_devclass;
DRIVER_MODULE(dpms, vgapci, dpms_driver, dpms_devclass, NULL, NULL);
+MODULE_DEPEND(dpms, x86emu, 1, 1, 1);
+
+static uint8_t
+vm86_emu_inb(struct x86emu *emu, uint16_t port)
+{
+ if (port == 0xb2) /* APM scratch register */
+ return 0;
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return 0;
+ return inb(port);
+}
+
+static uint16_t
+vm86_emu_inw(struct x86emu *emu, uint16_t port)
+{
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return 0;
+ return inw(port);
+}
+
+static uint32_t
+vm86_emu_inl(struct x86emu *emu, uint16_t port)
+{
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return 0;
+ return inl(port);
+}
+
+static void
+vm86_emu_outb(struct x86emu *emu, uint16_t port, uint8_t val)
+{
+ if (port == 0xb2) /* APM scratch register */
+ return;
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return;
+ outb(port, val);
+}
+
+static void
+vm86_emu_outw(struct x86emu *emu, uint16_t port, uint16_t val)
+{
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return;
+ outw(port, val);
+}
+
+static void
+vm86_emu_outl(struct x86emu *emu, uint16_t port, uint32_t val)
+{
+ if (port >= 0x80 && port < 0x88) /* POST status register */
+ return;
+ outl(port, val);
+}
static void
dpms_identify(driver_t *driver, device_t parent)
@@ -132,6 +192,7 @@ dpms_identify(driver_t *driver, device_t parent)
*/
if (devclass_get_device(dpms_devclass, 0) == NULL)
device_add_child(parent, "dpms", 0);
+
}
static int
@@ -139,6 +200,21 @@ dpms_probe(device_t dev)
{
int error, states;
+ emumem = pmap_mapbios(0x0, 0xc00000);
+
+ memset(&vesa_emu, 0, sizeof(vesa_emu));
+ x86emu_init_default(&vesa_emu);
+
+ vesa_emu.emu_inb = vm86_emu_inb;
+ vesa_emu.emu_inw = vm86_emu_inw;
+ vesa_emu.emu_inl = vm86_emu_inl;
+ vesa_emu.emu_outb = vm86_emu_outb;
+ vesa_emu.emu_outw = vm86_emu_outw;
+ vesa_emu.emu_outl = vm86_emu_outl;
+
+ vesa_emu.mem_base = (char *)emumem;
+ vesa_emu.mem_size = 1024 * 1024;
+
error = dpms_get_supported_states(&states);
if (error)
return (error);
@@ -164,6 +240,8 @@ dpms_attach(device_t dev)
static int
dpms_detach(device_t dev)
{
+ if (emumem)
+ pmap_unmapdev((vm_offset_t)emumem, 0xc00000);
return (0);
}
@@ -189,21 +267,19 @@ dpms_resume(device_t dev)
static int
dpms_call_bios(int subfunction, int *bh)
{
- struct vm86frame vmf;
- int error;
+ vesa_emu.x86.R_AX = VBE_DPMS_FUNCTION;
+ vesa_emu.x86.R_BL = subfunction;
+ vesa_emu.x86.R_BH = *bh;
+ vesa_emu.x86.R_ES = 0;
+ vesa_emu.x86.R_DI = 0;
+ x86emu_exec_intr(&vesa_emu, 0x10);
- bzero(&vmf, sizeof(vmf));
- vmf.vmf_ax = VBE_DPMS_FUNCTION;
- vmf.vmf_bl = subfunction;
- vmf.vmf_bh = *bh;
- vmf.vmf_es = 0;
- vmf.vmf_di = 0;
- error = vm86_intcall(0x10, &vmf);
- if (error == 0 && (vmf.vmf_eax & 0xffff) != 0x004f)
- error = ENXIO;
- if (error == 0)
- *bh = vmf.vmf_bh;
- return (error);
+ if ((vesa_emu.x86.R_EAX & 0xffff) != 0x004f)
+ return (ENXIO);
+
+ *bh = vesa_emu.x86.R_BH;
+
+ return (0);
}
static int
OpenPOWER on IntegriCloud