diff --git a/src/mem/mem.c b/src/mem/mem.c index cf6813d2a..be8f0d505 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -80,7 +80,8 @@ page_t *pages, /* RAM page table */ **page_lookup; /* pagetable lookup */ uint32_t pages_sz; /* #pages in table */ -uint8_t *ram, *ram2; /* the virtual RAM */ +uint8_t *low_ram, + *ram, *ram2; /* the virtual RAM */ uint8_t page_ff[4096]; uint32_t rammask; @@ -588,10 +589,12 @@ addreadlookup(uint32_t virt, uint32_t phys) if (readlookup[readlnext] != (int) 0xffffffff) readlookup2[readlookup[readlnext]] = LOOKUP_INV; - a = (uintptr_t)(phys & ~0xfff) - (uintptr_t)(virt & ~0xfff); + a = (uint32_t)(phys & ~0xfff) - (uint32_t)(virt & ~0xfff); if ((phys & ~0xfff) >= (1 << 30)) readlookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)]; + else if (a >= 0xfff00000) + readlookup2[virt>>12] = (uintptr_t)&low_ram[a & 0x000fffff]; else readlookup2[virt>>12] = (uintptr_t)&ram[a]; @@ -632,10 +635,12 @@ addwritelookup(uint32_t virt, uint32_t phys) #endif page_lookup[virt >> 12] = &pages[phys >> 12]; else { - a = (uintptr_t)(phys & ~0xfff) - (uintptr_t)(virt & ~0xfff); + a = (uint32_t)(phys & ~0xfff) - (uint32_t)(virt & ~0xfff); if ((phys & ~0xfff) >= (1 << 30)) writelookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)]; + else if (a >= 0xfff00000) + writelookup2[virt>>12] = (uintptr_t)&low_ram[a & 0x000fffff]; else writelookup2[virt>>12] = (uintptr_t)&ram[a]; } @@ -2526,26 +2531,36 @@ mem_reset(void) memset(page_ff, 0xff, sizeof(page_ff)); m = 1024UL * mem_size; - if (ram != NULL) { - free(ram); - ram = NULL; + if (low_ram != NULL) { + free(low_ram); + low_ram = NULL; } +#if (defined __amd64__ || defined _M_X64) if (ram2 != NULL) { free(ram2); ram2 = NULL; } +#endif if (mem_size > 2097152) fatal("Attempting to use more than 2 GB of guest RAM\n"); +#if (defined __amd64__ || defined _M_X64) if (mem_size > 1048576) { - ram = (uint8_t *)malloc(1 << 30); /* allocate and clear the RAM block of the first 1 GB */ - memset(ram, 0x00, 1 << 30); + low_ram = (uint8_t *)malloc((1 << 30) + (1 << 10)); /* allocate and clear the RAM block of the first 1 GB */ + memset(low_ram, 0x00, (1 << 30) + (1 << 10)); ram2 = (uint8_t *)malloc(m - (1 << 30)); /* allocate and clear the RAM block above 1 GB */ memset(ram2, 0x00, m - (1 << 30)); } else { - ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ - memset(ram, 0x00, m); + low_ram = (uint8_t *)malloc(m + (1 << 10)); /* allocate and clear the RAM block */ + memset(low_ram, 0x00, m + (1 << 10)); } +#else + low_ram = (uint8_t *)malloc(m + (1 << 10)); /* allocate and clear the RAM block */ + memset(low_ram, 0x00, m + (1 << 10)); + if (mem_size > 1048576) + ram2 = &(low_ram[(1 << 30) + (1 << 10)]); +#endif + ram = &(low_ram[1 << 10]); /* * Allocate the page table based on how much RAM we have. @@ -2758,6 +2773,7 @@ void mem_init(void) { /* Perform a one-time init. */ + low_ram = NULL; ram = rom = NULL; ram2 = NULL; pages = NULL;