svn commit: r204546 - in stable/8: . lib share/man/man4 share/man/man4/man4.i386 sys/amd64/conf sys/compat/x86bios sys/conf sys/contrib/x86emu sys/dev/atkbdc sys/dev/dpms sys/dev/fb sys/dev/pci sys...

Xin LI delphij at FreeBSD.org
Tue Mar 2 01:56:55 UTC 2010


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 <jhb at 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 <ddkprog at yahoo.com>
- * Public domain.
+ * Copyright (c) 2009 Alex Keda <admin at lissyara.su>
+ * Copyright (c) 2009 Jung-uk Kim <jkim at 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 <ddkprog at yahoo.com>
- * Public domain.
+ * Copyright (c) 2009 Alex Keda <admin at 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 ***


More information about the svn-src-stable-8 mailing list