summaryrefslogtreecommitdiff
path: root/board/MAI/bios_emulator/x86interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/x86interface.c')
-rw-r--r--board/MAI/bios_emulator/x86interface.c814
1 files changed, 0 insertions, 814 deletions
diff --git a/board/MAI/bios_emulator/x86interface.c b/board/MAI/bios_emulator/x86interface.c
deleted file mode 100644
index 909cb3c..0000000
--- a/board/MAI/bios_emulator/x86interface.c
+++ /dev/null
@@ -1,814 +0,0 @@
-#include "x86emu.h"
-#include "glue.h"
-
-
-/*
- * This isn't nice, but there are a lot of incompatibilities in the U-Boot and scitech include
- * files that this is the only really workable solution.
- * Might be cleaned out later.
- */
-
-#ifdef DEBUG
-#undef DEBUG
-#endif
-
-#undef IO_LOGGING
-#undef MEM_LOGGING
-
-#ifdef IO_LOGGING
-#define LOGIO(port, format, args...) if (dolog(port)) _printf(format , ## args)
-#else
-#define LOGIO(port, format, args...)
-#endif
-
-#ifdef MEM_LOGGIN
-#define LOGMEM(format, args...) _printf(format , ## args)
-#else
-#define LOGMEM(format, args...)
-#endif
-
-#ifdef DEBUG
-#define PRINTF(format, args...) _printf(format , ## args)
-#else
-#define PRINTF(format, argc...)
-#endif
-
-typedef unsigned char UBYTE;
-typedef unsigned short UWORD;
-typedef unsigned long ULONG;
-
-typedef char BYTE;
-typedef short WORT;
-typedef long LONG;
-
-#define EMULATOR_MEM_SIZE (1024*1024)
-#define EMULATOR_BIOS_OFFSET 0xC0000
-#define EMULATOR_STRAP_OFFSET 0x30000
-#define EMULATOR_STACK_OFFSET 0x20000
-#define EMULATOR_LOGO_OFFSET 0x40000 /* If you change this, change the strap code, too */
-#define VIDEO_BASE (void *)0xFD0B8000
-
-extern char *getenv(char *);
-extern int tstc(void);
-extern int getc(void);
-extern unsigned char video_get_attr(void);
-
-int atoi(char *string)
-{
- int res = 0;
- while (*string>='0' && *string <='9')
- {
- res *= 10;
- res += *string-'0';
- string++;
- }
-
- return res;
-}
-
-void cons_gets(char *buffer)
-{
- int i = 0;
- char c = 0;
-
- buffer[0] = 0;
- if (getenv("x86_runthru")) return; /*FIXME: */
- while (c != 0x0D && c != 0x0A)
- {
- while (!tstc());
- c = getc();
- if (c>=32 && c < 127)
- {
- buffer[i] = c;
- i++;
- buffer[i] = 0;
- putc(c);
- }
- else
- {
- if (c == 0x08)
- {
- if (i>0) i--;
- buffer[i] = 0;
- }
- }
- }
- buffer[i] = '\n';
- buffer[i+1] = 0;
-}
-
-char *bios_date = "08/14/02";
-UBYTE model = 0xFC;
-UBYTE submodel = 0x00;
-
-static inline UBYTE read_byte(volatile UBYTE* from)
-{
- int x;
- asm volatile ("lbz %0,%1\n eieio" : "=r" (x) : "m" (*from));
- return (UBYTE)x;
-}
-
-static inline void write_byte(volatile UBYTE *to, int x)
-{
- asm volatile ("stb %1,%0\n eieio" : "=m" (*to) : "r" (x));
-}
-
-static inline UWORD read_word_little(volatile UWORD *from)
-{
- int x;
- asm volatile ("lhbrx %0,0,%1\n eieio" : "=r" (x) : "r" (from), "m" (*from));
- return (UWORD)x;
-}
-
-static inline UWORD read_word_big(volatile UWORD *from)
-{
- int x;
- asm volatile ("lhz %0,%1\n eieio" : "=r" (x) : "m" (*from));
- return (UWORD)x;
-}
-
-static inline void write_word_little(volatile UWORD *to, int x)
-{
- asm volatile ("sthbrx %1,0,%2\n eieio" : "=m" (*to) : "r" (x), "r" (to));
-}
-
-static inline void write_word_big(volatile UWORD *to, int x)
-{
- asm volatile ("sth %1,%0\n eieio" : "=m" (*to) : "r" (x));
-}
-
-static inline ULONG read_long_little(volatile ULONG *from)
-{
- unsigned long x;
- asm volatile ("lwbrx %0,0,%1\n eieio" : "=r" (x) : "r" (from), "m"(*from));
- return (ULONG)x;
-}
-
-static inline ULONG read_long_big(volatile ULONG *from)
-{
- unsigned long x;
- asm volatile ("lwz %0,%1\n eieio" : "=r" (x) : "m" (*from));
- return (ULONG)x;
-}
-
-static inline void write_long_little(volatile ULONG *to, ULONG x)
-{
- asm volatile ("stwbrx %1,0,%2\n eieio" : "=m" (*to) : "r" (x), "r" (to));
-}
-
-static inline void write_long_big(volatile ULONG *to, ULONG x)
-{
- asm volatile ("stw %1,%0\n eieio" : "=m" (*to) : "r" (x));
-}
-
-static int log_init = 0;
-static int log_do = 0;
-static int log_low = 0;
-
-int dolog(int port)
-{
- if (log_init && log_do)
- {
- if (log_low && port > 0x400) return 0;
- return 1;
- }
-
- if (!log_init)
- {
- log_init = 1;
- log_do = (getenv("x86_logio") != (char *)0);
- log_low = (getenv("x86_loglow") != (char *)0);
- if (log_do)
- {
- if (log_low && port > 0x400) return 0;
- return 1;
- }
- }
- return 0;
-}
-
-/* Converts an emulator address to a physical address. */
-/* Handles all special cases (bios date, model etc), and might need work */
-u32 memaddr(u32 addr)
-{
-/* if (addr >= 0xF0000 && addr < 0xFFFFF) printf("WARNING: Segment F access (0x%x)\n", addr); */
-/* printf("MemAddr=%p\n", addr); */
- if (addr >= 0xA0000 && addr < 0xC0000)
- return 0xFD000000 + addr;
- else if (addr >= 0xFFFF5 && addr < 0xFFFFE)
- {
- return (u32)bios_date+addr-0xFFFF5;
- }
- else if (addr == 0xFFFFE)
- return (u32)&model;
- else if (addr == 0xFFFFF)
- return (u32)&submodel;
- else if (addr >= 0x80000000)
- {
- /*printf("Warning: High memory access at 0x%x\n", addr); */
- return addr;
- }
- else
- return (u32)M.mem_base+addr;
-}
-
-u8 A1_rdb(u32 addr)
-{
- u8 a = read_byte((UBYTE *)memaddr(addr));
- LOGMEM("rdb: %x -> %x\n", addr, a);
- return a;
-}
-
-u16 A1_rdw(u32 addr)
-{
- u16 a = read_word_little((UWORD *)memaddr(addr));
- LOGMEM("rdw: %x -> %x\n", addr, a);
- return a;
-}
-
-u32 A1_rdl(u32 addr)
-{
- u32 a = read_long_little((ULONG *)memaddr(addr));
- LOGMEM("rdl: %x -> %x\n", addr, a);
- return a;
-}
-
-void A1_wrb(u32 addr, u8 val)
-{
- LOGMEM("wrb: %x <- %x\n", addr, val);
- write_byte((UBYTE *)memaddr(addr), val);
-}
-
-void A1_wrw(u32 addr, u16 val)
-{
- LOGMEM("wrw: %x <- %x\n", addr, val);
- write_word_little((UWORD *)memaddr(addr), val);
-}
-
-void A1_wrl(u32 addr, u32 val)
-{
- LOGMEM("wrl: %x <- %x\n", addr, val);
- write_long_little((ULONG *)memaddr(addr), val);
-}
-
-X86EMU_memFuncs _A1_mem =
-{
- A1_rdb,
- A1_rdw,
- A1_rdl,
- A1_wrb,
- A1_wrw,
- A1_wrl,
-};
-
-#define ARTICIAS_PCI_CFGADDR 0xfec00cf8
-#define ARTICIAS_PCI_CFGDATA 0xfee00cfc
-#define IOBASE 0xFE000000
-
-#define in_byte(from) read_byte( (UBYTE *)port_to_mem(from))
-#define in_word(from) read_word_little((UWORD *)port_to_mem(from))
-#define in_long(from) read_long_little((ULONG *)port_to_mem(from))
-#define out_byte(to, val) write_byte((UBYTE *)port_to_mem(to), val)
-#define out_word(to, val) write_word_little((UWORD *)port_to_mem(to), val)
-#define out_long(to, val) write_long_little((ULONG *)port_to_mem(to), val)
-
-u32 port_to_mem(int port)
-{
- if (port >= 0xCFC && port <= 0xCFF) return 0xFEE00000+port;
- else if (port >= 0xCF8 && port <= 0xCFB) return 0xFEC00000+port;
- else return IOBASE + port;
-}
-
-u8 A1_inb(int port)
-{
- u8 a;
- /*if (port == 0x3BA) return 0; */
- a = in_byte(port);
- LOGIO(port, "inb: %Xh -> %d (%Xh)\n", port, a, a);
- return a;
-}
-
-u16 A1_inw(int port)
-{
- u16 a = in_word(port);
- LOGIO(port, "inw: %Xh -> %d (%Xh)\n", port, a, a);
- return a;
-}
-
-u32 A1_inl(int port)
-{
- u32 a = in_long(port);
- LOGIO(port, "inl: %Xh -> %d (%Xh)\n", port, a, a);
- return a;
-}
-
-void A1_outb(int port, u8 val)
-{
- LOGIO(port, "outb: %Xh <- %d (%Xh)\n", port, val, val);
-/* if (port == 0xCF8) port = 0xCFB;
- else if (port == 0xCF9) port = 0xCFA;
- else if (port == 0xCFA) port = 0xCF9;
- else if (port == 0xCFB) port = 0xCF8;*/
- out_byte(port, val);
-}
-
-void A1_outw(int port, u16 val)
-{
- LOGIO(port, "outw: %Xh <- %d (%Xh)\n", port, val, val);
- out_word(port, val);
-}
-
-void A1_outl(int port, u32 val)
-{
- LOGIO(port, "outl: %Xh <- %d (%Xh)\n", port, val, val);
- out_long(port, val);
-}
-
-X86EMU_pioFuncs _A1_pio =
-{
- A1_inb,
- A1_inw,
- A1_inl,
- A1_outb,
- A1_outw,
- A1_outl,
-};
-
-static int reloced_ops = 0;
-
-void reloc_ops(void *reloc_addr)
-{
- extern void (*x86emu_optab[256])(u8);
- extern void (*x86emu_optab2[256])(u8);
- extern void tables_relocate(unsigned int offset);
- int i;
- unsigned long delta;
- if (reloced_ops == 1) return;
- reloced_ops = 1;
-
- delta = TEXT_BASE - (unsigned long)reloc_addr;
-
- for (i=0; i<256; i++)
- {
- x86emu_optab[i] -= delta;
- x86emu_optab2[i] -= delta;
- }
-
- _A1_mem.rdb = A1_rdb;
- _A1_mem.rdw = A1_rdw;
- _A1_mem.rdl = A1_rdl;
- _A1_mem.wrb = A1_wrb;
- _A1_mem.wrw = A1_wrw;
- _A1_mem.wrl = A1_wrl;
-
- _A1_pio.inb = A1_inb;
- _A1_pio.inw = A1_inw;
- _A1_pio.inl = A1_inl;
- _A1_pio.outb = A1_outb;
- _A1_pio.outw = A1_outw;
- _A1_pio.outl = A1_outl;
-
- tables_relocate(delta);
-
-}
-
-
-#define ANY_KEY(text) \
- printf(text); \
- while (!tstc());
-
-
-unsigned char more_strap[] = {
- 0xb4, 0x0, 0xb0, 0x2, 0xcd, 0x10,
-};
-#define MORE_STRAP_BYTES 6 /* Additional bytes of strap code */
-
-
-unsigned char *done_msg="VGA Initialized\0";
-
-int execute_bios(pci_dev_t gr_dev, void *reloc_addr)
-{
- extern void bios_init(void);
- extern void remove_init_data(void);
- extern int video_rows(void);
- extern int video_cols(void);
- extern int video_size(int, int);
- u8 *strap;
- unsigned char *logo;
- u8 cfg;
- int i;
- char c;
- char *s;
-#ifdef EASTEREGG
- int easteregg_active = 0;
-#endif
- char *pal_reset;
- u8 *fb;
- unsigned char *msg;
- unsigned char current_attr;
-
- PRINTF("Trying to remove init data\n");
- remove_init_data();
- PRINTF("Removed init data from cache, now in RAM\n");
-
- reloc_ops(reloc_addr);
- PRINTF("Attempting to run emulator on %02x:%02x:%02x\n",
- PCI_BUS(gr_dev), PCI_DEV(gr_dev), PCI_FUNC(gr_dev));
-
- /* Enable compatibility hole for emulator access to frame buffer */
- PRINTF("Enabling compatibility hole\n");
- enable_compatibility_hole();
-
- /* Allocate memory */
- /* FIXME: We shouldn't use this much memory really. */
- memset(&M, 0, sizeof(X86EMU_sysEnv));
- M.mem_base = malloc(EMULATOR_MEM_SIZE);
- M.mem_size = EMULATOR_MEM_SIZE;
-
- if (!M.mem_base)
- {
- PRINTF("Unable to allocate one megabyte for emulator\n");
- return 0;
- }
-
- if (attempt_map_rom(gr_dev, M.mem_base + EMULATOR_BIOS_OFFSET) == 0)
- {
- PRINTF("Error mapping rom. Emulation terminated\n");
- return 0;
- }
-
-#if 1 /*def DEBUG*/
- s = getenv("x86_ask_start");
- if (s)
- {
- printf("Press 'q' to skip initialization, 'd' for dry init\n'i' for i/o session");
- while (!tstc());
- c = getc();
- if (c == 'q') return 0;
- if (c == 'd')
- {
- extern void bios_set_mode(int mode);
- bios_set_mode(0x03);
- return 0;
- }
- if (c == 'i') do_inout();
- }
-
-
-#endif
-
-#ifdef EASTEREGG
-/* if (tstc())
- {
- if (getc() == 'c')
- {
- easteregg_active = 1;
- }
- }
-*/
- if (getenv("easteregg"))
- {
- easteregg_active = 1;
- }
-
- if (easteregg_active)
- {
- /* Yay! */
- setenv("x86_mode", "1");
- setenv("vga_fg_color", "11");
- setenv("vga_bg_color", "1");
- easteregg_active = 1;
- }
-#endif
-
- strap = (u8*)M.mem_base + EMULATOR_STRAP_OFFSET;
-
- {
- char *m = getenv("x86_mode");
- if (m)
- {
- more_strap[3] = atoi(m);
- if (more_strap[3] == 1) video_size(40, 25);
- else video_size(80, 25);
- }
- }
-
- /*
- * Poke the strap routine. This might need a bit of extending
- * if there is a mode switch involved, i.e. we want to int10
- * afterwards to set a different graphics mode, or alternatively
- * there might be a different start address requirement if the
- * ROM doesn't have an x86 image in its first image.
- */
-
- PRINTF("Poking strap...\n");
-
- /* FAR CALL c000:0003 */
- *strap++ = 0x9A; *strap++ = 0x03; *strap++ = 0x00;
- *strap++ = 0x00; *strap++ = 0xC0;
-
-#if 1
- /* insert additional strap code */
- for (i=0; i < MORE_STRAP_BYTES; i++)
- {
- *strap++ = more_strap[i];
- }
-#endif
- /* HALT */
- *strap++ = 0xF4;
-
- PRINTF("Setting up logo data\n");
- logo = (unsigned char *)M.mem_base + EMULATOR_LOGO_OFFSET;
- for (i=0; i<16; i++)
- {
- *logo++ = 0xFF;
- }
-
- /*
- * Setup the init parameters.
- * Per PCI specs, AH must contain the bus and AL
- * must contain the devfn, encoded as (dev<<3)|fn
- */
-
- /* Execution starts here */
- M.x86.R_CS = SEG(EMULATOR_STRAP_OFFSET);
- M.x86.R_IP = OFF(EMULATOR_STRAP_OFFSET);
-
- /* Stack at top of ram */
- M.x86.R_SS = SEG(EMULATOR_STACK_OFFSET);
- M.x86.R_SP = OFF(EMULATOR_STACK_OFFSET);
-
- /* Input parameters */
- M.x86.R_AH = PCI_BUS(gr_dev);
- M.x86.R_AL = (PCI_DEV(gr_dev)<<3) | PCI_FUNC(gr_dev);
-
- /* Set the I/O and memory access functions */
- X86EMU_setupMemFuncs(&_A1_mem);
- X86EMU_setupPioFuncs(&_A1_pio);
-
- /* Enable timer 2 */
- cfg = in_byte(0x61); /* Get Misc control */
- cfg |= 0x01; /* Enable timer 2 */
- out_byte(0x61, cfg); /* output again */
-
- /* Set up the timers */
- out_byte(0x43, 0x54);
- out_byte(0x41, 0x18);
-
- out_byte(0x43, 0x36);
- out_byte(0x40, 0x00);
- out_byte(0x40, 0x00);
-
- out_byte(0x43, 0xb6);
- out_byte(0x42, 0x31);
- out_byte(0x42, 0x13);
-
- /* Init the "BIOS". */
- bios_init();
-
- /* Video Card Reset */
- out_byte(0x3D8, 0);
- out_byte(0x3B8, 1);
- (void)in_byte(0x3BA);
- (void)in_byte(0x3DA);
- out_byte(0x3C0, 0);
- out_byte(0x61, 0xFC);
-
-#ifdef DEBUG
- s = _getenv("x86_singlestep");
- if (s && strcmp(s, "on")==0)
- {
- PRINTF("Enabling single stepping for debug\n");
- X86EMU_trace_on();
- }
-#endif
-
- /* Ready set go... */
- PRINTF("Running emulator\n");
- X86EMU_exec();
- PRINTF("Done running emulator\n");
-
-/* FIXME: Remove me */
- pal_reset = getenv("x86_palette_reset");
- if (pal_reset && strcmp(pal_reset, "on") == 0)
- {
- PRINTF("Palette reset\n");
- /*(void)in_byte(0x3da); */
- /*out_byte(0x3c0, 0); */
-
- out_byte(0x3C8, 0);
- out_byte(0x3C9, 0);
- out_byte(0x3C9, 0);
- out_byte(0x3C9, 0);
- for (i=0; i<254; i++)
- {
- out_byte(0x3C9, 63);
- out_byte(0x3C9, 63);
- out_byte(0x3C9, 63);
- }
-
- out_byte(0x3c0, 0x20);
- }
-/* FIXME: remove me */
-#ifdef EASTEREGG
- if (easteregg_active)
- {
- extern void video_easteregg(void);
- video_easteregg();
- }
-#endif
-/*
- current_attr = video_get_attr();
- fb = (u8 *)VIDEO_BASE;
- for (i=0; i<video_rows()*video_cols()*2; i+=2)
- {
- *(fb+i) = ' ';
- *(fb+i+1) = current_attr;
- }
-
- fb = (u8 *)VIDEO_BASE + (video_rows())-1*(video_cols()*2);
- for (i=0; i<video_cols(); i++)
- {
- *(fb + 2*i) = 32;
- *(fb + 2*i + 1) = 0x17;
- }
-
- msg = done_msg;
- while (*msg)
- {
- *fb = *msg;
- fb += 2;
- msg ++;
- }
-*/
-#ifdef DEBUG
- if (getenv("x86_do_inout")) do_inout();
-#endif
-
-/*FIXME: dcache_disable(); */
- return 1;
-}
-
-/* Clean up the x86 mess */
-void shutdown_bios(void)
-{
-/* disable_compatibility_hole(); */
- /* Free the memory associated */
- free(M.mem_base);
-
-}
-
-int to_int(char *buffer)
-{
- int base = 0;
- int res = 0;
-
- if (*buffer == '$')
- {
- base = 16;
- buffer++;
- }
- else base = 10;
-
- for (;;)
- {
- switch(*buffer)
- {
- case '0' ... '9':
- res *= base;
- res += *buffer - '0';
- break;
- case 'A':
- case 'a':
- res *= base;
- res += 10;
- break;
- case 'B':
- case 'b':
- res *= base;
- res += 11;
- break;
- case 'C':
- case 'c':
- res *= base;
- res += 12;
- break;
- case 'D':
- case 'd':
- res *= base;
- res += 13;
- break;
- case 'E':
- case 'e':
- res *= base;
- res += 14;
- break;
- case 'F':
- case 'f':
- res *= base;
- res += 15;
- break;
- default:
- return res;
- }
- buffer++;
- }
- return res;
-}
-
-void one_arg(char *buffer, int *a)
-{
- while (*buffer && *buffer != '\n')
- {
- if (*buffer == ' ') buffer++;
- else break;
- }
-
- *a = to_int(buffer);
-}
-
-void two_args(char *buffer, int *a, int *b)
-{
- while (*buffer && *buffer != '\n')
- {
- if (*buffer == ' ') buffer++;
- else break;
- }
-
- *a = to_int(buffer);
-
- while (*buffer && *buffer != '\n')
- {
- if (*buffer != ' ') buffer++;
- else break;
- }
-
- while (*buffer && *buffer != '\n')
- {
- if (*buffer == ' ') buffer++;
- else break;
- }
-
- *b = to_int(buffer);
-}
-
-void do_inout(void)
-{
- char buffer[256];
- char *arg1, *arg2;
- int a,b;
-
- printf("In/Out Session\nUse 'i[bwl]' for in, 'o[bwl]' for out and 'q' to quit\n");
-
- do
- {
- cons_gets(buffer);
- printf("\n");
-
- *arg1 = buffer;
- while (*arg1 != ' ' ) arg1++;
- while (*arg1 == ' ') arg1++;
-
- if (buffer[0] == 'i')
- {
- one_arg(buffer+2, &a);
- switch (buffer[1])
- {
- case 'b':
- printf("in_byte(%xh) = %xh\n", a, A1_inb(a));
- break;
- case 'w':
- printf("in_word(%xh) = %xh\n", a, A1_inw(a));
- break;
- case 'l':
- printf("in_dword(%xh) = %xh\n", a, A1_inl(a));
- break;
- default:
- printf("Invalid length '%c'\n", buffer[1]);
- break;
- }
- }
- else if (buffer[0] == 'o')
- {
- two_args(buffer+2, &a, &b);
- switch (buffer[1])
- {
- case 'b':
- printf("out_byte(%d, %d)\n", a, b);
- A1_outb(a,b);
- break;
- case 'w':
- printf("out_word(%d, %d)\n", a, b);
- A1_outw(a, b);
- break;
- case 'l':
- printf("out_long(%d, %d)\n", a, b);
- A1_outl(a, b);
- break;
- default:
- printf("Invalid length '%c'\n", buffer[1]);
- break;
- }
- } else if (buffer[0] == 'q') return;
- } while (1);
-}