diff options
Diffstat (limited to 'util/vgabios/helper_exec.c')
-rw-r--r-- | util/vgabios/helper_exec.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/util/vgabios/helper_exec.c b/util/vgabios/helper_exec.c new file mode 100644 index 0000000000..ee03f4eca3 --- /dev/null +++ b/util/vgabios/helper_exec.c @@ -0,0 +1,267 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/int10/helper_exec.c,v 1.16 2001/04/30 14:34:57 tsi Exp $ */ +/* + * XFree86 int10 module + * execute BIOS int 10h calls in x86 real mode environment + * Copyright 1999 Egbert Eich + * + * Part of this is based on code taken from DOSEMU + * (C) Copyright 1992, ..., 1999 the "DOSEMU-Development-Team" + */ + +/* + * To debug port accesses define PRINT_PORT. + * Note! You also have to comment out ioperm() + * in xf86EnableIO(). Otherwise we won't trap + * on PIO. + */ +#include <x86emu.h> +#include "test.h" +#include <asm/io.h> +#include <sys/time.h> + +int port_rep_inb(u16 port, u32 base, int d_f, u32 count); +u8 x_inb(u16 port); +u16 x_inw(u16 port); +void x_outb(u16 port, u8 val); +void x_outw(u16 port, u16 val); +u32 x_inl(u16 port); +void x_outl(u16 port, u32 val); + +/* general software interrupt handler */ +u32 getIntVect(int num) +{ + return MEM_RW(num << 2) + (MEM_RW((num << 2) + 2) << 4); +} + +void pushw(u16 val) +{ + X86_ESP -= 2; + MEM_WW(((u32) X86_SS << 4) + X86_SP, val); +} + +int run_bios_int(int num) +{ + u32 eflags; + + eflags = X86_EFLAGS; + pushw(eflags); + pushw(X86_CS); + pushw(X86_IP); + X86_CS = MEM_RW((num << 2) + 2); + X86_IP = MEM_RW(num << 2); + + //printf("%s: INT %x CS:IP = %x:%x\n", __FUNCTION__, + // num, MEM_RW((num << 2) + 2), MEM_RW(num << 2)); + + return 1; +} + +int port_rep_inb(u16 port, u32 base, int d_f, u32 count) +{ + register int inc = d_f ? -1 : 1; + u32 dst = base; + while (count--) { + MEM_WB(dst, x_inb(port)); + dst += inc; + } + return dst - base; +} + +int port_rep_inw(u16 port, u32 base, int d_f, u32 count) +{ + register int inc = d_f ? -2 : 2; + u32 dst = base; + while (count--) { + MEM_WW(dst, x_inw(port)); + dst += inc; + } + return dst - base; +} + +int port_rep_inl(u16 port, u32 base, int d_f, u32 count) +{ + register int inc = d_f ? -4 : 4; + u32 dst = base; + while (count--) { + MEM_WL(dst, x_inl(port)); + dst += inc; + } + return dst - base; +} + +int port_rep_outb(u16 port, u32 base, int d_f, u32 count) +{ + register int inc = d_f ? -1 : 1; + u32 dst = base; + while (count--) { + x_outb(port, MEM_RB(dst)); + dst += inc; + } + return dst - base; +} + +int port_rep_outw(u16 port, u32 base, int d_f, u32 count) +{ + register int inc = d_f ? -2 : 2; + u32 dst = base; + while (count--) { + x_outw(port, MEM_RW(dst)); + dst += inc; + } + return dst - base; +} + +int port_rep_outl(u16 port, u32 base, int d_f, u32 count) +{ + register int inc = d_f ? -4 : 4; + u32 dst = base; + while (count--) { + x_outl(port, MEM_RL(dst)); + dst += inc; + } + return dst - base; +} + +u8 x_inb(u16 port) +{ + u8 val; + + val = inb(port); + + //printf("inb(0x%04x) = 0x%02x\n", port, val); + + return val; +} + +u16 x_inw(u16 port) +{ + u16 val; + + val = inw(port); + + //printf("inw(0x%04x) = 0x%04x\n", port, val); + return val; +} + +u32 x_inl(u16 port) +{ + u32 val; + + val = inl(port); + + //printf("inl(0x%04x) = 0x%08x\n", port, val); + return val; +} + +void x_outb(u16 port, u8 val) +{ + //printf("outb(0x%02x, 0x%04x)\n", val, port); + outb(val, port); +} + +void x_outw(u16 port, u16 val) +{ + //printf("outw(0x%04x, 0x%04x)\n", val, port); + outw(val, port); +} + +void x_outl(u16 port, u32 val) +{ + //printf("outl(0x%08x, 0x%04x)\n", val, port); + outl(val, port); +} + +u8 Mem_rb(int addr) +{ + return (*current->mem->rb) (current, addr); +} + +u16 Mem_rw(int addr) +{ + return (*current->mem->rw) (current, addr); +} + +u32 Mem_rl(int addr) +{ + return (*current->mem->rl) (current, addr); +} + +void Mem_wb(int addr, u8 val) +{ + (*current->mem->wb) (current, addr, val); +} + +void Mem_ww(int addr, u16 val) +{ + (*current->mem->ww) (current, addr, val); +} + +void Mem_wl(int addr, u32 val) +{ + (*current->mem->wl) (current, addr, val); +} + +void getsecs(unsigned long *sec, unsigned long *usec) +{ + struct timeval tv; + gettimeofday(&tv, 0); + *sec = tv.tv_sec; + *usec = tv.tv_usec; +} + +#define TAG(Cfg1Addr) (Cfg1Addr & 0xffff00) +#define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff) + +u8 bios_checksum(u8 * start, int size) +{ + u8 sum = 0; + + while (size-- > 0) + sum += *start++; + return sum; +} + +/* + * Lock/Unlock legacy VGA. Some Bioses try to be very clever and make + * an attempt to detect a legacy ISA card. If they find one they might + * act very strange: for example they might configure the card as a + * monochrome card. This might cause some drivers to choke. + * To avoid this we attempt legacy VGA by writing to all know VGA + * disable registers before we call the BIOS initialization and + * restore the original values afterwards. In beween we hold our + * breath. To get to a (possibly exising) ISA card need to disable + * our current PCI card. + */ +/* + * This is just for booting: we just want to catch pure + * legacy vga therefore we don't worry about mmio etc. + * This stuff should really go into vgaHW.c. However then + * the driver would have to load the vga-module prior to + * doing int10. + */ +/*void +LockLegacyVGA(int screenIndex,legacyVGAPtr vga) +{ + xf86SetCurrentAccess(FALSE, xf86Screens[screenIndex]); + vga->save_msr = inb(0x3CC); + vga->save_vse = inb(0x3C3); + vga->save_46e8 = inb(0x46e8); + vga->save_pos102 = inb(0x102); + outb(0x3C2, ~(u8)0x03 & vga->save_msr); + outb(0x3C3, ~(u8)0x01 & vga->save_vse); + outb(0x46e8, ~(u8)0x08 & vga->save_46e8); + outb(0x102, ~(u8)0x01 & vga->save_pos102); + xf86SetCurrentAccess(TRUE, xf86Screens[screenIndex]); +} + +void +UnlockLegacyVGA(int screenIndex, legacyVGAPtr vga) +{ + xf86SetCurrentAccess(FALSE, xf86Screens[screenIndex]); + outb(0x102, vga->save_pos102); + outb(0x46e8, vga->save_46e8); + outb(0x3C3, vga->save_vse); + outb(0x3C2, vga->save_msr); + xf86SetCurrentAccess(TRUE, xf86Screens[screenIndex]); +} +*/ |