summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Bennett <sb476@cam.ac.uk>2007-11-24 00:54:45 +0000
committerStuart Bennett <sb476@cam.ac.uk>2007-11-24 00:54:45 +0000
commitc02f1b8467800c9bf7b7ebd0e84576bb631d14ad (patch)
tree3d84610272c554e224c3a54e77233d9f4429a8ce
parent085b7ac63713f69aedcffd428dedfd2a1f13aa1f (diff)
More elegant bios replacement
-rw-r--r--nvbiosemu.c44
-rw-r--r--thunk.c10
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);
diff --git a/thunk.c b/thunk.c
index a1c7fd3..868d597 100644
--- a/thunk.c
+++ b/thunk.c
@@ -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();