📄 x86interface.c
字号:
#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...)#endiftypedef 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 *)0xFD0B8000extern 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -