summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/biosemu
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/biosemu')
-rw-r--r--board/MAI/bios_emulator/scitech/src/biosemu/besys.c408
-rw-r--r--board/MAI/bios_emulator/scitech/src/biosemu/bios.c250
-rw-r--r--board/MAI/bios_emulator/scitech/src/biosemu/biosemu.c445
-rw-r--r--board/MAI/bios_emulator/scitech/src/biosemu/biosemui.h79
-rw-r--r--board/MAI/bios_emulator/scitech/src/biosemu/makefile99
-rw-r--r--board/MAI/bios_emulator/scitech/src/biosemu/makefile.cross10
-rw-r--r--board/MAI/bios_emulator/scitech/src/biosemu/warmboot.c569
7 files changed, 1860 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/biosemu/besys.c b/board/MAI/bios_emulator/scitech/src/biosemu/besys.c
new file mode 100644
index 0000000000..7f7ea99939
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/biosemu/besys.c
@@ -0,0 +1,408 @@
+/****************************************************************************
+*
+* BIOS emulator and interface
+* to Realmode X86 Emulator Library
+*
+* Copyright (C) 1996-1999 SciTech Software, Inc.
+*
+* ========================================================================
+*
+* 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.
+*
+* ========================================================================
+*
+* Language: ANSI C
+* Environment: Any
+* Developer: Kendall Bennett
+*
+* Description: This file includes BIOS emulator I/O and memory access
+* functions.
+*
+****************************************************************************/
+
+#include "biosemui.h"
+
+/*------------------------------- Macros ----------------------------------*/
+
+/* Macros to read and write values to x86 bus memory. Replace these as
+ * necessary if you need to do something special to access memory over
+ * the bus on a particular processor family.
+ */
+
+#define readb(base,off) *((u8*)((u32)(base) + (off)))
+#define readw(base,off) *((u16*)((u32)(base) + (off)))
+#define readl(base,off) *((u32*)((u32)(base) + (off)))
+#define writeb(v,base,off) *((u8*)((u32)(base) + (off))) = (v)
+#define writew(v,base,off) *((u16*)((u32)(base) + (off))) = (v)
+#define writel(v,base,off) *((u32*)((u32)(base) + (off))) = (v)
+
+/*----------------------------- Implementation ----------------------------*/
+
+#ifdef DEBUG
+# define DEBUG_MEM() (M.x86.debug & DEBUG_MEM_TRACE_F)
+#else
+# define DEBUG_MEM()
+#endif
+
+/****************************************************************************
+PARAMETERS:
+addr - Emulator memory address to read
+
+RETURNS:
+Byte value read from emulator memory.
+
+REMARKS:
+Reads a byte value from the emulator memory. We have three distinct memory
+regions that are handled differently, which this function handles.
+****************************************************************************/
+u8 X86API BE_rdb(
+ u32 addr)
+{
+ u8 val = 0;
+
+ if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
+ val = *(u8*)(_BE_env.biosmem_base + addr - 0xC0000);
+ }
+ else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
+ val = readb(_BE_env.busmem_base, addr - 0xA0000);
+ }
+ else if (addr > M.mem_size - 1) {
+DB( printk("mem_read: address %#lx out of range!\n", addr);)
+ HALT_SYS();
+ }
+ else {
+ val = *(u8*)(M.mem_base + addr);
+ }
+DB( if (DEBUG_MEM())
+ printk("%#08x 1 -> %#x\n", addr, val);)
+ return val;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr - Emulator memory address to read
+
+RETURNS:
+Word value read from emulator memory.
+
+REMARKS:
+Reads a word value from the emulator memory. We have three distinct memory
+regions that are handled differently, which this function handles.
+****************************************************************************/
+u16 X86API BE_rdw(
+ u32 addr)
+{
+ u16 val = 0;
+
+ if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x1) {
+ addr -= 0xC0000;
+ val = ( *(u8*)(_BE_env.biosmem_base + addr) |
+ (*(u8*)(_BE_env.biosmem_base + addr + 1) << 8));
+ }
+ else
+#endif
+ val = *(u16*)(_BE_env.biosmem_base + addr - 0xC0000);
+ }
+ else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x1) {
+ addr -= 0xA0000;
+ val = ( readb(_BE_env.busmem_base, addr) |
+ (readb(_BE_env.busmem_base, addr + 1) << 8));
+ }
+ else
+#endif
+ val = readw(_BE_env.busmem_base, addr - 0xA0000);
+ }
+ else if (addr > M.mem_size - 2) {
+DB( printk("mem_read: address %#lx out of range!\n", addr);)
+ HALT_SYS();
+ }
+ else {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x1) {
+ val = ( *(u8*)(M.mem_base + addr) |
+ (*(u8*)(M.mem_base + addr + 1) << 8));
+ }
+ else
+#endif
+ val = *(u16*)(M.mem_base + addr);
+ }
+DB( if (DEBUG_MEM())
+ printk("%#08x 2 -> %#x\n", addr, val);)
+ return val;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr - Emulator memory address to read
+
+RETURNS:
+Long value read from emulator memory.
+
+REMARKS:
+Reads a long value from the emulator memory. We have three distinct memory
+regions that are handled differently, which this function handles.
+****************************************************************************/
+u32 X86API BE_rdl(
+ u32 addr)
+{
+ u32 val = 0;
+
+ if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x3) {
+ addr -= 0xC0000;
+ val = ( *(u8*)(_BE_env.biosmem_base + addr + 0) |
+ (*(u8*)(_BE_env.biosmem_base + addr + 1) << 8) |
+ (*(u8*)(_BE_env.biosmem_base + addr + 2) << 16) |
+ (*(u8*)(_BE_env.biosmem_base + addr + 3) << 24));
+ }
+ else
+#endif
+ val = *(u32*)(_BE_env.biosmem_base + addr - 0xC0000);
+ }
+ else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x3) {
+ addr -= 0xA0000;
+ val = ( readb(_BE_env.busmem_base, addr) |
+ (readb(_BE_env.busmem_base, addr + 1) << 8) |
+ (readb(_BE_env.busmem_base, addr + 2) << 16) |
+ (readb(_BE_env.busmem_base, addr + 3) << 24));
+ }
+ else
+#endif
+ val = readl(_BE_env.busmem_base, addr - 0xA0000);
+ }
+ else if (addr > M.mem_size - 4) {
+DB( printk("mem_read: address %#lx out of range!\n", addr);)
+ HALT_SYS();
+ }
+ else {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x3) {
+ val = ( *(u8*)(M.mem_base + addr + 0) |
+ (*(u8*)(M.mem_base + addr + 1) << 8) |
+ (*(u8*)(M.mem_base + addr + 2) << 16) |
+ (*(u8*)(M.mem_base + addr + 3) << 24));
+ }
+ else
+#endif
+ val = *(u32*)(M.mem_base + addr);
+ }
+DB( if (DEBUG_MEM())
+ printk("%#08x 4 -> %#x\n", addr, val);)
+ return val;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr - Emulator memory address to read
+val - Value to store
+
+REMARKS:
+Writes a byte value to emulator memory. We have three distinct memory
+regions that are handled differently, which this function handles.
+****************************************************************************/
+void X86API BE_wrb(
+ u32 addr,
+ u8 val)
+{
+DB( if (DEBUG_MEM())
+ printk("%#08x 1 <- %#x\n", addr, val);)
+ if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
+ *(u8*)(_BE_env.biosmem_base + addr - 0xC0000) = val;
+ }
+ else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
+ writeb(val, _BE_env.busmem_base, addr - 0xA0000);
+ }
+ else if (addr > M.mem_size-1) {
+DB( printk("mem_write: address %#lx out of range!\n", addr);)
+ HALT_SYS();
+ }
+ else {
+ *(u8*)(M.mem_base + addr) = val;
+ }
+}
+
+/****************************************************************************
+PARAMETERS:
+addr - Emulator memory address to read
+val - Value to store
+
+REMARKS:
+Writes a word value to emulator memory. We have three distinct memory
+regions that are handled differently, which this function handles.
+****************************************************************************/
+void X86API BE_wrw(
+ u32 addr,
+ u16 val)
+{
+DB( if (DEBUG_MEM())
+ printk("%#08x 2 <- %#x\n", addr, val);)
+ if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x1) {
+ addr -= 0xC0000;
+ *(u8*)(_BE_env.biosmem_base + addr + 0) = (val >> 0) & 0xff;
+ *(u8*)(_BE_env.biosmem_base + addr + 1) = (val >> 8) & 0xff;
+ }
+ else
+#endif
+ *(u16*)(_BE_env.biosmem_base + addr - 0xC0000) = val;
+ }
+ else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x1) {
+ addr -= 0xA0000;
+ writeb(val >> 0, _BE_env.busmem_base, addr);
+ writeb(val >> 8, _BE_env.busmem_base, addr + 1);
+ }
+ else
+#endif
+ writew(val, _BE_env.busmem_base, addr - 0xA0000);
+ }
+ else if (addr > M.mem_size-2) {
+DB( printk("mem_write: address %#lx out of range!\n", addr);)
+ HALT_SYS();
+ }
+ else {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x1) {
+ *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
+ *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
+ }
+ else
+#endif
+ *(u16*)(M.mem_base + addr) = val;
+ }
+}
+
+/****************************************************************************
+PARAMETERS:
+addr - Emulator memory address to read
+val - Value to store
+
+REMARKS:
+Writes a long value to emulator memory. We have three distinct memory
+regions that are handled differently, which this function handles.
+****************************************************************************/
+void X86API BE_wrl(
+ u32 addr,
+ u32 val)
+{
+DB( if (DEBUG_MEM())
+ printk("%#08x 4 <- %#x\n", addr, val);)
+ if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x1) {
+ addr -= 0xC0000;
+ *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
+ *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
+ *(u8*)(M.mem_base + addr + 2) = (val >> 16) & 0xff;
+ *(u8*)(M.mem_base + addr + 3) = (val >> 24) & 0xff;
+ }
+ else
+#endif
+ *(u32*)(M.mem_base + addr - 0xC0000) = val;
+ }
+ else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x3) {
+ addr -= 0xA0000;
+ writeb(val >> 0, _BE_env.busmem_base, addr);
+ writeb(val >> 8, _BE_env.busmem_base, addr + 1);
+ writeb(val >> 16, _BE_env.busmem_base, addr + 1);
+ writeb(val >> 24, _BE_env.busmem_base, addr + 1);
+ }
+ else
+#endif
+ writel(val, _BE_env.busmem_base, addr - 0xA0000);
+ }
+ else if (addr > M.mem_size-4) {
+DB( printk("mem_write: address %#lx out of range!\n", addr);)
+ HALT_SYS();
+ }
+ else {
+#ifdef __BIG_ENDIAN__
+ if (addr & 0x1) {
+ *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
+ *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
+ *(u8*)(M.mem_base + addr + 2) = (val >> 16) & 0xff;
+ *(u8*)(M.mem_base + addr + 3) = (val >> 24) & 0xff;
+ }
+ else
+#endif
+ *(u32*)(M.mem_base + addr) = val;
+ }
+}
+
+/* Debug functions to do ISA/PCI bus port I/O */
+
+#ifdef DEBUG
+#define DEBUG_IO() (M.x86.debug & DEBUG_IO_TRACE_F)
+
+u8 X86API BE_inb(int port)
+{
+ u8 val = PM_inpb(port);
+ if (DEBUG_IO())
+ printk("%04X:%04X: inb.%04X -> %02X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
+ return val;
+}
+
+u16 X86API BE_inw(int port)
+{
+ u16 val = PM_inpw(port);
+ if (DEBUG_IO())
+ printk("%04X:%04X: inw.%04X -> %04X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
+ return val;
+}
+
+u32 X86API BE_inl(int port)
+{
+ u32 val = PM_inpd(port);
+ if (DEBUG_IO())
+ printk("%04X:%04X: inl.%04X -> %08X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
+ return val;
+}
+
+void X86API BE_outb(int port, u8 val)
+{
+ if (DEBUG_IO())
+ printk("%04X:%04X: outb.%04X <- %02X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
+ PM_outpb(port,val);
+}
+
+void X86API BE_outw(int port, u16 val)
+{
+ if (DEBUG_IO())
+ printk("%04X:%04X: outw.%04X <- %04X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
+ PM_outpw(port,val);
+}
+
+void X86API BE_outl(int port, u32 val)
+{
+ if (DEBUG_IO())
+ printk("%04X:%04X: outl.%04X <- %08X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
+ PM_outpd(port,val);
+}
+#endif
diff --git a/board/MAI/bios_emulator/scitech/src/biosemu/bios.c b/board/MAI/bios_emulator/scitech/src/biosemu/bios.c
new file mode 100644
index 0000000000..3fb4c3608a
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/biosemu/bios.c
@@ -0,0 +1,250 @@
+/****************************************************************************
+*
+* BIOS emulator and interface
+* to Realmode X86 Emulator Library
+*
+* Copyright (C) 1996-1999 SciTech Software, Inc.
+*
+* ========================================================================
+*
+* 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.
+*
+* ========================================================================
+*
+* Language: ANSI C
+* Environment: Any
+* Developer: Kendall Bennett
+*
+* Description: Module implementing the BIOS specific functions.
+*
+****************************************************************************/
+
+#include "biosemui.h"
+
+/*----------------------------- Implementation ----------------------------*/
+
+/****************************************************************************
+PARAMETERS:
+intno - Interrupt number being serviced
+
+REMARKS:
+Handler for undefined interrupts.
+****************************************************************************/
+static void X86API undefined_intr(
+ int intno)
+{
+ if (BE_rdw(intno * 4 + 2) == BIOS_SEG)
+ printk("biosEmu: undefined interrupt %xh called!\n",intno);
+ else
+ X86EMU_prepareForInt(intno);
+}
+
+/****************************************************************************
+PARAMETERS:
+intno - Interrupt number being serviced
+
+REMARKS:
+This function handles the default system BIOS Int 10h (the default is stored
+in the Int 42h vector by the system BIOS at bootup). We only need to handle
+a small number of special functions used by the BIOS during POST time.
+****************************************************************************/
+static void X86API int42(
+ int intno)
+{
+ if (M.x86.R_AH == 0x12 && M.x86.R_BL == 0x32) {
+ if (M.x86.R_AL == 0) {
+ /* Enable CPU accesses to video memory */
+ PM_outpb(0x3c2, PM_inpb(0x3cc) | (u8)0x02);
+ return;
+ }
+ else if (M.x86.R_AL == 1) {
+ /* Disable CPU accesses to video memory */
+ PM_outpb(0x3c2, PM_inpb(0x3cc) & (u8)~0x02);
+ return;
+ }
+#ifdef DEBUG
+ else {
+ printk("biosEmu/bios.int42: unknown function AH=0x12, BL=0x32, AL=%#02x\n",M.x86.R_AL);
+ }
+#endif
+ }
+#ifdef DEBUG
+ else {
+ printk("biosEmu/bios.int42: unknown function AH=%#02x, AL=%#02x, BL=%#02x\n",M.x86.R_AH, M.x86.R_AL, M.x86.R_BL);
+ }
+#endif
+}
+
+/****************************************************************************
+PARAMETERS:
+intno - Interrupt number being serviced
+
+REMARKS:
+This function handles the default system BIOS Int 10h. If the POST code
+has not yet re-vectored the Int 10h BIOS interrupt vector, we handle this
+by simply calling the int42 interrupt handler above. Very early in the
+BIOS POST process, the vector gets replaced and we simply let the real
+mode interrupt handler process the interrupt.
+****************************************************************************/
+static void X86API int10(
+ int intno)
+{
+ if (BE_rdw(intno * 4 + 2) == BIOS_SEG)
+ int42(intno);
+ else
+ X86EMU_prepareForInt(intno);
+}
+
+/* Result codes returned by the PCI BIOS */
+
+#define SUCCESSFUL 0x00
+#define FUNC_NOT_SUPPORT 0x81
+#define BAD_VENDOR_ID 0x83
+#define DEVICE_NOT_FOUND 0x86
+#define BAD_REGISTER_NUMBER 0x87
+#define SET_FAILED 0x88
+#define BUFFER_TOO_SMALL 0x89
+
+/****************************************************************************
+PARAMETERS:
+intno - Interrupt number being serviced
+
+REMARKS:
+This function handles the default Int 1Ah interrupt handler for the real
+mode code, which provides support for the PCI BIOS functions. Since we only
+want to allow the real mode BIOS code *only* see the PCI config space for
+its own device, we only return information for the specific PCI config
+space that we have passed in to the init function. This solves problems
+when using the BIOS to warm boot a secondary adapter when there is an
+identical adapter before it on the bus (some BIOS'es get confused in this
+case).
+****************************************************************************/
+static void X86API int1A(
+ unused)
+{
+ u16 pciSlot;
+
+ /* Fail if no PCI device information has been registered */
+ if (!_BE_env.vgaInfo.pciInfo)
+ return;
+ pciSlot = (u16)(_BE_env.vgaInfo.pciInfo->slot.i >> 8);
+ switch (M.x86.R_AX) {
+ case 0xB101: /* PCI bios present? */
+ M.x86.R_AL = 0x00; /* no config space/special cycle generation support */
+ M.x86.R_EDX = 0x20494350; /* " ICP" */
+ M.x86.R_BX = 0x0210; /* Version 2.10 */
+ M.x86.R_CL = 0; /* Max bus number in system */
+ CLEAR_FLAG(F_CF);
+ break;
+ case 0xB102: /* Find PCI device */
+ M.x86.R_AH = DEVICE_NOT_FOUND;
+ if (M.x86.R_DX == _BE_env.vgaInfo.pciInfo->VendorID &&
+ M.x86.R_CX == _BE_env.vgaInfo.pciInfo->DeviceID &&
+ M.x86.R_SI == 0) {
+ M.x86.R_AH = SUCCESSFUL;
+ M.x86.R_BX = pciSlot;
+ }
+ CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
+ break;
+ case 0xB103: /* Find PCI class code */
+ M.x86.R_AH = DEVICE_NOT_FOUND;
+ if (M.x86.R_CL == _BE_env.vgaInfo.pciInfo->Interface &&
+ M.x86.R_CH == _BE_env.vgaInfo.pciInfo->SubClass &&
+ (u8)(M.x86.R_ECX >> 16) == _BE_env.vgaInfo.pciInfo->BaseClass) {
+ M.x86.R_AH = SUCCESSFUL;
+ M.x86.R_BX = pciSlot;
+ }
+ CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
+ break;
+ case 0xB108: /* Read configuration byte */
+ M.x86.R_AH = BAD_REGISTER_NUMBER;
+ if (M.x86.R_BX == pciSlot) {
+ M.x86.R_AH = SUCCESSFUL;
+ M.x86.R_CL = (u8)PCI_accessReg(M.x86.R_DI,0,PCI_READ_BYTE,_BE_env.vgaInfo.pciInfo);
+ }
+ CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
+ break;
+ case 0xB109: /* Read configuration word */
+ M.x86.R_AH = BAD_REGISTER_NUMBER;
+ if (M.x86.R_BX == pciSlot) {
+ M.x86.R_AH = SUCCESSFUL;
+ M.x86.R_CX = (u16)PCI_accessReg(M.x86.R_DI,0,PCI_READ_WORD,_BE_env.vgaInfo.pciInfo);
+ }
+ CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
+ break;
+ case 0xB10A: /* Read configuration dword */
+ M.x86.R_AH = BAD_REGISTER_NUMBER;
+ if (M.x86.R_BX == pciSlot) {
+ M.x86.R_AH = SUCCESSFUL;
+ M.x86.R_ECX = (u32)PCI_accessReg(M.x86.R_DI,0,PCI_READ_DWORD,_BE_env.vgaInfo.pciInfo);
+ }
+ CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
+ break;
+ case 0xB10B: /* Write configuration byte */
+ M.x86.R_AH = BAD_REGISTER_NUMBER;
+ if (M.x86.R_BX == pciSlot) {
+ M.x86.R_AH = SUCCESSFUL;
+ PCI_accessReg(M.x86.R_DI,M.x86.R_CL,PCI_WRITE_BYTE,_BE_env.vgaInfo.pciInfo);
+ }
+ CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
+ break;
+ case 0xB10C: /* Write configuration word */
+ M.x86.R_AH = BAD_REGISTER_NUMBER;
+ if (M.x86.R_BX == pciSlot) {
+ M.x86.R_AH = SUCCESSFUL;
+ PCI_accessReg(M.x86.R_DI,M.x86.R_CX,PCI_WRITE_WORD,_BE_env.vgaInfo.pciInfo);
+ }
+ CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
+ break;
+ case 0xB10D: /* Write configuration dword */
+ M.x86.R_AH = BAD_REGISTER_NUMBER;
+ if (M.x86.R_BX == pciSlot) {
+ M.x86.R_AH = SUCCESSFUL;
+ PCI_accessReg(M.x86.R_DI,M.x86.R_ECX,PCI_WRITE_DWORD,_BE_env.vgaInfo.pciInfo);
+ }
+ CONDITIONAL_SET_FLAG((M.x86.R_AH != SUCCESSFUL), F_CF);
+ break;
+ default:
+ printk("biosEmu/bios.int1a: unknown function AX=%#04x\n", M.x86.R_AX);
+ }
+}
+
+/****************************************************************************
+REMARKS:
+This function initialises the BIOS emulation functions for the specific
+PCI display device. We insulate the real mode BIOS from any other devices
+on the bus, so that it will work correctly thinking that it is the only
+device present on the bus (ie: avoiding any adapters present in from of
+the device we are trying to control).
+****************************************************************************/
+void _BE_bios_init(
+ u32 *intrTab)
+{
+ int i;
+ X86EMU_intrFuncs bios_intr_tab[256];
+
+ for (i = 0; i < 256; ++i) {
+ intrTab[i] = BIOS_SEG << 16;
+ bios_intr_tab[i] = undefined_intr;
+ }
+ bios_intr_tab[0x10] = int10;
+ bios_intr_tab[0x1A] = int1A;
+ bios_intr_tab[0x42] = int42;
+ X86EMU_setupIntrFuncs(bios_intr_tab);
+}
diff --git a/board/MAI/bios_emulator/scitech/src/biosemu/biosemu.c b/board/MAI/bios_emulator/scitech/src/biosemu/biosemu.c
new file mode 100644
index 0000000000..ed2717c218
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/biosemu/biosemu.c
@@ -0,0 +1,445 @@
+/****************************************************************************
+*
+* BIOS emulator and interface
+* to Realmode X86 Emulator Library
+*
+* Copyright (C) 1996-1999 SciTech Software, Inc.
+*
+* ========================================================================
+*
+* 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.
+*
+* ========================================================================
+*
+* Language: ANSI C
+* Environment: Any
+* Developer: Kendall Bennett
+*
+* Description: Module implementing the system specific functions. This
+* module is always compiled and linked in the OS depedent
+* libraries, and never in a binary portable driver.
+*
+****************************************************************************/
+
+#include "biosemui.h"
+#include <string.h>
+#include <stdlib.h>
+
+/*------------------------- Global Variables ------------------------------*/
+
+BE_sysEnv _BE_env;
+#ifdef __DRIVER__
+PM_imports _VARAPI _PM_imports;
+#endif
+static X86EMU_memFuncs _BE_mem = {
+ BE_rdb,
+ BE_rdw,
+ BE_rdl,
+ BE_wrb,
+ BE_wrw,
+ BE_wrl,
+ };
+#ifdef DEBUG
+static X86EMU_pioFuncs _BE_pio = {
+ BE_inb,
+ BE_inw,
+ BE_inl,
+ BE_outb,
+ BE_outw,
+ BE_outl,
+ };
+#else
+static X86EMU_pioFuncs _BE_pio = {
+ (void*)PM_inpb,
+ (void*)PM_inpw,
+ (void*)PM_inpd,
+ (void*)PM_outpb,
+ (void*)PM_outpw,
+ (void*)PM_outpd,
+ };
+#endif
+
+/*-------------------------- Implementation -------------------------------*/
+
+#define OFF(addr) (u16)(((addr) >> 0) & 0xffff)
+#define SEG(addr) (u16)(((addr) >> 4) & 0xf000)
+
+/****************************************************************************
+PARAMETERS:
+debugFlags - Flags to enable debugging options (debug builds only)
+memSize - Amount of memory to allocate for real mode machine
+info - Pointer to default VGA device information
+
+REMARKS:
+This functions initialises the BElib, and uses the passed in
+BIOS image as the BIOS that is used and emulated at 0xC0000.
+****************************************************************************/
+ibool PMAPI BE_init(
+ u32 debugFlags,
+ int memSize,
+ BE_VGAInfo *info)
+{
+#ifndef __DRIVER__
+ PM_init();
+#endif
+ memset(&M,0,sizeof(M));
+ if (memSize < 20480)
+ PM_fatalError("Emulator requires at least 20Kb of memory!\n");
+ if ((M.mem_base = (unsigned long)malloc(memSize)) == NULL)
+ PM_fatalError("Out of memory!");
+ M.mem_size = memSize;
+ _BE_env.busmem_base = (ulong)PM_mapPhysicalAddr(0xA0000,0x5FFFF,true);
+ M.x86.debug = debugFlags;
+ _BE_bios_init((u32*)info->LowMem);
+ X86EMU_setupMemFuncs(&_BE_mem);
+ X86EMU_setupPioFuncs(&_BE_pio);
+ BE_setVGA(info);
+ return true;
+}
+
+/****************************************************************************
+PARAMETERS:
+debugFlags - Flags to enable debugging options (debug builds only)
+
+REMARKS:
+This function allows the application to enable logging and debug flags
+on a function call basis, so we can specifically enable logging only
+for specific functions that are causing problems in debug mode.
+****************************************************************************/
+void PMAPI BE_setDebugFlags(
+ u32 debugFlags)
+{
+ M.x86.debug = debugFlags;
+}
+
+/****************************************************************************
+PARAMETERS:
+info - Pointer to VGA device information to make current
+
+REMARKS:
+This function sets the VGA BIOS functions in the emulator to point to the
+specific VGA BIOS in use. This includes swapping the BIOS interrupt
+vectors, BIOS image and BIOS data area to the new BIOS. This allows the
+real mode BIOS to be swapped without resetting the entire emulator.
+****************************************************************************/
+void PMAPI BE_setVGA(
+ BE_VGAInfo *info)
+{
+ _BE_env.vgaInfo.pciInfo = info->pciInfo;
+ _BE_env.vgaInfo.BIOSImage = info->BIOSImage;
+ if (info->BIOSImage) {
+ _BE_env.biosmem_base = (ulong)info->BIOSImage;
+ _BE_env.biosmem_limit = 0xC0000 + info->BIOSImageLen-1;
+ }
+ else {
+ _BE_env.biosmem_base = _BE_env.busmem_base + 0x20000;
+ _BE_env.biosmem_limit = 0xC7FFF;
+ }
+ if (*((u32*)info->LowMem) == 0)
+ _BE_bios_init((u32*)info->LowMem);
+ memcpy((u8*)M.mem_base,info->LowMem,sizeof(info->LowMem));
+}
+
+/****************************************************************************
+PARAMETERS:
+info - Pointer to VGA device information to retrieve current
+
+REMARKS:
+This function returns the VGA BIOS functions currently active in the
+emulator, so they can be restored at a later date.
+****************************************************************************/
+void PMAPI BE_getVGA(
+ BE_VGAInfo *info)
+{
+ info->pciInfo = _BE_env.vgaInfo.pciInfo;
+ info->BIOSImage = _BE_env.vgaInfo.BIOSImage;
+ memcpy(info->LowMem,(u8*)M.mem_base,sizeof(info->LowMem));
+}
+
+/****************************************************************************
+PARAMETERS:
+r_seg - Segment for pointer to convert
+r_off - Offset for pointer to convert
+
+REMARKS:
+This function maps a real mode pointer in the emulator memory to a protected
+mode pointer that can be used to directly access the memory.
+
+NOTE: The memory is *always* in little endian format, son on non-x86
+ systems you will need to do endian translations to access this
+ memory.
+****************************************************************************/
+void * PMAPI BE_mapRealPointer(
+ uint r_seg,
+ uint r_off)
+{
+ u32 addr = ((u32)r_seg << 4) + r_off;
+
+ if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
+ return (void*)(_BE_env.biosmem_base + addr - 0xC0000);
+ }
+ else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
+ return (void*)(_BE_env.busmem_base + addr - 0xA0000);
+ }
+ return (void*)(M.mem_base + addr);
+}
+
+/****************************************************************************
+PARAMETERS:
+len - Return the length of the VESA buffer
+rseg - Place to store VESA buffer segment
+roff - Place to store VESA buffer offset
+
+REMARKS:
+This function returns the address of the VESA transfer buffer in real
+mode emulator memory. The VESA transfer buffer is always 1024 bytes long,
+and located at 15Kb into the start of the real mode memory (16Kb is where
+we put the real mode code we execute for issuing interrupts).
+
+NOTE: The memory is *always* in little endian format, son on non-x86
+ systems you will need to do endian translations to access this
+ memory.
+****************************************************************************/
+void * PMAPI BE_getVESABuf(
+ uint *len,
+ uint *rseg,
+ uint *roff)
+{
+ *len = 1024;
+ *rseg = SEG(0x03C00);
+ *roff = OFF(0x03C00);
+ return (void*)(M.mem_base + ((u32)*rseg << 4) + *roff);
+}
+
+/****************************************************************************
+REMARKS:
+Cleans up and exits the emulator.
+****************************************************************************/
+void PMAPI BE_exit(void)
+{
+ free((void*)M.mem_base);
+ PM_freePhysicalAddr((void*)_BE_env.busmem_base,0x5FFFF);
+}
+
+/****************************************************************************
+PARAMETERS:
+seg - Segment of code to call
+off - Offset of code to call
+regs - Real mode registers to load
+sregs - Real mode segment registers to load
+
+REMARKS:
+This functions calls a real mode far function at the specified address,
+and loads all the x86 registers from the passed in registers structure.
+On exit the registers returned from the call are returned in the same
+structures.
+****************************************************************************/
+void PMAPI BE_callRealMode(
+ uint seg,
+ uint off,
+ RMREGS *regs,
+ RMSREGS *sregs)
+{
+ M.x86.R_EAX = regs->e.eax;
+ M.x86.R_EBX = regs->e.ebx;
+ M.x86.R_ECX = regs->e.ecx;
+ M.x86.R_EDX = regs->e.edx;
+ M.x86.R_ESI = regs->e.esi;
+ M.x86.R_EDI = regs->e.edi;
+ M.x86.R_DS = sregs->ds;
+ M.x86.R_ES = sregs->es;
+ M.x86.R_FS = sregs->fs;
+ M.x86.R_GS = sregs->gs;
+ M.x86.R_CS = (u16)seg;
+ M.x86.R_IP = (u16)off;
+ M.x86.R_SS = SEG(M.mem_size - 1);
+ M.x86.R_SP = OFF(M.mem_size - 1);
+ X86EMU_exec();
+ regs->e.cflag = M.x86.R_EFLG & F_CF;
+ regs->e.eax = M.x86.R_EAX;
+ regs->e.ebx = M.x86.R_EBX;
+ regs->e.ecx = M.x86.R_ECX;
+ regs->e.edx = M.x86.R_EDX;
+ regs->e.esi = M.x86.R_ESI;
+ regs->e.edi = M.x86.R_EDI;
+ sregs->ds = M.x86.R_DS;
+ sregs->es = M.x86.R_ES;
+ sregs->fs = M.x86.R_FS;
+ sregs->gs = M.x86.R_GS;
+}
+
+/****************************************************************************
+PARAMETERS:
+intno - Interrupt number to execute
+in - Real mode registers to load
+out - Place to store resulting real mode registers
+
+REMARKS:
+This functions calls a real mode interrupt function at the specified address,
+and loads all the x86 registers from the passed in registers structure.
+On exit the registers returned from the call are returned in out stucture.
+****************************************************************************/
+int PMAPI BE_int86(
+ int intno,
+ RMREGS *in,
+ RMREGS *out)
+{
+ M.x86.R_EAX = in->e.eax;
+ M.x86.R_EBX = in->e.ebx;
+ M.x86.R_ECX = in->e.ecx;
+ M.x86.R_EDX = in->e.edx;
+ M.x86.R_ESI = in->e.esi;
+ M.x86.R_EDI = in->e.edi;
+ ((u8*)M.mem_base)[0x4000] = 0xCD;
+ ((u8*)M.mem_base)[0x4001] = (u8)intno;
+ ((u8*)M.mem_base)[0x4002] = 0xC3;
+ M.x86.R_CS = SEG(0x04000);
+ M.x86.R_IP = OFF(0x04000);
+ M.x86.R_SS = SEG(M.mem_size - 1);
+ M.x86.R_SP = OFF(M.mem_size - 1);
+ X86EMU_exec();
+ out->e.cflag = M.x86.R_EFLG & F_CF;
+ out->e.eax = M.x86.R_EAX;
+ out->e.ebx = M.x86.R_EBX;
+ out->e.ecx = M.x86.R_ECX;
+ out->e.edx = M.x86.R_EDX;
+ out->e.esi = M.x86.R_ESI;
+ out->e.edi = M.x86.R_EDI;
+ return out->x.ax;
+}
+
+/****************************************************************************
+PARAMETERS:
+intno - Interrupt number to execute
+in - Real mode registers to load
+out - Place to store resulting real mode registers
+sregs - Real mode segment registers to load
+
+REMARKS:
+This functions calls a real mode interrupt function at the specified address,
+and loads all the x86 registers from the passed in registers structure.
+On exit the registers returned from the call are returned in out stucture.
+****************************************************************************/
+int PMAPI BE_int86x(
+ int intno,
+ RMREGS *in,
+ RMREGS *out,
+ RMSREGS *sregs)
+{
+ M.x86.R_EAX = in->e.eax;
+ M.x86.R_EBX = in->e.ebx;
+ M.x86.R_ECX = in->e.ecx;
+ M.x86.R_EDX = in->e.edx;
+ M.x86.R_ESI = in->e.esi;
+ M.x86.R_EDI = in->e.edi;
+ M.x86.R_DS = sregs->ds;
+ M.x86.R_ES = sregs->es;
+ M.x86.R_FS = sregs->fs;
+ M.x86.R_GS = sregs->gs;
+ ((u8*)M.mem_base)[0x4000] = 0xCD;
+ ((u8*)M.mem_base)[0x4001] = (u8)intno;
+ ((u8*)M.mem_base)[0x4002] = 0xC3;
+ M.x86.R_CS = SEG(0x04000);
+ M.x86.R_IP = OFF(0x04000);
+ M.x86.R_SS = SEG(M.mem_size - 1);
+ M.x86.R_SP = OFF(M.mem_size - 1);
+ X86EMU_exec();
+ out->e.cflag = M.x86.R_EFLG & F_CF;
+ out->e.eax = M.x86.R_EAX;
+ out->e.ebx = M.x86.R_EBX;
+ out->e.ecx = M.x86.R_ECX;
+ out->e.edx = M.x86.R_EDX;
+ out->e.esi = M.x86.R_ESI;
+ out->e.edi = M.x86.R_EDI;
+ sregs->ds = M.x86.R_DS;
+ sregs->es = M.x86.R_ES;
+ sregs->fs = M.x86.R_FS;
+ sregs->gs = M.x86.R_GS;
+ return out->x.ax;
+}
+
+#ifdef __DRIVER__
+
+/****************************************************************************
+REMARKS:
+Empty log function for binary portable DLL. The BPD is compiled without
+debug information, so very little is logged anyway so it is simpler this
+way.
+****************************************************************************/
+void printk(const char *msg, ...)
+{
+}
+
+/****************************************************************************
+REMARKS:
+Fatal error handler called when a non-imported function is called by the
+driver. We leave this to a runtime error so that older applications and
+shell drivers will work with newer bpd drivers provided no newer functions
+are required by the driver itself. If they are, the application or shell
+driver needs to be recompiled.
+****************************************************************************/
+static void _PM_fatalErrorHandler(void)
+{
+ PM_fatalError("Unsupported PM_imports import function called! Please re-compile!\n");
+}
+
+/****************************************************************************
+PARAMETERS:
+beImp - BE library imports
+beImp - Generic emulator imports
+
+RETURNS:
+Pointer to exported function list
+
+REMARKS:
+This function initialises the BIOS emulator library and returns the list of
+loader library exported functions.
+{secret}
+****************************************************************************/
+BE_exports * _CEXPORT BE_initLibrary(
+ PM_imports *pmImp)
+{
+ static BE_exports _BE_exports = {
+ sizeof(BE_exports),
+ BE_init,
+ BE_setVGA,
+ BE_getVGA,
+ BE_mapRealPointer,
+ BE_getVESABuf,
+ BE_callRealMode,
+ BE_int86,
+ BE_int86x,
+ NULL,
+ BE_exit,
+ };
+ int i,max;
+ ulong *p;
+
+ // Initialize all default imports to point to fatal error handler
+ // for upwards compatibility.
+ max = sizeof(_PM_imports)/sizeof(BE_initLibrary_t);
+ for (i = 0,p = (ulong*)&_PM_imports; i < max; i++)
+ *p++ = (ulong)_PM_fatalErrorHandler;
+
+ // Now copy all our imported functions
+ memcpy(&_PM_imports,pmImp,MIN(sizeof(_PM_imports),pmImp->dwSize));
+ return &_BE_exports;
+}
+
+#endif /* __DRIVER__ */
diff --git a/board/MAI/bios_emulator/scitech/src/biosemu/biosemui.h b/board/MAI/bios_emulator/scitech/src/biosemu/biosemui.h
new file mode 100644
index 0000000000..23edebc95c
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/biosemu/biosemui.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+*
+* BIOS emulator and interface
+* to Realmode X86 Emulator Library
+*
+* Copyright (C) 1996-1999 SciTech Software, Inc.
+*
+* ========================================================================
+*
+* 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.
+*
+* ========================================================================
+*
+* Language: ANSI C
+* Environment: Any
+* Developer: Kendall Bennett
+*
+* Description: Internal header file for the BIOS emulator library.
+*
+****************************************************************************/
+
+#ifndef __BIOSEMUI_H
+#define __BIOSEMUI_H
+
+#include <biosemu.h>
+
+/*---------------------- Macros and type definitions ----------------------*/
+
+#ifdef DEBUG
+#define DB(x) x
+#else
+#define DB(x)
+#endif
+
+#define BIOS_SEG 0xfff0
+
+#define M _X86EMU_env
+
+/*-------------------------- Function Prototypes --------------------------*/
+
+/* bios.c */
+
+void _BE_bios_init(u32 *intrTab);
+void _BE_setup_funcs(void);
+
+/* besys.c */
+
+u8 X86API BE_rdb(u32 addr);
+u16 X86API BE_rdw(u32 addr);
+u32 X86API BE_rdl(u32 addr);
+void X86API BE_wrb(u32 addr,u8 val);
+void X86API BE_wrw(u32 addr,u16 val);
+void X86API BE_wrl(u32 addr,u32 val);
+#ifdef DEBUG
+u8 X86API BE_inb(int port);
+u16 X86API BE_inw(int port);
+u32 X86API BE_inl(int port);
+void X86API BE_outb(int port, u8 val);
+void X86API BE_outw(int port, u16 val);
+void X86API BE_outl(int port, u32 val);
+#endif
+
+#endif /* __BIOSEMUI_H */
diff --git a/board/MAI/bios_emulator/scitech/src/biosemu/makefile b/board/MAI/bios_emulator/scitech/src/biosemu/makefile
new file mode 100644
index 0000000000..80730b2997
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/biosemu/makefile
@@ -0,0 +1,99 @@
+#############################################################################
+#
+# BIOS emulator and interface
+# to Realmode X86 Emulator Library
+#
+# Copyright (C) 1996-1999 SciTech Software, Inc.
+#
+# ========================================================================
+#
+# 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.
+#
+# ========================================================================
+#
+# Descripton: Generic makefile for the x86emu library. Requires
+# the SciTech Software makefile definitions package to be
+# installed, which uses the DMAKE make program.
+#
+#############################################################################
+
+.IMPORT .IGNORE: DEBUG
+
+#----------------------------------------------------------------------------
+# Define the lists of object files
+#----------------------------------------------------------------------------
+
+DLL_OBJS = dllstart$O _pm_imp$O
+BIOS_OBJS = biosemu$O bios$O besys$O
+X86_OBJS = sys$O decode$O ops$O ops2$O prim_ops$O fpu$O debug$O
+CFLAGS += -DSCITECH -I$(SCITECH)\src\x86emu
+
+.IF $(BUILD_DLL)
+
+CFLAGS += -I$(PRIVATE)\include\drvlib -I$(SCITECH)\include\drvlib -D__DRIVER__
+ASFLAGS += -d__DRIVER__
+EXELIBS = drvlib$L
+
+.ELSE
+
+.IF $(DEBUG)
+CFLAGS += -DDEBUG
+.ENDIF
+OBJECTS = $(BIOS_OBJS) $(X86_OBJS)
+LIBCLEAN = *.dll *.lib *.a
+LIBFILE = $(LP)biosemu$L
+
+.ENDIF
+
+#----------------------------------------------------------------------------
+# Sample test programs
+#----------------------------------------------------------------------------
+
+all: $(LIBFILE) warmboot$E
+
+warmboot$E: warmboot$O $(LIBFILE)
+
+#----------------------------------------------------------------------------
+# Target to build the Binary Portable DLL target
+#----------------------------------------------------------------------------
+
+biosemu.dll: $(DLL_OBJS) $(BIOS_OBJS) $(X86_OBJS)
+
+#----------------------------------------------------------------------------
+# Target to build all Intel binary drivers
+#----------------------------------------------------------------------------
+
+.PHONY mkdrv:
+ @build wc11-w32 biosemu.dll -u BUILD_DLL=1 NO_RUNTIME=1 OPT=1
+ @$(CP) biosemu.dll $(PRIVATE)\nucleus\graphics\biosemu.bpd
+ @dmake cleanexe
+
+.PHONY db:
+ @build wc11-w32 biosemu.dll BUILD_DLL=1 NO_RUNTIME=1 OPT=1
+ @$(CP) biosemu.dll $(PRIVATE)\nucleus\graphics\biosemu.bpd
+
+#----------------------------------------------------------------------------
+# Define the list of object files to create dependency information for
+#----------------------------------------------------------------------------
+
+DEPEND_OBJ = warmboot$O $(BIOS_OBJS) $(X86_OBJS) $(DLL_OBJS)
+DEPEND_SRC = $(SCITECH)/src/x86emu;$(PRIVATE)/src/common
+.SOURCE: $(SCITECH)/src/x86emu $(PRIVATE)/src/common
+
+.INCLUDE: "$(SCITECH)/makedefs/common.mk"
diff --git a/board/MAI/bios_emulator/scitech/src/biosemu/makefile.cross b/board/MAI/bios_emulator/scitech/src/biosemu/makefile.cross
new file mode 100644
index 0000000000..9141003076
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/biosemu/makefile.cross
@@ -0,0 +1,10 @@
+CC = ppc-elf32-gcc
+AR = ppc-elf32-ar
+
+CFLAGS = -D__DRIVER__ -I../../include -DDEBUG -I.
+
+BIOS_OBJS = biosemu.o bios.o besys.o
+X86_OBJS = sys.o decode.o ops.o prim_ops.o fpu.o debug.o
+
+libbios.a: $(BIOS_OBJS)
+ $(AR) rcs libbios.a $(BIOS_OBJS) \ No newline at end of file
diff --git a/board/MAI/bios_emulator/scitech/src/biosemu/warmboot.c b/board/MAI/bios_emulator/scitech/src/biosemu/warmboot.c
new file mode 100644
index 0000000000..96fa5a0e0f
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/biosemu/warmboot.c
@@ -0,0 +1,569 @@
+/****************************************************************************
+*
+* BIOS emulator and interface
+* to Realmode X86 Emulator Library
+*
+* Copyright (C) 1996-1999 SciTech Software, Inc.
+*
+* ========================================================================
+*
+* 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.
+*
+* ========================================================================
+*
+* Language: ANSI C
+* Environment: Any
+* Developer: Kendall Bennett
+*
+* Description: Module to implement warm booting of all PCI/AGP controllers
+* on the bus. We use the x86 real mode emulator to run the
+* BIOS on the primary and secondary controllers to bring
+* the cards up.
+*
+****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "biosemu.h"
+#ifndef _MAX_PATH
+#define _MAX_PATH 256
+#endif
+
+/*------------------------- Global Variables ------------------------------*/
+
+static PCIDeviceInfo PCI[MAX_PCI_DEVICES];
+static int NumPCI = -1;
+static int BridgeIndex[MAX_PCI_DEVICES] = {0};
+static int NumBridges;
+static PCIBridgeInfo *AGPBridge = NULL;
+static int DeviceIndex[MAX_PCI_DEVICES] = {0};
+static int NumDevices;
+static u32 debugFlags = 0;
+static BE_VGAInfo VGAInfo[MAX_PCI_DEVICES] = {{0}};
+static ibool useV86 = false;
+static ibool forcePost = false;
+
+/* Length of the BIOS image */
+
+#define MAX_BIOSLEN (64 * 1024L)
+#define FINAL_BIOSLEN (32 * 1024L)
+
+/* Macro to determine if the VGA is enabled and responding */
+
+#define VGA_NOT_ACTIVE() (forcePost || (PM_inpb(0x3CC) == 0xFF) || ((PM_inpb(0x3CC) & 0x2) == 0))
+
+#define ENABLE_DEVICE(device) \
+ PCI_writePCIRegB(0x4,PCI[DeviceIndex[device]].Command | 0x7,device)
+
+#define DISABLE_DEVICE(device) \
+ PCI_writePCIRegB(0x4,0,device)
+
+/* Macros to enable and disable AGP VGA resources */
+
+#define ENABLE_AGP_VGA() \
+ PCI_accessReg(0x3E,AGPBridge->BridgeControl | 0x8,PCI_WRITE_WORD,(PCIDeviceInfo*)AGPBridge)
+
+#define DISABLE_AGP_VGA() \
+ PCI_accessReg(0x3E,AGPBridge->BridgeControl & ~0x8,PCI_WRITE_WORD,(PCIDeviceInfo*)AGPBridge)
+
+#define RESTORE_AGP_VGA() \
+ PCI_accessReg(0x3E,AGPBridge->BridgeControl,PCI_WRITE_WORD,(PCIDeviceInfo*)AGPBridge)
+
+/*-------------------------- Implementation -------------------------------*/
+
+/****************************************************************************
+RETURNS:
+The address to use to map the secondary BIOS (PCI/AGP devices)
+
+REMARKS:
+Searches all the PCI base address registers for the device looking for a
+memory mapping that is large enough to hold our ROM BIOS. We usually end up
+finding the framebuffer mapping (usually BAR 0x10), and we use this mapping
+to map the BIOS for the device into. We use a mapping that is already
+assigned to the device to ensure the memory range will be passed through
+by any PCI->PCI or AGP->PCI bridge that may be present.
+
+NOTE: Usually this function is only used for AGP devices, but it may be
+ used for PCI devices that have already been POST'ed and the BIOS
+ ROM base address has been zero'ed out.
+****************************************************************************/
+static ulong PCI_findBIOSAddr(
+ int device)
+{
+ ulong base,size;
+ int bar;
+
+ for (bar = 0x10; bar <= 0x14; bar++) {
+ base = PCI_readPCIRegL(bar,device) & ~0xFF;
+ if (!(base & 0x1)) {
+ PCI_writePCIRegL(bar,0xFFFFFFFF,device);
+ size = PCI_readPCIRegL(bar,device) & ~0xFF;
+ size = ~size+1;
+ PCI_writePCIRegL(bar,0,device);
+ if (size >= MAX_BIOSLEN)
+ return base;
+ }
+ }
+ return 0;
+}
+
+/****************************************************************************
+REMARKS:
+Re-writes the PCI base address registers for the secondary PCI controller
+with the values from our initial PCI bus enumeration. This fixes up the
+values after we have POST'ed the secondary display controller BIOS, which
+may have incorrectly re-programmed the base registers the same as the
+primary display controller (the case for identical S3 cards).
+****************************************************************************/
+static void _PCI_fixupSecondaryBARs(void)
+{
+ int i;
+
+ for (i = 0; i < NumDevices; i++) {
+ PCI_writePCIRegL(0x10,PCI[DeviceIndex[i]].BaseAddress10,i);
+ PCI_writePCIRegL(0x14,PCI[DeviceIndex[i]].BaseAddress14,i);
+ PCI_writePCIRegL(0x18,PCI[DeviceIndex[i]].BaseAddress18,i);
+ PCI_writePCIRegL(0x1C,PCI[DeviceIndex[i]].BaseAddress1C,i);
+ PCI_writePCIRegL(0x20,PCI[DeviceIndex[i]].BaseAddress20,i);
+ PCI_writePCIRegL(0x24,PCI[DeviceIndex[i]].BaseAddress24,i);
+ }
+}
+
+/****************************************************************************
+RETURNS:
+True if successfully initialised, false if not.
+
+REMARKS:
+This function executes the BIOS POST code on the controller. We assume that
+at this stage the controller has its I/O and memory space enabled and
+that all other controllers are in a disabled state.
+****************************************************************************/
+static void PCI_doBIOSPOST(
+ int device,
+ ulong BIOSPhysAddr,
+ void *mappedBIOS,
+ ulong BIOSLen)
+{
+ RMREGS regs;
+ RMSREGS sregs;
+
+ // Determine the value to store in AX for BIOS POST
+ regs.x.ax = (u16)(PCI[DeviceIndex[device]].slot.i >> 8);
+ if (useV86) {
+ // Post the BIOS using the PM functions (ie: v86 mode on Linux)
+ if (!PM_doBIOSPOST(regs.x.ax,BIOSPhysAddr,mappedBIOS,BIOSLen)) {
+ // If the PM function fails, this probably means are we are on
+ // DOS and can't re-map the real mode 0xC0000 region. In thise
+ // case if the device is the primary, we can use the real
+ // BIOS at 0xC0000 directly.
+ if (device == 0)
+ PM_doBIOSPOST(regs.x.ax,0xC0000,mappedBIOS,BIOSLen);
+ }
+ }
+ else {
+ // Setup the X86 emulator for the VGA BIOS
+ BE_setVGA(&VGAInfo[device]);
+
+ // Execute the BIOS POST code
+ BE_callRealMode(0xC000,0x0003,&regs,&sregs);
+
+ // Cleanup and exit
+ BE_getVGA(&VGAInfo[device]);
+ }
+}
+
+/****************************************************************************
+RETURNS:
+True if successfully initialised, false if not.
+
+REMARKS:
+Loads and POST's the secondary controllers BIOS, directly from the BIOS
+image we can extract over the PCI bus.
+****************************************************************************/
+static ibool PCI_postControllers(void)
+{
+ int device;
+ ulong BIOSImageLen,mappedBIOSPhys;
+ uchar *mappedBIOS,*copyOfBIOS;
+ char filename[_MAX_PATH];
+ FILE *f;
+
+ // Disable the primary display controller and AGP VGA pass-through
+ DISABLE_DEVICE(0);
+ if (AGPBridge)
+ DISABLE_AGP_VGA();
+
+ // Now POST all the secondary controllers
+ for (device = 0; device < NumDevices; device++) {
+ // Skip the device if it is not enabled (probably an ISA device)
+ if (DeviceIndex[device] == -1)
+ continue;
+
+ // Enable secondary display controller. If the secondary controller
+ // is on the AGP bus, then enable VGA resources for the AGP device.
+ ENABLE_DEVICE(device);
+ if (AGPBridge && AGPBridge->SecondayBusNumber == PCI[DeviceIndex[device]].slot.p.Bus)
+ ENABLE_AGP_VGA();
+
+ // Check if the controller has already been POST'ed
+ if (VGA_NOT_ACTIVE()) {
+ // Find a viable place to map the secondary PCI BIOS image and map it
+ printk("Device %d not enabled, so attempting warm boot it\n", device);
+
+ // For AGP devices (and PCI devices that do have the ROM base
+ // address zero'ed out) we have to map the BIOS to a location
+ // that is passed by the AGP bridge to the bus. Some AGP devices
+ // have the ROM base address already set up for us, and some
+ // do not (we map to one of the existing BAR locations in
+ // this case).
+ mappedBIOS = NULL;
+ if (PCI[DeviceIndex[device]].ROMBaseAddress != 0)
+ mappedBIOSPhys = PCI[DeviceIndex[device]].ROMBaseAddress & ~0xF;
+ else
+ mappedBIOSPhys = PCI_findBIOSAddr(device);
+ printk("Mapping BIOS image to 0x%08X\n", mappedBIOSPhys);
+ mappedBIOS = PM_mapPhysicalAddr(mappedBIOSPhys,MAX_BIOSLEN-1,false);
+ PCI_writePCIRegL(0x30,mappedBIOSPhys | 0x1,device);
+ BIOSImageLen = mappedBIOS[2] * 512;
+ if ((copyOfBIOS = malloc(BIOSImageLen)) == NULL)
+ return false;
+ memcpy(copyOfBIOS,mappedBIOS,BIOSImageLen);
+ PM_freePhysicalAddr(mappedBIOS,MAX_BIOSLEN-1);
+
+ // Allocate memory to store copy of BIOS from secondary controllers
+ VGAInfo[device].pciInfo = &PCI[DeviceIndex[device]];
+ VGAInfo[device].BIOSImage = copyOfBIOS;
+ VGAInfo[device].BIOSImageLen = BIOSImageLen;
+
+ // Restore device mappings
+ PCI_writePCIRegL(0x30,PCI[DeviceIndex[device]].ROMBaseAddress,device);
+ PCI_writePCIRegL(0x10,PCI[DeviceIndex[device]].BaseAddress10,device);
+ PCI_writePCIRegL(0x14,PCI[DeviceIndex[device]].BaseAddress14,device);
+
+ // Now execute the BIOS POST for the device
+ if (copyOfBIOS[0] == 0x55 && copyOfBIOS[1] == 0xAA) {
+ printk("Executing BIOS POST for controller.\n");
+ PCI_doBIOSPOST(device,mappedBIOSPhys,copyOfBIOS,BIOSImageLen);
+ }
+
+ // Reset the size of the BIOS image to the final size
+ VGAInfo[device].BIOSImageLen = FINAL_BIOSLEN;
+
+ // Save the BIOS and interrupt vector information to disk
+ sprintf(filename,"%s/bios.%02d",PM_getNucleusConfigPath(),device);
+ if ((f = fopen(filename,"wb")) != NULL) {
+ fwrite(copyOfBIOS,1,FINAL_BIOSLEN,f);
+ fwrite(VGAInfo[device].LowMem,1,sizeof(VGAInfo[device].LowMem),f);
+ fclose(f);
+ }
+ }
+ else {
+ // Allocate memory to store copy of BIOS from secondary controllers
+ if ((copyOfBIOS = malloc(FINAL_BIOSLEN)) == NULL)
+ return false;
+ VGAInfo[device].pciInfo = &PCI[DeviceIndex[device]];
+ VGAInfo[device].BIOSImage = copyOfBIOS;
+ VGAInfo[device].BIOSImageLen = FINAL_BIOSLEN;
+
+ // Load the BIOS and interrupt vector information from disk
+ sprintf(filename,"%s/bios.%02d",PM_getNucleusConfigPath(),device);
+ if ((f = fopen(filename,"rb")) != NULL) {
+ fread(copyOfBIOS,1,FINAL_BIOSLEN,f);
+ fread(VGAInfo[device].LowMem,1,sizeof(VGAInfo[device].LowMem),f);
+ fclose(f);
+ }
+ }
+
+ // Fix up all the secondary PCI base address registers
+ // (restores them all from the values we read previously)
+ _PCI_fixupSecondaryBARs();
+
+ // Disable the secondary controller and AGP VGA pass-through
+ DISABLE_DEVICE(device);
+ if (AGPBridge)
+ DISABLE_AGP_VGA();
+ }
+
+ // Reenable primary display controller and reset AGP bridge control
+ if (AGPBridge)
+ RESTORE_AGP_VGA();
+ ENABLE_DEVICE(0);
+
+ // Free physical BIOS image mapping
+ PM_freePhysicalAddr(mappedBIOS,MAX_BIOSLEN-1);
+
+ // Restore the X86 emulator BIOS info to primary controller
+ if (!useV86)
+ BE_setVGA(&VGAInfo[0]);
+ return true;
+}
+
+/****************************************************************************
+REMARKS:
+Enumerates the PCI bus and dumps the PCI configuration information to the
+log file.
+****************************************************************************/
+static void EnumeratePCI(void)
+{
+ int i,index;
+ PCIBridgeInfo *info;
+
+ printk("Displaying enumeration of PCI bus (%d devices, %d display devices)\n",
+ NumPCI, NumDevices);
+ for (index = 0; index < NumDevices; index++)
+ printk(" Display device %d is PCI device %d\n",index,DeviceIndex[index]);
+ printk("\n");
+ printk("Bus Slot Fnc DeviceID SubSystem Rev Class IRQ Int Cmd\n");
+ for (i = 0; i < NumPCI; i++) {
+ printk("%2d %2d %2d %04X:%04X %04X:%04X %02X %02X:%02X %02X %02X %04X ",
+ PCI[i].slot.p.Bus,
+ PCI[i].slot.p.Device,
+ PCI[i].slot.p.Function,
+ PCI[i].VendorID,
+ PCI[i].DeviceID,
+ PCI[i].SubSystemVendorID,
+ PCI[i].SubSystemID,
+ PCI[i].RevID,
+ PCI[i].BaseClass,
+ PCI[i].SubClass,
+ PCI[i].InterruptLine,
+ PCI[i].InterruptPin,
+ PCI[i].Command);
+ for (index = 0; index < NumDevices; index++) {
+ if (DeviceIndex[index] == i)
+ break;
+ }
+ if (index < NumDevices)
+ printk("<- %d\n", index);
+ else
+ printk("\n");
+ }
+ printk("\n");
+ printk("DeviceID Stat Ifc Cch Lat Hdr BIST\n");
+ for (i = 0; i < NumPCI; i++) {
+ printk("%04X:%04X %04X %02X %02X %02X %02X %02X ",
+ PCI[i].VendorID,
+ PCI[i].DeviceID,
+ PCI[i].Status,
+ PCI[i].Interface,
+ PCI[i].CacheLineSize,
+ PCI[i].LatencyTimer,
+ PCI[i].HeaderType,
+ PCI[i].BIST);
+ for (index = 0; index < NumDevices; index++) {
+ if (DeviceIndex[index] == i)
+ break;
+ }
+ if (index < NumDevices)
+ printk("<- %d\n", index);
+ else
+ printk("\n");
+ }
+ printk("\n");
+ printk("DeviceID Base10h Base14h Base18h Base1Ch Base20h Base24h ROMBase\n");
+ for (i = 0; i < NumPCI; i++) {
+ printk("%04X:%04X %08X %08X %08X %08X %08X %08X %08X ",
+ PCI[i].VendorID,
+ PCI[i].DeviceID,
+ PCI[i].BaseAddress10,
+ PCI[i].BaseAddress14,
+ PCI[i].BaseAddress18,
+ PCI[i].BaseAddress1C,
+ PCI[i].BaseAddress20,
+ PCI[i].BaseAddress24,
+ PCI[i].ROMBaseAddress);
+ for (index = 0; index < NumDevices; index++) {
+ if (DeviceIndex[index] == i)
+ break;
+ }
+ if (index < NumDevices)
+ printk("<- %d\n", index);
+ else
+ printk("\n");
+ }
+ printk("\n");
+ printk("DeviceID BAR10Len BAR14Len BAR18Len BAR1CLen BAR20Len BAR24Len ROMLen\n");
+ for (i = 0; i < NumPCI; i++) {
+ printk("%04X:%04X %08X %08X %08X %08X %08X %08X %08X ",
+ PCI[i].VendorID,
+ PCI[i].DeviceID,
+ PCI[i].BaseAddress10Len,
+ PCI[i].BaseAddress14Len,
+ PCI[i].BaseAddress18Len,
+ PCI[i].BaseAddress1CLen,
+ PCI[i].BaseAddress20Len,
+ PCI[i].BaseAddress24Len,
+ PCI[i].ROMBaseAddressLen);
+ for (index = 0; index < NumDevices; index++) {
+ if (DeviceIndex[index] == i)
+ break;
+ }
+ if (index < NumDevices)
+ printk("<- %d\n", index);
+ else
+ printk("\n");
+ }
+ printk("\n");
+ printk("Displaying enumeration of %d bridge devices\n",NumBridges);
+ printk("\n");
+ printk("DeviceID P# S# B# IOB IOL MemBase MemLimit PreBase PreLimit Ctrl\n");
+ for (i = 0; i < NumBridges; i++) {
+ info = (PCIBridgeInfo*)&PCI[BridgeIndex[i]];
+ printk("%04X:%04X %02X %02X %02X %04X %04X %08X %08X %08X %08X %04X\n",
+ info->VendorID,
+ info->DeviceID,
+ info->PrimaryBusNumber,
+ info->SecondayBusNumber,
+ info->SubordinateBusNumber,
+ ((u16)info->IOBase << 8) & 0xF000,
+ info->IOLimit ?
+ ((u16)info->IOLimit << 8) | 0xFFF : 0,
+ ((u32)info->MemoryBase << 16) & 0xFFF00000,
+ info->MemoryLimit ?
+ ((u32)info->MemoryLimit << 16) | 0xFFFFF : 0,
+ ((u32)info->PrefetchableMemoryBase << 16) & 0xFFF00000,
+ info->PrefetchableMemoryLimit ?
+ ((u32)info->PrefetchableMemoryLimit << 16) | 0xFFFFF : 0,
+ info->BridgeControl);
+ }
+ printk("\n");
+}
+
+/****************************************************************************
+RETURNS:
+Number of display devices found.
+
+REMARKS:
+This function enumerates the number of available display devices on the
+PCI bus, and returns the number found.
+****************************************************************************/
+static int PCI_enumerateDevices(void)
+{
+ int i,j;
+ PCIBridgeInfo *info;
+
+ // If this is the first time we have been called, enumerate all
+ // devices on the PCI bus.
+ if (NumPCI == -1) {
+ for (i = 0; i < MAX_PCI_DEVICES; i++)
+ PCI[i].dwSize = sizeof(PCI[i]);
+ if ((NumPCI = PCI_enumerate(PCI,MAX_PCI_DEVICES)) == 0)
+ return -1;
+
+ // Build a list of all PCI bridge devices
+ for (i = 0,NumBridges = 0,BridgeIndex[0] = -1; i < NumPCI; i++) {
+ if (PCI[i].BaseClass == PCI_BRIDGE_CLASS) {
+ if (NumBridges < MAX_PCI_DEVICES)
+ BridgeIndex[NumBridges++] = i;
+ }
+ }
+
+ // Now build a list of all display class devices
+ for (i = 0,NumDevices = 1,DeviceIndex[0] = -1; i < NumPCI; i++) {
+ if (PCI_IS_DISPLAY_CLASS(&PCI[i])) {
+ if ((PCI[i].Command & 0x3) == 0x3) {
+ DeviceIndex[0] = i;
+ }
+ else {
+ if (NumDevices < MAX_PCI_DEVICES)
+ DeviceIndex[NumDevices++] = i;
+ }
+ if (PCI[i].slot.p.Bus != 0) {
+ // This device is on a different bus than the primary
+ // PCI bus, so it is probably an AGP device. Find the
+ // AGP bus device that controls that bus so we can
+ // control it.
+ for (j = 0; j < NumBridges; j++) {
+ info = (PCIBridgeInfo*)&PCI[BridgeIndex[j]];
+ if (info->SecondayBusNumber == PCI[i].slot.p.Bus) {
+ AGPBridge = info;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Enumerate all PCI and bridge devices to log file
+ EnumeratePCI();
+ }
+ return NumDevices;
+}
+
+FILE *logfile;
+
+void printk(const char *fmt, ...)
+{
+ va_list argptr;
+ va_start(argptr, fmt);
+ vfprintf(logfile, fmt, argptr);
+ fflush(logfile);
+ va_end(argptr);
+}
+
+int main(int argc,char *argv[])
+{
+ while (argc > 1) {
+ if (stricmp(argv[1],"-usev86") == 0) {
+ useV86 = true;
+ }
+ else if (stricmp(argv[1],"-force") == 0) {
+ forcePost = true;
+ }
+#ifdef DEBUG
+ else if (stricmp(argv[1],"-decode") == 0) {
+ debugFlags |= DEBUG_DECODE_F;
+ }
+ else if (stricmp(argv[1],"-iotrace") == 0) {
+ debugFlags |= DEBUG_IO_TRACE_F;
+ }
+#endif
+ else {
+ printf("Usage: warmboot [-usev86] [-force] [-decode] [-iotrace]\n");
+ exit(-1);
+ }
+ argc--;
+ argv++;
+ }
+ if ((logfile = fopen("warmboot.log","w")) == NULL)
+ exit(1);
+
+ PM_init();
+ if (!useV86) {
+ // Initialise the x86 BIOS emulator
+ BE_init(false,debugFlags,65536,&VGAInfo[0]);
+ }
+
+ // Enumerate all devices (which POST's them at the same time)
+ if (PCI_enumerateDevices() < 1) {
+ printk("No PCI display devices found!\n");
+ return -1;
+ }
+
+ // Post all the display controller BIOS'es
+ PCI_postControllers();
+
+ // Cleanup and exit the emulator
+ if (!useV86)
+ BE_exit();
+ fclose(logfile);
+ return 0;
+}
OpenPOWER on IntegriCloud