Author: delphij
Date: Tue Mar  2 01:56:55 2010
New Revision: 204546
URL: http://svn.freebsd.org/changeset/base/204546

Log:
  MFC x86emu/x86bios emulator and make previously i386 only dpms and vesa
  framebuffer driver, etc. work on FreeBSD/amd64.
  
  A significant amount of improvements were done by jkim@ during the recent
  months to make vesa(4) work better, over the initial code import.  This
  work is based on OpenBSD's x86emu implementation and contributed by
  paradox <ddkprog yahoo com> and swell.k at gmail com.
  
  Hopefully I have stolen all their work to 8-STABLE :)
  
  All bugs in this commit are mine, as usual.

Added:
  stable/8/share/man/man4/dpms.4
     - copied unchanged from r197025, head/share/man/man4/dpms.4
  stable/8/sys/compat/x86bios/
     - copied from r197444, head/sys/compat/x86bios/
  stable/8/sys/contrib/x86emu/
     - copied from r197009, head/sys/contrib/x86emu/
  stable/8/sys/dev/dpms/
     - copied from r197021, head/sys/dev/dpms/
  stable/8/sys/dev/dpms/dpms.c
     - copied, changed from r197022, head/sys/dev/dpms/dpms.c
  stable/8/sys/dev/fb/vesa.c
     - copied, changed from r197022, head/sys/dev/fb/vesa.c
  stable/8/sys/dev/fb/vesa.h
     - copied, changed from r197022, head/sys/dev/fb/vesa.h
  stable/8/sys/modules/x86bios/
     - copied from r197383, head/sys/modules/x86bios/
  stable/8/sys/modules/x86emu/
     - copied from r197019, head/sys/modules/x86emu/
Deleted:
  stable/8/share/man/man4/man4.i386/dpms.4
  stable/8/sys/i386/include/pc/vesa.h
  stable/8/sys/i386/isa/dpms.c
  stable/8/sys/i386/isa/vesa.c
Modified:
  stable/8/ObsoleteFiles.inc   (contents, props changed)
  stable/8/lib/Makefile   (contents, props changed)
  stable/8/share/man/man4/Makefile
  stable/8/share/man/man4/syscons.4
  stable/8/sys/amd64/conf/NOTES
  stable/8/sys/compat/x86bios/x86bios.c
  stable/8/sys/compat/x86bios/x86bios.h
  stable/8/sys/conf/NOTES
  stable/8/sys/conf/files
  stable/8/sys/conf/files.amd64
  stable/8/sys/conf/files.i386
  stable/8/sys/conf/options
  stable/8/sys/conf/options.amd64
  stable/8/sys/contrib/x86emu/x86emu.c   (contents, props changed)
  stable/8/sys/contrib/x86emu/x86emu.h   (contents, props changed)
  stable/8/sys/dev/atkbdc/atkbd.c
  stable/8/sys/dev/fb/s3_pci.c
  stable/8/sys/dev/fb/vga.c
  stable/8/sys/dev/fb/vgareg.h
  stable/8/sys/dev/pci/vga_pci.c
  stable/8/sys/dev/syscons/scvesactl.c
  stable/8/sys/dev/syscons/scvgarndr.c
  stable/8/sys/dev/syscons/scvidctl.c
  stable/8/sys/dev/syscons/syscons.c
  stable/8/sys/dev/syscons/syscons.h
  stable/8/sys/i386/conf/NOTES
  stable/8/sys/isa/vga_isa.c
  stable/8/sys/modules/Makefile
  stable/8/sys/modules/dpms/Makefile
  stable/8/sys/modules/vesa/Makefile
  stable/8/sys/modules/x86bios/Makefile
  stable/8/sys/sys/fbio.h
  stable/8/sys/sys/param.h
Directory Properties:
  stable/8/share/man/man4/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/netinet/   (props changed)

Modified: stable/8/ObsoleteFiles.inc
==============================================================================
--- stable/8/ObsoleteFiles.inc  Tue Mar  2 01:45:02 2010        (r204545)
+++ stable/8/ObsoleteFiles.inc  Tue Mar  2 01:56:55 2010        (r204546)
@@ -14,6 +14,9 @@
 # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last.
 #
 
+# 20100301: vesa and dpms promoted to be i386/amd64 common
+OLD_FILES+=usr/include/machine/pc/vesa.h
+OLD_FILES+=usr/share/man/man4/i386/dpms.4.gz
 # 20091218: removal of rc.early(8) link
 OLD_FILES+=usr/share/man/man8/rc.early.8.gz
 # 20091027: pselect.3 implemented as syscall

Modified: stable/8/lib/Makefile
==============================================================================
--- stable/8/lib/Makefile       Tue Mar  2 01:45:02 2010        (r204545)
+++ stable/8/lib/Makefile       Tue Mar  2 01:56:55 2010        (r204546)
@@ -112,6 +112,7 @@ _libsmb=    libsmb
 _libncp=       libncp
 .endif
 _libsmb=       libsmb
+_libvgl=       libvgl
 .endif
 
 .if ${MACHINE_ARCH} == "powerpc"

Modified: stable/8/share/man/man4/Makefile
==============================================================================
--- stable/8/share/man/man4/Makefile    Tue Mar  2 01:45:02 2010        
(r204545)
+++ stable/8/share/man/man4/Makefile    Tue Mar  2 01:56:55 2010        
(r204546)
@@ -86,6 +86,7 @@ MAN=  aac.4 \
        digi.4 \
        disc.4 \
        divert.4 \
+       ${_dpms.4} \
        dpt.4 \
        dummynet.4 \
        ed.4 \
@@ -622,6 +623,7 @@ _amdtemp.4= amdtemp.4
 _asmc.4=       asmc.4
 _coretemp.4=   coretemp.4
 _cpuctl.4=     cpuctl.4
+_dpms.4=       dpms.4
 _hptiop.4=     hptiop.4
 _hptmv.4=      hptmv.4
 _hptrr.4=      hptrr.4

Copied: stable/8/share/man/man4/dpms.4 (from r197025, 
head/share/man/man4/dpms.4)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ stable/8/share/man/man4/dpms.4      Tue Mar  2 01:56:55 2010        
(r204546, copy of r197025, head/share/man/man4/dpms.4)
@@ -0,0 +1,58 @@
+.\" Copyright (c) 2008 Yahoo!, Inc.
+.\" All rights reserved.
+.\" Written by: John Baldwin <j...@freebsd.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of any co-contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 23, 2008
+.Dt DPMS 4
+.Os
+.Sh NAME
+.Nm dpms
+.Nd VESA BIOS DPMS driver
+.Sh SYNOPSIS
+.Cd "device dpms"
+.Sh DESCRIPTION
+The
+.Nm
+driver uses the VESA BIOS to manage an external display during suspend and
+resume.
+When the machine suspends,
+the
+.Nm
+driver turns the external display off.
+When the machine resumes,
+it restores the display to its state when the driver was first loaded.
+.Sh SEE ALSO
+.Xr acpi_video 4
+.Sh BUGS
+.Pp
+The VESA BIOS DPMS calls do not provide any way to identify a particular
+display or adapter to manipulate.
+As a result,
+this driver may have unexpected results on systems with multiple displays
+and/or adapters.

Modified: stable/8/share/man/man4/syscons.4
==============================================================================
--- stable/8/share/man/man4/syscons.4   Tue Mar  2 01:45:02 2010        
(r204545)
+++ stable/8/share/man/man4/syscons.4   Tue Mar  2 01:56:55 2010        
(r204546)
@@ -26,7 +26,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 22, 2006
+.Dd September 10, 2009
 .Dt SYSCONS 4
 .Os
 .Sh NAME
@@ -325,7 +325,7 @@ This mode is useful on some laptop compu
 most other systems, and it adds substantial amount of code to syscons.
 If this option is NOT defined, you can reduce the kernel size a lot.
 See the
-.Dv VESA800X600
+.Dv VESAMODE
 flag below.
 .It Dv SC_TWOBUTTON_MOUSE
 If you have a two button mouse, you may want to add this option
@@ -426,15 +426,15 @@ or else at the loader prompt (see
 .\".It bit 6 (QUIET_BELL)
 .\"This option suppresses the bell, whether audible or visual,
 .\"if it is rung in a background virtual terminal.
-.It 0x0080 (VESA800X600)
-This option puts the video card in the VESA 800x600 pixel, 16 color
-mode.
-It may be useful for laptop computers for which the 800x600 mode
-is otherwise unsupported by the X server.
+.It 0x0080 (VESAMODE)
+This option puts the video card in the VESA mode specified by higher
+16 bits of the flags during kernel initialization.
 Note that in order for this flag to work, the kernel must be
 compiled with the
 .Dv SC_PIXEL_MODE
 option explained above.
+A list of the available mode can be obtained via
+.Xr vidcontrol 1 .
 .\"Note also that the ``copy-and-paste'' function is not currently supported
 .\"in this mode and the mouse pointer will not be displayed.
 .It 0x0100 (AUTODETECT_KBD)

Modified: stable/8/sys/amd64/conf/NOTES
==============================================================================
--- stable/8/sys/amd64/conf/NOTES       Tue Mar  2 01:45:02 2010        
(r204545)
+++ stable/8/sys/amd64/conf/NOTES       Tue Mar  2 01:56:55 2010        
(r204546)
@@ -154,6 +154,17 @@ options    AGP_DEBUG
 #####################################################################
 # HARDWARE DEVICE CONFIGURATION
 
+# To include support for VGA VESA video modes
+options        VESA
+
+# Turn on extra debugging checks and output for VESA support.
+options        VESA_DEBUG
+
+device         dpms            # DPMS suspend & resume via VESA BIOS
+
+# x86 real mode BIOS emulator, required by atkbdc/dpms/vesa
+options                X86BIOS
+
 #
 # Optional devices:
 #
@@ -213,6 +224,9 @@ options     VGA_WIDTH90             # support 90 colum
 # Debugging.
 options        VGA_DEBUG
 
+# Linear framebuffer driver for S3 VESA 1.2 cards. Works on top of VESA.
+device         s3pci
+
 # 3Dfx Voodoo Graphics, Voodoo II /dev/3dfx CDEV support.  This will create
 # the /dev/3dfx0 device to work with glide implementations.  This should get
 # linked to /dev/3dfx and /dev/voodoo.  Note that this is not the same as

Modified: stable/8/sys/compat/x86bios/x86bios.c
==============================================================================
--- head/sys/compat/x86bios/x86bios.c   Wed Sep 23 20:49:14 2009        
(r197444)
+++ stable/8/sys/compat/x86bios/x86bios.c       Tue Mar  2 01:56:55 2010        
(r204546)
@@ -1,6 +1,28 @@
 /*-
- * Written by paradox <ddkp...@yahoo.com>
- * Public domain.
+ * Copyright (c) 2009 Alex Keda <ad...@lissyara.su>
+ * Copyright (c) 2009 Jung-uk Kim <j...@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #include <sys/cdefs.h>
@@ -9,29 +31,164 @@ __FBSDID("$FreeBSD$");
 #include "opt_x86bios.h"
 
 #include <sys/param.h>
+#include <sys/bus.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
+#include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+
+#include <contrib/x86emu/x86emu.h>
+#include <contrib/x86emu/x86emu_regs.h>
+#include <compat/x86bios/x86bios.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <machine/cpufunc.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
-#include <machine/cpufunc.h>
+#define        X86BIOS_PAGE_SIZE       0x00001000      /* 4K */
 
-#include <contrib/x86emu/x86emu.h>
-#include <contrib/x86emu/x86emu_regs.h>
-#include <compat/x86bios/x86bios.h>
+#define        X86BIOS_IVT_SIZE        0x00000500      /* 1K + 256 (BDA) */
+#define        X86BIOS_SEG_SIZE        0x00010000      /* 64K */
+#define        X86BIOS_MEM_SIZE        0x00100000      /* 1M */
+
+#define        X86BIOS_IVT_BASE        0x00000000
+#define        X86BIOS_RAM_BASE        0x00001000
+#define        X86BIOS_ROM_BASE        0x000a0000      /* XXX EBDA? */
+
+#define        X86BIOS_ROM_SIZE        (X86BIOS_MEM_SIZE - X86BIOS_ROM_BASE)
 
-u_char *pbiosMem = NULL;
-static u_char *pbiosStack = NULL;
+#define        X86BIOS_PAGES           (X86BIOS_MEM_SIZE / X86BIOS_PAGE_SIZE)
 
-int busySegMap[5];
+#define        X86BIOS_R_DS            _pad1
+#define        X86BIOS_R_SS            _pad2
 
 static struct x86emu x86bios_emu;
 
 static struct mtx x86bios_lock;
 
+static void *x86bios_ivt;
+static void *x86bios_rom;
+static void *x86bios_seg;
+
+static vm_offset_t *x86bios_map;
+
+static vm_paddr_t x86bios_seg_phys;
+
+SYSCTL_NODE(_debug, OID_AUTO, x86bios, CTLFLAG_RD, NULL, "x86bios debugging");
+static int x86bios_trace_call;
+TUNABLE_INT("debug.x86bios.call", &x86bios_trace_call);
+SYSCTL_INT(_debug_x86bios, OID_AUTO, call, CTLFLAG_RW, &x86bios_trace_call, 0,
+    "Trace far function calls");
+static int x86bios_trace_int;
+TUNABLE_INT("debug.x86bios.int", &x86bios_trace_int);
+SYSCTL_INT(_debug_x86bios, OID_AUTO, int, CTLFLAG_RW, &x86bios_trace_int, 0,
+    "Trace software interrupt handlers");
+
+static void *
+x86bios_get_pages(uint32_t offset, size_t size)
+{
+       int i;
+
+       if (offset + size > X86BIOS_MEM_SIZE)
+               return (NULL);
+
+       i = offset / X86BIOS_PAGE_SIZE;
+       if (x86bios_map[i] != 0)
+               return ((void *)(x86bios_map[i] + offset -
+                   i * X86BIOS_PAGE_SIZE));
+
+       return (NULL);
+}
+
+static void
+x86bios_set_pages(vm_offset_t va, vm_paddr_t pa, size_t size)
+{
+       int i, j;
+
+       for (i = pa / X86BIOS_PAGE_SIZE, j = 0;
+           j < howmany(size, X86BIOS_PAGE_SIZE); i++, j++)
+               x86bios_map[i] = va + j * X86BIOS_PAGE_SIZE;
+}
+
+static uint8_t
+x86bios_emu_rdb(struct x86emu *emu, uint32_t addr)
+{
+       uint8_t *va;
+
+       va = x86bios_get_pages(addr, sizeof(*va));
+       if (va == NULL)
+               x86emu_halt_sys(emu);
+
+       return (*va);
+}
+
+static uint16_t
+x86bios_emu_rdw(struct x86emu *emu, uint32_t addr)
+{
+       uint16_t *va;
+
+       va = x86bios_get_pages(addr, sizeof(*va));
+       if (va == NULL)
+               x86emu_halt_sys(emu);
+
+       return (le16toh(*va));
+}
+
+static uint32_t
+x86bios_emu_rdl(struct x86emu *emu, uint32_t addr)
+{
+       uint32_t *va;
+
+       va = x86bios_get_pages(addr, sizeof(*va));
+       if (va == NULL)
+               x86emu_halt_sys(emu);
+
+       return (le32toh(*va));
+}
+
+static void
+x86bios_emu_wrb(struct x86emu *emu, uint32_t addr, uint8_t val)
+{
+       uint8_t *va;
+
+       va = x86bios_get_pages(addr, sizeof(*va));
+       if (va == NULL)
+               x86emu_halt_sys(emu);
+
+       *va = val;
+}
+
+static void
+x86bios_emu_wrw(struct x86emu *emu, uint32_t addr, uint16_t val)
+{
+       uint16_t *va;
+
+       va = x86bios_get_pages(addr, sizeof(*va));
+       if (va == NULL)
+               x86emu_halt_sys(emu);
+
+       *va = htole16(val);
+}
+
+static void
+x86bios_emu_wrl(struct x86emu *emu, uint32_t addr, uint32_t val)
+{
+       uint32_t *va;
+
+       va = x86bios_get_pages(addr, sizeof(*va));
+       if (va == NULL)
+               x86emu_halt_sys(emu);
+
+       *va = htole32(val);
+}
+
 static uint8_t
 x86bios_emu_inb(struct x86emu *emu, uint16_t port)
 {
@@ -40,6 +197,7 @@ x86bios_emu_inb(struct x86emu *emu, uint
                return (0);
        if (port >= 0x80 && port < 0x88) /* POST status register */
                return (0);
+
        return (inb(port));
 }
 
@@ -49,6 +207,7 @@ x86bios_emu_inw(struct x86emu *emu, uint
 
        if (port >= 0x80 && port < 0x88) /* POST status register */
                return (0);
+
        return (inw(port));
 }
 
@@ -58,6 +217,7 @@ x86bios_emu_inl(struct x86emu *emu, uint
 
        if (port >= 0x80 && port < 0x88) /* POST status register */
                return (0);
+
        return (inl(port));
 }
 
@@ -69,6 +229,7 @@ x86bios_emu_outb(struct x86emu *emu, uin
                return;
        if (port >= 0x80 && port < 0x88) /* POST status register */
                return;
+
        outb(port, val);
 }
 
@@ -78,6 +239,7 @@ x86bios_emu_outw(struct x86emu *emu, uin
 
        if (port >= 0x80 && port < 0x88) /* POST status register */
                return;
+
        outw(port, val);
 }
 
@@ -87,44 +249,245 @@ x86bios_emu_outl(struct x86emu *emu, uin
 
        if (port >= 0x80 && port < 0x88) /* POST status register */
                return;
+
        outl(port, val);
 }
 
+static void
+x86bios_emu_get_intr(struct x86emu *emu, int intno)
+{
+       uint16_t *sp;
+       uint32_t iv;
+
+       emu->x86.R_SP -= 6;
+
+       sp = (uint16_t *)((vm_offset_t)x86bios_seg + emu->x86.R_SP);
+       sp[0] = htole16(emu->x86.R_IP);
+       sp[1] = htole16(emu->x86.R_CS);
+       sp[2] = htole16(emu->x86.R_FLG);
+
+       iv = x86bios_get_intr(intno);
+       emu->x86.R_IP = iv & 0x000f;
+       emu->x86.R_CS = (iv >> 12) & 0xffff;
+       emu->x86.R_FLG &= ~(F_IF | F_TF);
+}
+
+void *
+x86bios_alloc(uint32_t *offset, size_t size)
+{
+       void *vaddr;
+
+       if (offset == NULL || size == 0)
+               return (NULL);
+
+       vaddr = contigmalloc(size, M_DEVBUF, M_NOWAIT, X86BIOS_RAM_BASE,
+           X86BIOS_ROM_BASE, X86BIOS_PAGE_SIZE, 0);
+       if (vaddr != NULL) {
+               *offset = vtophys(vaddr);
+               x86bios_set_pages((vm_offset_t)vaddr, *offset, size);
+       }
+
+       return (vaddr);
+}
+
 void
-x86biosCall(struct x86regs *regs, int intno)
+x86bios_free(void *addr, size_t size)
 {
+       vm_paddr_t paddr;
 
-       if (intno < 0 || intno > 255)
+       if (addr == NULL || size == 0)
+               return;
+
+       paddr = vtophys(addr);
+       if (paddr < X86BIOS_RAM_BASE || paddr >= X86BIOS_ROM_BASE ||
+           paddr % X86BIOS_PAGE_SIZE != 0)
                return;
 
+       bzero(x86bios_map + paddr / X86BIOS_PAGE_SIZE,
+           sizeof(*x86bios_map) * howmany(size, X86BIOS_PAGE_SIZE));
+       contigfree(addr, size, M_DEVBUF);
+}
+
+void
+x86bios_init_regs(struct x86regs *regs)
+{
+
+       bzero(regs, sizeof(*regs));
+       regs->X86BIOS_R_DS = regs->X86BIOS_R_SS = x86bios_seg_phys >> 4;
+}
+
+void
+x86bios_call(struct x86regs *regs, uint16_t seg, uint16_t off)
+{
+
+       if (x86bios_map == NULL)
+               return;
+
+       if (x86bios_trace_call)
+               printf("Calling 0x%05x (ax=0x%04x bx=0x%04x "
+                   "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n",
+                   (seg << 4) + off, regs->R_AX, regs->R_BX, regs->R_CX,
+                   regs->R_DX, regs->R_ES, regs->R_DI);
+
        mtx_lock_spin(&x86bios_lock);
+       memcpy(&x86bios_emu.x86, regs, sizeof(*regs));
+       x86emu_exec_call(&x86bios_emu, seg, off);
+       memcpy(regs, &x86bios_emu.x86, sizeof(*regs));
+       mtx_unlock_spin(&x86bios_lock);
+
+       if (x86bios_trace_call)
+               printf("Exiting 0x%05x (ax=0x%04x bx=0x%04x "
+                   "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n",
+                   (seg << 4) + off, regs->R_AX, regs->R_BX, regs->R_CX,
+                   regs->R_DX, regs->R_ES, regs->R_DI);
+}
+
+uint32_t
+x86bios_get_intr(int intno)
+{
+       uint32_t *iv;
+
+       iv = (uint32_t *)((vm_offset_t)x86bios_ivt + intno * 4);
+
+       return (le32toh(*iv));
+}
+
+void
+x86bios_intr(struct x86regs *regs, int intno)
+{
+
+       if (intno < 0 || intno > 255)
+               return;
+
+       if (x86bios_map == NULL)
+               return;
 
+       if (x86bios_trace_int)
+               printf("Calling int 0x%x (ax=0x%04x bx=0x%04x "
+                   "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n",
+                   intno, regs->R_AX, regs->R_BX, regs->R_CX,
+                   regs->R_DX, regs->R_ES, regs->R_DI);
+
+       mtx_lock_spin(&x86bios_lock);
        memcpy(&x86bios_emu.x86, regs, sizeof(*regs));
        x86emu_exec_intr(&x86bios_emu, intno);
        memcpy(regs, &x86bios_emu.x86, sizeof(*regs));
-
        mtx_unlock_spin(&x86bios_lock);
+
+       if (x86bios_trace_int)
+               printf("Exiting int 0x%x (ax=0x%04x bx=0x%04x "
+                   "cx=0x%04x dx=0x%04x es=0x%04x di=0x%04x)\n",
+                   intno, regs->R_AX, regs->R_BX, regs->R_CX,
+                   regs->R_DX, regs->R_ES, regs->R_DI);
+}
+
+void *
+x86bios_offset(uint32_t offset)
+{
+
+       return (x86bios_get_pages(offset, 1));
 }
 
 void *
-x86biosOffs(uint32_t offs)
+x86bios_get_orm(uint32_t offset)
 {
+       uint8_t *p;
+
+       /* Does the shadow ROM contain BIOS POST code for x86? */
+       p = x86bios_offset(offset);
+       if (p == NULL || p[0] != 0x55 || p[1] != 0xaa || p[3] != 0xe9)
+               return (NULL);
 
-       return (pbiosMem + offs);
+       return (p);
+}
+
+int
+x86bios_match_device(uint32_t offset, device_t dev)
+{
+       uint8_t *p;
+       uint16_t device, vendor;
+       uint8_t class, progif, subclass;
+
+       /* Does the shadow ROM contain BIOS POST code for x86? */
+       p = x86bios_get_orm(offset);
+       if (p == NULL)
+               return (0);
+
+       /* Does it contain PCI data structure? */
+       p += le16toh(*(uint16_t *)(p + 0x18));
+       if (bcmp(p, "PCIR", 4) != 0 ||
+           le16toh(*(uint16_t *)(p + 0x0a)) < 0x18 || *(p + 0x14) != 0)
+               return (0);
+
+       /* Does it match the vendor, device, and classcode? */
+       vendor = le16toh(*(uint16_t *)(p + 0x04));
+       device = le16toh(*(uint16_t *)(p + 0x06));
+       progif = *(p + 0x0d);
+       subclass = *(p + 0x0e);
+       class = *(p + 0x0f);
+       if (vendor != pci_get_vendor(dev) || device != pci_get_device(dev) ||
+           class != pci_get_class(dev) || subclass != pci_get_subclass(dev) ||
+           progif != pci_get_progif(dev))
+               return (0);
+
+       return (1);
+}
+
+static __inline int
+x86bios_map_mem(void)
+{
+
+       x86bios_ivt = pmap_mapbios(X86BIOS_IVT_BASE, X86BIOS_IVT_SIZE);
+       if (x86bios_ivt == NULL)
+               return (1);
+       x86bios_rom = pmap_mapdev(X86BIOS_ROM_BASE, X86BIOS_ROM_SIZE);
+       if (x86bios_rom == NULL) {
+               pmap_unmapdev((vm_offset_t)x86bios_ivt, X86BIOS_IVT_SIZE);
+               return (1);
+       }
+       x86bios_seg = contigmalloc(X86BIOS_SEG_SIZE, M_DEVBUF, M_WAITOK,
+           X86BIOS_RAM_BASE, X86BIOS_ROM_BASE, X86BIOS_PAGE_SIZE, 0);
+       x86bios_seg_phys = vtophys(x86bios_seg);
+
+       return (0);
+}
+
+static __inline void
+x86bios_unmap_mem(void)
+{
+
+       pmap_unmapdev((vm_offset_t)x86bios_ivt, X86BIOS_IVT_SIZE);
+       pmap_unmapdev((vm_offset_t)x86bios_rom, X86BIOS_ROM_SIZE);
+       contigfree(x86bios_seg, X86BIOS_SEG_SIZE, M_DEVBUF);
 }
 
 static void
 x86bios_init(void *arg __unused)
 {
-       int offs;
+       int i;
 
        mtx_init(&x86bios_lock, "x86bios lock", NULL, MTX_SPIN);
 
-       /* Can pbiosMem be NULL here? */
-       pbiosMem = pmap_mapbios(0x0, MAPPED_MEMORY_SIZE);
+       if (x86bios_map_mem() != 0)
+               return;
 
-       memset(&x86bios_emu, 0, sizeof(x86bios_emu));
-       x86emu_init_default(&x86bios_emu);
+       x86bios_map = malloc(sizeof(*x86bios_map) * X86BIOS_PAGES, M_DEVBUF,
+           M_WAITOK | M_ZERO);
+       x86bios_set_pages((vm_offset_t)x86bios_ivt, X86BIOS_IVT_BASE,
+           X86BIOS_IVT_SIZE);
+       x86bios_set_pages((vm_offset_t)x86bios_rom, X86BIOS_ROM_BASE,
+           X86BIOS_ROM_SIZE);
+       x86bios_set_pages((vm_offset_t)x86bios_seg, x86bios_seg_phys,
+           X86BIOS_SEG_SIZE);
+
+       bzero(&x86bios_emu, sizeof(x86bios_emu));
+
+       x86bios_emu.emu_rdb = x86bios_emu_rdb;
+       x86bios_emu.emu_rdw = x86bios_emu_rdw;
+       x86bios_emu.emu_rdl = x86bios_emu_rdl;
+       x86bios_emu.emu_wrb = x86bios_emu_wrb;
+       x86bios_emu.emu_wrw = x86bios_emu_wrw;
+       x86bios_emu.emu_wrl = x86bios_emu_wrl;
 
        x86bios_emu.emu_inb = x86bios_emu_inb;
        x86bios_emu.emu_inw = x86bios_emu_inw;
@@ -133,23 +496,24 @@ x86bios_init(void *arg __unused)
        x86bios_emu.emu_outw = x86bios_emu_outw;
        x86bios_emu.emu_outl = x86bios_emu_outl;
 
-       x86bios_emu.mem_base = (char *)pbiosMem;
-       x86bios_emu.mem_size = 1024 * 1024;
-
-       memset(busySegMap, 0, sizeof(busySegMap));
-
-       pbiosStack = x86biosAlloc(1, &offs);
+       for (i = 0; i < 256; i++)
+               x86bios_emu._x86emu_intrTab[i] = x86bios_emu_get_intr;
 }
 
 static void
 x86bios_uninit(void *arg __unused)
 {
+       vm_offset_t *map = x86bios_map;
 
-       x86biosFree(pbiosStack, 1);
+       mtx_lock_spin(&x86bios_lock);
+       if (x86bios_map != NULL) {
+               free(x86bios_map, M_DEVBUF);
+               x86bios_map = NULL;
+       }
+       mtx_unlock_spin(&x86bios_lock);
 
-       if (pbiosMem)
-               pmap_unmapdev((vm_offset_t)pbiosMem,
-                   MAPPED_MEMORY_SIZE);
+       if (map != NULL)
+               x86bios_unmap_mem();
 
        mtx_destroy(&x86bios_lock);
 }
@@ -157,7 +521,6 @@ x86bios_uninit(void *arg __unused)
 static int
 x86bios_modevent(module_t mod __unused, int type, void *data __unused)
 {
-       int err = 0;
 
        switch (type) {
        case MOD_LOAD:
@@ -167,11 +530,10 @@ x86bios_modevent(module_t mod __unused, 
                x86bios_uninit(NULL);
                break;
        default:
-               err = ENOTSUP;
-               break;
+               return (ENOTSUP);
        }
 
-       return (err);
+       return (0);
 }
 
 static moduledata_t x86bios_mod = {

Modified: stable/8/sys/compat/x86bios/x86bios.h
==============================================================================
--- head/sys/compat/x86bios/x86bios.h   Wed Sep 23 20:49:14 2009        
(r197444)
+++ stable/8/sys/compat/x86bios/x86bios.h       Tue Mar  2 01:56:55 2010        
(r204546)
@@ -1,48 +1,73 @@
 /*-
- * Written by paradox <ddkp...@yahoo.com>
- * Public domain.
+ * Copyright (c) 2009 Alex Keda <ad...@lissyara.su>
+ * All rights reserved.
  *
- * x86 registers were borrowed from x86emu.h x86emu_regs.h
- * for compatability.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  *
  * $FreeBSD$
  */
+/*
+ * x86 registers were borrowed from x86emu.h x86emu_regs.h
+ * for compatability.
+ */
 
 #ifndef _X86BIOS_H_
-#define _X86BIOS_H_
+#define        _X86BIOS_H_
 
-#include <sys/types.h>
 #include <sys/endian.h>
 #include <sys/systm.h>
+#include <sys/types.h>
 
 #ifdef __BIG_ENDIAN__
 
 struct x86_register32 {
-       uint32_t e_reg;
+       uint32_t                e_reg;
 };
 
 struct x86_register16 {
-       uint16_t filler0;
-       uint16_t x_reg;
+       uint16_t                filler0;
+       uint16_t                x_reg;
 };
 
 struct x86_register8 {
-       uint8_t filler0, filler1;
-       uint8_t h_reg, l_reg;
+       uint8_t                 filler0;
+       uint8_t                 filler1;
+       uint8_t                 h_reg;
+       uint8_t                 l_reg;
 };
 
 #else /* !__BIG_ENDIAN__ */
 
 struct x86_register32 {
-       uint32_t e_reg;
+       uint32_t                e_reg;
 };
 
 struct x86_register16 {
-       uint16_t x_reg;
+       uint16_t                x_reg;
 };
 
 struct x86_register8 {
-       uint8_t l_reg, h_reg;
+       uint8_t                 l_reg;
+       uint8_t                 h_reg;
 };
 
 #endif /* __BIG_ENDIAN__ */
@@ -54,85 +79,78 @@ union x86_register {
 };
 
 struct x86regs {
-       uint16_t                register_cs;
-       uint16_t                register_ds;
+       uint16_t                _pad0;          /* CS */
+       uint16_t                _pad1;          /* DS */
        uint16_t                register_es;
        uint16_t                register_fs;
        uint16_t                register_gs;
-       uint16_t                register_ss;
+       uint16_t                _pad2;          /* SS */
        uint32_t                register_flags;
        union x86_register      register_a;
        union x86_register      register_b;
        union x86_register      register_c;
        union x86_register      register_d;
 
-       union x86_register      register_sp;
+       union x86_register      _pad3;          /* SP */
        union x86_register      register_bp;
        union x86_register      register_si;
        union x86_register      register_di;
-       union x86_register      register_ip;
 };
 
 typedef struct x86regs x86regs_t;
 
 /* 8 bit registers */
-#define R_AH   register_a.I8_reg.h_reg
-#define R_AL   register_a.I8_reg.l_reg
-#define R_BH   register_b.I8_reg.h_reg
-#define R_BL   register_b.I8_reg.l_reg
-#define R_CH   register_c.I8_reg.h_reg
-#define R_CL   register_c.I8_reg.l_reg
-#define R_DH   register_d.I8_reg.h_reg
-#define R_DL   register_d.I8_reg.l_reg
+#define        R_AH            register_a.I8_reg.h_reg
+#define        R_AL            register_a.I8_reg.l_reg
+#define        R_BH            register_b.I8_reg.h_reg
+#define        R_BL            register_b.I8_reg.l_reg
+#define        R_CH            register_c.I8_reg.h_reg
+#define        R_CL            register_c.I8_reg.l_reg
+#define        R_DH            register_d.I8_reg.h_reg
+#define        R_DL            register_d.I8_reg.l_reg
 
 /* 16 bit registers */
-#define R_AX   register_a.I16_reg.x_reg
-#define R_BX   register_b.I16_reg.x_reg
-#define R_CX   register_c.I16_reg.x_reg
-#define R_DX   register_d.I16_reg.x_reg
+#define        R_AX            register_a.I16_reg.x_reg
+#define        R_BX            register_b.I16_reg.x_reg
+#define        R_CX            register_c.I16_reg.x_reg
+#define        R_DX            register_d.I16_reg.x_reg
 
 /* 32 bit extended registers */
-#define R_EAX  register_a.I32_reg.e_reg
-#define R_EBX  register_b.I32_reg.e_reg
-#define R_ECX  register_c.I32_reg.e_reg
-#define R_EDX  register_d.I32_reg.e_reg
+#define        R_EAX           register_a.I32_reg.e_reg
+#define        R_EBX           register_b.I32_reg.e_reg
+#define        R_ECX           register_c.I32_reg.e_reg
+#define        R_EDX           register_d.I32_reg.e_reg
 
 /* special registers */
-#define R_SP   register_sp.I16_reg.x_reg
-#define R_BP   register_bp.I16_reg.x_reg
-#define R_SI   register_si.I16_reg.x_reg
-#define R_DI   register_di.I16_reg.x_reg
-#define R_IP   register_ip.I16_reg.x_reg
-#define R_FLG  register_flags
+#define        R_BP            register_bp.I16_reg.x_reg
+#define        R_SI            register_si.I16_reg.x_reg
+#define        R_DI            register_di.I16_reg.x_reg
+#define        R_FLG           register_flags
 
 /* special registers */
-#define R_ESP  register_sp.I32_reg.e_reg
-#define R_EBP  register_bp.I32_reg.e_reg
-#define R_ESI  register_si.I32_reg.e_reg
-#define R_EDI  register_di.I32_reg.e_reg
-#define R_EIP  register_ip.I32_reg.e_reg
-#define R_EFLG register_flags
+#define        R_EBP           register_bp.I32_reg.e_reg
+#define        R_ESI           register_si.I32_reg.e_reg
+#define        R_EDI           register_di.I32_reg.e_reg
+#define        R_EFLG          register_flags
 
 /* segment registers */
-#define R_CS   register_cs
-#define R_DS   register_ds
-#define R_SS   register_ss
-#define R_ES   register_es
-#define R_FS   register_fs
-#define R_GS   register_gs
-
-#define SEG_ADDR(x)    (((x) >> 4) & 0x00F000)
-#define SEG_OFF(x)     ((x) & 0x0FFFF)
-#define FARP(x)                ((le32toh(x) & 0xffff) + ((le32toh(x) >> 12) & 
0xffff00))
+#define        R_ES            register_es
+#define        R_FS            register_fs
+#define        R_GS            register_gs
 
-#define MAPPED_MEMORY_SIZE     0xc00000
-#define PAGE_RESERV            (4096*5)
+#define        X86BIOS_PHYSTOSEG(x)    (((x) >> 4) & 0xffff)
+#define        X86BIOS_PHYSTOOFF(x)    ((x) & 0x000f)
 
 __BEGIN_DECLS
-void  x86biosCall(struct x86regs *regs, int intno);
-void *x86biosAlloc(int count, int *segs);
-void  x86biosFree(void *pbuf, int count);
-void *x86biosOffs(uint32_t offs);
+void   *x86bios_alloc(uint32_t *offset, size_t size);
+void    x86bios_call(struct x86regs *regs, uint16_t seg, uint16_t off);
+void    x86bios_free(void *addr, size_t size);
+uint32_t x86bios_get_intr(int intno);
+void   *x86bios_get_orm(uint32_t offset);
+void    x86bios_init_regs(struct x86regs *regs);
+void    x86bios_intr(struct x86regs *regs, int intno);
+int     x86bios_match_device(uint32_t offset, device_t dev);
+void   *x86bios_offset(uint32_t offset);
 __END_DECLS
 
 #endif /* !_X86BIOS_H_ */

Modified: stable/8/sys/conf/NOTES
==============================================================================
--- stable/8/sys/conf/NOTES     Tue Mar  2 01:45:02 2010        (r204545)
+++ stable/8/sys/conf/NOTES     Tue Mar  2 01:56:55 2010        (r204546)
@@ -2821,3 +2821,4 @@ options   AAC_DEBUG       # Debugging levels:
 ##options      BKTR_ALLOC_PAGES=(217*4+1)
 options        BROOKTREE_ALLOC_PAGES=(217*4+1)
 options        MAXFILES=999
+

Modified: stable/8/sys/conf/files
==============================================================================
--- stable/8/sys/conf/files     Tue Mar  2 01:45:02 2010        (r204545)
+++ stable/8/sys/conf/files     Tue Mar  2 01:56:55 2010        (r204546)
@@ -2893,4 +2893,3 @@ dev/xen/netfront/netfront.c       optional xen
 dev/xen/xenpci/xenpci.c                optional xenpci
 dev/xen/xenpci/evtchn.c         optional xenpci
 dev/xen/xenpci/machine_reboot.c optional xenpci
-

Modified: stable/8/sys/conf/files.amd64
==============================================================================
--- stable/8/sys/conf/files.amd64       Tue Mar  2 01:45:02 2010        
(r204545)
+++ stable/8/sys/conf/files.amd64       Tue Mar  2 01:56:55 2010        
(r204546)
@@ -163,6 +163,7 @@ dev/atkbdc/atkbdc_subr.c    optional        atkbdc
 dev/atkbdc/psm.c               optional        psm atkbdc
 dev/coretemp/coretemp.c                optional        coretemp
 dev/cpuctl/cpuctl.c            optional        cpuctl
+dev/dpms/dpms.c                        optional        dpms
 # There are no systems with isa slots, so all ed isa entries should go..
 dev/ed/if_ed_3c503.c           optional        ed isa ed_3c503
 dev/ed/if_ed_isa.c             optional        ed isa
@@ -170,6 +171,8 @@ dev/ed/if_ed_wd80x3.c               optional        ed isa
 dev/ed/if_ed_hpp.c             optional        ed isa ed_hpp
 dev/ed/if_ed_sic.c             optional        ed isa ed_sic
 dev/fb/fb.c                    optional        fb | vga
+dev/fb/s3_pci.c                        optional        s3pci
+dev/fb/vesa.c                  optional        vga vesa
 dev/fb/vga.c                   optional        vga
 dev/ichwd/ichwd.c              optional        ichwd
 dev/if_ndis/if_ndis.c          optional        ndis
@@ -220,6 +223,7 @@ dev/sio/sio_puc.c           optional        sio puc
 dev/speaker/spkr.c             optional        speaker
 dev/syscons/apm/apm_saver.c    optional        apm_saver apm
 dev/syscons/scterm-teken.c     optional        sc
+dev/syscons/scvesactl.c                optional        sc vga vesa
 dev/syscons/scvgarndr.c                optional        sc vga
 dev/syscons/scvtb.c            optional        sc
 dev/syscons/teken/teken.c      optional sc
@@ -294,3 +298,8 @@ i386/cpufreq/p4tcc.c                optional        cpufreq
 #
 libkern/memmove.c              standard
 libkern/memset.c               standard
+#
+# x86 real mode BIOS emulator, required by atkbdc/dpms/vesa
+#
+compat/x86bios/x86bios.c       optional x86bios | atkbd | dpms | vesa
+contrib/x86emu/x86emu.c                optional x86bios | atkbd | dpms | vesa

Modified: stable/8/sys/conf/files.i386
==============================================================================
--- stable/8/sys/conf/files.i386        Tue Mar  2 01:45:02 2010        
(r204545)
+++ stable/8/sys/conf/files.i386        Tue Mar  2 01:56:55 2010        
(r204546)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to