summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGwenolé Beauchesne <gbeauchesne@mandriva.org>2004-08-25 05:45:29 +0000
committerGwenolé Beauchesne <gbeauchesne@mandriva.org>2004-08-25 05:45:29 +0000
commite0fbcfe868b509f256fcdc239178d32f617bb129 (patch)
tree26d7a7632d92979a6f7a39f0a707c935ca186e9f
parent56e607a5ce0c98074b0c3067e2bba76e9d73223d (diff)
downloaddrakx-e0fbcfe868b509f256fcdc239178d32f617bb129.tar
drakx-e0fbcfe868b509f256fcdc239178d32f617bb129.tar.gz
drakx-e0fbcfe868b509f256fcdc239178d32f617bb129.tar.bz2
drakx-e0fbcfe868b509f256fcdc239178d32f617bb129.tar.xz
drakx-e0fbcfe868b509f256fcdc239178d32f617bb129.zip
VGA softbootloader for Linux, uses an x86 CPU emulator on non x86 arches.
-rw-r--r--tools/ddcprobe/int10/AsmMacros.h458
-rw-r--r--tools/ddcprobe/int10/Makefile19
-rw-r--r--tools/ddcprobe/int10/README35
-rw-r--r--tools/ddcprobe/int10/emu_vm86.c154
-rw-r--r--tools/ddcprobe/int10/i10_int.c195
-rw-r--r--tools/ddcprobe/int10/i10_io.c108
-rw-r--r--tools/ddcprobe/int10/i10_pci.c866
-rw-r--r--tools/ddcprobe/int10/i10_v86.c515
-rw-r--r--tools/ddcprobe/int10/i10_vbios.c571
-rw-r--r--tools/ddcprobe/int10/pci.h127
-rw-r--r--tools/ddcprobe/int10/v86bios.h215
-rw-r--r--tools/ddcprobe/int10/vbios.h4
-rw-r--r--tools/ddcprobe/int10/vm86_struct.h135
13 files changed, 3402 insertions, 0 deletions
diff --git a/tools/ddcprobe/int10/AsmMacros.h b/tools/ddcprobe/int10/AsmMacros.h
new file mode 100644
index 000000000..68f955872
--- /dev/null
+++ b/tools/ddcprobe/int10/AsmMacros.h
@@ -0,0 +1,458 @@
+/* $XConsortium: AsmMacros.h /main/13 1996/10/25 11:33:12 kaleb $ */
+/*
+ * (c) Copyright 1993,1994 by David Wexelblat <dwex@xfree86.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID WEXELBLAT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of David Wexelblat shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from David Wexelblat.
+ *
+ */
+/*
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the source
+ * file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation" name
+ * nor any trademark or logo of Digital Equipment Corporation may be used
+ * to endorse or promote products derived from this software without the
+ * prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed. In
+ * no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for
+ * lost profits, loss of revenue or loss of use, whether such damages arise
+ * in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even if
+ * advised of the possibility of such damage.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/SuperProbe/AsmMacros.h,v 3.14 1999/09/25 14:36:58 dawes Exp $ */
+
+
+#if defined(__GNUC__)
+
+#if defined(linux) && (defined(__alpha__) || defined(__ia64__))
+
+#include <sys/io.h>
+
+#undef inb
+#undef inw
+#undef inl
+#undef outb
+#undef outw
+#undef outl
+
+static __inline__ unsigned int inb(unsigned long int p) { return _inb(p); };
+static __inline__ unsigned int inw(unsigned long int p) { return _inw(p); };
+static __inline__ unsigned int inl(unsigned long int p) { return _inl(p); };
+static __inline__ void outb(unsigned long int p, unsigned char v) { _outb(v,p); };
+static __inline__ void outw(unsigned long int p, unsigned short v) { _outw(v,p); };
+static __inline__ void outl(unsigned long int p, unsigned int v) { _outl(v,p); };
+
+#else
+
+#if defined(__sparc__)
+#ifndef ASI_PL
+#define ASI_PL 0x88
+#endif
+
+static __inline__ void
+outb(port, val)
+unsigned long port;
+char val;
+{
+ __asm__ __volatile__("stba %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL));
+}
+
+static __inline__ void
+outw(port, val)
+unsigned long port;
+char val;
+{
+ __asm__ __volatile__("stha %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL));
+}
+
+static __inline__ void
+outl(port, val)
+unsigned long port;
+char val;
+{
+ __asm__ __volatile__("sta %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL));
+}
+
+static __inline__ unsigned int
+inb(port)
+unsigned long port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("lduba [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(port)
+unsigned long port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("lduha [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned int
+inl(port)
+unsigned long port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("lda [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL));
+ return ret;
+}
+#else
+#ifdef __arm32__
+unsigned int IOPortBase; /* Memory mapped I/O port area */
+
+static __inline__ void
+outb(port, val)
+ short port;
+ char val;
+{
+ if ((unsigned short)port >= 0x400) return;
+
+ *(volatile unsigned char*)(((unsigned short)(port))+IOPortBase) = val;
+}
+
+static __inline__ void
+outw(port, val)
+ short port;
+ short val;
+{
+ if ((unsigned short)port >= 0x400) return;
+
+ *(volatile unsigned short*)(((unsigned short)(port))+IOPortBase) = val;
+}
+
+static __inline__ void
+outl(port, val)
+ short port;
+ int val;
+{
+ if ((unsigned short)port >= 0x400) return;
+
+ *(volatile unsigned long*)(((unsigned short)(port))+IOPortBase) = val;
+}
+
+static __inline__ unsigned int
+inb(port)
+ short port;
+{
+ if ((unsigned short)port >= 0x400) return((unsigned int)-1);
+
+ return(*(volatile unsigned char*)(((unsigned short)(port))+IOPortBase));
+}
+
+static __inline__ unsigned int
+inw(port)
+ short port;
+{
+ if ((unsigned short)port >= 0x400) return((unsigned int)-1);
+
+ return(*(volatile unsigned short*)(((unsigned short)(port))+IOPortBase));
+}
+
+static __inline__ unsigned int
+inl(port)
+ short port;
+{
+ if ((unsigned short)port >= 0x400) return((unsigned int)-1);
+
+ return(*(volatile unsigned long*)(((unsigned short)(port))+IOPortBase));
+}
+#else /* __arm32__ */
+#if defined(Lynx) && defined(__powerpc__)
+extern unsigned char *ioBase;
+
+static volatile void
+eieio()
+{
+ __asm__ __volatile__ ("eieio");
+}
+
+static void
+outb(port, value)
+short port;
+unsigned char value;
+{
+ *(uchar *)(ioBase + port) = value; eieio();
+}
+
+static void
+outw(port, value)
+short port;
+unsigned short value;
+{
+ *(unsigned short *)(ioBase + port) = value; eieio();
+}
+
+static void
+outl(port, value)
+short port;
+unsigned long value;
+{
+ *(unsigned long *)(ioBase + port) = value; eieio();
+}
+
+static unsigned char
+inb(port)
+short port;
+{
+ unsigned char val;
+
+ val = *((unsigned char *)(ioBase + port)); eieio();
+ return(val);
+}
+
+static unsigned short
+inw(port)
+short port;
+{
+ unsigned short val;
+
+ val = *((unsigned short *)(ioBase + port)); eieio();
+ return(val);
+}
+
+static unsigned long
+inl(port)
+short port;
+{
+ unsigned long val;
+
+ val = *((unsigned long *)(ioBase + port)); eieio();
+ return(val);
+}
+
+#else
+#if defined(__FreeBSD__) && defined(__alpha__)
+
+#include <sys/types.h>
+
+extern void outb(u_int32_t port, u_int8_t val);
+extern void outw(u_int32_t port, u_int16_t val);
+extern void outl(u_int32_t port, u_int32_t val);
+extern u_int8_t inb(u_int32_t port);
+extern u_int16_t inw(u_int32_t port);
+extern u_int32_t inl(u_int32_t port);
+
+#else
+#ifdef GCCUSESGAS
+static __inline__ void
+outb(port, val)
+short port;
+char val;
+{
+ __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outw(port, val)
+short port;
+short val;
+{
+ __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outl(port, val)
+short port;
+unsigned int val;
+{
+ __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(port)
+short port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("inb %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(port)
+short port;
+{
+ unsigned short ret;
+ __asm__ __volatile__("inw %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inl(port)
+short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("inl %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+#else /* GCCUSESGAS */
+
+static __inline__ void
+outb(port, val)
+ short port;
+ char val;
+{
+ __asm__ __volatile__("out%B0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outw(port, val)
+ short port;
+ short val;
+{
+ __asm__ __volatile__("out%W0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outl(port, val)
+ short port;
+ unsigned int val;
+{
+ __asm__ __volatile__("out%L0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(port)
+ short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("in%B0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(port)
+ short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("in%W0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inl(port)
+ short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("in%L0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+#endif /* GCCUSESGAS */
+#endif /* Lynx && __powerpc__ */
+#endif /* arm32 */
+#endif /* linux && __sparc__ */
+#endif /* linux && __alpha__ */
+#endif /* __FreeBSD__ && __alpha__ */
+
+#if defined(linux) || defined(__arm32__) || (defined(Lynx) && defined(__powerpc__))
+
+#define intr_disable()
+#define intr_enable()
+
+#else
+
+static __inline__ void
+intr_disable()
+{
+ __asm__ __volatile__("cli");
+}
+
+static __inline__ void
+intr_enable()
+{
+ __asm__ __volatile__("sti");
+}
+
+#endif /* else !linux && !__arm32__ */
+
+#else /* __GNUC__ */
+
+#if defined(_MINIX) && defined(_ACK)
+
+/* inb, outb, inw and outw are defined in the library */
+/* ... but I've no idea if the same is true for inl & outl */
+
+u8_t inb(U16_t);
+void outb(U16_t, U8_t);
+u16_t inw(U16_t);
+void outw(U16_t, U16_t);
+u32_t inl(U16_t);
+void outl(U16_t, U32_t);
+
+#else /* not _MINIX and _ACK */
+
+# if defined(__STDC__) && (__STDC__ == 1)
+# ifndef NCR
+# define asm __asm
+# endif
+# endif
+# ifdef SVR4
+# include <sys/types.h>
+# ifndef __USLC__
+# define __USLC__
+# endif
+# endif
+#ifndef SCO325
+# include <sys/inline.h>
+#else
+# include "../common/scoasm.h"
+#endif
+#define intr_disable() asm("cli")
+#define intr_enable() asm("sti")
+
+#endif /* _MINIX and _ACK */
+#endif /* __GNUC__ */
diff --git a/tools/ddcprobe/int10/Makefile b/tools/ddcprobe/int10/Makefile
new file mode 100644
index 000000000..b2a559140
--- /dev/null
+++ b/tools/ddcprobe/int10/Makefile
@@ -0,0 +1,19 @@
+CC = gcc
+INCS =
+CFLAGS = -O -Wall
+SRCS = emu_vm86.c i10_int.c i10_io.c i10_pci.c i10_v86.c i10_vbios.c
+OBJS = $(SRCS:%.c=%.o)
+
+TARGETLIB = ../libint10.a
+
+all: $(TARGETLIB)
+
+$(TARGETLIB): $(OBJS)
+ @ar rv $(TARGETLIB) $(OBJS)
+
+%.o: %.c
+ $(CC) $(CFLAGS) $(INCS) -c $< -o $@
+
+clean:
+ @rm -f $(TARGETLIB)
+ @rm -f $(OBJS) validate.o
diff --git a/tools/ddcprobe/int10/README b/tools/ddcprobe/int10/README
new file mode 100644
index 000000000..4b7d0fa02
--- /dev/null
+++ b/tools/ddcprobe/int10/README
@@ -0,0 +1,35 @@
+
+This is a preliminary version of a VGA softbooter for LINUX.
+
+It makes use of the of the vm86() call and is therefore only
+usable on ix86 systems.
+There are plans to port this program to use a x86 emulator
+like x86emu. Also it may be ported to other operating systems.
+
+So far it has been tested on a small number of cards. It might
+well be that it will fail on your card.
+
+If you need to make modifications to the programs to be able
+to boot your card please let the author know.
+
+So far there is no command line interface. All options need
+to be hardcoded. You can do this by editing debug.h. You can
+turn on a bunch of debug output. Other options allow you to
+boot the primary card (CONFIG_ACTIVE_DEVICE), save the bios
+to a file (SAVE_BIOS), and map the original system bios
+(MAP_SYS_BIOS).
+
+The author wants to thank
+ Hans Lermen (dosemu)
+ and
+ Kendall Bennett (x86emu)
+for their support.
+
+Parts of the code - especially in v86.c and io.c - are based on code
+taken from dosemu. Parts of the code in int.c are based on code taken
+from x86emu
+
+Egbert Eich. <Egbert.Eich@Physik.TU-Darmstadt.DE>
+
+
+
diff --git a/tools/ddcprobe/int10/emu_vm86.c b/tools/ddcprobe/int10/emu_vm86.c
new file mode 100644
index 000000000..2603a5aeb
--- /dev/null
+++ b/tools/ddcprobe/int10/emu_vm86.c
@@ -0,0 +1,154 @@
+#include <stdio.h>
+#include <stdarg.h>
+#ifdef __i386__
+#include <sys/vm86.h>
+#else
+#include "vm86_struct.h"
+#endif
+
+#define INT2PTR(a) ((a) + (unsigned char *) 0)
+
+#include "../x86emu/include/x86emu.h"
+#include "AsmMacros.h"
+
+int emu_vm86_ret;
+
+static u8 Mem_rb(u32 addr) {
+ return *(u8 *)(INT2PTR(addr));
+}
+static void Mem_wb(u32 addr, u8 val) {
+ *(u8 *)INT2PTR(addr) = val;
+}
+#ifdef __ia64__
+
+static u16 Mem_rw(u32 addr) {
+ return *(u8 *)INT2PTR(addr) | *(u8 *)INT2PTR(addr + 1) << 8;
+}
+static u32 Mem_rl(u32 addr) {
+ return *(u8 *)INT2PTR(addr) | *(u8 *)INT2PTR(addr + 1) << 8 |
+ *(u8 *)INT2PTR(addr + 2) << 16 | *(u8 *)INT2PTR(addr + 3) << 24;
+}
+static void Mem_ww(u32 addr, u16 val) {
+ *(u8 *)INT2PTR(addr) = val;
+ *(u8 *)INT2PTR(addr + 1) = val >> 8;
+}
+static void Mem_wl(u32 addr, u32 val) {
+ *(u8 *)INT2PTR(addr) = val;
+ *(u8 *)INT2PTR(addr + 1) = val >> 8;
+ *(u8 *)INT2PTR(addr + 2) = val >> 16;
+ *(u8 *)INT2PTR(addr + 3) = val >> 24;
+}
+
+#else
+
+static u16 Mem_rw(u32 addr) {
+ return *(u16 *)INT2PTR(addr);
+}
+static u32 Mem_rl(u32 addr) {
+ return *(u32 *)INT2PTR(addr);
+}
+static void Mem_ww(u32 addr, u16 val) {
+ *(u16 *)INT2PTR(addr) = val;
+}
+static void Mem_wl(u32 addr, u32 val) {
+ *(u32 *)INT2PTR(addr) = val;
+}
+
+#endif
+
+static void do_int(int num) {
+ emu_vm86_ret = VM86_INTx | (num << 8);
+ M.x86.intr = INTR_HALTED;
+}
+
+
+int
+emu_vm86(struct vm86_struct *vm)
+{
+ int i;
+
+ X86EMU_memFuncs memFuncs;
+ X86EMU_intrFuncs intFuncs[256];
+ X86EMU_pioFuncs pioFuncs;
+
+ memFuncs.rdb = Mem_rb;
+ memFuncs.rdw = Mem_rw;
+ memFuncs.rdl = Mem_rl;
+ memFuncs.wrb = Mem_wb;
+ memFuncs.wrw = Mem_ww;
+ memFuncs.wrl = Mem_wl;
+ X86EMU_setupMemFuncs(&memFuncs);
+
+ pioFuncs.inb = (u8(*)(u16))inb;
+ pioFuncs.inw = (u16(*)(u16))inw;
+ pioFuncs.inl = (u32(*)(u16))inl;
+ pioFuncs.outb = (void(*)(u16, u8))outb;
+ pioFuncs.outw = (void(*)(u16, u16))outw;
+ pioFuncs.outl = (void(*)(u16, u32))outl;
+ X86EMU_setupPioFuncs(&pioFuncs);
+
+ for (i=0;i<256;i++)
+ intFuncs[i] = do_int;
+ X86EMU_setupIntrFuncs(intFuncs);
+
+ M.mem_base = 0;
+ M.mem_size = 1024*1024 + 1024;
+
+ M.x86.R_EAX = vm->regs.eax;
+ M.x86.R_EBX = vm->regs.ebx;
+ M.x86.R_ECX = vm->regs.ecx;
+ M.x86.R_EDX = vm->regs.edx;
+
+ M.x86.R_ESP = vm->regs.esp;
+ M.x86.R_EBP = vm->regs.ebp;
+ M.x86.R_ESI = vm->regs.esi;
+ M.x86.R_EDI = vm->regs.edi;
+ M.x86.R_EIP = vm->regs.eip;
+ M.x86.R_EFLG = vm->regs.eflags;
+
+ M.x86.R_CS = vm->regs.cs;
+ M.x86.R_DS = vm->regs.ds;
+ M.x86.R_SS = vm->regs.ss;
+ M.x86.R_ES = vm->regs.es;
+ M.x86.R_FS = vm->regs.fs;
+ M.x86.R_GS = vm->regs.gs;
+
+ emu_vm86_ret = 0;
+ X86EMU_exec();
+
+ vm->regs.eax = M.x86.R_EAX;
+ vm->regs.ebx = M.x86.R_EBX;
+ vm->regs.ecx = M.x86.R_ECX;
+ vm->regs.edx = M.x86.R_EDX;
+
+ vm->regs.esp = M.x86.R_ESP;
+ vm->regs.ebp = M.x86.R_EBP;
+ vm->regs.esi = M.x86.R_ESI;
+ vm->regs.edi = M.x86.R_EDI;
+ vm->regs.eip = M.x86.R_EIP;
+ vm->regs.eflags = M.x86.R_EFLG;
+
+ vm->regs.cs = M.x86.R_CS;
+ vm->regs.ds = M.x86.R_DS;
+ vm->regs.ss = M.x86.R_SS;
+ vm->regs.es = M.x86.R_ES;
+ vm->regs.fs = M.x86.R_FS;
+ vm->regs.gs = M.x86.R_GS;
+
+ if (emu_vm86_ret == 0 && *(unsigned char *)INT2PTR(((u32)M.x86.R_CS << 4) + (M.x86.R_IP - 1)) == 0xf4)
+ {
+ vm->regs.eip--;
+ return VM86_UNKNOWN;
+ }
+ return emu_vm86_ret ? emu_vm86_ret : -1;
+}
+
+void
+printk(const char *fmt, ...)
+{
+ va_list argptr;
+ va_start(argptr, fmt);
+ vfprintf(stderr, fmt, argptr);
+ va_end(argptr);
+}
+
diff --git a/tools/ddcprobe/int10/i10_int.c b/tools/ddcprobe/int10/i10_int.c
new file mode 100644
index 000000000..99a009d0a
--- /dev/null
+++ b/tools/ddcprobe/int10/i10_int.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1999 Egbert Eich
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#if defined(__alpha__) || defined (__ia64__)
+#include <sys/io.h>
+#endif
+
+#include "v86bios.h"
+#include "AsmMacros.h"
+#include "pci.h"
+
+static int int1A_handler(struct regs86 *regs);
+static int int42_handler(int num, struct regs86 *regs);
+
+int
+int_handler(int num, struct regs86 *regs)
+{
+ switch (num) {
+ case 0x10:
+ case 0x42:
+ return (int42_handler(num,regs));
+ case 0x1A:
+ return (int1A_handler(regs));
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+static int
+int42_handler(int num,struct regs86 *regs)
+{
+ unsigned char c;
+ CARD32 val;
+
+ /*
+ * video bios has modified these -
+ * leave it to the video bios to do this
+ */
+
+ val = getIntVect(num);
+ if (val != 0xF000F065)
+ return 0;
+
+ if ((regs->ebx & 0xff) == 0x32) {
+ switch (regs->eax & 0xFFFF) {
+ case 0x1200:
+ c = inb(0x3cc);
+ c |= 0x02;
+ outb(0x3c2,c);
+ return 1;
+ case 0x1201:
+ c = inb(0x3cc);
+ c &= ~0x02;
+ outb(0x3c2,c);
+ return 1;
+ }
+ }
+ if (num == 0x42)
+ return 1;
+ else
+ return 0;
+}
+
+#define SUCCESSFUL 0x00
+#define DEVICE_NOT_FOUND 0x86
+#define BAD_REGISTER_NUMBER 0x87
+
+static int
+int1A_handler(struct regs86 *regs)
+{
+ CARD32 Slot;
+// PciStructPtr pPci;
+
+ if (! CurrentPci) return 0; /* oops */
+
+ switch (regs->eax & 0xFFFF) {
+ case 0xb101:
+ regs->eax &= 0xFF00; /* no config space/special cycle support */
+ regs->edx = 0x20494350; /* " ICP" */
+ regs->ebx = 0x0210; /* Version 2.10 */
+ regs->ecx &= 0xFF00;
+ regs->ecx |= (pciMaxBus & 0xFF); /* Max bus number in system */
+ regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */
+ return 1;
+ case 0xb102:
+ if (((regs->edx & 0xFFFF) == CurrentPci->VendorID) &&
+ ((regs->ecx & 0xFFFF) == CurrentPci->DeviceID) &&
+ (regs->esi == 0)) {
+ regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8);
+ regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */
+ regs->ebx = pciSlotBX(CurrentPci);
+ } else {
+ regs->eax = (regs->eax & 0x00FF) | (DEVICE_NOT_FOUND << 8);
+ regs->eflags |= ((unsigned long)0x01); /* set carry flag */
+ }
+ return 1;
+ case 0xb103:
+ if (((regs->ecx & 0xFF) == CurrentPci->Interface) &&
+ (((regs->ecx & 0xFF00) >> 8) == CurrentPci->SubClass) &&
+ (((regs->ecx & 0xFFFF0000) >> 16) == CurrentPci->BaseClass) &&
+ ((regs->esi & 0xff) == 0)) {
+ regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8);
+ regs->ebx = pciSlotBX(CurrentPci);
+ regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */
+ } else {
+ regs->eax = (regs->eax & 0x00FF) | (DEVICE_NOT_FOUND << 8);
+ regs->eflags |= ((unsigned long)0x01); /* set carry flag */
+ }
+ return 1;
+ case 0xb108:
+ if ((Slot = findPci(regs->ebx))) {
+ regs->ecx &= 0xFFFFFF00;
+ regs->ecx |= PciRead8(regs->edi,Slot);
+ regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8);
+ regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */
+ } else {
+ regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8);
+ regs->eflags |= ((unsigned long)0x01); /* set carry flag */
+ }
+ return 1;
+ case 0xb109:
+ if ((Slot = findPci(regs->ebx))) {
+ regs->ecx &= 0xFFFF0000;
+ regs->ecx |= PciRead16(regs->edi,Slot);
+ regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8);
+ regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */
+ } else {
+ regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8);
+ regs->eflags |= ((unsigned long)0x01); /* set carry flag */
+ }
+ return 1;
+ case 0xb10a:
+ if ((Slot = findPci(regs->ebx))) {
+ regs->ecx &= 0;
+ regs->ecx |= PciRead32(regs->edi,Slot);
+ regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8);
+ regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */
+ } else {
+ regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8);
+ regs->eflags |= ((unsigned long)0x01); /* set carry flag */
+ }
+ return 1;
+ case 0xb10b:
+ if ((Slot = findPci(regs->ebx))) {
+ PciWrite8(regs->edi,(CARD8)regs->ecx,Slot);
+ regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8);
+ regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */
+ } else {
+ regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8);
+ regs->eflags |= ((unsigned long)0x01); /* set carry flag */
+ }
+ return 1;
+ case 0xb10c:
+ if ((Slot = findPci(regs->ebx))) {
+ PciWrite16(regs->edi,(CARD16)regs->ecx,Slot);
+ regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8);
+ regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */
+ } else {
+ regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8);
+ regs->eflags |= ((unsigned long)0x01); /* set carry flag */
+ }
+ return 1;
+ case 0xb10d:
+ if ((Slot = findPci(regs->ebx))) {
+ PciWrite32(regs->edi,(CARD32)regs->ecx,Slot);
+ regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8);
+ regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */
+ } else {
+ regs->eax = (regs->eax & 0x00FF) | (BAD_REGISTER_NUMBER << 8);
+ regs->eflags |= ((unsigned long)0x01); /* set carry flag */
+ }
+ return 1;
+ default:
+ return 0;
+ }
+}
diff --git a/tools/ddcprobe/int10/i10_io.c b/tools/ddcprobe/int10/i10_io.c
new file mode 100644
index 000000000..717356f47
--- /dev/null
+++ b/tools/ddcprobe/int10/i10_io.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1999 Egbert Eich
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#if defined(__alpha__) || defined (__ia64__)
+#include <sys/io.h>
+#endif
+#include "AsmMacros.h"
+#include "v86bios.h"
+#include "pci.h"
+
+
+int
+port_rep_inb(CARD16 port, CARD8 *base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -1 : 1;
+ CARD8 *dst = base;
+
+ while (count--) {
+ *dst = inb(port);
+ dst += inc;
+ }
+ return (dst-base);
+}
+
+int
+port_rep_inw(CARD16 port, CARD16 *base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -1 : 1;
+ CARD16 *dst = base;
+
+ while (count--) {
+ *dst = inw(port);
+ dst += inc;
+ }
+ return (dst-base);
+}
+
+int
+port_rep_inl(CARD16 port, CARD32 *base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -1 : 1;
+ CARD32 *dst = base;
+
+ while (count--) {
+ *dst = inl(port);
+ dst += inc;
+ }
+ return (dst-base);
+}
+
+int
+port_rep_outb(CARD16 port, CARD8 *base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -1 : 1;
+ CARD8 *dst = base;
+
+ while (count--) {
+ outb(port,*dst);
+ dst += inc;
+ }
+ return (dst-base);
+}
+
+int
+port_rep_outw(CARD16 port, CARD16 *base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -1 : 1;
+ CARD16 *dst = base;
+
+ while (count--) {
+ outw(port,*dst);
+ dst += inc;
+ }
+ return (dst-base);
+}
+
+int
+port_rep_outl(CARD16 port, CARD32 *base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -1 : 1;
+ CARD32 *dst = base;
+
+ while (count--) {
+ outl(port,*dst);
+ dst += inc;
+ }
+ return (dst-base);
+}
diff --git a/tools/ddcprobe/int10/i10_pci.c b/tools/ddcprobe/int10/i10_pci.c
new file mode 100644
index 000000000..387cebb65
--- /dev/null
+++ b/tools/ddcprobe/int10/i10_pci.c
@@ -0,0 +1,866 @@
+/*
+ * Copyright 1999 Egbert Eich
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <fcntl.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#if defined (__alpha__) || defined (__ia64__)
+#include <sys/io.h>
+#endif
+#include "AsmMacros.h"
+
+#include "pci.h"
+
+#define RESORT 1
+#define FIX_ROM 0
+
+/*
+ * I'm rather simple mindend - therefore I do a poor man's
+ * pci scan without all the fancy stuff that is done in
+ * scanpci. However that's all we need.
+ */
+
+PciStructPtr PciStruct = NULL;
+PciBusPtr PciBuses = NULL;
+PciStructPtr CurrentPci = NULL;
+PciStructPtr PciList = NULL;
+int pciMaxBus = 0;
+
+static CARD32 PciCfg1Addr;
+
+static void readConfigSpaceCfg1(CARD32 bus, CARD32 dev, CARD32 func,
+ CARD32 *reg);
+static int checkSlotCfg1(CARD32 bus, CARD32 dev, CARD32 func);
+static int checkSlotCfg2(CARD32 bus, int dev);
+static void readConfigSpaceCfg2(CARD32 bus, int dev, CARD32 *reg);
+static CARD8 interpretConfigSpace(CARD32 *reg, int busidx,
+ CARD8 dev, CARD8 func);
+static CARD32 findBIOSMap(PciStructPtr pciP, CARD32 *biosSize);
+static void restoreMem(PciStructPtr pciP);
+
+
+#ifdef __alpha__
+#define PCI_BUS_FROM_TAG(tag) (((tag) & 0x00ff0000) >> 16)
+#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00) >> 8)
+
+#include <asm/unistd.h>
+
+CARD32
+axpPciCfgRead(CARD32 tag)
+{
+ int bus, dfn;
+ CARD32 val = 0xffffffff;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ dfn = PCI_DFN_FROM_TAG(tag);
+
+ syscall(__NR_pciconfig_read, bus, dfn, tag & 0xff, 4, &val);
+ return(val);
+}
+
+void
+axpPciCfgWrite(CARD32 tag, CARD32 val)
+{
+ int bus, dfn;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ dfn = PCI_DFN_FROM_TAG(tag);
+
+ syscall(__NR_pciconfig_write, bus, dfn, tag & 0xff, 4, &val);
+}
+
+static CARD32 (*readPci)(CARD32 reg) = axpPciCfgRead;
+static void (*writePci)(CARD32 reg, CARD32 val) = axpPciCfgWrite;
+#else
+static CARD32 readPciCfg1(CARD32 reg);
+static void writePciCfg1(CARD32 reg, CARD32 val);
+#ifndef __ia64__
+static CARD32 readPciCfg2(CARD32 reg);
+static void writePciCfg2(CARD32 reg, CARD32 val);
+#endif
+
+static CARD32 (*readPci)(CARD32 reg) = readPciCfg1;
+static void (*writePci)(CARD32 reg, CARD32 val) = writePciCfg1;
+#endif
+
+#if defined(__alpha__) || defined(__sparc__)
+#define PCI_EN 0x00000000
+#else
+#define PCI_EN 0x80000000
+#endif
+
+
+static int numbus;
+static int hostbridges = 1;
+static unsigned long pciMinMemReg = ~0;
+
+
+
+void
+scan_pci(int pci_cfg_method)
+{
+ unsigned short configtype;
+
+ CARD32 reg[64];
+ int busidx;
+ CARD8 cardnum;
+ CARD8 func;
+ int idx;
+
+ PciStructPtr pci1;
+ PciBusPtr pci_b1,pci_b2;
+
+ if(pci_cfg_method) {
+ configtype = pci_cfg_method;
+ }
+ else {
+#if defined(__alpha__) || defined(__powerpc__) || defined(__sparc__) || defined(__ia64__)
+ configtype = 1;
+#else
+ CARD8 tmp1, tmp2;
+ CARD32 tmp32_1, tmp32_2;
+ outb(PCI_MODE2_ENABLE_REG, 0x00);
+ outb(PCI_MODE2_FORWARD_REG, 0x00);
+ tmp1 = inb(PCI_MODE2_ENABLE_REG);
+ tmp2 = inb(PCI_MODE2_FORWARD_REG);
+ if ((tmp1 == 0x00) && (tmp2 == 0x00)) {
+ configtype = 2;
+ readPci = readPciCfg2;
+ writePci = writePciCfg2;
+ } else {
+ tmp32_1 = inl(PCI_MODE1_ADDRESS_REG);
+ outl(PCI_MODE1_ADDRESS_REG, PCI_EN);
+ tmp32_2 = inl(PCI_MODE1_ADDRESS_REG);
+ outl(PCI_MODE1_ADDRESS_REG, tmp32_1);
+ if (tmp32_2 == PCI_EN) {
+ configtype = 1;
+ } else {
+ return;
+ }
+ }
+#endif
+ }
+
+ if (configtype == 1) {
+ busidx = 0;
+ numbus = 1;
+ idx = 0;
+ do {
+ for (cardnum = 0; cardnum < MAX_DEV_PER_VENDOR_CFG1; cardnum++) {
+ func = 0;
+ do {
+ /* loop over the different functions, if present */
+ if (!checkSlotCfg1(busidx,cardnum,func)) {
+ if (!func)
+ break;
+ else {
+ func++;
+ continue;
+ }
+ }
+ readConfigSpaceCfg1(busidx,cardnum,func,reg);
+
+ func = interpretConfigSpace(reg,busidx,
+ cardnum,func);
+
+ if (++idx >= MAX_PCI_DEVICES)
+ break;
+ } while (func < 8);
+ if (idx >= MAX_PCI_DEVICES)
+ break;
+ }
+ if (idx >= MAX_PCI_DEVICES)
+ break;
+ } while (++busidx < PCI_MAXBUS);
+#if defined(__alpha__) || defined(__powerpc__) || defined(__sparc__) || defined(__ia64__)
+ /* don't use outl() ;-) */
+#else
+ outl(PCI_MODE1_ADDRESS_REG, 0);
+#endif
+ } else {
+ int slot;
+
+ busidx = 0;
+ numbus = 1;
+ idx = 0;
+ do {
+ for (slot=0xc0; slot<0xd0; slot++) {
+ if (!checkSlotCfg2(busidx,slot))
+ break;
+ readConfigSpaceCfg2(busidx,slot,reg);
+
+ interpretConfigSpace(reg,busidx,
+ slot,0);
+ if (++idx >= MAX_PCI_DEVICES)
+ break;
+ }
+ if (idx >= MAX_PCI_DEVICES)
+ break;
+ } while (++busidx < PCI_MAXBUS);
+ }
+
+
+ pciMaxBus = numbus - 1;
+
+ /* link buses */
+ pci_b1 = PciBuses;
+ while (pci_b1) {
+ pci_b2 = PciBuses;
+ pci_b1->pBus = NULL;
+ while (pci_b2) {
+ if (pci_b1->primary == pci_b2->secondary)
+ pci_b1->pBus = pci_b2;
+ pci_b2 = pci_b2->next;
+ }
+ pci_b1 = pci_b1->next;
+ }
+ pci1 = PciStruct;
+ while (pci1) {
+ pci_b2 = PciBuses;
+ pci1->pBus = NULL;
+ while (pci_b2) {
+ if (pci1->bus == pci_b2->secondary)
+ pci1->pBus = pci_b2;
+ pci_b2 = pci_b2->next;
+ }
+ pci1 = pci1->next;
+ }
+ if (RESORT) {
+ PciStructPtr tmp = PciStruct, tmp1;
+ PciStruct = NULL;
+ while (tmp) {
+ tmp1 = tmp->next;
+ tmp->next = PciStruct;
+ PciStruct = tmp;
+ tmp = tmp1;
+ }
+ }
+ PciList = CurrentPci = PciStruct;
+}
+
+#ifndef __alpha__
+static CARD32
+readPciCfg1(CARD32 reg)
+{
+ CARD32 val;
+
+ outl(PCI_MODE1_ADDRESS_REG, reg);
+ val = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, 0);
+ return val;
+}
+
+static void
+writePciCfg1(CARD32 reg, CARD32 val)
+{
+ outl(PCI_MODE1_ADDRESS_REG, reg);
+ outl(PCI_MODE1_DATA_REG,val);
+ outl(PCI_MODE1_ADDRESS_REG, 0);
+}
+
+#ifndef __ia64__
+static CARD32
+readPciCfg2(CARD32 reg)
+{
+ CARD32 val;
+ CARD8 bus = (reg >> 16) & 0xff;
+ CARD8 dev = (reg >> 11) & 0x1f;
+ CARD8 num = reg & 0xff;
+
+ outb(PCI_MODE2_ENABLE_REG, 0xF1);
+ outb(PCI_MODE2_FORWARD_REG, bus);
+ val = inl((dev << 8) + num);
+ outb(PCI_MODE2_ENABLE_REG, 0x00);
+ return val;
+}
+
+static void
+writePciCfg2(CARD32 reg, CARD32 val)
+{
+ CARD8 bus = (reg >> 16) & 0xff;
+ CARD8 dev = (reg >> 11) & 0x1f;
+ CARD8 num = reg & 0xff;
+
+ outb(PCI_MODE2_ENABLE_REG, 0xF1);
+ outb(PCI_MODE2_FORWARD_REG, bus);
+ outl((dev << 8) + num,val);
+ outb(PCI_MODE2_ENABLE_REG, 0x00);
+}
+#endif
+#endif
+
+void
+pciVideoDisable(void)
+{
+ /* disable VGA routing on bridges */
+ PciBusPtr pbp = PciBuses;
+ PciStructPtr pcp = PciStruct;
+
+ while (pbp) {
+ writePci(pbp->Slot.l | 0x3c, pbp->bctl & ~(CARD32)(8<<16));
+ pbp = pbp->next;
+ }
+ /* disable display devices */
+ while (pcp) {
+ writePci(pcp->Slot.l | 0x04, pcp->cmd_st & ~(CARD32)3);
+ writePci(pcp->Slot.l | 0x30, pcp->RomBase & ~(CARD32)1);
+ pcp = pcp->next;
+ }
+}
+
+void
+pciVideoRestore(void)
+{
+ /* disable VGA routing on bridges */
+ PciBusPtr pbp = PciBuses;
+ PciStructPtr pcp = PciStruct;
+
+ while (pbp) {
+ writePci(pbp->Slot.l | 0x3c, pbp->bctl);
+ pbp = pbp->next;
+ }
+ /* disable display devices */
+ while (pcp) {
+ writePci(pcp->Slot.l | 0x04, pcp->cmd_st);
+ writePci(pcp->Slot.l | 0x30, pcp->RomBase);
+ pcp = pcp->next;
+ }
+}
+
+void
+EnableCurrent()
+{
+ PciBusPtr pbp;
+ PciStructPtr pcp = CurrentPci;
+
+ pciVideoDisable();
+
+ pbp = pcp->pBus;
+ while (pbp) { /* enable bridges */
+ writePci(pbp->Slot.l | 0x3c, pbp->bctl | (CARD32)(8<<16));
+ pbp = pbp->pBus;
+ }
+ writePci(pcp->Slot.l | 0x04, pcp->cmd_st | (CARD32)3);
+ writePci(pcp->Slot.l | 0x30, pcp->RomBase | (CARD32)1);
+}
+
+CARD8
+PciRead8(int offset, CARD32 Slot)
+{
+ int shift = offset & 0x3;
+ offset = offset & 0xFC;
+ return ((readPci(Slot | offset) >> (shift << 3)) & 0xff);
+}
+
+CARD16
+PciRead16(int offset, CARD32 Slot)
+{
+ int shift = offset & 0x2;
+ offset = offset & 0xFC;
+ return ((readPci(Slot | offset) >> (shift << 3)) & 0xffff);
+}
+
+CARD32
+PciRead32(int offset, CARD32 Slot)
+{
+ offset = offset & 0xFC;
+ return (readPci(Slot | offset));
+}
+
+void
+PciWrite8(int offset, CARD8 byte, CARD32 Slot)
+{
+ CARD32 val;
+ int shift = offset & 0x3;
+ offset = offset & 0xFC;
+ val = readPci(Slot | offset);
+ val &= ~(CARD32)(0xff << (shift << 3));
+ val |= byte << (shift << 3);
+ writePci(Slot | offset, val);
+}
+
+void
+PciWrite16(int offset, CARD16 word, CARD32 Slot)
+{
+ CARD32 val;
+ int shift = offset & 0x2;
+ offset = offset & 0xFC;
+ val = readPci(Slot | offset);
+ val &= ~(CARD32)(0xffff << (shift << 3));
+ val |= word << (shift << 3);
+ writePci(Slot | offset, val);
+}
+
+void
+PciWrite32(int offset, CARD32 lg, CARD32 Slot)
+{
+ offset = offset & 0xFC;
+ writePci(Slot | offset, lg);
+}
+
+int
+mapPciRom(PciStructPtr pciP)
+{
+ unsigned long RomBase = 0;
+ int mem_fd;
+ unsigned char *mem, *ptr;
+ unsigned char *scratch = NULL;
+ int length = 0;
+ CARD32 biosSize = 0x1000000;
+ CARD32 enablePci = 0; /* to keep gcc happy */
+
+ if (!pciP)
+ pciP = CurrentPci;
+
+ if (FIX_ROM) {
+ RomBase = findBIOSMap(pciP, &biosSize);
+ if (!RomBase) {
+ RomBase = pciP->RomBase & ~(CARD32)0xFF;
+ }
+ } else {
+ RomBase = pciP->RomBase & ~(CARD32)0xFF;
+ if (~RomBase + 1 < biosSize || !RomBase)
+ RomBase = findBIOSMap(pciP, &biosSize);
+ }
+
+ if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
+ perror("opening memory");
+ restoreMem(pciP);
+ return (0);
+ }
+
+ PciWrite32(0x30,RomBase | 1,pciP->Slot.l);
+
+#ifdef __alpha__
+ mem = ptr = (unsigned char *)mmap(0, biosSize, PROT_READ,
+ MAP_SHARED, mem_fd, RomBase | _bus_base());
+#else
+ mem = ptr = (unsigned char *)mmap(0, biosSize, PROT_READ,
+ MAP_SHARED, mem_fd, RomBase);
+#endif
+ if (pciP != CurrentPci) {
+ enablePci = PciRead32(0x4,pciP->Slot.l);
+ PciWrite32(0x4,enablePci | 0x2,pciP->Slot.l);
+ }
+
+ while ( *ptr == 0x55 && *(ptr+1) == 0xAA) {
+ unsigned short data_off = *(ptr+0x18) | (*(ptr+0x19)<< 8);
+ unsigned char *data = ptr + data_off;
+ unsigned char type;
+ int i;
+
+ if (*data!='P' || *(data+1)!='C' || *(data+2)!='I' || *(data+3)!='R') {
+ break;
+ }
+ type = *(data + 0x14);
+
+ if (type != 0) { /* not PC-AT image: find next one */
+ unsigned int image_length;
+ unsigned char indicator = *(data + 0x15);
+ if (indicator & 0x80) /* last image */
+ break;
+ image_length = (*(data + 0x10)
+ | (*(data + 0x11) << 8)) << 9;
+ ptr = ptr + image_length;
+ continue;
+ }
+ /* OK, we have a PC Image */
+ length = (*(ptr + 2) << 9);
+ scratch = (unsigned char *)malloc(length);
+ /* don't use memcpy() here: Reading from bus! */
+ for (i=0;i<length;i++)
+ *(scratch + i)=*(ptr + i);
+ break;
+ }
+
+ if (pciP != CurrentPci)
+ PciWrite32(0x4,enablePci,pciP->Slot.l);
+
+ /* unmap/close/disable PCI bios mem */
+ munmap(mem, biosSize);
+ close(mem_fd);
+ /* disable and restore mapping */
+ writePci(pciP->Slot.l | 0x30, pciP->RomBase & ~(CARD32)1);
+
+ if (scratch && length) {
+ memcpy((unsigned char *)V_BIOS, scratch, length);
+ free(scratch);
+ }
+
+ restoreMem(pciP);
+ return length;
+}
+
+CARD32
+findPci(CARD16 slotBX)
+{
+ CARD32 slot = slotBX << 8;
+
+ if (slot == (CurrentPci->Slot.l & ~PCI_EN))
+ return (CurrentPci->Slot.l | PCI_EN);
+ else {
+#if !SHOW_ALL_DEV
+ PciBusPtr pBus = CurrentPci->pBus;
+ while (pBus) {
+ if (slot == (pBus->Slot.l & ~PCI_EN))
+ return pBus->Slot.l | PCI_EN;
+ pBus = pBus->next;
+ }
+#else
+ PciStructPtr pPci = PciStruct;
+ while (pPci) {
+ if (slot == (pPci->Slot.l & ~PCI_EN))
+ return pPci->Slot.l | PCI_EN;
+ pPci = pPci->next;
+ }
+#endif
+ }
+ return 0;
+}
+
+CARD16
+pciSlotBX(PciStructPtr pPci)
+{
+ return (CARD16)((pPci->Slot.l >> 8) & 0xFFFF);
+}
+
+PciStructPtr
+findPciDevice(CARD16 vendorID, CARD16 deviceID, char n)
+{
+ PciStructPtr pPci = CurrentPci;
+ n++;
+
+ while (pPci) {
+ if ((pPci->VendorID == vendorID) && (pPci->DeviceID == deviceID)) {
+ if (!(--n)) break;
+ }
+ pPci = pPci->next;
+ }
+ return pPci;
+}
+
+PciStructPtr
+findPciClass(CARD8 intf, CARD8 subClass, CARD16 class, char n)
+{
+ PciStructPtr pPci = CurrentPci;
+ n++;
+
+ while (pPci) {
+ if ((pPci->Interface == intf) && (pPci->SubClass == subClass)
+ && (pPci->BaseClass == class)) {
+ if (!(--n)) break;
+ }
+ pPci = pPci->next;
+ }
+ return pPci;
+}
+
+static void
+readConfigSpaceCfg1(CARD32 bus, CARD32 dev, CARD32 func, CARD32 *reg)
+{
+ CARD32 config_cmd = PCI_EN | (bus<<16) |
+ (dev<<11) | (func<<8);
+ int i;
+
+ for (i = 0; i<64;i+=4) {
+#ifdef __alpha__
+ reg[i] = axpPciCfgRead(config_cmd | i);
+#else
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | i);
+ reg[i] = inl(PCI_MODE1_DATA_REG);
+#endif
+
+ }
+}
+
+static int
+checkSlotCfg1(CARD32 bus, CARD32 dev, CARD32 func)
+{
+ CARD32 config_cmd = PCI_EN | (bus<<16) |
+ (dev<<11) | (func<<8);
+ CARD32 reg;
+#ifdef __alpha__
+ reg = axpPciCfgRead(config_cmd);
+#else
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd);
+ reg = inl(PCI_MODE1_DATA_REG);
+#endif
+ if (reg != 0xFFFFFFFF)
+ return 1;
+ else
+ return 0;
+}
+
+static int
+checkSlotCfg2(CARD32 bus, int dev)
+{
+ CARD32 val;
+
+ outb(PCI_MODE2_ENABLE_REG, 0xF1);
+ outb(PCI_MODE2_FORWARD_REG, bus);
+ val = inl(dev << 8);
+ outb(PCI_MODE2_FORWARD_REG, 0x00);
+ outb(PCI_MODE2_ENABLE_REG, 0x00);
+ if (val == 0xFFFFFFFF)
+ return 0;
+ if (val == 0xF0F0F0F0)
+ return 0;
+ return 1;
+}
+
+static void
+readConfigSpaceCfg2(CARD32 bus, int dev, CARD32 *reg)
+{
+ int i;
+
+ outb(PCI_MODE2_ENABLE_REG, 0xF1);
+ outb(PCI_MODE2_FORWARD_REG, bus);
+ for (i = 0; i<64;i+=4) {
+ reg[i] = inl((dev << 8) + i);
+ }
+ outb(PCI_MODE2_ENABLE_REG, 0x00);
+}
+
+static CARD8
+interpretConfigSpace(CARD32 *reg, int busidx, CARD8 dev, CARD8 func)
+{
+ CARD32 config_cmd;
+ CARD16 vendor, device;
+ CARD8 baseclass, subclass;
+ CARD8 primary, secondary;
+ CARD8 header, interface;
+ int i;
+
+ config_cmd = PCI_EN | busidx<<16 |
+ (dev<<11) | (func<<8);
+
+ for (i = 0x10; i < 0x28; i+=4) {
+ if (IS_MEM32(reg[i]))
+ if ((reg[i] & 0xFFFFFFF0) < pciMinMemReg)
+ pciMinMemReg = (reg[i] & 0xFFFFFFF0);
+#ifdef __alpha__
+ if (IS_MEM64(reg[i])) {
+ unsigned long addr = reg[i] |
+ (unsigned long)(reg[i+4]) << 32;
+ if ((addr & ~0xfL) < pciMinMemReg)
+ pciMinMemReg = (addr & ~0xfL);
+ i+=4;
+ }
+#endif
+ }
+ vendor = reg[0] & 0xFFFF;
+ device = reg[0] >> 16;
+ baseclass = reg[8] >> 24;
+ subclass = (reg[8] >> 16) & 0xFF;
+ interface = (reg[8] >> 8) & 0xFF;
+
+ header = (reg[0x0c] >> 16) & 0xff;
+ if (BRIDGE_CLASS(baseclass)) {
+ if (BRIDGE_PCI_CLASS(subclass)) {
+ PciBusPtr pbp = malloc(sizeof(PciBusRec));
+ primary = reg[0x18] & 0xFF;
+ secondary = (reg[0x18] >> 8) & 0xFF;
+ pbp->bctl = reg[0x3c];
+ pbp->primary = primary;
+ pbp->secondary = secondary;
+ pbp->Slot.l = config_cmd;
+ pbp->next = PciBuses;
+ PciBuses = pbp;
+ numbus++;
+ } else if (BRIDGE_HOST_CLASS(subclass)
+ && (hostbridges++ > 1)) {
+ numbus++;
+ }
+ } else if (VIDEO_CLASS(baseclass,subclass)) {
+ PciStructPtr pcp = malloc(sizeof(PciStructRec));
+ pcp->RomBase = reg[0x30];
+ pcp->cmd_st = reg[4];
+ pcp->active = (reg[4] & 0x03) == 3 ? 1 : 0;
+ pcp->VendorID = vendor;
+ pcp->DeviceID = device;
+ pcp->Interface = interface;
+ pcp->BaseClass = baseclass;
+ pcp->SubClass = subclass;
+ pcp->Slot.l = config_cmd;
+ pcp->bus = busidx;
+ pcp->dev = dev;
+ pcp->func = func;
+ pcp->next = PciStruct;
+ PciStruct = pcp;
+ }
+ if ((func == 0)
+ && ((header & PCI_MULTIFUNC_DEV) == 0))
+ func = 8;
+ else
+ func++;
+ return func;
+}
+
+static CARD32 remapMEM_val;
+static int remapMEM_num;
+
+static int /* map it on some other video device */
+remapMem(PciStructPtr pciP, int num, CARD32 size)
+{
+ PciStructPtr pciPtr = PciStruct;
+ int i;
+ CARD32 org;
+ CARD32 val;
+ CARD32 size_n;
+
+ org = PciRead32(num + 0x10,pciP->Slot.l);
+
+ while (pciPtr) {
+ for (i = 0; i < 20; i=i+4) {
+
+ val = PciRead32(i + 0x10,pciPtr->Slot.l);
+ /* don't map it on itself */
+ if ((org & 0xfffffff0) == (val & 0xfffffff0))
+ continue;
+ if (val && !(val & 1))
+ PciWrite32(i + 0x10,0xffffffff,pciPtr->Slot.l);
+ else
+ continue;
+ size_n = PciRead32(i + 0x10,pciPtr->Slot.l);
+ PciWrite32(i + 0x10,val,pciPtr->Slot.l);
+ size_n = ~(CARD32)(size_n & 0xfffffff0) + 1;
+
+ if (size_n >= size) {
+ PciWrite32(num + 0x10,val,pciP->Slot.l);
+ return 1;
+ }
+ }
+ pciPtr = pciPtr->next;
+ }
+ /* last resort: try to go below lowest PCI mem address */
+ val = ((pciMinMemReg & ~(CARD32)(size - 1)) - size);
+ if (val > 0x7fffffff) {
+ PciWrite32(num + 0x10,val, pciP->Slot.l);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+restoreMem(PciStructPtr pciP)
+{
+ if (remapMEM_val == 0) return;
+ PciWrite32(remapMEM_num + 0x10,remapMEM_val,pciP->Slot.l);
+ return;
+}
+
+static CARD32
+findBIOSMap(PciStructPtr pciP, CARD32 *biosSize)
+{
+ PciStructPtr pciPtr = PciStruct;
+ int i;
+ CARD32 val;
+ CARD32 size = 4*1024; /* should be fixed: size seems _really_ to be undefined below */
+
+ PciWrite32(0x30,0xffffffff,pciP->Slot.l);
+ *biosSize = PciRead32(0x30,pciP->Slot.l);
+ PciWrite32(0x30,pciP->RomBase,pciP->Slot.l);
+ *biosSize = ~(*biosSize & 0xFFFFFF00) + 1;
+ if (*biosSize > (1024 * 1024 * 16)) {
+ *biosSize = 1024 * 1024 * 16;
+ }
+ while (pciPtr) {
+ if (pciPtr->bus != pciP->bus) {
+ pciPtr = pciPtr->next;
+ continue;
+ }
+ for (i = 0; i < 20; i=i+4) {
+
+ val = PciRead32(i + 0x10,pciPtr->Slot.l);
+ if (!(val & 1))
+
+ PciWrite32(i + 0x10,0xffffffff,pciPtr->Slot.l);
+ else
+ continue;
+ size = PciRead32(i + 0x10,pciPtr->Slot.l);
+ PciWrite32(i + 0x10,val,pciPtr->Slot.l);
+ size = ~(CARD32)(size & 0xFFFFFFF0) + 1;
+ if (size >= *biosSize) {
+ if (pciP == pciPtr) { /* if same device remap ram*/
+ if (!(remapMem(pciP,i,size)))
+ continue;
+ remapMEM_val = val;
+ remapMEM_num = i;
+ } else {
+ remapMEM_val = 0;
+ }
+ return val & 0xFFFFFF00;
+ }
+ }
+ pciPtr = pciPtr->next;
+ }
+ remapMEM_val = 0;
+ /* very last resort */
+ if (pciP->bus == 0 && (pciMinMemReg > *biosSize))
+ return (pciMinMemReg - size) & ~(size - 1);
+
+ return 0;
+}
+
+int
+cfg1out(CARD16 addr, CARD32 val)
+{
+ if (addr == 0xCF8) {
+ PciCfg1Addr = val;
+ return 1;
+ } else if (addr == 0xCFC) {
+ writePci(PciCfg1Addr, val);
+ return 1;
+ }
+ return 0;
+}
+
+int
+cfg1in(CARD16 addr, CARD32 *val)
+{
+ if (addr == 0xCF8) {
+ *val = PciCfg1Addr;
+ return 1;
+ } else if (addr == 0xCFC) {
+ *val = readPci(PciCfg1Addr);
+ return 1;
+ }
+ return 0;
+}
+
+PciStructPtr
+findPciByIDs(int bus, int dev, int func)
+{
+ PciStructPtr pciP = PciList;
+
+ while (pciP) {
+ if (pciP->bus == (unsigned) bus && pciP->dev == (unsigned) dev && pciP->func == (unsigned) func)
+ return pciP;
+ pciP = pciP->next;
+ }
+ return NULL;
+}
diff --git a/tools/ddcprobe/int10/i10_v86.c b/tools/ddcprobe/int10/i10_v86.c
new file mode 100644
index 000000000..0e50b1576
--- /dev/null
+++ b/tools/ddcprobe/int10/i10_v86.c
@@ -0,0 +1,515 @@
+/*
+ * Copyright 1999 Egbert Eich
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+#include <asm/unistd.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef __i386__
+#include <sys/vm86.h>
+#else
+#include "vm86_struct.h"
+#endif
+#include <signal.h>
+#include "v86bios.h"
+#include "AsmMacros.h"
+
+extern int emu_vm86(struct vm86_struct *vm);
+
+#define INT2PTR(a) ((a) + (unsigned char *) 0)
+
+void log_err(char *format, ...) __attribute__ ((format (printf, 1, 2)));
+
+struct vm86_struct vm86s;
+
+static int vm86_GP_fault(void);
+static int vm86_do_int(int num);
+#ifdef __i386__
+static int vm86_rep(struct vm86_struct *ptr);
+#endif
+void log_registers(void);
+
+#define CPU_REG(x) (vm86s.regs.x)
+#define CPU_REG_LW(reg) (*((CARD16 *)&CPU_REG(reg)))
+#define CPU_REG_HW(reg) (*((CARD16 *)&CPU_REG(reg) + 1))
+#define CPU_REG_LB(reg) (*(CARD8 *)&CPU_REG(e##reg))
+#define SEG_ADR(type, seg, reg) type((CPU_REG_LW(seg) << 4) + CPU_REG_LW(e##reg) + (unsigned char *) 0)
+#define DF (1 << 10)
+
+struct pio P;
+
+void
+setup_io(void)
+{
+ P.inb = (CARD8(*)(CARD16))inb;
+ P.inw = (CARD16(*)(CARD16))inw;
+ P.inl = (CARD32(*)(CARD16))inl;
+ P.outb = (void(*)(CARD16,CARD8))outb;
+ P.outw = (void(*)(CARD16,CARD16))outw;
+ P.outl = (void(*)(CARD16,CARD32))outl;
+}
+
+
+static void
+setup_vm86(unsigned long bios_start, i86biosRegsPtr regs)
+{
+ CARD32 eip;
+ CARD16 cs;
+
+ vm86s.flags = VM86_SCREEN_BITMAP;
+ vm86s.flags = 0;
+ vm86s.screen_bitmap = 0;
+ vm86s.cpu_type = CPU_586;
+ memset(&vm86s.int_revectored, 0xff,sizeof(vm86s.int_revectored)) ;
+ memset(&vm86s.int21_revectored, 0xff,sizeof(vm86s.int21_revectored)) ;
+
+ eip = bios_start & 0xFFFF;
+ cs = (bios_start & 0xFF0000) >> 4;
+
+ CPU_REG(eax) = regs->ax;
+ CPU_REG(ebx) = regs->bx;
+ CPU_REG(ecx) = regs->cx;
+ CPU_REG(edx) = regs->dx;
+ CPU_REG(esi) = 0;
+ CPU_REG(edi) = regs->di;
+ CPU_REG(ebp) = 0;
+ CPU_REG(eip) = eip;
+ CPU_REG(cs) = cs;
+ CPU_REG(esp) = 0x100;
+ CPU_REG(ss) = 0x30; /* This is the standard pc bios stack */
+ CPU_REG(es) = regs->es;
+ CPU_REG(ds) = 0x40; /* standard pc ds */
+ CPU_REG(fs) = 0;
+ CPU_REG(gs) = 0;
+ CPU_REG(eflags) |= (VIF_MASK | VIP_MASK);
+}
+
+void
+collect_bios_regs(i86biosRegsPtr regs)
+{
+ regs->ax = CPU_REG(eax);
+ regs->bx = CPU_REG(ebx);
+ regs->cx = CPU_REG(ecx);
+ regs->dx = CPU_REG(edx);
+ regs->es = CPU_REG(es);
+ regs->ds = CPU_REG(ds);
+ regs->di = CPU_REG(edi);
+ regs->si = CPU_REG(esi);
+}
+
+static int do_vm86(int cpuemu)
+{
+ int retval;
+
+#ifdef V86BIOS_DEBUG
+ dump_registers();
+#endif
+
+#ifdef __i386__
+ if(cpuemu) {
+ retval = emu_vm86(&vm86s);
+ }
+ else {
+ retval = vm86_rep(&vm86s);
+ }
+#else
+ retval = emu_vm86(&vm86s);
+#endif
+
+ switch (VM86_TYPE(retval)) {
+ case VM86_UNKNOWN:
+ if (!vm86_GP_fault())
+ return 0;
+ break;
+ case VM86_STI:
+ log_err("vm86_sti :-((\n");
+ log_registers();
+ return 0;
+ case VM86_INTx:
+ if (!vm86_do_int(VM86_ARG(retval))) {
+ log_err("Unknown vm86_int: %X\n",VM86_ARG(retval));
+ log_registers();
+ return 0;
+ }
+ /* I'm not sure yet what to do if we can handle ints */
+ break;
+ case VM86_SIGNAL:
+ log_err("VBE: received a signal!\n");
+ log_registers();
+ return 0;
+ default:
+ log_err("unknown type(0x%x)=0x%x\n",
+ VM86_ARG(retval),VM86_TYPE(retval));
+ log_registers();
+ return 0;
+ }
+
+ return 1;
+}
+
+void
+do_x86(unsigned long bios_start, i86biosRegsPtr regs, int cpuemu)
+{
+ setup_vm86(bios_start, regs);
+ while(do_vm86(cpuemu)) {};
+ collect_bios_regs(regs);
+}
+
+/* get the linear address */
+#define LIN_PREF_SI ((pref_seg << 4) + CPU_REG_LW(esi))
+
+#define LWECX (prefix66 ^ prefix67 ? CPU_REG(ecx) : CPU_REG_LW(ecx))
+
+static int
+vm86_GP_fault(void)
+{
+ unsigned char *csp, *lina;
+ CARD32 org_eip;
+ int pref_seg;
+ int done,is_rep,prefix66,prefix67;
+
+
+ csp = lina = SEG_ADR((unsigned char *), cs, ip);
+#ifdef V86BIOS_DEBUG
+ printf("exception: \n");
+ dump_code();
+#endif
+
+ is_rep = 0;
+ prefix66 = prefix67 = 0;
+ pref_seg = -1;
+
+ /* eat up prefixes */
+ done = 0;
+ do {
+ switch (*(csp++)) {
+ case 0x66: /* operand prefix */ prefix66=1; break;
+ case 0x67: /* address prefix */ prefix67=1; break;
+ case 0x2e: /* CS */ pref_seg=CPU_REG(cs); break;
+ case 0x3e: /* DS */ pref_seg=CPU_REG(ds); break;
+ case 0x26: /* ES */ pref_seg=CPU_REG(es); break;
+ case 0x36: /* SS */ pref_seg=CPU_REG(ss); break;
+ case 0x65: /* GS */ pref_seg=CPU_REG(gs); break;
+ case 0x64: /* FS */ pref_seg=CPU_REG(fs); break;
+ case 0xf2: /* repnz */
+ case 0xf3: /* rep */ is_rep=1; break;
+ default: done=1;
+ }
+ } while (!done);
+ csp--; /* oops one too many */
+ org_eip = CPU_REG(eip);
+ CPU_REG_LW(eip) += (csp - lina);
+
+ switch (*csp) {
+
+ case 0x6c: /* insb */
+ /* NOTE: ES can't be overwritten; prefixes 66,67 should use esi,edi,ecx
+ * but is anyone using extended regs in real mode? */
+ /* WARNING: no test for DI wrapping! */
+ CPU_REG_LW(edi) += port_rep_inb(CPU_REG_LW(edx),
+ SEG_ADR((CARD8 *),es,di),
+ CPU_REG_LW(eflags)&DF,
+ (is_rep? LWECX:1));
+ if (is_rep) LWECX = 0;
+ CPU_REG_LW(eip)++;
+ break;
+
+ case 0x6d: /* (rep) insw / insd */
+ /* NOTE: ES can't be overwritten */
+ /* WARNING: no test for _DI wrapping! */
+ if (prefix66) {
+ CPU_REG_LW(edi) += port_rep_inl(CPU_REG_LW(edx),
+ SEG_ADR((CARD32 *),es,di),
+ CPU_REG_LW(eflags)&DF,
+ (is_rep? LWECX:1));
+ }
+ else {
+ CPU_REG_LW(edi) += port_rep_inw(CPU_REG_LW(edx),
+ SEG_ADR((CARD16 *),es,di),
+ CPU_REG_LW(eflags)&DF,
+ (is_rep? LWECX:1));
+ }
+ if (is_rep) LWECX = 0;
+ CPU_REG_LW(eip)++;
+ break;
+
+ case 0x6e: /* (rep) outsb */
+ if (pref_seg < 0) pref_seg = CPU_REG_LW(ds);
+ /* WARNING: no test for _SI wrapping! */
+ CPU_REG_LW(esi) += port_rep_outb(CPU_REG_LW(edx),(CARD8*)INT2PTR(LIN_PREF_SI),
+ CPU_REG_LW(eflags)&DF,
+ (is_rep? LWECX:1));
+ if (is_rep) LWECX = 0;
+ CPU_REG_LW(eip)++;
+ break;
+
+ case 0x6f: /* (rep) outsw / outsd */
+ if (pref_seg < 0) pref_seg = CPU_REG_LW(ds);
+ /* WARNING: no test for _SI wrapping! */
+ if (prefix66) {
+ CPU_REG_LW(esi) += port_rep_outl(CPU_REG_LW(edx),
+ (CARD32 *)INT2PTR(LIN_PREF_SI),
+ CPU_REG_LW(eflags)&DF,
+ (is_rep? LWECX:1));
+ }
+ else {
+ CPU_REG_LW(esi) += port_rep_outw(CPU_REG_LW(edx),
+ (CARD16 *)INT2PTR(LIN_PREF_SI),
+ CPU_REG_LW(eflags)&DF,
+ (is_rep? LWECX:1));
+ }
+ if (is_rep) LWECX = 0;
+ CPU_REG_LW(eip)++;
+ break;
+
+ case 0xe5: /* inw xx, inl xx */
+ if (prefix66) CPU_REG(eax) = P.inl((int) csp[1]);
+ else CPU_REG_LW(eax) = P.inw((int) csp[1]);
+ CPU_REG_LW(eip) += 2;
+ break;
+ case 0xe4: /* inb xx */
+ CPU_REG_LW(eax) &= ~(CARD32)0xff;
+ CPU_REG_LB(ax) |= P.inb((int) csp[1]);
+ CPU_REG_LW(eip) += 2;
+ break;
+ case 0xed: /* inw dx, inl dx */
+ if (prefix66) CPU_REG(eax) = P.inl(CPU_REG_LW(edx));
+ else CPU_REG_LW(eax) = P.inw(CPU_REG_LW(edx));
+ CPU_REG_LW(eip) += 1;
+ break;
+ case 0xec: /* inb dx */
+ CPU_REG_LW(eax) &= ~(CARD32)0xff;
+ CPU_REG_LB(ax) |= P.inb(CPU_REG_LW(edx));
+ CPU_REG_LW(eip) += 1;
+ break;
+
+ case 0xe7: /* outw xx */
+ if (prefix66) P.outl((int)csp[1], CPU_REG(eax));
+ else P.outw((int)csp[1], CPU_REG_LW(eax));
+ CPU_REG_LW(eip) += 2;
+ break;
+ case 0xe6: /* outb xx */
+ P.outb((int) csp[1], CPU_REG_LB(ax));
+ CPU_REG_LW(eip) += 2;
+ break;
+ case 0xef: /* outw dx */
+ if (prefix66) P.outl(CPU_REG_LW(edx), CPU_REG(eax));
+ else P.outw(CPU_REG_LW(edx), CPU_REG_LW(eax));
+ CPU_REG_LW(eip) += 1;
+ break;
+ case 0xee: /* outb dx */
+ P.outb(CPU_REG_LW(edx), CPU_REG_LB(ax));
+ CPU_REG_LW(eip) += 1;
+ break;
+
+ case 0xf4:
+#ifdef V86BIOS_DEBUG
+ printf("hlt at %p\n", lina);
+#endif
+ return 0;
+
+ case 0x0f:
+ log_err("CPU 0x0f Trap at eip=0x%lx\n",CPU_REG(eip));
+ goto op0ferr;
+ break;
+
+ case 0xf0: /* lock */
+ default:
+ log_err("unknown reason for exception\n");
+ log_registers();
+ op0ferr:
+ log_err("cannot continue\n");
+ return 0;
+ } /* end of switch() */
+ return 1;
+}
+
+static int
+vm86_do_int(int num)
+{
+ int val;
+ struct regs86 regs;
+
+ /* try to run bios interrupt */
+
+ /* if not installed fall back */
+#define COPY(x) regs.x = CPU_REG(x)
+#define COPY_R(x) CPU_REG(x) = regs.x
+
+ COPY(eax);
+ COPY(ebx);
+ COPY(ecx);
+ COPY(edx);
+ COPY(esi);
+ COPY(edi);
+ COPY(ebp);
+ COPY(eip);
+ COPY(esp);
+ COPY(cs);
+ COPY(ss);
+ COPY(ds);
+ COPY(es);
+ COPY(fs);
+ COPY(gs);
+ COPY(eflags);
+
+ if (!(val = int_handler(num,&regs)))
+ if (!(val = run_bios_int(num,&regs)))
+ return val;
+
+ COPY_R(eax);
+ COPY_R(ebx);
+ COPY_R(ecx);
+ COPY_R(edx);
+ COPY_R(esi);
+ COPY_R(edi);
+ COPY_R(ebp);
+ COPY_R(eip);
+ COPY_R(esp);
+ COPY_R(cs);
+ COPY_R(ss);
+ COPY_R(ds);
+ COPY_R(es);
+ COPY_R(fs);
+ COPY_R(gs);
+ COPY_R(eflags);
+
+ return val;
+#undef COPY
+#undef COPY_R
+}
+
+#ifdef __i386__
+
+static int
+vm86_rep(struct vm86_struct *ptr)
+{
+
+ int __res;
+
+ /* stay away from %ebx */
+ __asm__ __volatile__("push %%ebx\n\tmov %%ecx,%%ebx\n\tpush %%gs\n\tint $0x80\n\tpop %%gs\n\tpop %%ebx\n"
+ :"=a" (__res):"a" ((int)113),
+ "c" ((struct vm86_struct *)ptr));
+
+ if ((__res) < 0) {
+ errno = -__res;
+ __res=-1;
+ }
+ else errno = 0;
+ return __res;
+}
+
+#endif
+
+#ifdef __i386__
+
+#define pushw(base, ptr, val) \
+__asm__ __volatile__( \
+ "decw %w0\n\t" \
+ "movb %h2,(%1,%0)\n\t" \
+ "decw %w0\n\t" \
+ "movb %b2,(%1,%0)" \
+ : "=r" (ptr) \
+ : "r" (base), "q" (val), "0" (ptr))
+
+#else
+
+#define pushw(base, ptr, val) { \
+ ptr = ((ptr) - 1) & 0xffff; \
+ *((unsigned char *)(base) + (ptr)) = (val) >> 8; \
+ ptr = ((ptr) - 1) & 0xffff; \
+ *((unsigned char *)(base) + (ptr)) = (val); \
+ }
+
+#endif
+
+int
+run_bios_int(int num, struct regs86 *regs)
+{
+ CARD16 *ssp;
+ CARD32 sp;
+ CARD32 eflags;
+
+#ifdef V86BIOS_DEBUG
+ static int firsttime = 1;
+#endif
+ /* check if bios vector is initialized */
+ if (((CARD16*)0)[(num<<1)+1] == 0x0000) { /* SYS_BIOS_SEG ?*/
+ return 0;
+ }
+
+#ifdef V86BIOS_DEBUG
+ if (firsttime) {
+ dprint(0,0x3D0);
+ firsttime = 0;
+ }
+#endif
+
+ ssp = (CARD16*)INT2PTR(CPU_REG(ss)<<4);
+ sp = (CARD32) CPU_REG_LW(esp);
+
+ eflags = regs->eflags;
+ eflags = ((eflags & VIF_MASK) != 0)
+ ? (eflags | IF_MASK) : (eflags & ~(CARD32) IF_MASK);
+ pushw(ssp, sp, eflags);
+ pushw(ssp, sp, regs->cs);
+ pushw(ssp, sp, (CARD16)regs->eip);
+ regs->esp -= 6;
+ regs->cs = ((CARD16 *) 0)[(num << 1) + 1];
+ regs->eip = (regs->eip & 0xFFFF0000) | ((CARD16 *) 0)[num << 1];
+#ifdef V86BIOS_DEBUG
+ dump_code();
+#endif
+ regs->eflags = regs->eflags
+ & ~(VIF_MASK | TF_MASK | IF_MASK | NT_MASK);
+ return 1;
+}
+
+CARD32
+getIntVect(int num)
+{
+ return ((CARD32*)0)[num];
+}
+
+CARD32
+getIP(void)
+{
+ return (CPU_REG(cs) << 4) + CPU_REG(eip);
+}
+
+void log_registers()
+{
+ log_err(
+ " eax %08x, ebx %08x, ecx %08x, edx %08x\n"
+ " esi %08x, edi %08x, ebp %08x, esp %08x\n"
+ " ds %04x, es %04x, fs %04x, gs %04x, ss %04x\n"
+ " cs:eip %04x:%08x\n",
+ (unsigned) CPU_REG(eax), (unsigned) CPU_REG(ebx), (unsigned) CPU_REG(ecx), (unsigned) CPU_REG(edx),
+ (unsigned) CPU_REG(esi), (unsigned) CPU_REG(edi), (unsigned) CPU_REG(ebp), (unsigned) CPU_REG(esp),
+ (unsigned) CPU_REG(ds), (unsigned) CPU_REG(es),
+ (unsigned) CPU_REG(fs), (unsigned) CPU_REG(gs), (unsigned) CPU_REG(ss),
+ (unsigned) CPU_REG(cs), (unsigned) CPU_REG(eip)
+ );
+}
+
diff --git a/tools/ddcprobe/int10/i10_vbios.c b/tools/ddcprobe/int10/i10_vbios.c
new file mode 100644
index 000000000..89c6b7c5a
--- /dev/null
+++ b/tools/ddcprobe/int10/i10_vbios.c
@@ -0,0 +1,571 @@
+/*
+ * Copyright 1999 Egbert Eich
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <setjmp.h>
+#if defined(__alpha__) || defined (__ia64__)
+#include <sys/io.h>
+//#elif defined(HAVE_SYS_PERM)
+#else
+#include <sys/perm.h>
+#endif
+#include "v86bios.h"
+#include "pci.h"
+#include "AsmMacros.h"
+#include "vbios.h"
+
+void log_err(char *format, ...) __attribute__ ((format (printf, 1, 2)));
+
+#define SIZE 0x100000
+#define VRAM_START 0xA0000
+#define VRAM_SIZE 0x1FFFF
+#define V_BIOS_SIZE 0x1FFFF
+#define BIOS_START 0x7C00 /* default BIOS entry */
+
+static CARD8 code[] = { 0xcd, 0x10, 0xf4 }; /* int 0x10, hlt */
+// static CARD8 code13[] = { 0xcd, 0x13, 0xf4 }; /* int 0x13, hlt */
+
+static int map(void);
+static void unmap(void);
+static int map_vram(void);
+static void unmap_vram(void);
+static int copy_vbios(void);
+// static int copy_sbios(void);
+#if MAP_SYS_BIOS
+static int copy_sys_bios(void);
+#endif
+static int copy_bios_ram();
+static int setup_system_bios(void);
+static void setup_int_vect(void);
+static int chksum(CARD8 *start);
+
+void loadCodeToMem(unsigned char *ptr, CARD8 *code);
+
+static int vram_mapped = 0;
+static int int10inited = 0;
+
+static sigjmp_buf longjmp_buf;
+
+static void sigsegv_handler(int);
+
+int InitInt10(int pci_cfg_method)
+{
+ if(geteuid()) return -1;
+
+ if(!map()) return -1;
+
+ if(!setup_system_bios()) {
+ unmap();
+ return -1;
+ }
+
+ setup_io();
+
+ if(iopl(3) < 0) {
+ unmap();
+ return -1;
+ }
+
+ scan_pci(pci_cfg_method);
+
+ for(; CurrentPci; CurrentPci = CurrentPci->next) {
+ if(CurrentPci->active) break;
+ }
+
+ iopl(0);
+
+ setup_int_vect();
+
+ if(!copy_vbios()) {
+ unmap();
+ return -1;
+ }
+
+#if 0
+ if(!copy_sbios()) {
+ unmap();
+ return -1;
+ }
+#endif
+
+ if(!map_vram() || !copy_bios_ram()) {
+ unmap();
+ return -1;
+ }
+
+ int10inited = 1;
+
+#if 0
+ /* int 13 default location (fdd) */
+ ((CARD16*)0)[(0x13<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x13<<1] = 0xec59;
+#endif
+
+ return 0;
+}
+
+
+void FreeInt10()
+{
+ if(!int10inited) return;
+
+ unmap_vram();
+ unmap();
+
+ int10inited = 0;
+}
+
+
+void sigsegv_handler(int num)
+{
+ siglongjmp(longjmp_buf, num + 1000);
+}
+
+
+int CallInt10(int *ax, int *bx, int *cx, unsigned char *buf, int len, int cpuemu)
+{
+ i86biosRegs bRegs;
+ void (*old_sigsegv_handler)(int) = SIG_DFL;
+ void (*old_sigill_handler)(int) = SIG_DFL;
+ void (*old_sigtrap_handler)(int) = SIG_DFL;
+ int jmp;
+
+ if(!int10inited) return -1;
+ memset(&bRegs, 0, sizeof bRegs);
+ bRegs.ax = *ax;
+ bRegs.bx = *bx;
+ bRegs.cx = *cx;
+ bRegs.dx = 0;
+ bRegs.es = 0x7e0;
+ bRegs.di = 0x0;
+ if(buf) memcpy((unsigned char *) 0x7e00, buf, len);
+
+ iopl(3);
+
+ jmp = sigsetjmp(longjmp_buf, 1);
+
+ if(!jmp) {
+ old_sigsegv_handler = signal(SIGSEGV, sigsegv_handler);
+ old_sigill_handler = signal(SIGILL, sigsegv_handler);
+ old_sigtrap_handler = signal(SIGTRAP, sigsegv_handler);
+
+ loadCodeToMem((unsigned char *) BIOS_START, code);
+ do_x86(BIOS_START, &bRegs, cpuemu);
+ }
+ else {
+ int10inited = 0;
+ log_err("oops: got signal %d in vm86() code\n", jmp - 1000);
+ }
+
+ signal(SIGTRAP, old_sigtrap_handler);
+ signal(SIGILL, old_sigill_handler);
+ signal(SIGSEGV, old_sigsegv_handler);
+
+ iopl(0);
+
+ if(buf) memcpy(buf, (unsigned char *) 0x7e00, len);
+
+ *ax = bRegs.ax;
+ *bx = bRegs.bx;
+ *cx = bRegs.cx;
+
+ return bRegs.ax;
+}
+
+
+#if 0
+int CallInt13(int *ax, int *bx, int *cx, int *dx, unsigned char *buf, int len, int cpuemu)
+{
+ i86biosRegs bRegs;
+
+ if(!int10inited) return -1;
+ memset(&bRegs, 0, sizeof bRegs);
+ bRegs.ax = *ax;
+ bRegs.bx = *bx;
+ bRegs.cx = *cx;
+ bRegs.dx = *dx;
+ bRegs.es = 0x7e0;
+ bRegs.ds = 0x7e0;
+ bRegs.di = 0x0;
+ bRegs.si = 0x0;
+ if(buf) memcpy((unsigned char *) 0x7e00, buf, len);
+
+ iopl(3);
+
+ loadCodeToMem((unsigned char *) BIOS_START, code13);
+ do_x86(BIOS_START, &bRegs, cpuemu);
+
+ iopl(0);
+
+ if(buf) memcpy(buf, (unsigned char *) 0x7e00, len);
+
+ *ax = bRegs.ax;
+ *bx = bRegs.bx;
+ *cx = bRegs.cx;
+ *dx = bRegs.dx;
+
+ return bRegs.ax;
+}
+#endif
+
+
+int map()
+{
+ void* mem;
+
+ mem = mmap(0, (size_t) SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
+
+ if(mem) {
+ perror("anonymous map");
+ return 0;
+ }
+
+ memset(mem, 0, SIZE);
+
+ loadCodeToMem((unsigned char *) BIOS_START, code);
+
+ return 1;
+}
+
+
+void unmap()
+{
+ munmap(0, SIZE);
+}
+
+
+static int
+map_vram(void)
+{
+ int mem_fd;
+
+#ifdef __ia64__
+ if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
+#else
+ if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
+#endif
+ {
+ perror("opening memory");
+ return 0;
+ }
+
+#ifndef __alpha__
+ if (mmap((void *) VRAM_START, (size_t) VRAM_SIZE,
+ PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
+ mem_fd, VRAM_START) == (void *) -1)
+#else
+ if (!_bus_base()) sparse_shift = 7; /* Uh, oh, JENSEN... */
+ if (!_bus_base_sparse()) sparse_shift = 0;
+ if ((vram_map = mmap(0,(size_t) (VRAM_SIZE << sparse_shift),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ mem_fd, (VRAM_START << sparse_shift)
+ | _bus_base_sparse())) == (void *) -1)
+#endif
+ {
+ perror("mmap error in map_hardware_ram");
+ close(mem_fd);
+ return (0);
+ }
+ vram_mapped = 1;
+ close(mem_fd);
+ return (1);
+}
+
+
+void unmap_vram()
+{
+ if(!vram_mapped) return;
+
+ munmap((void*) VRAM_START, VRAM_SIZE);
+
+ vram_mapped = 0;
+}
+
+
+/*
+ * Read video BIOS from /dev/mem.
+ *
+ * Return:
+ * 0: failed
+ * 1: ok
+ */
+int copy_vbios()
+{
+ int mem_fd, size, ok = 0;
+ unsigned char tmp[3];
+
+ if((mem_fd = open(MEM_FILE, O_RDONLY)) == -1) {
+ log_err("vbe: failed to open BIOS memory, errno = %d", errno);
+
+ return 0;
+ }
+
+ if(lseek(mem_fd, (off_t) V_BIOS, SEEK_SET) != (off_t) V_BIOS) {
+ log_err("vbe: lseek failed, errno = %d\n", errno);
+ }
+ else {
+ if(read(mem_fd, tmp, sizeof tmp) != sizeof tmp) {
+ log_err("vbe: failed to read %u bytes at 0x%x, errno = %d\n", (unsigned) sizeof tmp, V_BIOS, errno);
+ }
+ else {
+ if(lseek(mem_fd, V_BIOS, SEEK_SET) != V_BIOS) {
+ log_err("vbe: lseek failed, errno = %d\n", errno);
+ }
+ else {
+ if(tmp[0] != 0x55 || tmp[1] != 0xAA ) {
+ log_err("vbe: no bios found at: 0x%x\n", V_BIOS);
+ }
+ else {
+ size = tmp[2] * 0x200;
+
+ if(read(mem_fd, (char *) V_BIOS, size) != size) {
+ log_err("vbe: failed to read %d bytes at 0x%x, errno = %d\n", size, V_BIOS, errno);
+ }
+ else {
+ if(chksum((CARD8 *) V_BIOS)) ok = 1;
+ }
+ }
+ }
+ }
+ }
+
+ close(mem_fd);
+
+ return ok;
+}
+
+
+#if 0
+#define SYS_BIOS 0xe0000
+#define SYS_BIOS_SIZE 0x20000
+int copy_sbios()
+{
+ int fd;
+
+ if((fd = open(MEM_FILE, O_RDONLY)) < 0) {
+ perror("opening memory");
+ return 0;
+ }
+
+ if(lseek(fd,(off_t) SYS_BIOS, SEEK_SET) == (off_t) SYS_BIOS) {
+ read(fd, (void *) SYS_BIOS, SYS_BIOS_SIZE);
+ }
+
+ close(fd);
+
+ return 1;
+}
+#endif
+
+
+#if MAP_SYS_BIOS
+static int
+copy_sys_bios(void)
+{
+#define SYS_BIOS 0xF0000
+ int mem_fd;
+
+ if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
+ perror("opening memory");
+ return (0);
+ }
+
+ if (lseek(mem_fd,(off_t) SYS_BIOS,SEEK_SET) != (off_t) SYS_BIOS)
+ goto Error;
+ if (read(mem_fd, (char *)SYS_BIOS, (size_t) 0xFFFF) != (size_t) 0xFFFF)
+ goto Error;
+
+ close(mem_fd);
+ return (1);
+
+Error:
+ perror("sys_bios");
+ close(mem_fd);
+ return (0);
+}
+#endif
+
+
+static int
+copy_bios_ram(void)
+{
+#define BIOS_RAM 0
+ int mem_fd;
+
+ if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
+ perror("opening memory");
+ return (0);
+ }
+
+ if (lseek(mem_fd,(off_t) BIOS_RAM,SEEK_SET) != (off_t) BIOS_RAM)
+ goto Error;
+ if (read(mem_fd, (char *)BIOS_RAM, (size_t) 0x1000) != (size_t) 0x1000)
+ goto Error;
+
+ close(mem_fd);
+ return (1);
+
+Error:
+ perror("bios_ram");
+ close(mem_fd);
+ return (0);
+}
+
+
+void loadCodeToMem(unsigned char *ptr, CARD8 *code)
+{
+ while((*ptr++ = *code++) != 0xf4 /* hlt */);
+
+ return;
+}
+
+
+/*
+ * here we are really paranoid about faking a "real"
+ * BIOS. Most of this information was pulled from
+ * dosem.
+ */
+static void
+setup_int_vect(void)
+{
+ const CARD16 cs = 0x0000;
+ const CARD16 ip = 0x0;
+ int i;
+
+ /* let the int vects point to the SYS_BIOS seg */
+ for (i=0; i<0x80; i++) {
+ ((CARD16*)0)[i<<1] = ip;
+ ((CARD16*)0)[(i<<1)+1] = cs;
+ }
+ /* video interrupts default location */
+ ((CARD16*)0)[(0x42<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x42<<1] = 0xf065;
+ ((CARD16*)0)[(0x10<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x10<<1] = 0xf065;
+ /* video param table default location (int 1d) */
+ ((CARD16*)0)[(0x1d<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x1d<<1] = 0xf0A4;
+ /* font tables default location (int 1F) */
+ ((CARD16*)0)[(0x1f<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x1f<<1] = 0xfa6e;
+
+ /* int 11 default location */
+ ((CARD16*)0)[(0x11<1)+1] = 0xf000;
+ ((CARD16*)0)[0x11<<1] = 0xf84d;
+ /* int 12 default location */
+ ((CARD16*)0)[(0x12<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x12<<1] = 0xf841;
+ /* int 15 default location */
+ ((CARD16*)0)[(0x15<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x15<<1] = 0xf859;
+ /* int 1A default location */
+ ((CARD16*)0)[(0x1a<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x1a<<1] = 0xff6e;
+ /* int 05 default location */
+ ((CARD16*)0)[(0x05<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x05<<1] = 0xff54;
+ /* int 08 default location */
+ ((CARD16*)0)[(0x8<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x8<<1] = 0xfea5;
+ /* int 13 default location (fdd) */
+ ((CARD16*)0)[(0x13<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x13<<1] = 0xec59;
+ /* int 0E default location */
+ ((CARD16*)0)[(0xe<<1)+1] = 0xf000;
+ ((CARD16*)0)[0xe<<1] = 0xef57;
+ /* int 17 default location */
+ ((CARD16*)0)[(0x17<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x17<<1] = 0xefd2;
+ /* fdd table default location (int 1e) */
+ ((CARD16*)0)[(0x1e<<1)+1] = 0xf000;
+ ((CARD16*)0)[0x1e<<1] = 0xefc7;
+}
+
+static int
+setup_system_bios(void)
+{
+ char *date = "06/01/99";
+ char *eisa_ident = "PCI/ISA";
+
+#if MAP_SYS_BIOS
+ if (!copy_sys_bios()) return 0;
+ return 1;
+#endif
+// memset((void *)0xF0000,0xf4,0xfff7);
+
+ /*
+ * we trap the "industry standard entry points" to the BIOS
+ * and all other locations by filling them with "hlt"
+ * TODO: implement hlt-handler for these
+ */
+ memset((void *)0xF0000,0xf4,0x10000);
+
+ /*
+ * TODO: we should copy the fdd table (0xfec59-0xfec5b)
+ * the video parameter table (0xf0ac-0xf0fb)
+ * and the font tables (0xfa6e-0xfe6d)
+ * from the original bios here
+ */
+
+ /* set bios date */
+ strcpy((char *)0xFFFF5,date);
+ /* set up eisa ident string */
+ strcpy((char *)0xFFFD9,eisa_ident);
+ /* write system model id for IBM-AT */
+ ((char *)0)[0xFFFFE] = 0xfc;
+
+ return 1;
+}
+
+
+/*
+ * Check BIOS CRC.
+ *
+ * Return:
+ * 0: failed
+ * 1: ok
+ */
+int chksum(CARD8 *start)
+{
+ CARD16 size;
+ CARD8 val = 0;
+ int i;
+
+ size = start[2] * 0x200;
+ for(i = 0; i < size; i++) val += start[i];
+
+ if(!val) return 1;
+
+ log_err("vbe: BIOS chksum wrong\n");
+
+ return 0;
+}
+
diff --git a/tools/ddcprobe/int10/pci.h b/tools/ddcprobe/int10/pci.h
new file mode 100644
index 000000000..840f9d4ae
--- /dev/null
+++ b/tools/ddcprobe/int10/pci.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright 1999 Egbert Eich
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "v86bios.h"
+
+#ifndef V86_PCI_H
+#define V86_PCI_H
+
+typedef union {
+ struct {
+ unsigned int zero:2;
+ unsigned int reg:6;
+ unsigned int func:3;
+ unsigned int dev:5;
+ unsigned int bus:8;
+ unsigned int reserved:7;
+ unsigned int enable:1;
+ } pci;
+ CARD32 l;
+} PciSlot;
+
+typedef struct pciBusRec {
+ CARD8 primary;
+ CARD8 secondary;
+ CARD32 bctl;
+ PciSlot Slot;
+ struct pciBusRec *next;
+ struct pciBusRec *pBus;
+} PciBusRec, *PciBusPtr;
+
+typedef struct pciStructRec {
+ CARD16 VendorID;
+ CARD16 DeviceID;
+ CARD8 Interface;
+ CARD8 BaseClass;
+ CARD8 SubClass;
+ CARD32 RomBase;
+ CARD32 bus;
+ CARD8 dev;
+ CARD8 func;
+ CARD32 cmd_st;
+ int active;
+ PciSlot Slot;
+ struct pciStructRec *next;
+ PciBusPtr pBus;
+} PciStructRec , *PciStructPtr;
+
+
+extern PciStructPtr CurrentPci;
+extern PciStructPtr PciList;
+extern PciStructPtr BootBios;
+extern int pciMaxBus;
+
+extern CARD32 findPci(CARD16 slotBX);
+extern CARD16 pciSlotBX(PciStructPtr);
+PciStructPtr findPciDevice(CARD16 vendorID, CARD16 deviceID, char n);
+PciStructPtr findPciClass(CARD8 intf, CARD8 subClass, CARD16 class, char n);
+
+extern CARD8 PciRead8(int offset, CARD32 slot);
+extern CARD16 PciRead16(int offset, CARD32 slot);
+extern CARD32 PciRead32(int offset, CARD32 slot);
+
+extern void PciWrite8(int offset,CARD8 byte, CARD32 slot);
+extern void PciWrite16(int offset,CARD16 word, CARD32 slot);
+extern void PciWrite32(int offset,CARD32 lg, CARD32 slot);
+
+extern void scan_pci(int);
+extern void pciVideoDisable(void);
+extern void pciVideoRestore(void);
+extern void EnableCurrent(void);
+extern int mapPciRom(PciStructPtr pciP);
+extern int cfg1out(CARD16 addr, CARD32 val);
+extern int cfg1in(CARD16 addr, CARD32 *val);
+extern void list_pci(void);
+extern PciStructPtr findPciByIDs(int bus, int dev, int func);
+
+#define PCI_MODE2_ENABLE_REG 0xCF8
+#define PCI_MODE2_FORWARD_REG 0xCFA
+#define PCI_MODE1_ADDRESS_REG 0xCF8
+#define PCI_MODE1_DATA_REG 0xCFC
+#if defined(__alpha__) || defined(__sparc__)
+#define PCI_EN 0x00000000
+#else
+#define PCI_EN 0x80000000
+#endif
+#define MAX_DEV_PER_VENDOR_CFG1 32
+#define BRIDGE_CLASS(x) (x == 0x06)
+#define BRIDGE_PCI_CLASS(x) (x == 0x04)
+#define BRIDGE_HOST_CLASS(x) (x == 0x00)
+#define PCI_CLASS_PREHISTORIC 0x00
+#define PCI_SUBCLASS_PREHISTORIC_VGA 0x01
+#define PCI_CLASS_DISPLAY 0x03
+#define PCI_SUBCLASS_DISPLAY_VGA 0x00
+#define PCI_SUBCLASS_DISPLAY_XGA 0x01
+#define PCI_SUBCLASS_DISPLAY_MISC 0x80
+#define VIDEO_CLASS(b,s) \
+ (((b) == PCI_CLASS_PREHISTORIC && (s) == PCI_SUBCLASS_PREHISTORIC_VGA) || \
+ ((b) == PCI_CLASS_DISPLAY && (s) == PCI_SUBCLASS_DISPLAY_VGA) ||\
+ ((b) == PCI_CLASS_DISPLAY && (s) == PCI_SUBCLASS_DISPLAY_XGA) ||\
+ ((b) == PCI_CLASS_DISPLAY && (s) == PCI_SUBCLASS_DISPLAY_MISC))
+#define PCI_MULTIFUNC_DEV 0x80
+#define MAX_PCI_DEVICES 64
+#define PCI_MAXBUS 16
+#define PCI_IS_MEM 0x00000001
+#define MAX_PCI_ROM_SIZE (1024 * 1024 * 16)
+
+#define IS_MEM32(x) ((x & 0x7) == 0 && x != 0)
+#define IS_MEM64(x) ((x & 0x7) == 0x4)
+#endif
diff --git a/tools/ddcprobe/int10/v86bios.h b/tools/ddcprobe/int10/v86bios.h
new file mode 100644
index 000000000..c0c8acca6
--- /dev/null
+++ b/tools/ddcprobe/int10/v86bios.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright 1999 Egbert Eich
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef V86_BIOS_H
+#define V86_BIOS_H
+
+#if defined (__i386__) || defined (__i486__) || defined (__i586__) || defined (__i686__) || defined (__k6__)
+# ifndef __ia32__
+# define __ia32__
+# endif
+#endif
+
+#include <stdio.h>
+
+#define p_printf(f,a...) do {if (Config.PrintPort) lprintf(f,##a);} \
+ while(0)
+#define i_printf(f,a...) do {if (Config.PrintIrq) lprintf(f,##a);} \
+ while(0)
+#define P_printf(f,a...) do {if (Config.PrintPci) lprintf(f,##a);} \
+ while(0)
+
+typedef unsigned char CARD8;
+typedef unsigned short CARD16;
+typedef unsigned int CARD32;
+#if defined (__alpha__) || defined (__ia64__)
+typedef unsigned long memType;
+#else
+typedef unsigned int memType;
+#endif
+
+typedef int Bool;
+
+#define FALSE 0
+#define TRUE 1
+
+struct config {
+ Bool PrintPort;
+ Bool IoStatistics;
+ Bool PrintIrq;
+ Bool PrintPci;
+ Bool ShowAllDev;
+ Bool PrintIp;
+ Bool SaveBios;
+ Bool Trace;
+ Bool ConfigActiveOnly;
+ Bool ConfigActiveDevice;
+ Bool MapSysBios;
+ Bool Resort;
+ Bool FixRom;
+ Bool NoConsole;
+ Bool BootOnly;
+ int Verbose;
+};
+
+struct pio {
+ CARD8 (*inb)(CARD16);
+ CARD16 (*inw)(CARD16);
+ CARD32 (*inl)(CARD16);
+ void (*outb)(CARD16,CARD8);
+ void (*outw)(CARD16,CARD16);
+ void (*outl)(CARD16,CARD32);
+};
+
+struct regs86 {
+ long ebx;
+ long ecx;
+ long edx;
+ long esi;
+ long edi;
+ long ebp;
+ long eax;
+ long eip;
+ long esp;
+ unsigned short cs;
+ unsigned short ss;
+ unsigned short es;
+ unsigned short ds;
+ unsigned short fs;
+ unsigned short gs;
+ long eflags;
+};
+
+typedef struct {
+ CARD32 ax;
+ CARD32 bx;
+ CARD32 cx;
+ CARD32 dx;
+ CARD32 cs;
+ CARD32 es;
+ CARD32 ds;
+ CARD32 si;
+ CARD32 di;
+} i86biosRegs, *i86biosRegsPtr;
+
+typedef struct {
+ int fd;
+ int vt;
+} console;
+
+typedef struct {
+ void* address;
+ CARD8 orgval;
+} haltpoints;
+
+enum dev_type { NONE, ISA, PCI };
+struct device {
+ Bool booted;
+ enum dev_type type;
+ union {
+ int none;
+ struct pci {
+ int bus;
+ int dev;
+ int func;
+ } pci;
+ } loc;
+};
+
+extern struct device Device;
+
+#ifdef __alpha__
+unsigned long _bus_base(void);
+extern void* vram_map;
+extern int sparse_shift;
+#endif
+
+extern struct pio P;
+extern struct config Config;
+#define IOPERM_BITS 1024
+extern int ioperm_list[IOPERM_BITS];
+
+extern void setup_io(void);
+extern void do_x86(unsigned long bios_start,i86biosRegsPtr regs, int cpuemu);
+extern int run_bios_int(int num, struct regs86 *regs);
+extern CARD32 getIntVect(int num);
+CARD32 getIP(void);
+
+extern void call_boot(struct device *dev);
+extern void runINT(int num,i86biosRegsPtr Regs);
+extern void add_hlt(unsigned long addr);
+extern void del_hlt(int addr);
+extern void list_hlt();
+
+extern int port_rep_inb(CARD16 port, CARD8 *base, int d_f, CARD32 count);
+extern int port_rep_inw(CARD16 port, CARD16 *base, int d_f, CARD32 count);
+extern int port_rep_inl(CARD16 port, CARD32 *base, int d_f, CARD32 count);
+extern int port_rep_outb(CARD16 port, CARD8 *base, int d_f, CARD32 count);
+extern int port_rep_outw(CARD16 port, CARD16 *base, int d_f, CARD32 count);
+extern int port_rep_outl(CARD16 port, CARD32 *base, int d_f, CARD32 count);
+extern CARD8 p_inb(CARD16 port);
+extern CARD16 p_inw(CARD16 port);
+extern CARD32 p_inl(CARD16 port);
+extern void p_outb(CARD16 port, CARD8 val);
+extern void p_outw(CARD16 port, CARD16 val);
+extern void p_outl(CARD16 port, CARD32 val);
+#ifdef __alpha__
+extern CARD8 a_inb(CARD16 port);
+extern CARD16 a_inw(CARD16 port);
+extern void a_outb(CARD16 port, CARD8 val);
+extern void a_outw(CARD16 port, CARD16 val);
+#endif
+#ifdef __alpha__
+CARD8 mem_rb(CARD32 addr);
+CARD16 mem_rw(CARD32 addr);
+CARD32 mem_rl(CARD32 addr);
+void mem_wb(CARD32 addr, CARD8 val);
+void mem_ww(CARD32 addr, CARD16 val);
+void mem_wl(CARD32 addr, CARD32 val);
+#endif
+extern void io_statistics(void);
+extern void clear_stat(void);
+extern int int_handler(int num, struct regs86 *regs);
+
+extern console open_console(void);
+extern void close_console(console);
+
+extern void dprint(unsigned long start, unsigned long size);
+
+extern Bool logging;
+extern Bool nostdout;
+extern char* logfile;
+extern void logon(void* ptr);
+extern void logoff();
+extern void lprintf(const char *f, ...);
+
+#define MEM_FILE "/dev/mem"
+#define DEFAULT_V_BIOS 0xc0000
+#ifndef V_BIOS
+#define V_BIOS DEFAULT_V_BIOS
+#endif
+
+#ifdef __alpha__
+#define NEED_PCI_IO
+#endif
+
+#endif
+
diff --git a/tools/ddcprobe/int10/vbios.h b/tools/ddcprobe/int10/vbios.h
new file mode 100644
index 000000000..6bd5e8043
--- /dev/null
+++ b/tools/ddcprobe/int10/vbios.h
@@ -0,0 +1,4 @@
+int InitInt10(int);
+int CallInt10(int *ax, int *bx, int *cx, unsigned char *buf, int len, int cpuemu);
+int CallInt13(int *ax, int *bx, int *cx, int *dx, unsigned char *buf, int len, int cpuemu);
+void FreeInt10(void);
diff --git a/tools/ddcprobe/int10/vm86_struct.h b/tools/ddcprobe/int10/vm86_struct.h
new file mode 100644
index 000000000..772e6cab2
--- /dev/null
+++ b/tools/ddcprobe/int10/vm86_struct.h
@@ -0,0 +1,135 @@
+#ifndef _LINUX_VM86_H
+#define _LINUX_VM86_H
+
+/*
+ * I'm guessing at the VIF/VIP flag usage, but hope that this is how
+ * the Pentium uses them. Linux will return from vm86 mode when both
+ * VIF and VIP is set.
+ *
+ * On a Pentium, we could probably optimize the virtual flags directly
+ * in the eflags register instead of doing it "by hand" in vflags...
+ *
+ * Linus
+ */
+
+#define TF_MASK 0x00000100
+#define IF_MASK 0x00000200
+#define IOPL_MASK 0x00003000
+#define NT_MASK 0x00004000
+#define VM_MASK 0x00020000
+#define AC_MASK 0x00040000
+#define VIF_MASK 0x00080000 /* virtual interrupt flag */
+#define VIP_MASK 0x00100000 /* virtual interrupt pending */
+#define ID_MASK 0x00200000
+
+#define BIOSSEG 0x0f000
+
+#define CPU_086 0
+#define CPU_186 1
+#define CPU_286 2
+#define CPU_386 3
+#define CPU_486 4
+#define CPU_586 5
+
+/*
+ * Return values for the 'vm86()' system call
+ */
+#define VM86_TYPE(retval) ((retval) & 0xff)
+#define VM86_ARG(retval) ((retval) >> 8)
+
+#define VM86_SIGNAL 0 /* return due to signal */
+#define VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */
+#define VM86_INTx 2 /* int3/int x instruction (ARG = x) */
+#define VM86_STI 3 /* sti/popf/iret instruction enabled virtual interrupts */
+
+/*
+ * Additional return values when invoking new vm86()
+ */
+#define VM86_PICRETURN 4 /* return due to pending PIC request */
+#define VM86_TRAP 6 /* return due to DOS-debugger request */
+
+/*
+ * function codes when invoking new vm86()
+ */
+#define VM86_PLUS_INSTALL_CHECK 0
+#define VM86_ENTER 1
+#define VM86_ENTER_NO_BYPASS 2
+#define VM86_REQUEST_IRQ 3
+#define VM86_FREE_IRQ 4
+#define VM86_GET_IRQ_BITS 5
+#define VM86_GET_AND_RESET_IRQ 6
+
+/*
+ * This is the stack-layout seen by the user space program when we have
+ * done a translation of "SAVE_ALL" from vm86 mode. The real kernel layout
+ * is 'kernel_vm86_regs' (see below).
+ */
+
+struct vm86_regs {
+/*
+ * normal regs, with special meaning for the segment descriptors..
+ */
+ long ebx;
+ long ecx;
+ long edx;
+ long esi;
+ long edi;
+ long ebp;
+ long eax;
+ long __null_ds;
+ long __null_es;
+ long __null_fs;
+ long __null_gs;
+ long orig_eax;
+ long eip;
+ unsigned short cs, __csh;
+ long eflags;
+ long esp;
+ unsigned short ss, __ssh;
+/*
+ * these are specific to v86 mode:
+ */
+ unsigned short es, __esh;
+ unsigned short ds, __dsh;
+ unsigned short fs, __fsh;
+ unsigned short gs, __gsh;
+};
+
+struct revectored_struct {
+ unsigned long __map[8]; /* 256 bits */
+};
+
+struct vm86_struct {
+ struct vm86_regs regs;
+ unsigned long flags;
+ unsigned long screen_bitmap;
+ unsigned long cpu_type;
+ struct revectored_struct int_revectored;
+ struct revectored_struct int21_revectored;
+};
+
+/*
+ * flags masks
+ */
+#define VM86_SCREEN_BITMAP 0x0001
+
+struct vm86plus_info_struct {
+ unsigned long force_return_for_pic:1;
+ unsigned long vm86dbg_active:1; /* for debugger */
+ unsigned long vm86dbg_TFpendig:1; /* for debugger */
+ unsigned long unused:28;
+ unsigned long is_vm86pus:1; /* for vm86 internal use */
+ unsigned char vm86dbg_intxxtab[32]; /* for debugger */
+};
+
+struct vm86plus_struct {
+ struct vm86_regs regs;
+ unsigned long flags;
+ unsigned long screen_bitmap;
+ unsigned long cpu_type;
+ struct revectored_struct int_revectored;
+ struct revectored_struct int21_revectored;
+ struct vm86plus_info_struct vm86plus;
+};
+
+#endif