PIC rewrite, proper SMRAM API, complete SiS 471 rewrite and addition of 40x, 460, and 461, changes to mem.c/h, disabled Voodoo memory dumping on exit, bumped SDL Hardware scale quality to 2, bumped IDE/ATAPI drives to ATA-6, finally bumped emulator version to 3.0, redid the bus type ID's to allow for planned ATAPI hard disks, made SST flash set its high mappings to the correct address if the CPU is 16-bit, and added the SiS 401 AMI 486 Clone, AOpen Vi15G, and the Soyo 4SA2 (486 with SiS 496/497 that can boot from CD-ROM), assorted 286+ protected mode fixes (for slightly more accuracy), and fixes to 808x emulation (MS Word 1.0 and 1.10 for DOS now work correctly from floppy).
This commit is contained in:
436
src/mem/mem.c
436
src/mem/mem.c
@@ -8,12 +8,6 @@
|
||||
*
|
||||
* Memory handling and MMU.
|
||||
*
|
||||
* NOTE: Experimenting with dynamically allocated lookup tables;
|
||||
* the DYNAMIC_TABLES=1 enables this. Will eventually go
|
||||
* away, either way...
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -58,12 +52,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
#define FIXME 0
|
||||
#define DYNAMIC_TABLES 0 /* experimental */
|
||||
|
||||
|
||||
mem_mapping_t base_mapping,
|
||||
ram_low_mapping, /* 0..640K mapping */
|
||||
mem_mapping_t ram_low_mapping, /* 0..640K mapping */
|
||||
#if 1
|
||||
ram_mid_mapping,
|
||||
#endif
|
||||
@@ -72,7 +61,6 @@ mem_mapping_t base_mapping,
|
||||
ram_2gb_mapping, /* 1024M+ mapping */
|
||||
ram_remapped_mapping,
|
||||
ram_split_mapping,
|
||||
ram_smram_mapping[2],
|
||||
bios_mapping,
|
||||
bios_high_mapping;
|
||||
|
||||
@@ -110,8 +98,6 @@ int cachesize = 256;
|
||||
uint32_t get_phys_virt,
|
||||
get_phys_phys;
|
||||
|
||||
smram_t smram[2] = { { 0x000a0000, 0x000a0000 }, { 0x000a0000, 0x000a0000 } };
|
||||
|
||||
int mem_a20_key = 0,
|
||||
mem_a20_alt = 0,
|
||||
mem_a20_state = 0;
|
||||
@@ -129,21 +115,13 @@ int use_phys_exec = 0;
|
||||
|
||||
|
||||
/* FIXME: re-do this with a 'mem_ops' struct. */
|
||||
static mem_mapping_t *base_mapping, *last_mapping;
|
||||
static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO];
|
||||
static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];
|
||||
static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff };
|
||||
static uint8_t *_mem_exec[MEM_MAPPINGS_NO];
|
||||
static uint32_t _mem_state[MEM_MAPPINGS_NO];
|
||||
|
||||
#if FIXME
|
||||
#if (MEM_GRANULARITY_BITS >= 12)
|
||||
static uint8_t ff_array[MEM_GRANULARITY_SIZE];
|
||||
#else
|
||||
static uint8_t ff_array[4096]; /* Must be at least one page. */
|
||||
#endif
|
||||
#else
|
||||
static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff };
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ENABLE_MEM_LOG
|
||||
int mem_do_log = ENABLE_MEM_LOG;
|
||||
@@ -179,17 +157,8 @@ resetreadlookup(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
/* This is NULL after app startup, when mem_init() has not yet run. */
|
||||
#if DYNAMIC_TABLES
|
||||
mem_log("MEM: reset_lookup: pages=%08lx, lookup=%08lx, pages_sz=%i\n", pages, page_lookup, pages_sz);
|
||||
#endif
|
||||
|
||||
/* Initialize the page lookup table. */
|
||||
#if DYNAMIC_TABLES
|
||||
memset(page_lookup, 0x00, pages_sz*sizeof(page_t *));
|
||||
#else
|
||||
memset(page_lookup, 0x00, (1<<20)*sizeof(page_t *));
|
||||
#endif
|
||||
|
||||
/* Initialize the tables for lower (<= 1024K) RAM. */
|
||||
for (c = 0; c < 256; c++) {
|
||||
@@ -198,13 +167,8 @@ mem_log("MEM: reset_lookup: pages=%08lx, lookup=%08lx, pages_sz=%i\n", pages, pa
|
||||
}
|
||||
|
||||
/* Initialize the tables for high (> 1024K) RAM. */
|
||||
#if DYNAMIC_TABLES
|
||||
memset(readlookup2, 0xff, pages_sz*sizeof(uintptr_t));
|
||||
memset(writelookup2, 0xff, pages_sz*sizeof(uintptr_t));
|
||||
#else
|
||||
memset(readlookup2, 0xff, (1<<20)*sizeof(uintptr_t));
|
||||
memset(writelookup2, 0xff, (1<<20)*sizeof(uintptr_t));
|
||||
#endif
|
||||
|
||||
readlnext = 0;
|
||||
writelnext = 0;
|
||||
@@ -692,11 +656,33 @@ getpccache(uint32_t a)
|
||||
|
||||
mem_log("Bad getpccache %08X%08X\n", (uint32_t) (a >> 32), (uint32_t) (a & 0xffffffff));
|
||||
|
||||
#if FIXME
|
||||
return &ff_array[0-(uintptr_t)(a2 & ~0xfff)];
|
||||
#else
|
||||
return (uint8_t *)&ff_pccache;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
read_mem_b(uint32_t addr)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
mem_logical_addr = addr;
|
||||
|
||||
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
if (map && map->read_b)
|
||||
return map->read_b(addr, map->p);
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
write_mem_b(uint32_t addr, uint8_t val)
|
||||
{
|
||||
mem_mapping_t *map;
|
||||
mem_logical_addr = addr;
|
||||
|
||||
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||
if (map && map->write_b)
|
||||
map->write_b(addr, val, map->p);
|
||||
}
|
||||
|
||||
|
||||
@@ -1093,8 +1079,7 @@ readmemwl(uint32_t seg, uint32_t addr)
|
||||
}
|
||||
if (is386) return readmemb386l(seg,addr)|(((uint16_t) readmemb386l(seg,addr+1))<<8);
|
||||
else return readmembl(seg+addr)|(((uint16_t) readmembl(seg+addr+1))<<8);
|
||||
}
|
||||
else if (readlookup2[addr2 >> 12] != (uintptr_t) LOOKUP_INV)
|
||||
} else if (readlookup2[addr2 >> 12] != (uintptr_t) LOOKUP_INV)
|
||||
return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2);
|
||||
}
|
||||
|
||||
@@ -1584,7 +1569,8 @@ mem_read_ram(uint32_t addr, void *priv)
|
||||
mem_log("Read B %02X from %08X\n", ram[addr], addr);
|
||||
#endif
|
||||
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
if (AT)
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
|
||||
return ram[addr];
|
||||
}
|
||||
@@ -1598,7 +1584,8 @@ mem_read_ramw(uint32_t addr, void *priv)
|
||||
mem_log("Read W %04X from %08X\n", *(uint16_t *)&ram[addr], addr);
|
||||
#endif
|
||||
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
if (AT)
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
|
||||
return *(uint16_t *)&ram[addr];
|
||||
}
|
||||
@@ -1612,7 +1599,8 @@ mem_read_raml(uint32_t addr, void *priv)
|
||||
mem_log("Read L %08X from %08X\n", *(uint32_t *)&ram[addr], addr);
|
||||
#endif
|
||||
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
if (AT)
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
|
||||
return *(uint32_t *)&ram[addr];
|
||||
}
|
||||
@@ -1660,45 +1648,6 @@ mem_read_ram_2gbl(uint32_t addr, void *priv)
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
mem_read_smram(uint32_t addr, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gb(new_addr, priv);
|
||||
else
|
||||
return mem_read_ram(new_addr, priv);
|
||||
}
|
||||
|
||||
|
||||
uint16_t
|
||||
mem_read_smramw(uint32_t addr, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gbw(new_addr, priv);
|
||||
else
|
||||
return mem_read_ramw(new_addr, priv);
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
mem_read_smraml(uint32_t addr, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gbl(new_addr, priv);
|
||||
else
|
||||
return mem_read_raml(new_addr, priv);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
static inline int
|
||||
page_index(page_t *p)
|
||||
@@ -1894,8 +1843,11 @@ mem_write_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
if ((addr >= 0xa0000) && (addr <= 0xbffff))
|
||||
mem_log("Write B %02X to %08X\n", val, addr);
|
||||
#endif
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_ramb_page(addr, val, &pages[addr >> 12]);
|
||||
if (AT) {
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_ramb_page(addr, val, &pages[addr >> 12]);
|
||||
} else
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
@@ -1906,8 +1858,11 @@ mem_write_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
if ((addr >= 0xa0000) && (addr <= 0xbffff))
|
||||
mem_log("Write W %04X to %08X\n", val, addr);
|
||||
#endif
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_ramw_page(addr, val, &pages[addr >> 12]);
|
||||
if (AT) {
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_ramw_page(addr, val, &pages[addr >> 12]);
|
||||
} else
|
||||
*(uint16_t *)&ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
@@ -1918,38 +1873,11 @@ mem_write_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
if ((addr >= 0xa0000) && (addr <= 0xbffff))
|
||||
mem_log("Write L %08X to %08X\n", val, addr);
|
||||
#endif
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_raml_page(addr, val, &pages[addr >> 12]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mem_write_smram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
mem_write_ram(new_addr, val, priv);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mem_write_smramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
mem_write_ramw(new_addr, val, priv);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mem_write_smraml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
mem_write_raml(new_addr, val, priv);
|
||||
if (AT) {
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_raml_page(addr, val, &pages[addr >> 12]);
|
||||
} else
|
||||
*(uint32_t *)&ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
@@ -1958,7 +1886,8 @@ mem_read_remapped(uint32_t addr, void *priv)
|
||||
{
|
||||
if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
|
||||
addr = 0xA0000 + (addr - (mem_size * 1024));
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
if (AT)
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
return ram[addr];
|
||||
}
|
||||
|
||||
@@ -1968,7 +1897,8 @@ mem_read_remappedw(uint32_t addr, void *priv)
|
||||
{
|
||||
if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
|
||||
addr = 0xA0000 + (addr - (mem_size * 1024));
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
if (AT)
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
return *(uint16_t *)&ram[addr];
|
||||
}
|
||||
|
||||
@@ -1978,7 +1908,8 @@ mem_read_remappedl(uint32_t addr, void *priv)
|
||||
{
|
||||
if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
|
||||
addr = 0xA0000 + (addr - (mem_size * 1024));
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
if (AT)
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
return *(uint32_t *)&ram[addr];
|
||||
}
|
||||
|
||||
@@ -1989,8 +1920,11 @@ mem_write_remapped(uint32_t addr, uint8_t val, void *priv)
|
||||
uint32_t oldaddr = addr;
|
||||
if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
|
||||
addr = 0xA0000 + (addr - (mem_size * 1024));
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]);
|
||||
if (AT) {
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]);
|
||||
} else
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
@@ -2000,8 +1934,11 @@ mem_write_remappedw(uint32_t addr, uint16_t val, void *priv)
|
||||
uint32_t oldaddr = addr;
|
||||
if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
|
||||
addr = 0xA0000 + (addr - (mem_size * 1024));
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]);
|
||||
if (AT) {
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]);
|
||||
} else
|
||||
*(uint16_t *)&ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
@@ -2011,50 +1948,11 @@ mem_write_remappedl(uint32_t addr, uint32_t val, void *priv)
|
||||
uint32_t oldaddr = addr;
|
||||
if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024)))
|
||||
addr = 0xA0000 + (addr - (mem_size * 1024));
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_raml_page(addr, val, &pages[oldaddr >> 12]);
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
mem_read_bios(uint32_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = rom[addr - biosaddr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint16_t
|
||||
mem_read_biosw(uint32_t addr, void *priv)
|
||||
{
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = *(uint16_t *)&rom[addr - biosaddr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
mem_read_biosl(uint32_t addr, void *priv)
|
||||
{
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = *(uint32_t *)&rom[addr - biosaddr];
|
||||
|
||||
return ret;
|
||||
if (AT) {
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
mem_write_raml_page(addr, val, &pages[oldaddr >> 12]);
|
||||
} else
|
||||
*(uint32_t *)&ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
@@ -2224,10 +2122,13 @@ mem_mapping_write_allowed(uint32_t flags, uint32_t state)
|
||||
void
|
||||
mem_mapping_recalc(uint64_t base, uint64_t size)
|
||||
{
|
||||
mem_mapping_t *map = base_mapping.next;
|
||||
mem_mapping_t *map;
|
||||
uint64_t c;
|
||||
|
||||
if (! size) return;
|
||||
if (!size || (base_mapping == NULL))
|
||||
return;
|
||||
|
||||
map = base_mapping;
|
||||
|
||||
/* Clear out old mappings. */
|
||||
for (c = base; c < base + size; c += MEM_GRANULARITY_SIZE) {
|
||||
@@ -2239,6 +2140,7 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
|
||||
/* Walk mapping list. */
|
||||
while (map != NULL) {
|
||||
/*In range?*/
|
||||
mem_log("mem_mapping_recalc(): %08X -> %08X\n", map, map->next);
|
||||
if (map->enable && (uint64_t)map->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)map->base + (uint64_t)map->size) > (uint64_t)base) {
|
||||
uint64_t start = (map->base < base) ? map->base : base;
|
||||
uint64_t end = (((uint64_t)map->base + (uint64_t)map->size) < (base + size)) ? ((uint64_t)map->base + (uint64_t)map->size) : (base + size);
|
||||
@@ -2282,18 +2184,35 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
|
||||
void
|
||||
mem_mapping_del(mem_mapping_t *map)
|
||||
{
|
||||
mem_mapping_t *ptr;
|
||||
/* Do a sanity check */
|
||||
if ((base_mapping == NULL) && (last_mapping != NULL)) {
|
||||
fatal("mem_mapping_del(): NULL base mapping with non-NULL last mapping\n");
|
||||
return;
|
||||
} else if ((base_mapping != NULL) && (last_mapping == NULL)) {
|
||||
fatal("mem_mapping_del(): Non-NULL base mapping with NULL last mapping\n");
|
||||
return;
|
||||
} else if ((base_mapping != NULL) && (base_mapping->prev != NULL)) {
|
||||
fatal("mem_mapping_del(): Base mapping with a preceding mapping\n");
|
||||
return;
|
||||
} else if ((last_mapping != NULL) && (last_mapping->next != NULL)) {
|
||||
fatal("mem_mapping_del(): Last mapping with a following mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable the entry. */
|
||||
mem_mapping_disable(map);
|
||||
|
||||
/* Zap it from the list. */
|
||||
for (ptr = &base_mapping; ptr->next != NULL; ptr = ptr->next) {
|
||||
if (ptr->next == map) {
|
||||
ptr->next = map->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (map->prev != NULL)
|
||||
map->prev->next = map->next;
|
||||
if (map->next != NULL)
|
||||
map->next->prev = map->prev;
|
||||
|
||||
/* Check if it's the first or the last mapping. */
|
||||
if (base_mapping == map)
|
||||
base_mapping = map->next;
|
||||
if (last_mapping == map)
|
||||
last_mapping = map->prev;
|
||||
}
|
||||
|
||||
|
||||
@@ -2311,17 +2230,37 @@ mem_mapping_add(mem_mapping_t *map,
|
||||
uint32_t fl,
|
||||
void *p)
|
||||
{
|
||||
mem_mapping_t *dest = &base_mapping;
|
||||
/* Do a sanity check */
|
||||
if ((base_mapping == NULL) && (last_mapping != NULL)) {
|
||||
fatal("mem_mapping_add(): NULL base mapping with non-NULL last mapping\n");
|
||||
return;
|
||||
} else if ((base_mapping != NULL) && (last_mapping == NULL)) {
|
||||
fatal("mem_mapping_add(): Non-NULL base mapping with NULL last mapping\n");
|
||||
return;
|
||||
} else if ((base_mapping != NULL) && (base_mapping->prev != NULL)) {
|
||||
fatal("mem_mapping_add(): Base mapping with a preceding mapping\n");
|
||||
return;
|
||||
} else if ((last_mapping != NULL) && (last_mapping->next != NULL)) {
|
||||
fatal("mem_mapping_add(): Last mapping with a following mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add mapping to the beginning of the list if necessary.*/
|
||||
if (base_mapping == NULL)
|
||||
base_mapping = map;
|
||||
|
||||
/* Add mapping to the end of the list.*/
|
||||
while (dest->next)
|
||||
dest = dest->next;
|
||||
dest->next = map;
|
||||
map->prev = dest;
|
||||
if (last_mapping == NULL)
|
||||
map->prev = NULL;
|
||||
else {
|
||||
map->prev = last_mapping;
|
||||
last_mapping->next = map;
|
||||
}
|
||||
last_mapping = map;
|
||||
|
||||
if (size)
|
||||
if (size != 0x00000000)
|
||||
map->enable = 1;
|
||||
else
|
||||
else
|
||||
map->enable = 0;
|
||||
map->base = base;
|
||||
map->size = size;
|
||||
@@ -2336,8 +2275,11 @@ mem_mapping_add(mem_mapping_t *map,
|
||||
map->p = p;
|
||||
map->dev = NULL;
|
||||
map->next = NULL;
|
||||
mem_log("mem_mapping_add(): Linked list structure: %08X -> %08X -> %08X\n", map->prev, map, map->next);
|
||||
|
||||
mem_mapping_recalc(map->base, map->size);
|
||||
/* If the mapping is disabled, there is no need to recalc anything. */
|
||||
if (size != 0x00000000)
|
||||
mem_mapping_recalc(map->base, map->size);
|
||||
}
|
||||
|
||||
|
||||
@@ -2474,47 +2416,6 @@ mem_set_state(int smm, int mode, uint32_t base, uint32_t size, uint32_t state)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mem_add_bios(void)
|
||||
{
|
||||
int temp_cpu_type, temp_cpu_16bitbus = 1;
|
||||
|
||||
if (AT) {
|
||||
temp_cpu_type = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type;
|
||||
temp_cpu_16bitbus = (temp_cpu_type == CPU_286 || temp_cpu_type == CPU_386SX || temp_cpu_type == CPU_486SLC || temp_cpu_type == CPU_IBM386SLC || temp_cpu_type == CPU_IBM486SLC );
|
||||
}
|
||||
|
||||
if (biosmask > 0x1ffff) {
|
||||
/* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */
|
||||
mem_mapping_add(&bios_mapping, 0xe0000, 0x20000,
|
||||
mem_read_bios,mem_read_biosw,mem_read_biosl,
|
||||
mem_write_null,mem_write_nullw,mem_write_nulll,
|
||||
&rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||
|
||||
mem_set_mem_state_both(0x0e0000, 0x20000,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
} else {
|
||||
mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1,
|
||||
mem_read_bios,mem_read_biosw,mem_read_biosl,
|
||||
mem_write_null,mem_write_nullw,mem_write_nulll,
|
||||
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||
|
||||
mem_set_mem_state_both(biosaddr, biosmask + 1,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
}
|
||||
|
||||
if (AT) {
|
||||
mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
|
||||
mem_read_bios,mem_read_biosw,mem_read_biosl,
|
||||
mem_write_null,mem_write_nullw,mem_write_nulll,
|
||||
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||
|
||||
mem_set_mem_state_both(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mem_a20_init(void)
|
||||
{
|
||||
@@ -2530,15 +2431,28 @@ mem_a20_init(void)
|
||||
}
|
||||
|
||||
|
||||
/* Close all the memory mappings. */
|
||||
void
|
||||
mem_close(void)
|
||||
{
|
||||
mem_mapping_t *map = base_mapping, *next;
|
||||
|
||||
while (map != NULL) {
|
||||
next = map->next;
|
||||
mem_mapping_del(map);
|
||||
map = next;
|
||||
}
|
||||
|
||||
base_mapping = last_mapping = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Reset the memory state. */
|
||||
void
|
||||
mem_reset(void)
|
||||
{
|
||||
uint32_t c, m, m2;
|
||||
|
||||
#if FIXME
|
||||
memset(ff_array, 0xff, sizeof(ff_array));
|
||||
#endif
|
||||
memset(page_ff, 0xff, sizeof(page_ff));
|
||||
|
||||
m = 1024UL * mem_size;
|
||||
@@ -2618,9 +2532,6 @@ mem_reset(void)
|
||||
* Allocate and initialize the (new) page table.
|
||||
* We only do this if the size of the page table has changed.
|
||||
*/
|
||||
#if DYNAMIC_TABLES
|
||||
mem_log("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz);
|
||||
#endif
|
||||
if (pages_sz != m) {
|
||||
pages_sz = m;
|
||||
if (pages) {
|
||||
@@ -2628,29 +2539,9 @@ mem_log("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz);
|
||||
pages = NULL;
|
||||
}
|
||||
pages = (page_t *)malloc(m*sizeof(page_t));
|
||||
#if DYNAMIC_TABLES
|
||||
mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
|
||||
#endif
|
||||
|
||||
#if DYNAMIC_TABLES
|
||||
/* Allocate the (new) lookup tables. */
|
||||
if (page_lookup != NULL) free(page_lookup);
|
||||
page_lookup = (page_t **)malloc(pages_sz*sizeof(page_t *));
|
||||
|
||||
if (readlookup2 != NULL) free(readlookup2);
|
||||
readlookup2 = malloc(pages_sz*sizeof(uintptr_t));
|
||||
|
||||
if (writelookup2 != NULL) free(writelookup2);
|
||||
writelookup2 = malloc(pages_sz*sizeof(uintptr_t));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DYNAMIC_TABLES
|
||||
memset(page_lookup, 0x00, pages_sz * sizeof(page_t *));
|
||||
#else
|
||||
memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *));
|
||||
#endif
|
||||
|
||||
memset(pages, 0x00, pages_sz*sizeof(page_t));
|
||||
|
||||
@@ -2705,7 +2596,7 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
|
||||
|
||||
memset(_mem_exec, 0x00, sizeof(_mem_exec));
|
||||
|
||||
memset(&base_mapping, 0x00, sizeof(base_mapping));
|
||||
base_mapping = last_mapping = NULL;
|
||||
|
||||
memset(_mem_state, 0x00, sizeof(_mem_state));
|
||||
|
||||
@@ -2766,27 +2657,13 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
|
||||
ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL);
|
||||
}
|
||||
|
||||
mem_mapping_add(&ram_smram_mapping[0], 0xa0000, 0x60000,
|
||||
mem_read_smram,mem_read_smramw,mem_read_smraml,
|
||||
mem_write_smram,mem_write_smramw,mem_write_smraml,
|
||||
ram + 0xa0000, MEM_MAPPING_SMRAM, &(smram[0]));
|
||||
mem_mapping_add(&ram_smram_mapping[1], 0xa0000, 0x60000,
|
||||
mem_read_smram,mem_read_smramw,mem_read_smraml,
|
||||
mem_write_smram,mem_write_smramw,mem_write_smraml,
|
||||
ram + 0xa0000, MEM_MAPPING_SMRAM, &(smram[1]));
|
||||
mem_mapping_disable(&ram_smram_mapping[0]);
|
||||
mem_mapping_disable(&ram_smram_mapping[1]);
|
||||
|
||||
mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024,
|
||||
mem_read_remapped,mem_read_remappedw,mem_read_remappedl,
|
||||
mem_write_remapped,mem_write_remappedw,mem_write_remappedl,
|
||||
ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL);
|
||||
mem_mapping_disable(&ram_remapped_mapping);
|
||||
|
||||
mem_a20_init();
|
||||
|
||||
smram[0].host_base = smram[0].ram_base = smram[0].size = 0x00000000;
|
||||
smram[1].host_base = smram[1].ram_base = smram[1].size = 0x00000000;
|
||||
mem_a20_init();
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
purgable_page_list_head = 0;
|
||||
@@ -2802,22 +2679,11 @@ mem_init(void)
|
||||
ram = rom = NULL;
|
||||
ram2 = NULL;
|
||||
pages = NULL;
|
||||
#if DYNAMIC_TABLES
|
||||
page_lookup = NULL;
|
||||
readlookup2 = NULL;
|
||||
writelookup2 = NULL;
|
||||
|
||||
#else
|
||||
/* Allocate the lookup tables. */
|
||||
page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *));
|
||||
|
||||
readlookup2 = malloc((1<<20)*sizeof(uintptr_t));
|
||||
|
||||
writelookup2 = malloc((1<<20)*sizeof(uintptr_t));
|
||||
#endif
|
||||
|
||||
/* Reset the memory state. */
|
||||
mem_reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/plat.h>
|
||||
@@ -316,6 +317,89 @@ rom_reset(uint32_t addr, int sz)
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
bios_read(uint32_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = rom[addr - biosaddr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint16_t
|
||||
bios_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = *(uint16_t *)&rom[addr - biosaddr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
bios_readl(uint32_t addr, void *priv)
|
||||
{
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
addr &= 0x000fffff;
|
||||
|
||||
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
|
||||
ret = *(uint32_t *)&rom[addr - biosaddr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
bios_add(void)
|
||||
{
|
||||
int temp_cpu_type, temp_cpu_16bitbus = 1;
|
||||
|
||||
if (AT) {
|
||||
temp_cpu_type = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type;
|
||||
temp_cpu_16bitbus = (temp_cpu_type == CPU_286 || temp_cpu_type == CPU_386SX || temp_cpu_type == CPU_486SLC || temp_cpu_type == CPU_IBM386SLC || temp_cpu_type == CPU_IBM486SLC );
|
||||
}
|
||||
|
||||
if (biosmask > 0x1ffff) {
|
||||
/* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */
|
||||
mem_mapping_add(&bios_mapping, 0xe0000, 0x20000,
|
||||
bios_read,bios_readw,bios_readl,
|
||||
mem_write_null,mem_write_nullw,mem_write_nulll,
|
||||
&rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||
|
||||
mem_set_mem_state_both(0x0e0000, 0x20000,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
} else {
|
||||
mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1,
|
||||
bios_read,bios_readw,bios_readl,
|
||||
mem_write_null,mem_write_nullw,mem_write_nulll,
|
||||
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||
|
||||
mem_set_mem_state_both(biosaddr, biosmask + 1,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
}
|
||||
|
||||
if (AT) {
|
||||
mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
|
||||
bios_read,bios_readw,bios_readl,
|
||||
mem_write_null,mem_write_nullw,mem_write_nulll,
|
||||
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||
|
||||
mem_set_mem_state_both(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
|
||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* These four are for loading the BIOS. */
|
||||
int
|
||||
bios_load(wchar_t *fn1, wchar_t *fn2, uint32_t addr, int sz, int off, int flags)
|
||||
@@ -359,7 +443,7 @@ bios_load(wchar_t *fn1, wchar_t *fn2, uint32_t addr, int sz, int off, int flags)
|
||||
}
|
||||
|
||||
if (!bios_only && ret && !(flags & FLAG_AUX))
|
||||
mem_add_bios();
|
||||
bios_add();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
366
src/mem/smram.c
Normal file
366
src/mem/smram.c
Normal file
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* SMRAM handling.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86.h"
|
||||
#include <86box/config.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/smram.h>
|
||||
|
||||
|
||||
static smram_t *base_smram, *last_smram;
|
||||
|
||||
|
||||
#ifdef ENABLE_SMRAM_LOG
|
||||
int smram_do_log = ENABLE_SMRAM_LOG;
|
||||
|
||||
|
||||
static void
|
||||
smram_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (smram_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define smram_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static uint8_t
|
||||
smram_read(uint32_t addr, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gb(new_addr, priv);
|
||||
else
|
||||
return mem_read_ram(new_addr, priv);
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
smram_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gbw(new_addr, priv);
|
||||
else
|
||||
return mem_read_ramw(new_addr, priv);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
smram_readl(uint32_t addr, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
if (new_addr >= (1 << 30))
|
||||
return mem_read_ram_2gbl(new_addr, priv);
|
||||
else
|
||||
return mem_read_raml(new_addr, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smram_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
mem_write_ram(new_addr, val, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smram_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
mem_write_ramw(new_addr, val, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
smram_writel(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
smram_t *dev = (smram_t *) priv;
|
||||
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
|
||||
|
||||
mem_write_raml(new_addr, val, priv);
|
||||
}
|
||||
|
||||
|
||||
/* Make a backup copy of host_base and size of all the SMRAM structs, needed so that if
|
||||
the SMRAM mappings change while in SMM, they will be recalculated on return. */
|
||||
void
|
||||
smram_backup_all(void)
|
||||
{
|
||||
smram_t *temp_smram = base_smram, *next;
|
||||
|
||||
while (temp_smram != NULL) {
|
||||
temp_smram->old_host_base = temp_smram->host_base;
|
||||
temp_smram->old_size = temp_smram->size;
|
||||
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Recalculate any mappings, including the backup if returning from SMM. */
|
||||
void
|
||||
smram_recalc_all(int ret)
|
||||
{
|
||||
smram_t *temp_smram = base_smram, *next;
|
||||
|
||||
if (base_smram == NULL)
|
||||
return;
|
||||
|
||||
if (ret) {
|
||||
while (temp_smram != NULL) {
|
||||
if (temp_smram->old_size != 0x00000000)
|
||||
mem_mapping_recalc(temp_smram->old_host_base, temp_smram->old_size);
|
||||
temp_smram->old_host_base = temp_smram->old_size = 0x00000000;
|
||||
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
}
|
||||
}
|
||||
|
||||
temp_smram = base_smram;
|
||||
|
||||
while (temp_smram != NULL) {
|
||||
if (temp_smram->size != 0x00000000)
|
||||
mem_mapping_recalc(temp_smram->host_base, temp_smram->size);
|
||||
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
/* Delete a SMRAM mapping. */
|
||||
void
|
||||
smram_del(smram_t *smr)
|
||||
{
|
||||
/* Do a sanity check */
|
||||
if ((base_smram == NULL) && (last_smram != NULL)) {
|
||||
fatal("smram_del(): NULL base SMRAM with non-NULL last SMRAM\n");
|
||||
return;
|
||||
} else if ((base_smram != NULL) && (last_smram == NULL)) {
|
||||
fatal("smram_del(): Non-NULL base SMRAM with NULL last SMRAM\n");
|
||||
return;
|
||||
} else if ((base_smram != NULL) && (base_smram->prev != NULL)) {
|
||||
fatal("smram_del(): Base SMRAM with a preceding SMRAM\n");
|
||||
return;
|
||||
} else if ((last_smram != NULL) && (last_smram->next != NULL)) {
|
||||
fatal("smram_del(): Last SMRAM with a following SMRAM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (smr == NULL) {
|
||||
fatal("smram_del(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable the entry. */
|
||||
smram_disable(smr);
|
||||
|
||||
/* Zap it from the list. */
|
||||
if (smr->prev != NULL)
|
||||
smr->prev->next = smr->next;
|
||||
if (smr->next != NULL)
|
||||
smr->next->prev = smr->prev;
|
||||
|
||||
/* Check if it's the first or the last mapping. */
|
||||
if (base_smram == smr)
|
||||
base_smram = smr->next;
|
||||
if (last_smram == smr)
|
||||
last_smram = smr->prev;
|
||||
|
||||
free(smr);
|
||||
}
|
||||
|
||||
|
||||
/* Add a SMRAM mapping. */
|
||||
smram_t *
|
||||
smram_add(void)
|
||||
{
|
||||
smram_t *temp_smram;
|
||||
|
||||
/* Do a sanity check */
|
||||
if ((base_smram == NULL) && (last_smram != NULL)) {
|
||||
fatal("smram_add(): NULL base SMRAM with non-NULL last SMRAM\n");
|
||||
return NULL;
|
||||
} else if ((base_smram != NULL) && (last_smram == NULL)) {
|
||||
fatal("smram_add(): Non-NULL base SMRAM with NULL last SMRAM\n");
|
||||
return NULL;
|
||||
} else if ((base_smram != NULL) && (base_smram->prev != NULL)) {
|
||||
fatal("smram_add(): Base SMRAM with a preceding SMRAM\n");
|
||||
return NULL;
|
||||
} else if ((last_smram != NULL) && (last_smram->next != NULL)) {
|
||||
fatal("smram_add(): Last SMRAM with a following SMRAM\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
temp_smram = (smram_t *) malloc(sizeof(smram_t));
|
||||
if (temp_smram == NULL) {
|
||||
fatal("smram_add(): temp_smram malloc failed\n");
|
||||
return NULL;
|
||||
}
|
||||
memset(temp_smram, 0x00, sizeof(smram_t));
|
||||
memset(&(temp_smram->mapping), 0x00, sizeof(mem_mapping_t));
|
||||
|
||||
/* Add struct to the beginning of the list if necessary.*/
|
||||
if (base_smram == NULL)
|
||||
base_smram = temp_smram;
|
||||
|
||||
/* Add struct to the end of the list.*/
|
||||
if (last_smram == NULL)
|
||||
temp_smram->prev = NULL;
|
||||
else {
|
||||
temp_smram->prev = last_smram;
|
||||
last_smram->next = temp_smram;
|
||||
}
|
||||
last_smram = temp_smram;
|
||||
|
||||
mem_mapping_add(&(temp_smram->mapping), 0x00000000, 0x00000000,
|
||||
smram_read,smram_readw,smram_readl,
|
||||
smram_write,smram_writew,smram_writel,
|
||||
ram, MEM_MAPPING_SMRAM, temp_smram);
|
||||
|
||||
return temp_smram;
|
||||
}
|
||||
|
||||
|
||||
/* Set memory state in the specified model (normal or SMM) according to the specified flags. */
|
||||
void
|
||||
smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
|
||||
{
|
||||
mem_set_mem_state_smram(smm, addr, size, is_smram);
|
||||
}
|
||||
|
||||
|
||||
/* Disable a specific SMRAM mapping. */
|
||||
void
|
||||
smram_disable(smram_t *smr)
|
||||
{
|
||||
if (smr == NULL) {
|
||||
fatal("smram_disable(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (smr->size != 0x00000000) {
|
||||
smram_map(0, smr->host_base, smr->size, 0);
|
||||
smram_map(1, smr->host_base, smr->size, 0);
|
||||
|
||||
smr->host_base = smr->ram_base = 0x00000000;
|
||||
smr->size = 0x00000000;
|
||||
|
||||
mem_mapping_disable(&(smr->mapping));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Disable all SMRAM mappings. */
|
||||
void
|
||||
smram_disable_all(void)
|
||||
{
|
||||
smram_t *temp_smram = base_smram, *next;
|
||||
|
||||
while (temp_smram != NULL) {
|
||||
smram_disable(temp_smram);
|
||||
|
||||
next = temp_smram->next;
|
||||
temp_smram = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Enable SMRAM mappings according to flags for both normal and SMM modes. */
|
||||
void
|
||||
smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, int flags_normal, int flags_smm)
|
||||
{
|
||||
if (smr == NULL) {
|
||||
fatal("smram_add(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((size != 0x00000000) && (flags_normal || flags_smm)) {
|
||||
smr->host_base = host_base;
|
||||
smr->ram_base = ram_base,
|
||||
smr->size = size;
|
||||
|
||||
mem_mapping_set_addr(&(smr->mapping), smr->host_base, smr->size);
|
||||
if (smr->ram_base < (1 << 30))
|
||||
mem_mapping_set_exec(&(smr->mapping), ram + smr->ram_base);
|
||||
else
|
||||
mem_mapping_set_exec(&(smr->mapping), ram2 + smr->ram_base - (1 << 30));
|
||||
|
||||
smram_map(0, host_base, size, flags_normal);
|
||||
smram_map(1, host_base, size, flags_smm);
|
||||
} else
|
||||
smram_disable(smr);
|
||||
}
|
||||
|
||||
|
||||
/* Checks if a SMRAM mapping is enabled or not. */
|
||||
int
|
||||
smram_enabled(smram_t *smr)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (smr == NULL)
|
||||
ret = 0;
|
||||
else
|
||||
ret = (smr->size != 0x00000000);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Changes the SMRAM state. */
|
||||
void
|
||||
smram_state_change(smram_t *smr, int smm, int flags)
|
||||
{
|
||||
if (smr == NULL) {
|
||||
fatal("smram_tate_change(): Invalid SMRAM mapping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
smram_map(smm, smr->host_base, smr->size, flags);
|
||||
}
|
||||
@@ -323,7 +323,7 @@ sst_add_mappings(sst_t *dev)
|
||||
sst_write, NULL, NULL,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
}
|
||||
mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000), 0x10000,
|
||||
mem_mapping_add(&(dev->mapping_h[i]), (base | (cpu_16bitbus ? 0xf00000 : 0xfff00000)), 0x10000,
|
||||
sst_read, sst_readw, sst_readl,
|
||||
sst_write, NULL, NULL,
|
||||
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROMCS, (void *) dev);
|
||||
|
||||
Reference in New Issue
Block a user