diff options
author | Stuart Bennett <sb476@cam.ac.uk> | 2007-11-24 00:54:45 +0000 |
---|---|---|
committer | Stuart Bennett <sb476@cam.ac.uk> | 2007-11-24 00:54:45 +0000 |
commit | c02f1b8467800c9bf7b7ebd0e84576bb631d14ad (patch) | |
tree | 3d84610272c554e224c3a54e77233d9f4429a8ce | |
parent | 085b7ac63713f69aedcffd428dedfd2a1f13aa1f (diff) |
More elegant bios replacement
-rw-r--r-- | nvbiosemu.c | 44 | ||||
-rw-r--r-- | thunk.c | 10 |
2 files changed, 26 insertions, 28 deletions
diff --git a/nvbiosemu.c b/nvbiosemu.c index c8e0309..96c89ce 100644 --- a/nvbiosemu.c +++ b/nvbiosemu.c @@ -20,6 +20,8 @@ #define TRUE true #define FALSE false #define ScrnInfoPtr void * + +#define VBIOS_ROM 0xc0000 #define NV_PROM_SIZE 0x10000 static uint32_t *PMC; @@ -47,14 +49,14 @@ static void unmap_dev_mem (unsigned long Base, unsigned long Size) munmap((caddr_t)(Base - alignOff), (Size + alignOff)); } -static Bool nv_cksum(const uint8_t *data, unsigned int offset, unsigned int length) +static Bool nv_cksum(const uint8_t *data, unsigned int length) { /* there's a few checksums in the BIOS, so here's a generic checking function */ int i; uint8_t sum = 0; for (i = 0; i < length; i++) - sum += data[offset + i]; + sum += data[i]; if (sum) return TRUE; @@ -70,7 +72,7 @@ static Bool NVValidVBIOS(ScrnInfoPtr pScrn, const uint8_t *data) return FALSE; } - if (nv_cksum(data, 0, data[2] * 512)) { + if (nv_cksum(data, data[2] * 512)) { printf("... BIOS checksum invalid\n"); return FALSE; } else @@ -139,27 +141,23 @@ static Bool NVShadowVBIOS(ScrnInfoPtr pScrn, uint32_t *data) return FALSE; } -int fake_bios(int fd, uint8_t *bios) +int mmap_in_bios(uint8_t *bios) { - uint8_t *emumem, *sysmem; - int i; + int zfd, i; - /* this does not get free'd until exit */ - if (!(emumem = malloc(1024 * 1024))) { - printf("Couldn't allocate fake system memory\n"); + if ((zfd = open("/dev/zero", O_RDWR)) == -1) { + printf("Can't open /dev/zero\n"); return 1; } - sysmem = map_dev_mem(fd, 0, 1024*1024); + mmap((void *)VBIOS_ROM, NV_PROM_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_FIXED | MAP_SHARED, zfd, 0); - for (i = 0; i < 1024*1024; i++) - emumem[i] = sysmem[i]; - for (i = 0; i < NV_PROM_SIZE; i++) - emumem[0xc0000 + i] = bios[i]; + close(zfd); - unmap_dev_mem((unsigned long)sysmem, 1024*1024); - - M.mem_base = (uintptr_t)emumem; + for (i = 0; i < NV_PROM_SIZE; i++) + *((uint8_t *)VBIOS_ROM + i) = bios[i]; return 0; } @@ -169,27 +167,27 @@ int reload_nv_bios(uintptr_t pcimemaddr) int fd; uint8_t bios[NV_PROM_SIZE]; - if( (fd = open("/dev/mem", O_RDWR)) == -1 ) { + if ((fd = open("/dev/mem", O_RDWR)) == -1) { printf("Can't open /dev/mem\n"); return 0; } printf("Using card memory region at %p\n", (void *)pcimemaddr); - PMC = map_dev_mem(fd, pcimemaddr + 0x000000, 0xffff); + PMC = map_dev_mem(fd, pcimemaddr + 0x000000, 0x2000); PRAMIN = map_dev_mem(fd, pcimemaddr + 0x700000, NV_PROM_SIZE); PROM = map_dev_mem(fd, pcimemaddr + 0x300000, NV_PROM_SIZE); PNV50 = map_dev_mem(fd, pcimemaddr + 0x610000, 0xffff); + close(fd); + if (NVShadowVBIOS(NULL, (uint32_t *)bios)) { - if (fake_bios(fd, bios)) + if (mmap_in_bios(bios)) return 1; } else return 1; - close(fd); - - unmap_dev_mem((unsigned long)PMC, NV_PROM_SIZE); + unmap_dev_mem((unsigned long)PMC, 0x2000); unmap_dev_mem((unsigned long)PRAMIN, NV_PROM_SIZE); unmap_dev_mem((unsigned long)PROM, NV_PROM_SIZE); unmap_dev_mem((unsigned long)PNV50, 0xffff); @@ -161,20 +161,20 @@ int LRMI_init() { X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK; - M.mem_base = 0; - M.mem_size = 1024*1024; - /* * Allocate a 64k stack. */ stack = LRMI_alloc_real(64 * 1024); X86_SS = (unsigned long)stack >> 4; X86_ESP = 0xFFF9; - memset (M.mem_base + stack, 0, 64*1024); + memset (stack, 0, 64*1024); *((char *)0) = 0x4f; /* Make sure that we end up jumping back to a halt instruction */ + M.mem_base = 0; + M.mem_size = 1024*1024; + return 1; } @@ -210,7 +210,7 @@ int real_call(struct LRMI_regs *registers) { X86_ESP = 0xFFF9; } - memset (M.mem_base + stack, 0, 64*1024); + memset (stack, 0, 64*1024); X86EMU_exec(); |