summaryrefslogtreecommitdiff
path: root/board/MAI/bios_emulator/scitech/src/v86bios
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/v86bios')
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/AsmMacros.h450
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/README35
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/awk.scr15
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/cbios.c415
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/command.c41
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/console.c104
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/debug.h62
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/happy_cards76
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/hexdump3
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/int.c238
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/io.c257
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/lex.l79
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/main.c616
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/makefile.linux59
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/mem.c126
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/parser.y498
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/pci.c903
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/pci.h127
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/v86.c562
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/v86bios.c933
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/v86bios.h215
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/working_cards7
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/x86emu.c316
23 files changed, 6137 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/AsmMacros.h b/board/MAI/bios_emulator/scitech/src/v86bios/AsmMacros.h
new file mode 100644
index 0000000000..e824299c05
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/AsmMacros.h
@@ -0,0 +1,450 @@
+/* $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__))
+#undef inb
+#define inb _inb
+#undef inw
+#define inw _inw
+#undef inl
+#define inl _inl
+#undef outb
+#define outb(p,v) _outb((v),(p))
+#undef outw
+#define outw(p,v) _outw((v),(p))
+#undef outl
+#define outl(p,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/board/MAI/bios_emulator/scitech/src/v86bios/README b/board/MAI/bios_emulator/scitech/src/v86bios/README
new file mode 100644
index 0000000000..4b7d0fa029
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/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/board/MAI/bios_emulator/scitech/src/v86bios/awk.scr b/board/MAI/bios_emulator/scitech/src/v86bios/awk.scr
new file mode 100644
index 0000000000..9d2a80d7d8
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/awk.scr
@@ -0,0 +1,15 @@
+/.*\(0x3da.*/||/.*\(0x3ba.*/ {
+ if (v_3da != 1) print "_v_retrace_";
+ v_3da = 1;
+ next;
+ }
+/.*\(0x42.*/||/.*\(0x43.*/ {
+ if (v_4x != 1) print "_timer_";
+ v_4x = 1;
+ next;
+}
+{
+ print;
+ v_3da = 0;
+ v_4x = 0;
+}
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/cbios.c b/board/MAI/bios_emulator/scitech/src/v86bios/cbios.c
new file mode 100644
index 0000000000..4173c953ba
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/cbios.c
@@ -0,0 +1,415 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <getopt.h>
+#if defined(__alpha__) || defined (__ia64__)
+#include <sys/io.h>
+#elif defined(HAVE_SYS_PERM)
+#include <sys/perm.h>
+#endif
+#include "debug.h"
+#include "v86bios.h"
+#include "pci.h"
+#include "AsmMacros.h"
+
+#define SIZE 0x100000
+#define VRAM_START 0xA0000
+#define VRAM_SIZE 0x1FFFF
+#define V_BIOS_SIZE 0x1FFFF
+#define BIOS_START 0x7C00 /* default BIOS entry */
+#define BIOS_MEM 0x600
+
+CARD8 code[] = { 0xcd, 0x10, 0xf4 };
+struct config Config;
+
+static int map(void);
+static void unmap(void);
+static void runBIOS(int argc, char **argv);
+static int map_vram(void);
+static void unmap_vram(void);
+static int copy_vbios(memType base);
+static int copy_sys_bios(void);
+static CARD32 setup_int_vect(void);
+static void update_bios_vars(void);
+static int chksum(CARD8 *start);
+static void setup_bios_regs(i86biosRegsPtr regs, int argc, char **argv);
+static void print_regs(i86biosRegsPtr regs);
+void dprint(unsigned long start, unsigned long size);
+
+void loadCodeToMem(unsigned char *ptr, CARD8 *code);
+
+static int vram_mapped = 0;
+static char* bios_var;
+
+
+int
+main(int argc,char **argv)
+{
+ CARD32 vbios_base;
+
+ Config.PrintPort = PRINT_PORT;
+ Config.IoStatistics = IO_STATISTICS;
+ Config.PrintIrq = PRINT_IRQ;
+ Config.PrintPci = PRINT_PCI;
+ Config.ShowAllDev = SHOW_ALL_DEV;
+ Config.PrintIp = PRINT_IP;
+ Config.SaveBios = SAVE_BIOS;
+ Config.Trace = TRACE;
+ Config.ConfigActiveOnly = CONFIG_ACTIVE_ONLY;
+ Config.ConfigActiveDevice = CONFIG_ACTIVE_DEVICE;
+ Config.MapSysBios = MAP_SYS_BIOS;
+ Config.Resort = RESORT;
+ Config.FixRom = FIX_ROM;
+ Config.NoConsole = NO_CONSOLE;
+ Config.Verbose = VERBOSE;
+
+ if (!map())
+ exit(1);
+ if (!copy_sys_bios())
+ exit(1);
+ if (!(vbios_base = setup_int_vect()))
+ exit(1);
+ if (!map_vram())
+ exit(1);
+ if (!copy_vbios(vbios_base))
+ exit(1);
+
+ iopl(3);
+ setup_io();
+ runBIOS(argc,argv);
+ update_bios_vars();
+ unmap_vram();
+ iopl(0);
+ unmap();
+ printf("done !\n");
+ exit (1);
+}
+
+int
+map(void)
+{
+ void* mem;
+
+ mem = mmap(0, (size_t)SIZE,
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_FIXED | MAP_PRIVATE | MAP_ANON,
+ -1, 0 );
+ if (mem != 0) {
+ perror("anonymous map");
+ return (0);
+ }
+ memset(mem,0,SIZE);
+
+ loadCodeToMem((unsigned char *) BIOS_START, code);
+ return (1);
+}
+
+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);
+}
+
+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);
+}
+
+static int
+copy_vbios(memType v_base)
+{
+ int mem_fd;
+ unsigned char *tmp;
+ int size;
+
+ if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
+ perror("opening memory");
+ return (0);
+ }
+
+ if (lseek(mem_fd,(off_t) v_base, SEEK_SET) != (off_t) v_base) {
+ fprintf(stderr,"Cannot lseek\n");
+ goto Error;
+ }
+ tmp = (unsigned char *)malloc(3);
+ if (read(mem_fd, (char *)tmp, (size_t) 3) != (size_t) 3) {
+ fprintf(stderr,"Cannot read\n");
+ goto Error;
+ }
+ if (lseek(mem_fd,(off_t) v_base,SEEK_SET) != (off_t) v_base)
+ goto Error;
+
+ if (*tmp != 0x55 || *(tmp+1) != 0xAA ) {
+ fprintf(stderr,"No bios found at: 0x%lx\n",v_base);
+ goto Error;
+ }
+#ifdef DEBUG
+ dprint((unsigned long)tmp,0x100);
+#endif
+ size = *(tmp+2) * 512;
+
+ if (read(mem_fd, (char *)v_base, (size_t) size) != (size_t) size) {
+ fprintf(stderr,"Cannot read\n");
+ goto Error;
+ }
+ free(tmp);
+ close(mem_fd);
+ if (!chksum((CARD8*)v_base))
+ return (0);
+
+ return (1);
+
+Error:
+ perror("v_bios");
+ close(mem_fd);
+ return (0);
+}
+
+static void
+unmap(void)
+{
+ munmap(0,SIZE);
+}
+
+static void
+unmap_vram(void)
+{
+ if (!vram_mapped) return;
+
+ munmap((void*)VRAM_START,VRAM_SIZE);
+ vram_mapped = 0;
+}
+
+static void
+runBIOS(int argc, char ** argv)
+{
+ i86biosRegs bRegs;
+#ifdef V86BIOS_DEBUG
+ printf("starting BIOS\n");
+#endif
+ setup_bios_regs(&bRegs, argc, argv);
+ do_x86(BIOS_START,&bRegs);
+ print_regs(&bRegs);
+#ifdef V86BIOS_DEBUG
+ printf("done\n");
+#endif
+}
+
+static CARD32
+setup_int_vect(void)
+{
+ int mem_fd;
+ CARD32 vbase;
+ void *map;
+
+ if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
+ perror("opening memory");
+ return (0);
+ }
+
+ if ((map = mmap((void *) 0, (size_t) 0x2000,
+ PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
+ mem_fd, 0)) == (void *)-1) {
+ perror("mmap error in map_hardware_ram");
+ close(mem_fd);
+ return (0);
+ }
+
+ close(mem_fd);
+ memcpy(0,map,BIOS_MEM);
+ munmap(map,0x2000);
+ /*
+ * create a backup copy of the bios variables to write back the
+ * modified values
+ */
+ bios_var = (char *)malloc(BIOS_MEM);
+ memcpy(bios_var,0,BIOS_MEM);
+
+ vbase = (*((CARD16*)(0x10 << 2) + 1)) << 4;
+ fprintf(stderr,"vbase: 0x%x\n",vbase);
+ return vbase;
+}
+
+static void
+update_bios_vars(void)
+{
+ int mem_fd;
+ void *map;
+ memType i;
+
+#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;
+ }
+
+ if ((map = mmap((void *) 0, (size_t) 0x2000,
+ PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
+ mem_fd, 0)) == (void *)-1) {
+ perror("mmap error in map_hardware_ram");
+ close(mem_fd);
+ return;
+ }
+
+ for (i = 0; i < BIOS_MEM; i++) {
+ if (bios_var[i] != *(CARD8*)i)
+ *((CARD8*)map + i) = *(CARD8*)i;
+ }
+
+ munmap(map,0x2000);
+ close(mem_fd);
+}
+
+
+static void
+setup_bios_regs(i86biosRegsPtr regs, int argc, char **argv)
+{
+ int c;
+
+ regs->ax = 0;
+ regs->bx = 0;
+ regs->cx = 0;
+ regs->dx = 0;
+ regs->es = 0;
+ regs->di = 0;
+ opterr = 0;
+ while ((c = getopt(argc,argv,"a:b:c:d:e:i:")) != EOF) {
+ switch (c) {
+ case 'a':
+ regs->ax = strtol(optarg,NULL,0);
+ break;
+ case 'b':
+ regs->bx = strtol(optarg,NULL,0);
+ break;
+ case 'c':
+ regs->cx = strtol(optarg,NULL,0);
+ break;
+ case 'd':
+ regs->dx = strtol(optarg,NULL,0);
+ break;
+ case 'e':
+ regs->es = strtol(optarg,NULL,0);
+ break;
+ case 'i':
+ regs->di = strtol(optarg,NULL,0);
+ break;
+ }
+ }
+}
+
+
+static int
+chksum(CARD8 *start)
+{
+ CARD16 size;
+ CARD8 val = 0;
+ int i;
+
+ size = *(start+2) * 512;
+ for (i = 0; i<size; i++)
+ val += *(start + i);
+
+ if (!val)
+ return 1;
+
+ fprintf(stderr,"BIOS cksum wrong!\n");
+ return 0;
+}
+
+static void
+print_regs(i86biosRegsPtr regs)
+{
+ printf("ax=%x bx=%x cx=%x dx=%x es=%x di=%x\n",(CARD16)regs->ax,
+ (CARD16)regs->bx,(CARD16)regs->cx,(CARD16)regs->dx,
+ (CARD16)regs->es,(CARD16)regs->di);
+}
+
+void
+loadCodeToMem(unsigned char *ptr, CARD8 code[])
+{
+ int i;
+ CARD8 val;
+
+ for ( i=0;;i++) {
+ val = code[i];
+ *ptr++ = val;
+ if (val == 0xf4) break;
+ }
+ return;
+}
+
+void
+dprint(unsigned long start, unsigned long size)
+{
+ int i,j;
+ char *c = (char *)start;
+
+ for (j = 0; j < (size >> 4); j++) {
+ printf ("\n0x%lx: ",(unsigned long)c);
+ for (i = 0; i<16; i++)
+ printf("%x ",(unsigned char) (*(c++)));
+ }
+ printf("\n");
+}
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/command.c b/board/MAI/bios_emulator/scitech/src/v86bios/command.c
new file mode 100644
index 0000000000..3a468da313
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/command.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+#include <malloc.h>
+
+#define PROMPT ">"
+
+
+void
+getline(char *buf,int *num,int max_num)
+{
+ static int line_len = 0;
+ static char *line = NULL;
+ static char *line_pointer = NULL;
+ static int len = 0;
+ int tmp_len;
+ char *buff;
+
+ if (len <= 0) {
+ buff = readline(PROMPT);
+ add_history(buff);
+
+ if ((tmp_len = strlen(buff)) > line_len) {
+ free(line);
+ line = malloc(tmp_len);
+ line_len = tmp_len;
+ }
+ sprintf(line,"%s\n",buff);
+ free(buff);
+ line_pointer = line;
+ len = strlen(line);
+ }
+
+ *num = max_num > len? len : max_num;
+ strncpy(buf,line_pointer,*num);
+ line_pointer = line_pointer + *num;
+ len = len - *num;
+}
+
+
+
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/console.c b/board/MAI/bios_emulator/scitech/src/v86bios/console.c
new file mode 100644
index 0000000000..46805155f8
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/console.c
@@ -0,0 +1,104 @@
+/*
+ * 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 <sys/ioctl.h>
+#include <sys/vt.h>
+#include <sys/kd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "debug.h"
+#include "v86bios.h"
+
+console
+open_console(void)
+{
+ int fd;
+ int VTno;
+ char VTname[11];
+ console Con = {-1,-1};
+ struct vt_stat vts;
+
+ if (NO_CONSOLE)
+ return Con;
+
+ if ((fd = open("/dev/tty0",O_WRONLY,0)) < 0)
+ return Con;
+
+ if ((ioctl(fd, VT_OPENQRY, &VTno) < 0) || (VTno == -1)) {
+ fprintf(stderr,"cannot get a vt\n");
+ return Con;
+ }
+
+ close(fd);
+ sprintf(VTname,"/dev/tty%i",VTno);
+
+ if ((fd = open(VTname, O_RDWR|O_NDELAY, 0)) < 0) {
+ fprintf(stderr,"cannot open console\n");
+ return Con;
+ }
+
+ if (ioctl(fd, VT_GETSTATE, &vts) == 0)
+ Con.vt = vts.v_active;
+
+ if (ioctl(fd, VT_ACTIVATE, VTno) != 0) {
+ fprintf(stderr,"cannot activate console\n");
+ close(fd);
+ return Con;
+ }
+ if (ioctl(fd, VT_WAITACTIVE, VTno) != 0) {
+ fprintf(stderr,"wait for active console failed\n");
+ close(fd);
+ return Con;
+ }
+#if 0
+ if (ioctl(fd, KDSETMODE, KD_GRAPHICS) < 0) {
+ close(fd);
+ return Con;
+ }
+#endif
+ Con.fd = fd;
+ return Con;
+}
+
+void
+close_console(console Con)
+{
+ if (Con.fd == -1)
+ return;
+
+#if 0
+ ioctl(Con.fd, KDSETMODE, KD_TEXT);
+#endif
+ if (Con.vt >=0)
+ ioctl(Con.fd, VT_ACTIVATE, Con.vt);
+
+ close(Con.fd);
+}
+
+
+
+
+
+
+
+
+
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/debug.h b/board/MAI/bios_emulator/scitech/src/v86bios/debug.h
new file mode 100644
index 0000000000..bc0b1117db
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/debug.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+//#define V86BIOS_DEBUG
+
+/*
+ * uncomment the following if needed
+ * should be command line options
+ */
+
+#define PRINT_PORT 0
+#define IO_STATISTICS 0
+#define PRINT_IRQ 0
+#define PRINT_PCI 1
+#define PRINT_IP 0 /* print IP address with PIO information */
+#define TRACE 0 /* turn on debugger in x86emu */
+ /* requires x86emu compiled with -DDEBUG */
+
+/*
+ * these should not be here.
+ * Should be converted to command line options.
+ */
+#define CONFIG_ACTIVE_ONLY 0
+#define CONFIG_ACTIVE_DEVICE 1
+#define SAVE_BIOS 0
+#define MAP_SYS_BIOS 1
+#define RESORT 1
+#define FIX_ROM 0
+#define NO_CONSOLE 0
+#define SHOW_ALL_DEV 0
+#define VERBOSE 0
+
+//#define V_BIOS 0xe0000
+//#define V_BIOS 0xe4000
+
+
+
+
+#if (PRINT_IO == 1) && (PRINT_PORT == 0)
+# define PRINT_IO 0
+#endif
+#if (IO_STATISTICS == 1) && (PRINT_PORT == 0)
+# define IO_STATISTICS 0
+#endif
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/happy_cards b/board/MAI/bios_emulator/scitech/src/v86bios/happy_cards
new file mode 100644
index 0000000000..943d44ede4
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/happy_cards
@@ -0,0 +1,76 @@
+What I had to do to make cards happy:
+
+1. Tseng ET4000 W32P
+This card wants to call the original system BIOS video routines.
+It sets the int 0x42 vector to F000:F065, the entry point to the
+system bios video routines.
+CAVE: don't catch int 0x42 and use the vbios int 0x10 routines.
+At early stage during initialization they call int 0x42. This
+causes an infinite loop.
+
+2. ATi Mach64 Rage IIc AGP
+This card does similar things like the Tseng ET4000 W32P.
+However it doesn't have the problem with the ininite loop.
+
+3. Elsa Victory II-A16 AGP Banshee
+This card is very clever: It knows it is an AGP card. Therefore
+it knows it is behind a PCI-PCI bridge. It also knows that noone
+else is behind this bridge. Therefore it start reprogramming the
+bridge! For this it assumes the AGP bridge is on bus 1.
+
+4. Elsa Gloria Synergy 8 ViVo AGP PM2
+This card likes to see a complete interrupt vector table. If
+we fill this table with 0 the VBIOS detects this and quits
+initialization.
+
+5. Dimond Viper 330 AGP NVIDIA Riva 128.
+This card has a similar problem like the Elsa Gloria. It wants
+to read the system BIOS date at 0xffffd.
+
+6. Matrox Mystique PCI
+This card reads the IO port 0x62. If it doesn't like what it sees
+it loops forever. To keep the card happy put 0xfc into 0xffffe.
+This location holds the system model id. 0xfc means IBM-AT.
+ One can make an interesting observation: this card likes to know
+with whom it has to share the system. Therefore it accesses PCI
+config space of all the other cards. It does this bypassing the
+PCI BIOS by reading the PCI access ports directly.
+
+7. Matrox G100 AGP
+This card has the same problem as the Mystique.
+
+Apperantly this works now. However not all combinations of cards are
+checked, yet.
+
+Further notes:
+the IO register 0x42-0x43 as well as 0x61-0x63 are of special interest
+for many graphic cards. They should be emulated.
+The so called "Industry Standard BIOS Entry Points" to int 0x42 (0xFF065)
+and to int 0x1a (0xFFE6E) should be filled with useful code. This code
+needs to return as if it was called as int.
+The subvendor ID PCI registers might cause problems. On some chipsets
+they are programmed in a non-obivous non-PCI conformant way.
+V_Bioses are seen to modify the following int:
+0x10 (default video), 0x1f(font table), 0x42(copy of default video),
+0x43 (??), 0x6d (copy of default video - same as 0x10?)
+
+TODO:
+Int 0x6d needs to be done.
+All interrupts where there is no default industry standard entry point
+should point to an unused location in the 0xF000 segmant (possibly
+0xF0000). This way they could be trapped. A trap handler for
+a. int 0x42 and int 0x1a needs to be implemented.
+The default "industry entry point" for video and PCI (0xFFE6E) should
+also be implemented. (any others?) They should either be routed to
+int 0x42(0x6d?) (video) and 0x1A (PCI) or some other interrupts to
+trap them. Mapping of system bios might not be a good idea. Maybe
+the system bios area should just be filled with "hlt" to trap any
+access there.
+Handling of timer IO registers 0x42, 0x43 and IO registers 0x61, 0x62.
+
+Find documentation:
+- on interrupt vector table
+- on industry standard entry points to the system bios
+- on IO registers 0x61 and 0x62
+
+
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/hexdump b/board/MAI/bios_emulator/scitech/src/v86bios/hexdump
new file mode 100644
index 0000000000..4f359e5edd
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/hexdump
@@ -0,0 +1,3 @@
+"%06.6_ax " 16/1 "%02x "
+" " 16/1 "%_p"
+"\n"
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/int.c b/board/MAI/bios_emulator/scitech/src/v86bios/int.c
new file mode 100644
index 0000000000..40b17b1d70
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/int.c
@@ -0,0 +1,238 @@
+/*
+ * 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 "debug.h"
+#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;
+
+ i_printf("int 0x%x: ax:0x%lx bx:0x%lx cx:0x%lx dx:0x%lx\n",num,
+ regs->eax,regs->ebx, regs->ecx, regs->edx);
+
+ /*
+ * 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:
+ i_printf("enabling video\n");
+ c = inb(0x3cc);
+ c |= 0x02;
+ outb(0x3c2,c);
+ return 1;
+ case 0x1201:
+ i_printf("disabling video\n");
+ c = inb(0x3cc);
+ c &= ~0x02;
+ outb(0x3c2,c);
+ return 1;
+ default:
+ }
+ }
+ 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 */
+
+ i_printf("int 0x1a: ax=0x%lx bx=0x%lx cx=0x%lx dx=0x%lx di=0x%lx"
+ " si=0x%lx\n", regs->eax,regs->ebx,regs->ecx,regs->edx,
+ regs->edi,regs->esi);
+ 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 */
+ i_printf("ax=0x%lx dx=0x%lx bx=0x%lx cx=0x%lx flags=0x%lx\n",
+ regs->eax,regs->edx,regs->ebx,regs->ecx,regs->eflags);
+ 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 if (Config.ShowAllDev &&
+ (pPci = findPciDevice(regs->edx,regs->ecx,regs->esi)) != NULL) {
+ regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8);
+ regs->eflags &= ~((unsigned long)0x01); /* clear carry flag */
+ regs->ebx = pciSlotBX(pPci);
+ } else {
+ regs->eax = (regs->eax & 0x00FF) | (DEVICE_NOT_FOUND << 8);
+ regs->eflags |= ((unsigned long)0x01); /* set carry flag */
+ }
+ i_printf("ax=0x%lx bx=0x%lx flags=0x%lx\n",
+ regs->eax,regs->ebx,regs->eflags);
+ 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 if (Config.ShowAllDev
+ && (pPci = findPciClass(regs->ecx & 0xFF, (regs->ecx & 0xff00) >> 8,
+ (regs->ecx & 0xffff0000) >> 16, regs->esi)) != NULL) {
+ regs->eax = (regs->eax & 0x00FF) | (SUCCESSFUL << 8);
+ regs->ebx = pciSlotBX(pPci);
+ 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 */
+ }
+ i_printf("ax=0x%lx flags=0x%lx\n",regs->eax,regs->eflags);
+ return 1;
+ case 0xb108:
+ i_printf("Slot=0x%x\n",CurrentPci->Slot.l);
+ 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 */
+ }
+ i_printf("ax=0x%lx cx=0x%lx flags=0x%lx\n",
+ regs->eax,regs->ecx,regs->eflags);
+ return 1;
+ case 0xb109:
+ i_printf("Slot=0x%x\n",CurrentPci->Slot.l);
+ 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 */
+ }
+ i_printf("ax=0x%lx cx=0x%lx flags=0x%lx\n",
+ regs->eax,regs->ecx,regs->eflags);
+ return 1;
+ case 0xb10a:
+ i_printf("Slot=0x%x\n",CurrentPci->Slot.l);
+ 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 */
+ }
+ i_printf("ax=0x%lx cx=0x%lx flags=0x%lx\n",
+ regs->eax,regs->ecx,regs->eflags);
+ return 1;
+ case 0xb10b:
+ i_printf("Slot=0x%x\n",CurrentPci->Slot.l);
+ 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 */
+ }
+ i_printf("ax=0x%lx flags=0x%lx\n", regs->eax,regs->eflags);
+ return 1;
+ case 0xb10c:
+ i_printf("Slot=0x%x\n",CurrentPci->Slot.l);
+ 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 */
+ }
+ i_printf("ax=0x%lx flags=0x%lx\n", regs->eax,regs->eflags);
+ return 1;
+ case 0xb10d:
+ i_printf("Slot=0x%x\n",CurrentPci->Slot.l);
+ 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 */
+ }
+ i_printf("ax=0x%lx flags=0x%lx\n", regs->eax,regs->eflags);
+ return 1;
+ default:
+ return 0;
+ }
+}
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/io.c b/board/MAI/bios_emulator/scitech/src/v86bios/io.c
new file mode 100644
index 0000000000..129e24f383
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/io.c
@@ -0,0 +1,257 @@
+/*
+ * 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 "debug.h"
+
+#include <stdio.h>
+#if defined(__alpha__) || defined (__ia64__)
+#include <sys/io.h>
+#endif
+#include "AsmMacros.h"
+#include "v86bios.h"
+#include "pci.h"
+
+int r_inb = 0, r_inw = 0, r_inl = 0, r_outb = 0, r_outw = 0, r_outl = 0;
+int in_b = 0, in_w = 0, in_l = 0, out_b = 0, out_w = 0, out_l = 0;
+
+
+int
+port_rep_inb(CARD16 port, CARD8 *base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -1 : 1;
+ CARD8 *dst = base;
+
+ p_printf(" rep_insb(%#x) %d bytes at %p %s",
+ port, count, base, d_f?"up":"down");
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ r_inb++;
+ 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;
+
+ p_printf(" rep_insw(%#x) %d bytes at %p %s",
+ port, count, base, d_f?"up":"down");
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ r_inw++;
+ 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;
+
+ p_printf(" rep_insl(%#x) %d bytes at %p %s",
+ port, count, base, d_f?"up":"down");
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ r_inl++;
+ 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;
+
+ p_printf(" rep_outb(%#x) %d bytes at %p %s",
+ port, count, base, d_f?"up":"down");
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ r_outb++;
+ 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;
+
+ p_printf(" rep_outw(%#x) %d bytes at %p %s",
+ port, count, base, d_f?"up":"down");
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ r_outw++;
+ 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;
+
+ p_printf(" rep_outl(%#x) %d bytes at %p %s",
+ port, count, base, d_f?"up":"down");
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ r_outl++;
+ while (count--) {
+ outl(port,*dst);
+ dst += inc;
+ }
+ return (dst-base);
+}
+
+CARD8
+p_inb(CARD16 port)
+{
+ CARD8 val = 0;
+ in_b++;
+ val = inb(port);
+ p_printf(" inb(%#x) = %2.2x",port,val);
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ return val;
+}
+
+CARD16
+p_inw(CARD16 port)
+{
+ CARD16 val = 0;
+ in_w++;
+ val = inw(port);
+ p_printf(" inw(%#x) = %4.4x",port,val);
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ return val;
+}
+
+CARD32
+p_inl(CARD16 port)
+{
+ CARD32 val = 0;
+ in_l++;
+#ifdef NEED_PCI_IO
+ if (cfg1in(port,&val))
+ return val;
+ else
+#endif
+ val = inl(port);
+ p_printf(" inl(%#x) = %8.8x",port,val);
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ return val;
+}
+
+void
+p_outb(CARD16 port, CARD8 val)
+{
+ out_b++;
+ p_printf(" outb(%#x, %2.2x)",port,val);
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ outb(port,val);
+}
+
+void
+p_outw(CARD16 port, CARD16 val)
+{
+ out_w++;
+ p_printf(" outw(%#x, %4.4x)",port,val);
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+ outw(port,val);
+}
+
+void
+p_outl(CARD16 port, CARD32 val)
+{
+ out_l++;
+ p_printf(" outl(%#x, %8.8x)",port,val);
+ if (Config.PrintIp)
+ p_printf(" %x\n",getIP());
+ else p_printf("\n");
+
+#ifdef NEED_PCI_IO
+ if (cfg1out(port,val))
+ return;
+#endif
+ outl(port,val);
+}
+
+void
+io_statistics(void)
+{
+ p_printf("rep: inb: %i, inw: %i, inl: %i, outb: %i, outw: %i, outl: %i\n",
+ r_inb,r_inw,r_inl,r_outb,r_outw,r_outl);
+ p_printf("inb: %i, inw: %i, inl: %i, outb: %i, outw: %i, outl: %i\n",
+ in_b,in_w,in_l,out_b,out_w,out_l);
+}
+
+void
+clear_stat(void)
+{
+ r_inb = r_inw = r_inl = r_outb = r_outw = r_outl = 0;
+ in_b = in_w = in_l = out_b = out_w = out_l = 0;
+}
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/lex.l b/board/MAI/bios_emulator/scitech/src/v86bios/lex.l
new file mode 100644
index 0000000000..3a3391c7b4
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/lex.l
@@ -0,0 +1,79 @@
+%{
+#include "parser.h"
+
+#include <string.h>
+#include <stdio.h>
+
+ void getline(char *buf,int *num,int max_num);
+
+#define YY_INPUT(buf,result,max_size) {\
+ getline(buf,&result,max_size);\
+ }
+
+ void
+ yyerror (char *s)
+ {
+ printf ("%s\n", s);
+ }
+
+%}
+
+DIGIT [0-9a-fA-F]
+
+%%
+
+"0x"?{DIGIT}+ { yylval = strtol(yytext,NULL,0); return TOK_NUM; }
+"ax" { return TOK_REG_AX; }
+"bx" { return TOK_REG_BX; }
+"cx" { return TOK_REG_CX; }
+"dx" { return TOK_REG_DX; }
+"di" { return TOK_REG_SI; }
+"si" { return TOK_REG_DI; }
+"ds" { return TOK_SEG_DS; }
+"es" { return TOK_SEG_ES; }
+":" { return TOK_SEP;}
+"$"{DIGIT}{1,2} { yylval = strtol(yytext+1,NULL,0); return TOK_VAR; }
+"$mem" { return TOK_VAR_MEM; }
+[ \t]+
+"#".*[\n] { return TOK_END; }
+"boot" { return TOK_COMMAND_BOOT; }
+"do" { return TOK_COMMAND_EXEC; }
+"\"".*"\"" { yylval = (unsigned long) yytext; return TOK_STRING; }
+"byte" { return TOK_BYTE; }
+"word" { return TOK_WORD; }
+"long" { return TOK_LONG; }
+"setmem" { return TOK_COMMAND_MEMSET; }
+"dumpmem" { return TOK_COMMAND_MEMDUMP; }
+"quit" { return TOK_COMMAND_QUIT; }
+"\n" { return TOK_END; }
+"select" { return TOK_SELECT; }
+"isa" { return TOK_ISA; }
+"pci" { return TOK_PCI; }
+"pport" { return TOK_PRINT_PORT; }
+"iostat" { return TOK_IOSTAT; }
+"pirq" { return TOK_PRINT_IRQ; }
+"ppci" { return TOK_PPCI; }
+"pip" { return TOK_PIP; }
+"trace" { return TOK_TRACE; }
+"on" { return TOK_ON; }
+"off" { return TOK_OFF; }
+"verbose" { return TOK_VERBOSE; }
+"log" { return TOK_LOG; }
+"print" { return TOK_STDOUT; }
+"clstat" { return TOK_CLSTAT; }
+"hlt" { return TOK_HLT; }
+"del" { return TOK_DEL; }
+"ioperm" { return TOK_IOPERM; }
+"lpci" { return TOK_DUMP_PCI; }
+"bootbios" { return TOK_BOOT_BIOS; }
+"?" { return '?'; }
+. { return TOK_ERROR; }
+
+%%
+
+
+
+
+
+
+
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/main.c b/board/MAI/bios_emulator/scitech/src/v86bios/main.c
new file mode 100644
index 0000000000..b73d05776e
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/main.c
@@ -0,0 +1,616 @@
+/*
+ * 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.
+ */
+#define DELETE
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/stat.h>
+#if defined(__alpha__) || defined (__ia64__)
+#include <sys/io.h>
+#elif defined(HAVE_SYS_PERM)
+#include <sys/perm.h>
+#endif
+#include "debug.h"
+#include "v86bios.h"
+#include "pci.h"
+#include "AsmMacros.h"
+
+#define SIZE 0x100000
+#define VRAM_START 0xA0000
+#define VRAM_SIZE 0x1FFFF
+#define V_BIOS_SIZE 0x1FFFF
+#define BIOS_START 0x7C00 /* default BIOS entry */
+
+//CARD8 code[] = { 0xb8 , 0xf0 , 0xf0, 0xf4 };
+#define VB_X(x) (V_BIOS >> x) & 0xFF
+CARD8 code[] = { 0x9a, 0x03, 0x00, 0x00, VB_X(12), 0xf4 };
+//CARD8 code[] = { 0x9a, 0x03, 0x00, 0x00, VB_X(12), 0xb8, 0x03, 0x00,
+//0xcd, 0x10, 0xf4 };
+//CARD8 code[] = { 0xb8 , 0xf0 , 0xf0 ,0xf4 };
+
+static void sig_handler(int);
+static int map(void);
+static void unmap(void);
+static void bootBIOS(CARD16 ax);
+static int map_vram(void);
+static void unmap_vram(void);
+static int copy_vbios(void);
+static int copy_sys_bios(void);
+static void save_bios_to_file(void);
+static int setup_system_bios(void);
+static void setup_int_vect(void);
+static int chksum(CARD8 *start);
+static void setup_bios_regs(i86biosRegsPtr regs, CARD32 ax);
+
+void loadCodeToMem(unsigned char *ptr, CARD8 *code);
+void dprint(unsigned long start, unsigned long size);
+
+static int vram_mapped = 0;
+static CARD8 save_msr;
+static CARD8 save_pos102;
+static CARD8 save_vse;
+static CARD8 save_46e8;
+console Console;
+struct config Config;
+
+
+int
+main(void)
+{
+ int Active_is_Pci = 0;
+#ifdef DELETE
+ Config.PrintPort = PRINT_PORT;
+ Config.IoStatistics = IO_STATISTICS;
+ Config.PrintIrq = PRINT_IRQ;
+ Config.PrintPci = PRINT_PCI;
+ Config.ShowAllDev = SHOW_ALL_DEV;
+ Config.PrintIp = PRINT_IP;
+ Config.SaveBios = SAVE_BIOS;
+ Config.Trace = TRACE;
+ Config.ConfigActiveOnly = CONFIG_ACTIVE_ONLY;
+ Config.ConfigActiveDevice = CONFIG_ACTIVE_DEVICE;
+ Config.MapSysBios = MAP_SYS_BIOS;
+ Config.Resort = RESORT;
+ Config.FixRom = FIX_ROM;
+ Config.NoConsole = NO_CONSOLE;
+ Config.Verbose = VERBOSE;
+
+ if (!map())
+ exit(1);
+
+ if (!setup_system_bios())
+ exit(1);
+
+ iopl(3);
+ setup_io();
+
+ scan_pci();
+ if (!CurrentPci && !Config.ConfigActiveDevice && !Config.ConfigActiveOnly)
+ exit (1);
+#endif
+ Console = open_console();
+
+ if (Config.ConfigActiveOnly) {
+ CARD16 ax;
+ int activePci = 0;
+ int error = 0;
+
+ while (CurrentPci) {
+ if (CurrentPci->active) {
+ activePci = 1;
+ if (!(mapPciRom(NULL) && chksum((CARD8*)V_BIOS)))
+ error = 1;
+ break;
+ }
+ CurrentPci = CurrentPci->next;
+ }
+ ax = ((CARD16)(CurrentPci->bus) << 8)
+ | (CurrentPci->dev << 3) | (CurrentPci->func & 0x7);
+ P_printf("ax: 0x%x\n",ax);
+ setup_int_vect();
+ if (!error && (activePci || copy_vbios())) {
+
+ if (Config.SaveBios) save_bios_to_file();
+ if (map_vram()) {
+ printf("initializing ISA\n");
+ bootBIOS(0);
+ }
+ }
+ unmap_vram();
+ sleep(1);
+ } else {
+ /* disable primary card */
+ save_msr = inb(0x3CC);
+ save_vse = inb(0x3C3);
+ save_46e8 = inb(0x46e8);
+ save_pos102 = inb(0x102);
+
+ signal(2,sig_handler);
+ signal(11,sig_handler);
+
+ outb(0x3C2,~(CARD8)0x03 & save_msr);
+ outb(0x3C3,~(CARD8)0x01 & save_vse);
+ outb(0x46e8, ~(CARD8)0x08 & save_46e8);
+ outb(0x102, ~(CARD8)0x01 & save_pos102);
+
+ pciVideoDisable();
+
+ while (CurrentPci) {
+ CARD16 ax;
+
+ if (CurrentPci->active) {
+ Active_is_Pci = 1;
+ if (!Config.ConfigActiveDevice) {
+ CurrentPci = CurrentPci->next;
+ continue;
+ }
+ }
+
+ EnableCurrent();
+
+ if (CurrentPci->active) {
+ outb(0x102, save_pos102);
+ outb(0x46e8, save_46e8);
+ outb(0x3C3, save_vse);
+ outb(0x3C2, save_msr);
+ }
+
+ /* clear interrupt vectors */
+ setup_int_vect();
+
+ ax = ((CARD16)(CurrentPci->bus) << 8)
+ | (CurrentPci->dev << 3) | (CurrentPci->func & 0x7);
+ P_printf("ax: 0x%x\n",ax);
+
+ if (!((mapPciRom(NULL) && chksum((CARD8*)V_BIOS))
+ || (CurrentPci->active && copy_vbios()))) {
+ CurrentPci = CurrentPci->next;
+ continue;
+ }
+ if (!map_vram()) {
+ CurrentPci = CurrentPci->next;
+ continue;
+ }
+ if (Config.SaveBios) save_bios_to_file();
+ printf("initializing PCI bus: %i dev: %i func: %i\n",CurrentPci->bus,
+ CurrentPci->dev,CurrentPci->func);
+ bootBIOS(ax);
+ unmap_vram();
+
+ CurrentPci = CurrentPci->next;
+ }
+
+ /* We have an ISA device - configure if requested */
+ if (!Active_is_Pci && Config.ConfigActiveDevice) {
+ pciVideoDisable();
+
+ outb(0x102, save_pos102);
+ outb(0x46e8, save_46e8);
+ outb(0x3C3, save_vse);
+ outb(0x3C2, save_msr);
+
+ setup_int_vect();
+ if (copy_vbios()) {
+
+ if (Config.SaveBios) save_bios_to_file();
+ if (map_vram()) {
+ printf("initializing ISA\n");
+ bootBIOS(0);
+ }
+ }
+
+ unmap_vram();
+ sleep(1);
+ }
+
+ pciVideoRestore();
+
+ outb(0x102, save_pos102);
+ outb(0x46e8, save_46e8);
+ outb(0x3C3, save_vse);
+ outb(0x3C2, save_msr);
+ }
+
+ close_console(Console);
+#ifdef DELETE
+ iopl(0);
+ unmap();
+
+ printf("done !\n");
+#endif
+ if (Config.IoStatistics)
+ io_statistics();
+#ifdef DELETE
+ exit(0);
+#endif
+}
+
+int
+map(void)
+{
+ void* mem;
+
+ mem = mmap(0, (size_t)SIZE,
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_FIXED | MAP_PRIVATE | MAP_ANON,
+ -1, 0 );
+ if (mem != 0) {
+ perror("anonymous map");
+ return (0);
+ }
+ memset(mem,0,SIZE);
+
+ loadCodeToMem((unsigned char *) BIOS_START, code);
+ return (1);
+}
+
+static void
+unmap(void)
+{
+ munmap(0,SIZE);
+}
+
+static void
+bootBIOS(CARD16 ax)
+{
+ i86biosRegs bRegs;
+#ifdef V86BIOS_DEBUG
+ printf("starting BIOS\n");
+#endif
+ setup_bios_regs(&bRegs, ax);
+ do_x86(BIOS_START,&bRegs);
+#ifdef V86BIOS_DEBUG
+ printf("done\n");
+#endif
+}
+
+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);
+}
+
+static void
+unmap_vram(void)
+{
+ if (!vram_mapped) return;
+
+ munmap((void*)VRAM_START,VRAM_SIZE);
+ vram_mapped = 0;
+}
+
+static int
+copy_vbios(void)
+{
+ int mem_fd;
+ unsigned char *tmp;
+ int size;
+
+ if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
+ perror("opening memory");
+ return (0);
+ }
+
+ if (lseek(mem_fd,(off_t) V_BIOS, SEEK_SET) != (off_t) V_BIOS) {
+ fprintf(stderr,"Cannot lseek\n");
+ goto Error;
+ }
+ tmp = (unsigned char *)malloc(3);
+ if (read(mem_fd, (char *)tmp, (size_t) 3) != (size_t) 3) {
+ fprintf(stderr,"Cannot read\n");
+ goto Error;
+ }
+ if (lseek(mem_fd,(off_t) V_BIOS,SEEK_SET) != (off_t) V_BIOS)
+ goto Error;
+
+ if (*tmp != 0x55 || *(tmp+1) != 0xAA ) {
+#ifdef DEBUG
+ dprint((unsigned long)tmp,0x100);
+#endif
+ fprintf(stderr,"No bios found at: 0x%x\n",V_BIOS);
+ goto Error;
+ }
+ size = *(tmp+2) * 512;
+
+ if (read(mem_fd, (char *)V_BIOS, (size_t) size) != (size_t) size) {
+ fprintf(stderr,"Cannot read\n");
+ goto Error;
+ }
+ free(tmp);
+ close(mem_fd);
+ if (!chksum((CARD8)V_BIOS))
+ return (0);
+
+ return (1);
+
+Error:
+ perror("v_bios");
+ close(mem_fd);
+ return (0);
+}
+
+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);
+}
+
+void
+loadCodeToMem(unsigned char *ptr, CARD8 code[])
+{
+ int i;
+ CARD8 val;
+
+ for ( i=0;;i++) {
+ val = code[i];
+ *ptr++ = val;
+ if (val == 0xf4) break;
+ }
+ return;
+}
+
+void
+dprint(unsigned long start, unsigned long size)
+{
+ int i,j;
+ char *c = (char *)start;
+
+ for (j = 0; j < (size >> 4); j++) {
+ char *d = c;
+ printf("\n0x%lx: ",(unsigned long)c);
+ for (i = 0; i<16; i++)
+ printf("%2.2x ",(unsigned char) (*(c++)));
+ c = d;
+ for (i = 0; i<16; i++) {
+ printf("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ?
+ (unsigned char) (*(c)): '.');
+ c++;
+ }
+ }
+ printf("\n");
+}
+
+static void
+save_bios_to_file(void)
+{
+ static int num = 0;
+ int size, count;
+ char file_name[256];
+ int fd;
+
+ sprintf(file_name,"bios_%i.fil",num);
+ if ((fd = open(file_name,O_WRONLY | O_CREAT | O_TRUNC,00644)) == -1)
+ return;
+ size = (*(unsigned char*)(V_BIOS + 2)) * 512;
+#ifdef V86BIOS_DEBUG
+ dprint(V_BIOS,20);
+#endif
+ if ((count = write(fd,(void *)(V_BIOS),size)) != size)
+ fprintf(stderr,"only saved %i of %i bytes\n",size,count);
+ num++;
+}
+
+static void
+sig_handler(int unused)
+{
+ fflush(stdout);
+ fflush(stderr);
+
+ /* put system back in a save state */
+ unmap_vram();
+ pciVideoRestore();
+ outb(0x102, save_pos102);
+ outb(0x46e8, save_46e8);
+ outb(0x3C3, save_vse);
+ outb(0x3C2, save_msr);
+
+ close_console(Console);
+ iopl(0);
+ unmap();
+
+ exit(1);
+}
+
+/*
+ * For initialization we just pass ax to the BIOS.
+ * PCI BIOSes need this. All other register are set 0.
+ */
+static void setup_bios_regs(i86biosRegsPtr regs, CARD32 ax)
+{
+ regs->ax = ax;
+ regs->bx = 0;
+ regs->cx = 0;
+ regs->dx = 0;
+ regs->es = 0;
+ regs->di = 0;
+}
+
+/*
+ * 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;
+}
+
+static int
+chksum(CARD8 *start)
+{
+ CARD16 size;
+ CARD8 val = 0;
+ int i;
+
+ size = *(start+2) * 512;
+ for (i = 0; i<size; i++)
+ val += *(start + i);
+
+ if (!val)
+ return 1;
+
+ fprintf(stderr,"BIOS cksum wrong!\n");
+ return 0;
+}
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/makefile.linux b/board/MAI/bios_emulator/scitech/src/v86bios/makefile.linux
new file mode 100644
index 0000000000..5dfe306991
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/makefile.linux
@@ -0,0 +1,59 @@
+CFLAGS=-g -I/usr/include -I../../include/ -O0 -Wall
+CC=gcc
+
+.y.c:
+ bison -d -o $@ $<
+.l.c:
+ flex -o$@ $<
+
+SRCS = main.c io.c x86emu.c int.c pci.c
+OBJS = main.o io.o x86emu.o int.o pci.o
+
+all : vbios.vm86 v86bios.vm86 cbios.vm86 cbios.x86emu vbios.x86emu v86bios.x86emu
+#all : cbios.x86emu vbios.x86emu v86bios.x86emu
+
+parser.c : parser.y
+lex.c : lex.l
+cbios.o : cbios.c v86bios.h debug.h
+main.o : main.c v86bios.h pci.h debug.h
+io.o : v86bios.h AsmMacros.h debug.h
+mem.o : mem.c debug.h v86bios.h
+int.o : int.c v86bios.h debug.h
+pci.o : pci.c pci.h debug.h
+console.o : console.c v86bios.h debug.h
+v86.o : v86.c debug.h
+parser.o : parser.c
+lex.o : lex.c
+v86bios.o: v86bios.c v86bios.h pci.h debug.h
+logging.o: logging.c v86bios.h
+x86emu.o : x86emu.c v86bios.h debug.h
+ $(CC) -c -DX86EMU $(CFLAGS) $*.c
+
+vbios.x86emu : main.o x86emu.o io.o int.o pci.o console.o mem.o logging.o
+ gcc -Wl,-defsym -Wl,printk=lprintf -o vbios.x86emu main.o \
+ x86emu.o io.o int.o pci.o console.o mem.o logging.o \
+ -L../x86emu -lx86emud -lc
+vbios.vm86 : main.o v86.o io.o int.o pci.o console.o logging.o
+ gcc -o vbios.vm86 main.o v86.o io.o int.o pci.o console.o \
+ logging.o -lc
+cbios.x86emu : cbios.o x86emu.o io.o int.o pci.o console.o mem.o logging.o
+ gcc -Wl,-defsym -Wl,printk=lprintf -o cbios.x86emu cbios.o \
+ x86emu.o io.o int.o pci.o console.o mem.o logging.o \
+ -L../x86emu -lx86emud -lc
+cbios.vm86 : cbios.o v86.o io.o int.o pci.o console.o logging.o
+ gcc -o cbios.vm86 cbios.o v86.o io.o int.o pci.o console.o \
+ logging.o -lc
+v86bios.vm86: command.o parser.o lex.o v86bios.o v86.o io.o int.o pci.o console.o logging.o
+ gcc -o v86bios.vm86 command.o parser.o lex.o v86bios.o v86.o io.o \
+ int.o pci.o console.o logging.o -L/usr/lib/curses -lfl \
+ -lreadline -lc -lncurses /usr/lib/libc.a
+v86bios.x86emu: command.o parser.o lex.o v86bios.o x86emu.o io.o int.o pci.o console.o logging.o
+ gcc -Wl,-defsym -Wl,printk=lprintf -o v86bios.x86emu \
+ command.o parser.o lex.o v86bios.o x86emu.o io.o \
+ int.o pci.o console.o logging.o -L/usr/lib/curses -lfl \
+ -lreadline -lc -lncurses /usr/lib/libc.a -L../x86emu -lx86emud
+
+clean:
+ rm -f *.o vbios.x86emu vbios.vm86 cbios.x86emu cbios.vm86 parser.c \
+ lex.c parser.h v86bios.x86emu v86bios.vm86
+
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/mem.c b/board/MAI/bios_emulator/scitech/src/v86bios/mem.c
new file mode 100644
index 0000000000..50dc55fdf5
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/mem.c
@@ -0,0 +1,126 @@
+/*
+ * 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 "debug.h"
+#include "v86bios.h"
+#include "x86emu.h"
+
+#ifdef __alpha__
+
+void* vram_map = 0;
+int sparse_shift = 5;
+
+#define mem_barrier() __asm__ __volatile__("mb" : : : "memory")
+
+#define vuip volatile unsigned int *
+
+CARD8
+mem_rb(CARD32 addr)
+{
+ unsigned long result, shift;
+#if 1
+ if (addr >= 0xA0000 && addr <= 0xBFFFF) {
+ addr -= 0xA0000;
+ shift = (addr & 0x3) * 8;
+ result = *(vuip) ((unsigned long)vram_map + (addr << sparse_shift));
+ result >>= shift;
+ return 0xffUL & result;
+ } else
+#endif
+ return rdb(addr);
+}
+
+CARD16
+mem_rw(CARD32 addr)
+{
+ unsigned long result, shift;
+#if 1
+ if (addr >= 0xA0000 && addr <= 0xBFFFF) {
+ addr -= 0xA0000;
+ shift = (addr & 0x2) * 8;
+ result = *(vuip)((unsigned long)vram_map+(addr<<sparse_shift)
+ +(1<<(sparse_shift-2)));
+ result >>= shift;
+ return 0xffffUL & result;
+ } else
+#endif
+ return rdw(addr);
+}
+
+CARD32
+mem_rl(CARD32 addr)
+{
+ unsigned long result;
+#if 1
+ if (addr >= 0xA0000 && addr <= 0xBFFFF) {
+ addr -= 0xA0000;
+ result = *(vuip)((unsigned long)vram_map+(addr<<sparse_shift)+(3<<(sparse_shift-2)));
+ return result;
+ } else
+#endif
+ return rdl(addr);
+}
+
+void
+mem_wb(CARD32 addr, CARD8 val)
+{
+ unsigned int b = val & 0xffU;
+#if 1
+ if (addr >= 0xA0000 && addr <= 0xBFFFF) {
+ addr -= 0xA0000;
+ *(vuip) ((unsigned long)vram_map + (addr << sparse_shift)) = b * 0x01010101;
+ mem_barrier();
+ } else
+#endif
+ wrb(addr,val);
+}
+
+void
+mem_ww(CARD32 addr, CARD16 val)
+{
+ unsigned int w = val & 0xffffU;
+#if 1
+ if (addr >= 0xA0000 && addr <= 0xBFFFF) {
+ addr -= 0xA0000;
+ *(vuip)((unsigned long)vram_map+(addr<<sparse_shift)
+ +(1<<(sparse_shift-2))) = w * 0x00010001;
+ mem_barrier();
+ } else
+#endif
+ wrw(addr,val);
+}
+
+void
+mem_wl(CARD32 addr, CARD32 val)
+{
+#if 1
+ if (addr >= 0xA0000 && addr <= 0xBFFFF) {
+ addr -= 0xA0000;
+ *(vuip)((unsigned long)vram_map+(addr<<sparse_shift)
+ +(3<<(sparse_shift-2))) = val;
+ mem_barrier();
+ } else
+#endif
+ wrl(addr,val);
+}
+#endif
+
+
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/parser.y b/board/MAI/bios_emulator/scitech/src/v86bios/parser.y
new file mode 100644
index 0000000000..21c4023dcd
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/parser.y
@@ -0,0 +1,498 @@
+%{
+#include <malloc.h>
+#include <string.h>
+#include "v86bios.h"
+#include "pci.h"
+
+#define YYSTYPE unsigned long
+
+#define MAX_VAR 0x20
+
+ CARD32 var[MAX_VAR];
+ CARD32 var_mem;
+
+
+i86biosRegs regs = { 00 };
+
+enum mem_type { BYTE, WORD, LONG, STRING };
+union mem_val {
+ CARD32 integer;
+ char *ptr;
+} rec;
+
+struct mem {
+ enum mem_type type;
+ union mem_val val;
+ struct mem *next;
+};
+
+
+struct device Device = {FALSE,NONE,{0}};
+
+extern void yyerror(char *s);
+extern int yylex( void );
+
+static void boot(void);
+static void dump_mem(CARD32 addr, int len);
+static void exec_int(int num);
+static void *add_to_list(enum mem_type type, union mem_val *rec, void *next);
+static void do_list(struct mem *list, memType addr);
+static char * normalize_string(char *ptr);
+%}
+
+%token TOK_NUM
+%token TOK_REG_AX
+%token TOK_REG_BX
+%token TOK_REG_CX
+%token TOK_REG_DX
+%token TOK_REG_DI
+%token TOK_REG_SI
+%token TOK_SEG_DS
+%token TOK_SEG_ES
+%token TOK_SEP
+%token TOK_VAR
+%token TOK_VAR_MEM
+%token TOK_COMMAND_BOOT
+%token TOK_COMMAND_EXEC
+%token TOK_SELECT
+%token TOK_STRING
+%token TOK_MODIFIER_BYTE
+%token TOK_MODIFIER_WORD
+%token TOK_MODIFIER_LONG
+%token TOK_MODIFIER_MEMSET
+%token TOK_COMMAND_MEMSET
+%token TOK_COMMAND_MEMDUMP
+%token TOK_COMMAND_QUIT
+%token TOK_ERROR
+%token TOK_END
+%token TOK_ISA
+%token TOK_PCI
+%token TOK_BYTE
+%token TOK_WORD
+%token TOK_LONG
+%token TOK_PRINT_PORT
+%token TOK_IOSTAT
+%token TOK_PRINT_IRQ
+%token TOK_PPCI
+%token TOK_PIP
+%token TOK_TRACE
+%token TOK_ON
+%token TOK_OFF
+%token TOK_VERBOSE
+%token TOK_LOG
+%token TOK_LOGOFF
+%token TOK_CLSTAT
+%token TOK_STDOUT
+%token TOK_HLT
+%token TOK_DEL
+%token TOK_IOPERM
+%token TOK_DUMP_PCI
+%token TOK_BOOT_BIOS
+%%
+input: | input line
+line: end | com_reg | com_var | com_select
+ | com_boot | com_memset | com_memdump | com_quit
+ | com_exec | hlp | config | verbose | logging | print | clstat
+ | com_hlt | ioperm | list_pci | boot_bios
+ | error end { printf("unknown command\n"); }
+;
+end: TOK_END
+;
+com_reg: reg_off val end { *(CARD16*)$1 = $2 & 0xffff; }
+ | reg_seg TOK_SEP reg_off val end {
+ *(CARD16*)$1 = ($4 & 0xf0000) >> 4;
+ *(CARD16*)$3 = ($4 & 0x0ffff);
+ }
+ | reg_off '?' end { printf("0x%x\n",*(CARD16*)$1);}
+ | reg_seg TOK_SEP reg_off '?' end
+ { printf("0x%x:0x%x\n",*(CARD16*)$1,
+ *(CARD16*)$3); }
+;
+register_read: reg_seg TOK_SEP reg_off { $$ = (((*(CARD16*)$1) << 4)
+ | ((*(CARD16*)$3) & 0xffff));
+ }
+ | reg_off { $$ = ((*(CARD16*)$1) & 0xffff); }
+;
+reg_off: TOK_REG_AX { $$ = (unsigned long)&(regs.ax); }
+ | TOK_REG_BX { $$ = (unsigned long)&(regs.bx); }
+ | TOK_REG_CX { $$ = (unsigned long)&(regs.cx); }
+ | TOK_REG_DX { $$ = (unsigned long)&(regs.dx); }
+ | TOK_REG_DI { $$ = (unsigned long)&(regs.di); }
+ | TOK_REG_SI { $$ = (unsigned long)&(regs.si); }
+;
+reg_seg: TOK_SEG_DS { $$ = (unsigned long)&(regs.ds); }
+ | TOK_SEG_ES { $$ = (unsigned long)&(regs.es); }
+;
+com_var: TOK_VAR_MEM '?' end { printf("var mem: 0x%x\n",var_mem); }
+ | TOK_VAR '?' end { if ($1 < MAX_VAR)
+ printf("var[%i]: 0x%x\n",(int)$1,var[$1]);
+ else
+ printf("var index %i out of range\n",(int)$1); }
+ | TOK_VAR_MEM val end { var_mem = $2; }
+ | TOK_VAR val end { if ($1 <= MAX_VAR)
+ var[$1] = $2;
+ else
+ printf("var index %i out of range\n",(int)$1); }
+ | TOK_VAR error end { printf("$i val\n"); }
+ | TOK_VAR_MEM error end { printf("$i val\n"); }
+;
+com_boot: TOK_COMMAND_BOOT end { boot(); }
+ TOK_COMMAND_BOOT error end { boot(); }
+;
+com_select: TOK_SELECT TOK_ISA end { Device.booted = FALSE;
+ Device.type = ISA;
+ CurrentPci = NULL; }
+ | TOK_SELECT TOK_PCI val TOK_SEP val TOK_SEP val end
+ { Device.booted = FALSE;
+ Device.type = PCI;
+ Device.loc.pci.bus = $3;
+ Device.loc.pci.dev = $5;
+ Device.loc.pci.func = $7; }
+ | TOK_SELECT '?' end
+ { switch (Device.type) {
+ case ISA:
+ printf("isa\n");
+ break;
+ case PCI:
+ printf("pci: %x:%x:%x\n",Device.loc.pci.bus,
+ Device.loc.pci.dev,
+ Device.loc.pci.func);
+ break;
+ default:
+ printf("no device selected\n");
+ break;
+ }
+ }
+ | TOK_SELECT error end { printf("select ? | isa "
+ "| pci:bus:dev:func\n"); }
+;
+com_quit: TOK_COMMAND_QUIT end { return 0; }
+ | TOK_COMMAND_QUIT error end { logoff(); return 0; }
+;
+com_exec: TOK_COMMAND_EXEC end { exec_int(0x10); }
+ | TOK_COMMAND_EXEC val end { exec_int($2); }
+ | TOK_COMMAND_EXEC error end { exec_int(0x10); }
+;
+com_memdump: TOK_COMMAND_MEMDUMP val val end { dump_mem($2,$3); }
+ | TOK_COMMAND_MEMDUMP error end { printf("memdump start len\n"); }
+
+
+;
+com_memset: TOK_COMMAND_MEMSET val list end { do_list((struct mem*)$3,$2);}
+ | TOK_COMMAND_MEMSET error end { printf("setmem addr [byte val] "
+ "[word val] [long val] "
+ "[\"string\"]\n"); }
+;
+list: { $$ = 0; }
+ | TOK_BYTE val list { rec.integer = $2;
+ $$ = (unsigned long)add_to_list(BYTE,&rec,(void*)$3); }
+ | TOK_WORD val list { rec.integer = $2;
+ $$ = (unsigned long) add_to_list(WORD,&rec,(void*)$3); }
+ | TOK_LONG val list { rec.integer = $2;
+ $$ = (unsigned long) add_to_list(LONG,&rec,(void*)$3); }
+ | TOK_STRING list { rec.ptr = (void*)$1;
+ $$ = (unsigned long) add_to_list(STRING,&rec,(void*)$2); }
+;
+val: TOK_VAR { if ($1 > MAX_VAR) {
+ printf("variable index out of range\n");
+ $$=0;
+ } else
+ $$ = var[$1]; }
+ | TOK_NUM { $$ = $1; }
+ | register_read
+;
+bool: TOK_ON { $$ = 1; }
+ | TOK_OFF { $$ = 0; }
+;
+config: TOK_PRINT_PORT bool end { Config.PrintPort = $2; }
+ | TOK_PRINT_PORT '?' end { printf("print port %s\n",
+ Config.PrintPort?"on":"off"); }
+ | TOK_PRINT_PORT error end { printf("pport on | off | ?\n") }
+ | TOK_PRINT_IRQ bool end { Config.PrintIrq = $2; }
+ | TOK_PRINT_IRQ '?' end { printf("print irq %s\n",
+ Config.PrintIrq?"on":"off"); }
+ | TOK_PRINT_IRQ error end { printf("pirq on | off | ?\n") }
+ | TOK_PPCI bool end { Config.PrintPci = $2; }
+ | TOK_PPCI '?' end { printf("print PCI %s\n",
+ Config.PrintPci?"on":"off"); }
+ | TOK_PPCI error end { printf("ppci on | off | ?\n") }
+ | TOK_PIP bool end { Config.PrintIp = $2; }
+ | TOK_PIP '?' end { printf("printip %s\n",
+ Config.PrintIp?"on":"off"); }
+ | TOK_PIP error end { printf("pip on | off | ?\n") }
+ | TOK_IOSTAT bool end { Config.IoStatistics = $2; }
+ | TOK_IOSTAT '?' end { printf("io statistics %s\n",
+ Config.IoStatistics?"on":"off"); }
+ | TOK_IOSTAT error end { printf("iostat on | off | ?\n") }
+ | TOK_TRACE bool end { Config.Trace = $2; }
+ | TOK_TRACE '?' end { printf("trace %s\n",
+ Config.Trace ?"on":"off"); }
+ | TOK_TRACE error end { printf("trace on | off | ?\n") }
+;
+verbose: TOK_VERBOSE val end { Config.Verbose = $2; }
+ | TOK_VERBOSE '?' end { printf("verbose: %i\n",
+ Config.Verbose); }
+ | TOK_VERBOSE error end { printf("verbose val | ?\n"); }
+;
+logging: TOK_LOG TOK_STRING end { logon(normalize_string((char*)$2)); }
+ | TOK_LOG '?' end { if (logging) printf("logfile: %s\n",
+ logfile);
+ else printf("no logging\n?"); }
+ | TOK_LOG TOK_OFF end { logoff(); }
+ | TOK_LOG error end { printf("log \"<filename>\" | ? |"
+ " off\n"); }
+;
+clstat: TOK_CLSTAT end { clear_stat(); }
+ | TOK_CLSTAT error end { printf("clstat\n"); }
+;
+print: TOK_STDOUT bool end { nostdout = !$2; }
+ | TOK_STDOUT '?' end { printf("print %s\n",nostdout ?
+ "no":"yes"); }
+ | TOK_STDOUT error end { printf("print on | off\n"); }
+;
+com_hlt: TOK_HLT val end { add_hlt($2); }
+ | TOK_HLT TOK_DEL val end { del_hlt($3); }
+ | TOK_HLT TOK_DEL end { del_hlt(21); }
+ | TOK_HLT '?' end { list_hlt(); }
+ | TOK_HLT error end { printf(
+ "hlt val | del [val] | ?\n"); }
+;
+ioperm: TOK_IOPERM val val val end { int i,max;
+ if ($2 >= 0) {
+ max = $2 + $3 - 1;
+ if (max > IOPERM_BITS)
+ max = IOPERM_BITS;
+ for (i = $2;i <= max; i++)
+ ioperm_list[i]
+ = $4>0 ? 1 : 0;
+ }
+ }
+ | TOK_IOPERM '?' end { int i,start;
+ for (i=0; i <= IOPERM_BITS; i++) {
+ if (ioperm_list[i]) {
+ start = i;
+ for (; i <= IOPERM_BITS; i++)
+ if (!ioperm_list[i]) {
+ printf("ioperm on in "
+ "0x%x+0x%x\n", start,i-start);
+ break;
+ }
+ }
+ }
+ }
+ | TOK_IOPERM error end { printf("ioperm start len val\n"); }
+;
+list_pci: TOK_DUMP_PCI end { list_pci(); }
+ | TOK_DUMP_PCI error end { list_pci(); }
+;
+boot_bios: TOK_BOOT_BIOS '?' end { if (!BootBios) printf("No Boot BIOS\n");
+ else printf("BootBIOS from: %i:%i:%i\n",
+ BootBios->bus, BootBios->dev,
+ BootBios->func); }
+ | TOK_BOOT_BIOS error end { printf ("bootbios bus:dev:num\n"); }
+;
+hlp: '?' { printf("Command list:\n");
+ printf(" select isa | pci bus:dev:func\n");
+ printf(" boot\n");
+ printf(" seg:reg val | reg val \n");
+ printf(" $x val | $mem val\n");
+ printf(" setmem addr list; addr := val\n");
+ printf(" dumpmem addr len; addr,len := val\n");
+ printf(" do [val]\n");
+ printf(" quit\n");
+ printf(" ?\n");
+ printf(" seg := ds | es;"
+ " reg := ax | bx | cx | dx | si \n");
+ printf(" val := var | <hex-number> | seg:reg | seg\n");
+ printf(" var := $x | $mem; x := 0..20\n");
+ printf(" list := byte val | word val | long val "
+ "| \"string\"\n");
+ printf(" pport on | off | ?\n");
+ printf(" ppci on | off | ?\n");
+ printf(" pirq on | off | ?\n");
+ printf(" pip on | off | ?\n");
+ printf(" trace on | off | ?\n");
+ printf(" iostat on | off | ?\n");
+ printf(" verbose val\n");
+ printf(" log \"<filename>\" | off | ?\n");
+ printf(" print on | off\n");
+ printf(" hlt val | del [val] | ?\n");
+ printf(" clstat\n");
+ printf(" lpci\n");
+ printf ("bootbios ?\n");
+}
+;
+
+%%
+
+static void
+dump_mem(CARD32 addr, int len)
+{
+ dprint(addr,len);
+}
+
+static void
+exec_int(int num)
+{
+ if (num == 0x10) { /* video interrupt */
+ if (Device.type == NONE) {
+ CurrentPci = PciList;
+ while (CurrentPci) {
+ if (CurrentPci->active)
+ break;
+ CurrentPci = CurrentPci->next;
+ }
+ if (!CurrentPci)
+ Device.type = ISA;
+ else {
+ Device.type = PCI;
+ Device.loc.pci.dev = CurrentPci->dev;
+ Device.loc.pci.bus = CurrentPci->bus;
+ Device.loc.pci.func = CurrentPci->func;
+ }
+ }
+ if (Device.type != ISA) {
+ if (!Device.booted) {
+ if (!CurrentPci || (Device.type == PCI
+ && (!CurrentPci->active
+ && (Device.loc.pci.dev != CurrentPci->dev
+ || Device.loc.pci.bus != CurrentPci->bus
+ || Device.loc.pci.func != CurrentPci->func)))) {
+ printf("boot the device fist\n");
+ return;
+ }
+ }
+ } else
+ CurrentPci = NULL;
+ } else {
+ Device.booted = FALSE; /* we need this for sanity! */
+ }
+
+ runINT(num,&regs);
+}
+
+static void
+boot(void)
+{
+ if (Device.type == NONE) {
+ printf("select a device fist\n");
+ return;
+ }
+
+ call_boot(&Device);
+}
+
+static void *
+add_to_list(enum mem_type type, union mem_val *rec, void *next)
+{
+ struct mem *mem_rec = (struct mem *) malloc(sizeof(mem_rec));
+
+ mem_rec->type = type;
+ mem_rec->next = next;
+
+ switch (type) {
+ case BYTE:
+ case WORD:
+ case LONG:
+ mem_rec->val.integer = rec->integer;
+ break;
+ case STRING:
+ mem_rec->val.ptr = normalize_string(rec->ptr);
+ break;
+ }
+ return mem_rec;
+}
+
+static int
+validRange(int addr,int len)
+{
+ int end = addr + len;
+
+ if (addr < 0x1000 || end > 0xc0000)
+ return 0;
+ return 1;
+}
+
+static void
+do_list(struct mem *list, memType addr)
+{
+ struct mem *prev;
+ int len;
+
+ while (list) {
+ switch (list->type) {
+ case BYTE:
+ if (!validRange(addr,1)) goto error;
+ *(CARD8*)addr = list->val.integer;
+ addr =+ 1;
+ break;
+ case WORD:
+ if (!validRange(addr,2)) goto error;
+ *(CARD16*)addr = list->val.integer;
+ addr =+ 2;
+ break;
+ case LONG:
+ if (!validRange(addr,4)) goto error;
+ *(CARD32*)addr = list->val.integer;
+ addr =+ 4;
+ break;
+ case STRING:
+ len = strlen((char*)list->val.ptr);
+ if (!validRange(addr,len)) goto error;
+ memcpy((CARD8*)addr,(void*)list->val.ptr,len);
+ addr =+ len;
+ free(list->val.ptr);
+ break;
+ }
+ prev = list;
+ list = list->next;
+ free(prev);
+ continue;
+ error:
+ printf("address out of range\n");
+ while (list) {
+ prev = list;
+ list = list->next;
+ free(prev);
+ }
+ break;
+ }
+}
+
+static char *
+normalize_string(char *ptr)
+{
+ int i = 0, j = 0, c = 0, esc= 0;
+ int size;
+ char *mem_ptr;
+
+ size = strlen(ptr);
+ mem_ptr = malloc(size);
+ while (1) {
+ switch (*(ptr + i)) {
+ case '\\':
+ if (esc) {
+ *(mem_ptr + j++) = *(ptr + i);
+ esc = 0;
+ } else
+ esc = 1;
+ break;
+ case '\"':
+ if (esc) {
+ *(mem_ptr + j++) = *(ptr + i);
+ esc = 0;
+ } else
+ c++;
+ break;
+ default:
+ *(mem_ptr + j++) = *(ptr + i);
+ break;
+ }
+ if (c > 1) {
+ *(mem_ptr + j) = '\0';
+ break;
+ }
+ i++;
+ }
+ return mem_ptr;
+}
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/pci.c b/board/MAI/bios_emulator/scitech/src/v86bios/pci.c
new file mode 100644
index 0000000000..e68c61d5ef
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/pci.c
@@ -0,0 +1,903 @@
+/*
+ * 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 "debug.h"
+#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"
+
+/*
+ * 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;
+PciStructPtr BootBios = 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);
+static CARD32 readPciCfg2(CARD32 reg);
+static void writePciCfg2(CARD32 reg, CARD32 val);
+
+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(void)
+{
+ unsigned short configtype;
+
+ CARD32 reg[64];
+ int busidx;
+ CARD8 cardnum;
+ CARD8 func;
+ int idx;
+
+ int i;
+ PciStructPtr pci1;
+ PciBusPtr pci_b1,pci_b2;
+
+#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;
+ P_printf("PCI says configuration type 2\n");
+ } 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;
+ P_printf("PCI says configuration type 1\n");
+ } else {
+ P_printf("No PCI !\n");
+ return;
+ }
+ }
+#endif
+
+ if (configtype == 1) {
+ P_printf("PCI probing configuration type 1\n");
+ busidx = 0;
+ numbus = 1;
+ idx = 0;
+ do {
+ P_printf("\nProbing for devices on PCI bus %d:\n", busidx);
+ 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))
+ break;
+ readConfigSpaceCfg1(busidx,cardnum,func,reg);
+
+ func = interpretConfigSpace(reg,busidx,
+ cardnum,func);
+
+ if (idx++ > MAX_PCI_DEVICES)
+ continue;
+ } while (func < 8);
+ }
+ } 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;
+
+ P_printf("PCI probing configuration type 2\n");
+ busidx = 0;
+ numbus = 1;
+ idx = 0;
+ do {
+ for (slot=0xc0; slot<0xd0; i++) {
+ if (!checkSlotCfg2(busidx,slot))
+ break;
+ readConfigSpaceCfg2(busidx,slot,reg);
+
+ interpretConfigSpace(reg,busidx,
+ slot,0);
+ if (idx++ > MAX_PCI_DEVICES)
+ continue;
+ }
+ } while (++busidx < PCI_MAXBUS);
+ }
+
+
+ pciMaxBus = numbus - 1;
+ P_printf("Number of buses in system: %i\n",pciMaxBus + 1);
+ P_printf("Min PCI mem address: 0x%lx\n",pciMinMemReg);
+
+ /* 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);
+ P_printf("reading: 0x%x from 0x%x\n",val,reg);
+ return val;
+}
+
+static void
+writePciCfg1(CARD32 reg, CARD32 val)
+{
+ P_printf("writing: 0x%x to 0x%x\n",val,reg);
+ outl(PCI_MODE1_ADDRESS_REG, reg);
+ outl(PCI_MODE1_DATA_REG,val);
+ outl(PCI_MODE1_ADDRESS_REG, 0);
+}
+
+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);
+ P_printf("reading: 0x%x from 0x%x\n",val,reg);
+ return val;
+}
+
+static void
+writePciCfg2(CARD32 reg, CARD32 val)
+{
+ CARD8 bus = (reg >> 16) & 0xff;
+ CARD8 dev = (reg >> 11) & 0x1f;
+ CARD8 num = reg & 0xff;
+
+ P_printf("writing: 0x%x to 0x%x\n",val,reg);
+ outb(PCI_MODE2_ENABLE_REG, 0xF1);
+ outb(PCI_MODE2_FORWARD_REG, bus);
+ outl((dev << 8) + num,val);
+ outb(PCI_MODE2_ENABLE_REG, 0x00);
+}
+#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;
+
+ if (!pciP)
+ pciP = CurrentPci;
+
+ if (FIX_ROM) {
+ RomBase = findBIOSMap(pciP, &biosSize);
+ if (!RomBase) {
+ fprintf(stderr,"Cannot remap BIOS of %i:%i:%i "
+ "- trying preset address\n",pciP->bus,pciP->dev,
+ pciP->func);
+ RomBase = pciP->RomBase & ~(CARD32)0xFF;
+ }
+ } else {
+ RomBase = pciP->RomBase & ~(CARD32)0xFF;
+ if (~RomBase + 1 < biosSize || !RomBase)
+ RomBase = findBIOSMap(pciP, &biosSize);
+ }
+
+ P_printf("RomBase: 0x%lx\n",RomBase);
+
+ 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);
+ }
+
+#ifdef PRINT_PCI
+ dprint((unsigned long)ptr,0x30);
+#endif
+ 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);
+ P_printf("data segment in BIOS: 0x%x, type: 0x%x ",data_off,type);
+
+ 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;
+ P_printf("data image length: 0x%x, ind: 0x%x\n",
+ image_length,indicator);
+ ptr = ptr + image_length;
+ continue;
+ }
+ /* OK, we have a PC Image */
+ length = (*(ptr + 2) << 9);
+ P_printf("BIOS length: 0x%x\n",length);
+ 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) {
+ // fprintf(stderr,"slot: 0x%x bridge: 0x%x\n",slot, pBus->Slot.l);
+ if (slot == (pBus->Slot.l & ~PCI_EN))
+ return pBus->Slot.l | PCI_EN;
+ pBus = pBus->next;
+ }
+#else
+ PciStructPtr pPci = PciStruct;
+ while (pPci) {
+ //fprintf(stderr,"slot: 0x%x bridge: 0x%x\n",slot, pPci->Slot.l);
+ 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
+
+#ifdef V86BIOS_DEBUG
+ P_printf("0x%lx\n",reg[i]);
+#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);
+#ifdef V86BIOS_DEBUG
+ P_printf("0x%lx\n",reg[i]);
+#endif
+ }
+ 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;
+ P_printf("bus: %i card: %i func %i reg0: 0x%x ", busidx,dev,func,reg[0]);
+ baseclass = reg[8] >> 24;
+ subclass = (reg[8] >> 16) & 0xFF;
+ interface = (reg[8] >> 8) & 0xFF;
+
+ header = (reg[0x0c] >> 16) & 0xff;
+ P_printf("bc 0x%x, sub 0x%x, if 0x%x, hdr 0x%x\n",
+ baseclass,subclass,interface,header);
+ if (BRIDGE_CLASS(baseclass)) {
+ if (BRIDGE_PCI_CLASS(subclass)) {
+ PciBusPtr pbp = malloc(sizeof(PciBusRec));
+ P_printf("Pci-Pci Bridge found; ");
+ primary = reg[0x18] & 0xFF;
+ secondary = (reg[0x18] >> 8) & 0xFF;
+ P_printf("primary: 0x%x secondary: 0x%x\n",
+ primary,secondary);
+ 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));
+ P_printf("Display adapter found\n");
+ 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;
+
+ PciWrite32(0x30,0xffffffff,pciP->Slot.l);
+ *biosSize = PciRead32(0x30,pciP->Slot.l);
+ P_printf("bios size: 0x%x\n",*biosSize);
+ PciWrite32(0x30,pciP->RomBase,pciP->Slot.l);
+ *biosSize = ~(*biosSize & 0xFFFFFF00) + 1;
+ P_printf("bios size masked: 0x%x\n",*biosSize);
+ if (*biosSize > (1024 * 1024 * 16)) {
+ *biosSize = 1024 * 1024 * 16;
+ P_printf("fixing broken BIOS size: 0x%x\n",*biosSize);
+ }
+ 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;
+#ifdef V86_BIOS_DEBUG
+ P_printf("size: 0x%x\n",size);
+#endif
+ 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;
+}
+
+void
+list_pci(void)
+{
+ PciStructPtr pci = PciList;
+
+ while (pci) {
+ printf("[0x%x:0x%x:0x%x] vendor: 0x%4.4x dev: 0x%4.4x class: 0x%4.4x"
+ " subclass: 0x%4.4x\n",pci->bus,pci->dev,pci->func,
+ pci->VendorID,pci->DeviceID,pci->BaseClass,pci->SubClass);
+ pci = pci->next;
+ }
+}
+
+PciStructPtr
+findPciByIDs(int bus, int dev, int func)
+{
+ PciStructPtr pciP = PciList;
+
+ while (pciP) {
+ if (pciP->bus == bus && pciP->dev == dev && pciP->func == func)
+ return pciP;
+ pciP = pciP->next;
+ }
+ return NULL;
+}
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/pci.h b/board/MAI/bios_emulator/scitech/src/v86bios/pci.h
new file mode 100644
index 0000000000..0ab7363df2
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/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(void);
+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/board/MAI/bios_emulator/scitech/src/v86bios/v86.c b/board/MAI/bios_emulator/scitech/src/v86bios/v86.c
new file mode 100644
index 0000000000..3170a9cb55
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/v86.c
@@ -0,0 +1,562 @@
+/*
+ * 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 "debug.h"
+#include <sys/vm86.h>
+#include <unistd.h>
+#include <errno.h>
+#include <asm/unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <setjmp.h>
+#include "v86bios.h"
+#include "AsmMacros.h"
+
+struct vm86_struct vm86s;
+
+static int vm86_GP_fault(void);
+static int vm86_do_int(int num);
+static void dump_code(void);
+static void dump_registers(void);
+static void stack_trace(void);
+static int vm86_rep(struct vm86_struct *ptr);
+
+#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))
+#define DF (1 << 10)
+
+struct pio P;
+
+
+void
+setup_io(void)
+{
+ if (!Config.PrintPort && !Config.IoStatistics) {
+ 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;
+ } else {
+ P.inb = p_inb;
+ P.inw = p_inw;
+ P.inl = p_inl;
+ P.outb = p_outb;
+ P.outw = p_outw;
+ P.outl = p_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(void)
+{
+ int retval;
+
+#ifdef V86BIOS_DEBUG
+ dump_registers();
+#endif
+// retval = SYS_vm86old(&vm86s);
+// retval = syscall(SYS_vm86old,&vm86s);
+
+ retval = vm86_rep(&vm86s);
+
+ switch (VM86_TYPE(retval)) {
+ case VM86_UNKNOWN:
+ if (!vm86_GP_fault()) return 0;
+ break;
+ case VM86_STI:
+ fprintf(stderr,"vm86_sti :-((\n");
+ stack_trace();
+ dump_code();
+ return 0;
+ case VM86_INTx:
+ if (!vm86_do_int(VM86_ARG(retval))) {
+ fprintf(stderr,"\nUnknown vm86_int: %X\n\n",VM86_ARG(retval));
+ dump_registers();
+ return 0;
+ }
+ /* I'm not sure yet what to do if we can handle ints */
+ break;
+ case VM86_SIGNAL:
+ fprintf(stderr,"received signal\n");
+ return 0;
+ default:
+ fprintf(stderr,"unknown type(0x%x)=0x%x\n",
+ VM86_ARG(retval),VM86_TYPE(retval));
+ dump_registers();
+ dump_code();
+ stack_trace();
+ return 0;
+ }
+
+ return 1;
+}
+
+static jmp_buf x86_esc;
+static void
+vmexit(int unused)
+{
+ longjmp(x86_esc,1);
+}
+
+void
+do_x86(unsigned long bios_start, i86biosRegsPtr regs)
+{
+ static void (*org_handler)(int);
+
+ setup_vm86(bios_start, regs);
+ if (setjmp(x86_esc) == 0) {
+ org_handler = signal(2,vmexit);
+ while(do_vm86()) {};
+ signal(2,org_handler);
+ collect_bios_regs(regs);
+ } else {
+ signal(2,org_handler);
+ printf("interrupted at 0x%x\n",((CARD16)CPU_REG(cs)) << 4
+ | (CARD16)CPU_REG(eip));
+ }
+}
+
+/* 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*)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 *)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 *)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:
+ fprintf(stderr,"CPU 0x0f Trap at eip=0x%lx\n",CPU_REG(eip));
+ goto op0ferr;
+ break;
+
+ case 0xf0: /* lock */
+ default:
+ fprintf(stderr,"unknown reason for exception\n");
+ dump_registers();
+ stack_trace();
+ op0ferr:
+ dump_code();
+ fprintf(stderr,"cannot continue\n");
+ return 0;
+ } /* end of switch() */
+ return 1;
+}
+
+static int
+vm86_do_int(int num)
+{
+ int val;
+ struct regs86 regs;
+
+ i_printf("int 0x%x received: ax:0x%lx",num,CPU_REG(eax));
+ if (Config.PrintIp)
+ i_printf(" at: 0x%x\n",getIP());
+ else
+ i_printf("\n");
+
+ /* 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
+}
+
+static void
+dump_code(void)
+{
+ int i;
+ unsigned char *lina = SEG_ADR((unsigned char *), cs, ip);
+
+ fprintf(stderr,"code at 0x%8.8x: ",(CARD32)lina);
+ for (i=0; i<0x10; i++)
+ fprintf(stderr,"%2.2x ",*(lina + i));
+ fprintf(stderr,"\n ");
+ for (; i<0x20; i++)
+ fprintf(stderr,"%2.2x ",*(lina + i));
+ fprintf(stderr,"\n");
+}
+
+#define PRINT(x) fprintf(stderr,#x":%4.4x ",CPU_REG_LW(x))
+#define PRINT_FLAGS(x) fprintf(stderr,#x":%8.8x ",CPU_REG_LW(x))
+static void
+dump_registers(void)
+{
+ PRINT(eip);
+ PRINT(eax);
+ PRINT(ebx);
+ PRINT(ecx);
+ PRINT(edx);
+ PRINT(esi);
+ PRINT(edi);
+ PRINT(ebp);
+ fprintf(stderr,"\n");
+ PRINT(esp);
+ PRINT(cs);
+ PRINT(ss);
+ PRINT(es);
+ PRINT(ds);
+ PRINT(fs);
+ PRINT(gs);
+ PRINT_FLAGS(eflags);
+ fprintf(stderr,"\n");
+}
+
+static void
+stack_trace(void)
+{
+ int i;
+ unsigned char *stack = SEG_ADR((unsigned char *), ss, sp);
+
+ fprintf(stderr,"stack at 0x%8.8lx:\n",(unsigned long)stack);
+ for (i=0; i < 0x10; i++)
+ fprintf(stderr,"%2.2x ",*(stack + i));
+ fprintf(stderr,"\n");
+
+}
+
+static int
+vm86_rep(struct vm86_struct *ptr)
+{
+
+ int __res;
+
+ __asm__ __volatile__("int $0x80\n"
+ :"=a" (__res):"a" ((int)113),
+ "b" ((struct vm86_struct *)ptr));
+
+ if ((__res) < 0) {
+ errno = -__res;
+ __res=-1;
+ }
+ else errno = 0;
+ return __res;
+}
+
+#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))
+
+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 ?*/
+#ifdef V86BIOS_DEBUG
+ i_printf("card BIOS not loaded\n");
+#endif
+ return 0;
+ }
+
+#ifdef V86BIOS_DEBUG
+ if (firsttime) {
+ dprint(0,0x3D0);
+ firsttime = 0;
+ }
+#endif
+
+ i_printf("calling card BIOS at: ");
+ ssp = (CARD16*)(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];
+ i_printf("0x%x:%lx\n",regs->cs,regs->eip);
+#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);
+}
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/v86bios.c b/board/MAI/bios_emulator/scitech/src/v86bios/v86bios.c
new file mode 100644
index 0000000000..7a3fb36655
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/v86bios.c
@@ -0,0 +1,933 @@
+/*
+ * 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.
+ */
+#define DELETE
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+#if defined(__alpha__) || defined (__ia64__)
+#include <sys/io.h>
+#elif defined(HAVE_SYS_PERM)
+#include <sys/perm.h>
+#endif
+#include "debug.h"
+#include "v86bios.h"
+#include "pci.h"
+#include "AsmMacros.h"
+
+#define SIZE 0x100000
+#define VRAM_START 0xA0000
+#define VRAM_SIZE 0x1FFFF
+#define V_BIOS_SIZE 0x1FFFF
+#define BIOS_START 0x7C00 /* default BIOS entry */
+#define BIOS_MEM 0x600
+
+//CARD8 code[] = { 0xb8 , 0xf0 , 0xf0, 0xf4 };
+#define VB_X(x) (V_BIOS >> x) & 0xFF
+CARD8 code[] = { 6, 0x9a, 0x03, 0x00, 0x00, VB_X(12), 0xf4 };
+//CARD8 code[] = { 0x9a, 0x03, 0x00, 0x00, VB_X(12), 0xb8, 0x03, 0x00,
+//0xcd, 0x10, 0xf4 };
+//CARD8 code[] = { 0xb8 , 0xf0 , 0xf0 ,0xf4 };
+
+int ioperm_list[IOPERM_BITS] = {0,};
+
+static void sig_handler(int);
+static int map(void);
+static void unmap(void);
+static void bootBIOS(CARD16 ax);
+static int map_vram(void);
+static void unmap_vram(void);
+static int copy_vbios(memType v_base);
+static int copy_sys_bios(void);
+static void save_bios_to_file(void);
+static int setup_system_bios(void);
+static CARD32 setup_int_vect(void);
+#ifdef __ia32__
+static CARD32 setup_primary_int_vect(void);
+#endif
+static int chksum(CARD8 *start);
+static void setup_bios_regs(i86biosRegsPtr regs, CARD32 ax);
+static void print_regs(i86biosRegsPtr regs);
+static void print_usage(void);
+static void set_hlt(Bool set);
+static void set_ioperm(void);
+
+extern void yyparse();
+
+void loadCodeToMem(unsigned char *ptr, CARD8 *code);
+void dprint(unsigned long start, unsigned long size);
+
+static int vram_mapped = 0;
+static char* bios_var = NULL;
+static CARD8 save_msr;
+static CARD8 save_pos102;
+static CARD8 save_vse;
+static CARD8 save_46e8;
+static haltpoints hltp[20] = { {0, 0}, };
+
+console Console = {-1,-1};
+struct config Config;
+
+int main(int argc,char **argv)
+{
+ int c;
+
+ Config.PrintPort = PRINT_PORT;
+ Config.IoStatistics = IO_STATISTICS;
+ Config.PrintIrq = PRINT_IRQ;
+ Config.PrintPci = PRINT_PCI;
+ Config.ShowAllDev = SHOW_ALL_DEV;
+ Config.PrintIp = PRINT_IP;
+ Config.SaveBios = SAVE_BIOS;
+ Config.Trace = TRACE;
+ Config.ConfigActiveOnly = CONFIG_ACTIVE_ONLY; /* boot */
+ Config.ConfigActiveDevice = CONFIG_ACTIVE_DEVICE; /* boot */
+ Config.MapSysBios = MAP_SYS_BIOS;
+ Config.Resort = RESORT; /* boot */
+ Config.FixRom = FIX_ROM;
+ Config.NoConsole = NO_CONSOLE;
+ Config.BootOnly = FALSE;
+ Config.Verbose = VERBOSE;
+
+ opterr = 0;
+ while ((c = getopt(argc,argv,"psicaPStAdbrfnv:?")) != EOF) {
+ switch(c) {
+ case 'p':
+ Config.PrintPort = TRUE;
+ break;
+ case 's':
+ Config.IoStatistics = TRUE;
+ break;
+ case 'i':
+ Config.PrintIrq = TRUE;
+ break;
+ case 'c':
+ Config.PrintPci = TRUE;
+ break;
+ case 'a':
+ Config.ShowAllDev = TRUE;
+ break;
+ case 'P':
+ Config.PrintIp = TRUE;
+ break;
+ case 'S':
+ Config.SaveBios = TRUE;
+ break;
+ case 't':
+ Config.Trace = TRUE;
+ break;
+ case 'A':
+ Config.ConfigActiveOnly = TRUE;
+ break;
+ case 'd':
+ Config.ConfigActiveDevice = TRUE;
+ break;
+ case 'b':
+ Config.MapSysBios = TRUE;
+ break;
+ case 'r':
+ Config.Resort = TRUE;
+ break;
+ case 'f':
+ Config.FixRom = TRUE;
+ break;
+ case 'n':
+ Config.NoConsole = TRUE;
+ break;
+ case 'v':
+ Config.Verbose = strtol(optarg,NULL,0);
+ break;
+ case '?':
+ print_usage();
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ if (!map())
+ exit(1);
+
+ if (!setup_system_bios())
+ exit(1);
+
+ iopl(3);
+
+ scan_pci();
+
+ save_msr = inb(0x3CC);
+ save_vse = inb(0x3C3);
+ save_46e8 = inb(0x46e8);
+ save_pos102 = inb(0x102);
+
+ if (Config.BootOnly) {
+
+ if (!CurrentPci && !Config.ConfigActiveDevice
+ && !Config.ConfigActiveOnly) {
+ iopl(0);
+ unmap();
+ exit (1);
+ }
+ call_boot(NULL);
+ } else {
+ using_history();
+ yyparse();
+ }
+
+ unmap();
+
+ pciVideoRestore();
+
+ outb(0x102, save_pos102);
+ outb(0x46e8, save_46e8);
+ outb(0x3C3, save_vse);
+ outb(0x3C2, save_msr);
+
+ iopl(0);
+
+ close_console(Console);
+
+ exit(0);
+}
+
+
+void
+call_boot(struct device *dev)
+{
+ int Active_is_Pci = 0;
+ CARD32 vbios_base;
+
+ CurrentPci = PciList;
+ Console = open_console();
+
+ set_ioperm();
+
+
+ signal(2,sig_handler);
+ signal(11,sig_handler);
+
+ /* disable primary card */
+ pciVideoRestore(); /* reset PCI state to see primary card */
+ outb(0x3C2,~(CARD8)0x03 & save_msr);
+ outb(0x3C3,~(CARD8)0x01 & save_vse);
+ outb(0x46e8, ~(CARD8)0x08 & save_46e8);
+ outb(0x102, ~(CARD8)0x01 & save_pos102);
+
+ pciVideoDisable();
+
+ while (CurrentPci) {
+ CARD16 ax;
+
+ if (CurrentPci->active) {
+ Active_is_Pci = 1;
+ if (!Config.ConfigActiveDevice && !dev) {
+ CurrentPci = CurrentPci->next;
+ continue;
+ }
+ } else if (Config.ConfigActiveOnly && !dev) {
+ CurrentPci = CurrentPci->next;
+ continue;
+ }
+ if (dev && ((dev->type != PCI)
+ || (dev->type == PCI
+ && (dev->loc.pci.dev != CurrentPci->dev
+ || dev->loc.pci.bus != CurrentPci->bus
+ || dev->loc.pci.func != CurrentPci->func)))) {
+ CurrentPci = CurrentPci->next;
+ continue;
+ }
+
+ EnableCurrent();
+
+ if (CurrentPci->active) {
+ outb(0x102, save_pos102);
+ outb(0x46e8, save_46e8);
+ outb(0x3C3, save_vse);
+ outb(0x3C2, save_msr);
+ }
+
+ /* clear interrupt vectors */
+#ifdef __ia32__
+ vbios_base = CurrentPci->active ? setup_primary_int_vect()
+ : setup_int_vect();
+#else
+ vbios_base = setup_int_vect();
+#endif
+ ax = ((CARD16)(CurrentPci->bus) << 8)
+ | (CurrentPci->dev << 3) | (CurrentPci->func & 0x7);
+ if (Config.Verbose > 1) P_printf("ax: 0x%x\n",ax);
+
+ BootBios = findPciByIDs(CurrentPci->bus,CurrentPci->dev,
+ CurrentPci->func);
+ if (!((mapPciRom(BootBios) && chksum((CARD8*)V_BIOS))
+ || (CurrentPci->active && copy_vbios(vbios_base)))) {
+ CurrentPci = CurrentPci->next;
+ continue;
+ }
+ if (!map_vram()) {
+ CurrentPci = CurrentPci->next;
+ continue;
+ }
+ if (Config.SaveBios) save_bios_to_file();
+ printf("initializing PCI bus: %i dev: %i func: %i\n",CurrentPci->bus,
+ CurrentPci->dev,CurrentPci->func);
+ bootBIOS(ax);
+ unmap_vram();
+
+ if (CurrentPci->active)
+ close_console(Console);
+
+ if (dev) return;
+
+ CurrentPci = CurrentPci->next;
+ }
+
+ /* We have an ISA device - configure if requested */
+ if (!Active_is_Pci /* no isa card in system! */
+ && ((!dev && (Config.ConfigActiveDevice || Config.ConfigActiveOnly))
+ || (dev && dev->type == ISA))) {
+
+ pciVideoDisable();
+
+ if (!dev || dev->type == ISA) {
+ outb(0x102, save_pos102);
+ outb(0x46e8, save_46e8);
+ outb(0x3C3, save_vse);
+ outb(0x3C2, save_msr);
+
+#ifdef __ia32__
+ vbios_base = setup_primary_int_vect();
+#else
+ vbios_base = setup_int_vect();
+#endif
+ if (copy_vbios(vbios_base)) {
+
+ if (Config.SaveBios) save_bios_to_file();
+ if (map_vram()) {
+ printf("initializing ISA bus\n");
+ bootBIOS(0);
+ }
+ }
+
+ unmap_vram();
+ sleep(1);
+ close_console(Console);
+ }
+ }
+
+
+}
+
+int
+map(void)
+{
+ void* mem;
+ mem = mmap(0, (size_t)SIZE,
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_FIXED | MAP_PRIVATE | MAP_ANON,
+ -1, 0 );
+ if (mem != 0) {
+ perror("anonymous map");
+ return (0);
+ }
+ memset(mem,0,SIZE);
+
+ return (1);
+}
+
+static void
+unmap(void)
+{
+ munmap(0,SIZE);
+}
+
+static void
+bootBIOS(CARD16 ax)
+{
+ i86biosRegs bRegs;
+#ifdef V86BIOS_DEBUG
+ printf("starting BIOS\n");
+#endif
+ setup_io();
+ setup_bios_regs(&bRegs, ax);
+ loadCodeToMem((unsigned char *) BIOS_START, code);
+ do_x86(BIOS_START,&bRegs);
+#ifdef V86BIOS_DEBUG
+ printf("done\n");
+#endif
+}
+
+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;
+ }
+
+#ifdef __alpha__
+ 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)
+#else
+ 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)
+#endif
+ {
+ perror("mmap error in map_hardware_ram (1)");
+ close(mem_fd);
+ return (0);
+ }
+ vram_mapped = 1;
+ close(mem_fd);
+ return (1);
+}
+
+static void
+unmap_vram(void)
+{
+ if (!vram_mapped) return;
+
+ munmap((void*)VRAM_START,VRAM_SIZE);
+ vram_mapped = 0;
+}
+
+static int
+copy_vbios(memType v_base)
+{
+ int mem_fd;
+ unsigned char *tmp;
+ int size;
+
+ if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
+ perror("opening memory");
+ return (0);
+ }
+
+ if (lseek(mem_fd,(off_t) v_base, SEEK_SET) != (off_t) v_base) {
+ fprintf(stderr,"Cannot lseek\n");
+ goto Error;
+ }
+ tmp = (unsigned char *)malloc(3);
+ if (read(mem_fd, (char *)tmp, (size_t) 3) != (size_t) 3) {
+ fprintf(stderr,"Cannot read\n");
+ goto Error;
+ }
+ if (lseek(mem_fd,(off_t) v_base,SEEK_SET) != (off_t) v_base)
+ goto Error;
+
+ if (*tmp != 0x55 || *(tmp+1) != 0xAA ) {
+ fprintf(stderr,"No bios found at: 0x%lx\n",v_base);
+ goto Error;
+ }
+#ifdef DEBUG
+ dprint((unsigned long)tmp,0x100);
+#endif
+ size = *(tmp+2) * 512;
+
+ if (read(mem_fd, (char *)v_base, (size_t) size) != (size_t) size) {
+ fprintf(stderr,"Cannot read\n");
+ goto Error;
+ }
+ free(tmp);
+ close(mem_fd);
+ if (!chksum((CARD8*)v_base))
+ return (0);
+
+ return (1);
+
+Error:
+ perror("v_bios");
+ close(mem_fd);
+ return (0);
+}
+
+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);
+}
+
+void
+loadCodeToMem(unsigned char *ptr, CARD8 code[])
+{
+ int i;
+ CARD8 val;
+ int size = code[0];
+
+ for ( i=1;i<=size;i++) {
+ val = code[i];
+ *ptr++ = val;
+ }
+ return;
+}
+
+void
+dprint(unsigned long start, unsigned long size)
+{
+ int i,j;
+ char *c = (char *)start;
+
+ for (j = 0; j < (size >> 4); j++) {
+ char *d = c;
+ printf("\n0x%lx: ",(unsigned long)c);
+ for (i = 0; i<16; i++)
+ printf("%2.2x ",(unsigned char) (*(c++)));
+ c = d;
+ for (i = 0; i<16; i++) {
+ printf("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ?
+ (unsigned char) (*(c)): '.');
+ c++;
+ }
+ }
+ printf("\n");
+}
+
+static void
+save_bios_to_file(void)
+{
+ static int num = 0;
+ int size, count;
+ char file_name[256];
+ int fd;
+
+ sprintf(file_name,"bios_%i.fil",num);
+ if ((fd = open(file_name,O_WRONLY | O_CREAT | O_TRUNC,00644)) == -1)
+ return;
+ size = (*(unsigned char*)(V_BIOS + 2)) * 512;
+#ifdef V86BIOS_DEBUG
+ dprint(V_BIOS,20);
+#endif
+ if ((count = write(fd,(void *)(V_BIOS),size)) != size)
+ fprintf(stderr,"only saved %i of %i bytes\n",size,count);
+ num++;
+}
+
+static void
+sig_handler(int unused)
+{
+ fflush(stdout);
+ fflush(stderr);
+
+ /* put system back in a save state */
+ unmap_vram();
+ pciVideoRestore();
+ outb(0x102, save_pos102);
+ outb(0x46e8, save_46e8);
+ outb(0x3C3, save_vse);
+ outb(0x3C2, save_msr);
+
+ close_console(Console);
+ iopl(0);
+ unmap();
+
+ exit(1);
+}
+
+/*
+ * For initialization we just pass ax to the BIOS.
+ * PCI BIOSes need this. All other register are set 0.
+ */
+static void setup_bios_regs(i86biosRegsPtr regs, CARD32 ax)
+{
+ regs->ax = ax;
+ regs->bx = 0;
+ regs->cx = 0;
+ regs->dx = 0;
+ regs->es = 0;
+ regs->ds = 0x40; /* standard pc ds */
+ regs->si = 0;
+ regs->di = 0;
+}
+
+/*
+ * here we are really paranoid about faking a "real"
+ * BIOS. Most of this information was pulled from
+ * dosem.
+ */
+
+#ifdef __ia32__
+static CARD32
+setup_primary_int_vect(void)
+{
+ int mem_fd;
+ CARD32 vbase;
+ void *map;
+
+ if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
+ {
+ perror("opening memory");
+ return (0);
+ }
+
+ if ((map = mmap((void *) 0, (size_t) 0x2000,
+ PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
+ mem_fd, 0)) == (void *)-1) {
+ perror("mmap error in map_hardware_ram (2)");
+ close(mem_fd);
+ return (0);
+ }
+
+ close(mem_fd);
+ memcpy(0,map,BIOS_MEM);
+ munmap(map,0x2000);
+ /*
+ * create a backup copy of the bios variables to write back the
+ * modified values
+ */
+ if (!bios_var)
+ bios_var = (char *)malloc(BIOS_MEM);
+ memcpy(bios_var,0,BIOS_MEM);
+
+ vbase = (*((CARD16*)(0x10 << 2) + 1)) << 4;
+ if (Config.Verbose > 0) printf("vbase: 0x%x\n",vbase);
+ return vbase;
+}
+#endif
+
+static CARD32
+setup_int_vect(void)
+{
+ const CARD16 cs = 0x0;
+ 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;
+ return V_BIOS;
+}
+
+static int
+setup_system_bios(void)
+{
+ char *date = "06/01/99";
+ char *eisa_ident = "PCI/ISA";
+
+ if (Config.MapSysBios) {
+
+ if (!copy_sys_bios()) return 0;
+ return 1;
+
+ } else {
+
+// 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;
+ }
+
+}
+
+static void
+update_bios_vars(void)
+{
+ int mem_fd;
+ void *map;
+ memType i;
+
+#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;
+ }
+
+ if ((map = mmap((void *) 0, (size_t) 0x2000,
+ PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
+ mem_fd, 0)) == (void *)-1) {
+ perror("mmap error in map_hardware_ram (3)");
+ close(mem_fd);
+ return;
+ }
+
+ for (i = 0; i < BIOS_MEM; i++) {
+ if (bios_var[i] != *(CARD8*)i)
+ *((CARD8*)map + i) = *(CARD8*)i;
+ }
+
+ munmap(map,0x2000);
+ close(mem_fd);
+}
+
+static int
+chksum(CARD8 *start)
+{
+ CARD16 size;
+ CARD8 val = 0;
+ int i;
+
+ size = *(start+2) * 512;
+ for (i = 0; i<size; i++)
+ val += *(start + i);
+
+ if (!val)
+ return 1;
+
+ fprintf(stderr,"BIOS cksum wrong!\n");
+ return 0;
+}
+
+void
+runINT(int num, i86biosRegsPtr Regs)
+{
+ Bool isVideo = FALSE;
+ CARD8 code_int[] = { 3, 0xcd, 0x00, 0xf4 };
+
+ code_int[2] = (CARD8) num;
+
+ if (num == 0x10)
+ isVideo = TRUE;
+
+ if (!setup_system_bios())
+ return;
+
+ if ((isVideo && (!CurrentPci || CurrentPci->active)) || !isVideo) {
+ CARD32 vbios_base;
+
+#ifdef __ia32__
+ if (!(vbios_base = setup_primary_int_vect()))
+#else
+ if (!(vbios_base = setup_int_vect()))
+#endif
+ return;
+ if (!copy_vbios(vbios_base))
+ return;
+ }
+
+ if (!map_vram())
+ return;
+
+#ifdef V86BIOS_DEBUG
+ printf("starting BIOS\n");
+#endif
+ loadCodeToMem((unsigned char *) BIOS_START, code_int);
+ setup_io();
+ print_regs(Regs);
+ set_ioperm();
+ set_hlt(TRUE);
+ do_x86(BIOS_START,Regs);
+ set_hlt(FALSE);
+ print_regs(Regs);
+
+#ifdef V86BIOS_DEBUG
+ printf("done\n");
+#endif
+
+ if ((isVideo && (!CurrentPci || CurrentPci->active)) || !isVideo)
+ update_bios_vars();
+}
+
+static void
+print_regs(i86biosRegsPtr regs)
+{
+ printf("ax=%x bx=%x cx=%x dx=%x ds=%x es=%x di=%x si=%x\n",
+ (CARD16)regs->ax,(CARD16)regs->bx,(CARD16)regs->cx,(CARD16)regs->dx,
+ (CARD16)regs->ds,(CARD16)regs->es,(CARD16)regs->di,
+ (CARD16)regs->si);
+}
+
+static void
+print_usage(void)
+{
+}
+
+void
+add_hlt(unsigned long val)
+{
+ int i;
+
+ if (val < BIOS_MEM || (val > VRAM_START && val < (VRAM_START + VRAM_SIZE))
+ || val >= SIZE) {
+ printf("address out of range\n");
+ return;
+ }
+
+ for (i=0; i<20; i++) {
+ if (hltp[i].address == 0) {
+ hltp[i].address = (void*)val;
+ break;
+ }
+ }
+ if (i == 20) printf("no more hltpoints available\n");
+}
+
+void
+del_hlt(int val)
+{
+ if (val == 21) { /* delete all */
+ int i;
+ printf("clearing all hltpoints\n");
+ for (i=0; i <20; i++)
+ hltp[i].address = NULL;
+ } else if (val >= 0 && val <20)
+ hltp[val].address = NULL;
+ else printf("hltpoint %i out of range: valid range 0-19\n",val);
+}
+
+void
+list_hlt()
+{
+ int i;
+ for (i=0; i<20; i++)
+ if (hltp[i].address)
+ printf("hltpoint[%i]: 0x%lx\n",i,(unsigned long)hltp[i].address);
+}
+
+static void
+set_hlt(Bool set)
+{
+ int i;
+ for (i=0; i<20; i++)
+ if (hltp[i].address) {
+ if (set) {
+ hltp[i].orgval = *(CARD8*)hltp[i].address;
+ *(CARD8*)hltp[i].address = 0xf4;
+ } else
+ *(CARD8*)hltp[i].address = hltp[i].orgval;
+ }
+}
+
+static void
+set_ioperm(void)
+{
+ int i, start;
+
+ ioperm(0,IOPERM_BITS,0);
+
+ for (i = 0; i < IOPERM_BITS;i++)
+ if (ioperm_list[i]) {
+ start = i;
+ for (;i < IOPERM_BITS; i++) {
+ if (!ioperm_list[i]) {
+ ioperm(start,i - start, 1);
+ break;
+ }
+ }
+ }
+}
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/v86bios.h b/board/MAI/bios_emulator/scitech/src/v86bios/v86bios.h
new file mode 100644
index 0000000000..06d0f9ff52
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/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);
+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/board/MAI/bios_emulator/scitech/src/v86bios/working_cards b/board/MAI/bios_emulator/scitech/src/v86bios/working_cards
new file mode 100644
index 0000000000..7753f2495d
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/working_cards
@@ -0,0 +1,7 @@
+David Monro: Trident TGUI 9440
+ Virge/VX (Diamond Stealth 3D 3400)
+ Riva TNT (Diamond Viper V550) no vbios?
+Jarno Paananen <jpaana@s2.org>: Guillemot Maxigamer Xentor 32
+ (NVIDIA TNT2 Ultra)
+ Creative Graphics Blaster Exxtreme
+ (Permedia 2)
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/x86emu.c b/board/MAI/bios_emulator/scitech/src/v86bios/x86emu.c
new file mode 100644
index 0000000000..2cc72df995
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/x86emu.c
@@ -0,0 +1,316 @@
+/*
+ * 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 "debug.h"
+
+#define IF_MASK 0x00000200
+#define VIF_MASK 0x00080000 /* virtual interrupt flag */
+#define VIP_MASK 0x00100000 /* virtual interrupt pending */
+
+#include </usr/include/unistd.h>
+#include <errno.h>
+#include <asm/unistd.h>
+//#include <syscall-list.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#ifdef __alpha__
+#include <sys/io.h>
+#endif
+#include <signal.h>
+#include <setjmp.h>
+#include "AsmMacros.h"
+#include "v86bios.h"
+# define DEBUG
+#include "x86emu.h"
+#undef DEBUG
+
+#define M _X86EMU_env
+#define CPU_REG(reg) M.x86.R_##reg
+
+struct pio P;
+
+void
+setup_io(void)
+{
+ if (!Config.PrintPort && !Config.IoStatistics) {
+
+#if defined (__i386__)
+ P.inb = (u8(*)(u16))inb;
+ P.inw = (u16(*)(u16))inw;
+ P.outb = (void(*)(u16,u8))outb;
+ P.outw = (void(*)(u16,u16))outw;
+#else
+ P.inb = p_inb;
+ P.inw = p_inw;
+ P.outb = p_outb;
+ P.outw = p_outw;
+#endif
+#if defined (__i386__) && ! defined(NEED_PCI_IO)
+ P.inl = (u32(*)(u16))inl;
+ P.outl = (void(*)(u16,u32))outl;
+#else
+ P.inl = p_inl;
+ P.outl = p_outl;
+#endif
+ } else {
+ P.inb = p_inb;
+ P.inw = p_inw;
+ P.inl = p_inl;
+ P.outb = p_outb;
+ P.outw = p_outw;
+ P.outl = p_outl;
+ }
+}
+
+void
+x86emu_do_int(int num)
+{
+ struct regs86 regs;
+
+ i_printf("int 0x%x received: ax:0x%x",num,CPU_REG(AX));
+ if (Config.PrintIp)
+ i_printf(" at: 0x%x\n",getIP());
+ else
+ i_printf("\n");
+
+ /* try to run bios interrupt */
+
+ /* if not installed fall back */
+#define COPY(x,y) regs.y = M.x86.x
+#define COPY_R(x,y) M.x86.x = regs.y
+
+ COPY(R_EAX,eax);
+ COPY(R_EBX,ebx);
+ COPY(R_ECX,ecx);
+ COPY(R_EDX,edx);
+ COPY(R_ESI,esi);
+ COPY(R_EDI,edi);
+ COPY(R_EBP,ebp);
+ COPY(R_EIP,eip);
+ COPY(R_ESP,esp);
+ COPY(R_CS,cs);
+ COPY(R_SS,ss);
+ COPY(R_DS,ds);
+ COPY(R_ES,es);
+ COPY(R_FS,fs);
+ COPY(R_GS,gs);
+ COPY(R_EFLG,eflags);
+
+ if (!(int_handler(num,&regs))) {
+ if (!run_bios_int(num,&regs))
+ goto unknown_int;
+ else
+ return;
+ }
+
+ COPY_R(R_EAX,eax);
+ COPY_R(R_EBX,ebx);
+ COPY_R(R_ECX,ecx);
+ COPY_R(R_EDX,edx);
+ COPY_R(R_ESI,esi);
+ COPY_R(R_EDI,edi);
+ COPY_R(R_EBP,ebp);
+ COPY_R(R_EIP,eip);
+ COPY_R(R_ESP,esp);
+ COPY_R(R_CS,cs);
+ COPY_R(R_SS,ss);
+ COPY_R(R_DS,ds);
+ COPY_R(R_ES,es);
+ COPY_R(R_FS,fs);
+ COPY_R(R_GS,gs);
+ COPY_R(R_EFLG,eflags);
+ return;
+
+ unknown_int:
+ fprintf(stderr,"\nUnknown vm86_int: %X\n\n",num);
+ X86EMU_halt_sys();
+ return;
+
+#undef COPY
+#undef COPY_R
+}
+
+void
+setup_x86emu(unsigned long bios_start, i86biosRegsPtr regs)
+{
+ int i;
+ CARD32 eip;
+ CARD16 cs;
+ X86EMU_intrFuncs intFuncs[256];
+
+ X86EMU_pioFuncs pioFuncs = {
+ (u8(*)(u16))P.inb,
+ (u16(*)(u16))P.inw,
+ (u32(*)(u16))P.inl,
+ (void(*)(u16,u8))P.outb,
+ (void(*)(u16,u16))P.outw,
+ (void(*)(u16,u32))P.outl
+ };
+#ifdef __alpha__
+ X86EMU_memFuncs memFuncs = {
+ (u8(*)(u32))mem_rb,
+ (u16(*)(u32))mem_rw,
+ (u32(*)(u32))mem_rl,
+ (void(*)(u32,u8))mem_wb,
+ (void(*)(u32,u16))mem_ww,
+ (void(*)(u32,u32))mem_wl
+ };
+#endif
+ M.mem_base = 0;
+ M.mem_size = 1024*1024 + 1024;
+ // M.x86.debug = DEBUG_DISASSEMBLE_F | DEBUG_TRACE_F | DEBUG_DECODE_F;
+ // M.x86.debug |= DEBUG_DECODE_F | DEBUG_TRACE_F;
+/*
+ * For single step tracing compile x86emu with option -DDEBUG
+ */
+ M.x86.debug = 0;
+ if (Config.PrintIp)
+ M.x86.debug = DEBUG_SAVE_CS_IP;
+
+ if (Config.Trace)
+ X86EMU_trace_on();
+
+ X86EMU_setupPioFuncs(&pioFuncs);
+#ifdef __alpha__
+ X86EMU_setupMemFuncs(&memFuncs);
+#endif
+ for (i=0;i<256;i++)
+ intFuncs[i] = x86emu_do_int;
+ X86EMU_setupIntrFuncs(intFuncs);
+
+ 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) = regs->si;
+ CPU_REG(EDI) = regs->di;
+ CPU_REG(EBP) = 0;
+ CPU_REG(EIP) = eip;
+ CPU_REG(CS) = cs;
+ CPU_REG(SP) = 0x100;
+ CPU_REG(SS) = 0x30; /* This is the standard pc bios stack */
+ CPU_REG(ES) = regs->es;
+ CPU_REG(DS) = regs->ds;
+ CPU_REG(FS) = 0;
+ CPU_REG(GS) = 0;
+ CPU_REG(EFLG) |= (VIF_MASK | VIP_MASK | IF_MASK | 0x2);
+}
+
+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 void
+do_x86emu(void)
+{
+ X86EMU_exec();
+}
+
+static jmp_buf x86_esc;
+static void
+vmexit(int unused)
+{
+ longjmp(x86_esc,1);
+}
+
+void
+do_x86(unsigned long bios_start, i86biosRegsPtr regs)
+{
+ static void (*org_handler)(int);
+
+ setup_x86emu(bios_start,regs);
+ if (setjmp(x86_esc) == 0) {
+ org_handler = signal(2,vmexit);
+ do_x86emu();
+ signal(2,org_handler);
+ collect_bios_regs(regs);
+ } else {
+ signal(2,org_handler);
+ printf("interrupted at 0x%x\n",((CARD16)CPU_REG(CS)) << 4
+ | (CARD16)CPU_REG(EIP));
+ }
+}
+
+int
+run_bios_int(int num, struct regs86 *regs)
+{
+#ifdef V86BIOS_DEBUG
+ static int firsttime = 1;
+#endif
+ /* check if bios vector is initialized */
+ if (((CARD16*)0)[(num<<1)+1] == 0x0000) { /* SYS_BIOS_SEG ?*/
+#ifdef V86BIOS_DEBUG
+ i_printf("card BIOS not loaded\n");
+#endif
+ return 0;
+ }
+
+#ifdef V86BIOS_DEBUG
+ if (firsttime) {
+ dprint(0,0x3D0);
+ firsttime = 0;
+ }
+#endif
+
+ i_printf("calling card BIOS at: ");
+ i_printf("0x%x:%x\n",((CARD16 *) 0)[(num << 1) + 1],
+ (CARD32)((CARD16 *) 0)[num << 1]);
+ X86EMU_prepareForInt(num);
+
+ return 1;
+}
+
+CARD32
+getIntVect(int num)
+{
+ return ((CARD32*)0)[num];
+}
+#if 0
+void
+printk(const char *fmt, ...)
+{
+ va_list argptr;
+ va_start(argptr, fmt);
+ vfprintf(stdout, fmt, argptr);
+ fflush(stdout);
+ va_end(argptr);
+}
+#endif
+
+CARD32
+getIP(void)
+{
+ return (M.x86.saved_cs << 4) + M.x86.saved_ip;
+}