|
|
|
|
@@ -108,7 +108,6 @@ int mem_a20_alt = 0;
|
|
|
|
|
int mem_a20_state = 0;
|
|
|
|
|
|
|
|
|
|
int mmuflush = 0;
|
|
|
|
|
int mmu_perm = 4;
|
|
|
|
|
|
|
|
|
|
#ifdef USE_NEW_DYNAREC
|
|
|
|
|
uint64_t *byte_dirty_mask;
|
|
|
|
|
@@ -125,10 +124,6 @@ mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];
|
|
|
|
|
|
|
|
|
|
uint8_t *_mem_exec[MEM_MAPPINGS_NO];
|
|
|
|
|
|
|
|
|
|
/* FIXME: re-do this with a 'mem_ops' struct. */
|
|
|
|
|
static uint8_t *page_lookupp; /* pagetable mmu_perm lookup */
|
|
|
|
|
static uint8_t *readlookupp;
|
|
|
|
|
static uint8_t *writelookupp;
|
|
|
|
|
static mem_mapping_t *base_mapping;
|
|
|
|
|
static mem_mapping_t *last_mapping;
|
|
|
|
|
static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO];
|
|
|
|
|
@@ -187,10 +182,8 @@ resetreadlookup(void)
|
|
|
|
|
|
|
|
|
|
/* Initialize the tables for high (> 1024K) RAM. */
|
|
|
|
|
memset(readlookup2, 0xff, (1 << 20) * sizeof(uintptr_t));
|
|
|
|
|
memset(readlookupp, 0x04, (1 << 20) * sizeof(uint8_t));
|
|
|
|
|
|
|
|
|
|
memset(writelookup2, 0xff, (1 << 20) * sizeof(uintptr_t));
|
|
|
|
|
memset(writelookupp, 0x04, (1 << 20) * sizeof(uint8_t));
|
|
|
|
|
|
|
|
|
|
readlnext = 0;
|
|
|
|
|
writelnext = 0;
|
|
|
|
|
@@ -204,14 +197,11 @@ flushmmucache(void)
|
|
|
|
|
for (uint16_t c = 0; c < 256; c++) {
|
|
|
|
|
if (readlookup[c] != (int) 0xffffffff) {
|
|
|
|
|
readlookup2[readlookup[c]] = LOOKUP_INV;
|
|
|
|
|
readlookupp[readlookup[c]] = 4;
|
|
|
|
|
readlookup[c] = 0xffffffff;
|
|
|
|
|
}
|
|
|
|
|
if (writelookup[c] != (int) 0xffffffff) {
|
|
|
|
|
page_lookup[writelookup[c]] = NULL;
|
|
|
|
|
page_lookupp[writelookup[c]] = 4;
|
|
|
|
|
writelookup2[writelookup[c]] = LOOKUP_INV;
|
|
|
|
|
writelookupp[writelookup[c]] = 4;
|
|
|
|
|
writelookup[c] = 0xffffffff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -231,9 +221,7 @@ flushmmucache_write(void)
|
|
|
|
|
for (uint16_t c = 0; c < 256; c++) {
|
|
|
|
|
if (writelookup[c] != (int) 0xffffffff) {
|
|
|
|
|
page_lookup[writelookup[c]] = NULL;
|
|
|
|
|
page_lookupp[writelookup[c]] = 4;
|
|
|
|
|
writelookup2[writelookup[c]] = LOOKUP_INV;
|
|
|
|
|
writelookupp[writelookup[c]] = 4;
|
|
|
|
|
writelookup[c] = 0xffffffff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -259,14 +247,11 @@ flushmmucache_nopc(void)
|
|
|
|
|
for (uint16_t c = 0; c < 256; c++) {
|
|
|
|
|
if (readlookup[c] != (int) 0xffffffff) {
|
|
|
|
|
readlookup2[readlookup[c]] = LOOKUP_INV;
|
|
|
|
|
readlookupp[readlookup[c]] = 4;
|
|
|
|
|
readlookup[c] = 0xffffffff;
|
|
|
|
|
}
|
|
|
|
|
if (writelookup[c] != (int) 0xffffffff) {
|
|
|
|
|
page_lookup[writelookup[c]] = NULL;
|
|
|
|
|
page_lookupp[writelookup[c]] = 4;
|
|
|
|
|
writelookup2[writelookup[c]] = LOOKUP_INV;
|
|
|
|
|
writelookupp[writelookup[c]] = 4;
|
|
|
|
|
writelookup[c] = 0xffffffff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -348,7 +333,6 @@ mmutranslatereal_normal(uint32_t addr, int rw)
|
|
|
|
|
return 0xffffffffffffffffULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mmu_perm = temp & 4;
|
|
|
|
|
rammap(addr2) |= (rw ? 0x60 : 0x20);
|
|
|
|
|
|
|
|
|
|
uint64_t page = temp & ~0x3fffff;
|
|
|
|
|
@@ -371,7 +355,6 @@ mmutranslatereal_normal(uint32_t addr, int rw)
|
|
|
|
|
return 0xffffffffffffffffULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mmu_perm = temp & 4;
|
|
|
|
|
rammap(addr2) |= 0x20;
|
|
|
|
|
rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw ? 0x60 : 0x20);
|
|
|
|
|
|
|
|
|
|
@@ -435,7 +418,6 @@ mmutranslatereal_pae(uint32_t addr, int rw)
|
|
|
|
|
|
|
|
|
|
return 0xffffffffffffffffULL;
|
|
|
|
|
}
|
|
|
|
|
mmu_perm = temp & 4;
|
|
|
|
|
rammap64(addr3) |= (rw ? 0x60 : 0x20);
|
|
|
|
|
|
|
|
|
|
return ((temp & ~0x1fffffULL) + (addr & 0x1fffffULL)) & 0x000000ffffffffffULL;
|
|
|
|
|
@@ -456,7 +438,6 @@ mmutranslatereal_pae(uint32_t addr, int rw)
|
|
|
|
|
return 0xffffffffffffffffULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mmu_perm = temp & 4;
|
|
|
|
|
rammap64(addr3) |= 0x20;
|
|
|
|
|
rammap64(addr4) |= (rw ? 0x60 : 0x20);
|
|
|
|
|
|
|
|
|
|
@@ -631,7 +612,6 @@ addreadlookup(uint32_t virt, uint32_t phys)
|
|
|
|
|
else
|
|
|
|
|
readlookup2[virt >> 12] = (uintptr_t) &ram[a];
|
|
|
|
|
#endif
|
|
|
|
|
readlookupp[virt >> 12] = mmu_perm;
|
|
|
|
|
|
|
|
|
|
readlookup[readlnext++] = virt >> 12;
|
|
|
|
|
readlnext &= (cachesize - 1);
|
|
|
|
|
@@ -671,7 +651,6 @@ addwritelookup(uint32_t virt, uint32_t phys)
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
page_lookup[virt >> 12] = &pages[phys >> 12];
|
|
|
|
|
page_lookupp[virt >> 12] = mmu_perm;
|
|
|
|
|
} else {
|
|
|
|
|
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
|
|
|
|
writelookup2[virt >> 12] = (uintptr_t) &ram[(uintptr_t) (phys & ~0xFFF) - (uintptr_t) (virt & ~0xfff)];
|
|
|
|
|
@@ -684,7 +663,6 @@ addwritelookup(uint32_t virt, uint32_t phys)
|
|
|
|
|
writelookup2[virt >> 12] = (uintptr_t) &ram[a];
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
writelookupp[virt >> 12] = mmu_perm;
|
|
|
|
|
|
|
|
|
|
writelookup[writelnext++] = virt >> 12;
|
|
|
|
|
writelnext &= (cachesize - 1);
|
|
|
|
|
@@ -973,10 +951,8 @@ readmemwl(uint32_t addr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return readmembl_no_mmut(addr, addr64a[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8);
|
|
|
|
|
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
|
|
|
|
|
mmu_perm = readlookupp[addr >> 12];
|
|
|
|
|
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
|
|
|
|
return *(uint16_t *) (readlookup2[addr >> 12] + addr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cr0 >> 31) {
|
|
|
|
|
@@ -1044,7 +1020,6 @@ writememwl(uint32_t addr, uint16_t val)
|
|
|
|
|
writemembl_no_mmut(addr + 1, addr64a[1], val >> 8);
|
|
|
|
|
return;
|
|
|
|
|
} else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
|
|
|
|
|
mmu_perm = writelookupp[addr >> 12];
|
|
|
|
|
*(uint16_t *) (writelookup2[addr >> 12] + addr) = val;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -1052,7 +1027,6 @@ writememwl(uint32_t addr, uint16_t val)
|
|
|
|
|
|
|
|
|
|
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) {
|
|
|
|
|
page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]);
|
|
|
|
|
mmu_perm = page_lookupp[addr >> 12];
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1100,10 +1074,8 @@ readmemwl_no_mmut(uint32_t addr, uint32_t *a64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return readmembl_no_mmut(addr, a64[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8);
|
|
|
|
|
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
|
|
|
|
|
mmu_perm = readlookupp[addr >> 12];
|
|
|
|
|
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
|
|
|
|
return *(uint16_t *) (readlookup2[addr >> 12] + addr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cr0 >> 31) {
|
|
|
|
|
@@ -1149,14 +1121,12 @@ writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val)
|
|
|
|
|
writemembl_no_mmut(addr + 1, a64[1], val >> 8);
|
|
|
|
|
return;
|
|
|
|
|
} else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
|
|
|
|
|
mmu_perm = writelookupp[addr >> 12];
|
|
|
|
|
*(uint16_t *) (writelookup2[addr >> 12] + addr) = val;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) {
|
|
|
|
|
mmu_perm = page_lookupp[addr >> 12];
|
|
|
|
|
page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -1231,10 +1201,8 @@ readmemll(uint32_t addr)
|
|
|
|
|
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
|
|
|
|
|
their result as a parameter to be used if needed. */
|
|
|
|
|
return readmemwl_no_mmut(addr, addr64a) | (((uint32_t) readmemwl_no_mmut(addr + 2, &(addr64a[2]))) << 16);
|
|
|
|
|
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
|
|
|
|
|
mmu_perm = readlookupp[addr >> 12];
|
|
|
|
|
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
|
|
|
|
return *(uint32_t *) (readlookup2[addr >> 12] + addr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cr0 >> 31) {
|
|
|
|
|
@@ -1316,14 +1284,12 @@ writememll(uint32_t addr, uint32_t val)
|
|
|
|
|
writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16);
|
|
|
|
|
return;
|
|
|
|
|
} else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
|
|
|
|
|
mmu_perm = writelookupp[addr >> 12];
|
|
|
|
|
*(uint32_t *) (writelookup2[addr >> 12] + addr) = val;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) {
|
|
|
|
|
mmu_perm = page_lookupp[addr >> 12];
|
|
|
|
|
page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -1378,10 +1344,8 @@ readmemll_no_mmut(uint32_t addr, uint32_t *a64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return readmemwl_no_mmut(addr, a64) | ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16);
|
|
|
|
|
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
|
|
|
|
|
mmu_perm = readlookupp[addr >> 12];
|
|
|
|
|
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
|
|
|
|
return *(uint32_t *) (readlookup2[addr >> 12] + addr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cr0 >> 31) {
|
|
|
|
|
@@ -1429,14 +1393,12 @@ writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val)
|
|
|
|
|
writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16);
|
|
|
|
|
return;
|
|
|
|
|
} else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
|
|
|
|
|
mmu_perm = writelookupp[addr >> 12];
|
|
|
|
|
*(uint32_t *) (writelookup2[addr >> 12] + addr) = val;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) {
|
|
|
|
|
mmu_perm = page_lookupp[addr >> 12];
|
|
|
|
|
page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -1516,10 +1478,8 @@ readmemql(uint32_t addr)
|
|
|
|
|
/* No need to waste precious CPU host cycles on mmutranslate's that were already done, just pass
|
|
|
|
|
their result as a parameter to be used if needed. */
|
|
|
|
|
return readmemll_no_mmut(addr, addr64a) | (((uint64_t) readmemll_no_mmut(addr + 4, &(addr64a[4]))) << 32);
|
|
|
|
|
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
|
|
|
|
|
mmu_perm = readlookupp[addr >> 12];
|
|
|
|
|
} else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
|
|
|
|
return *(uint64_t *) (readlookup2[addr >> 12] + addr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cr0 >> 31) {
|
|
|
|
|
@@ -1611,14 +1571,12 @@ writememql(uint32_t addr, uint64_t val)
|
|
|
|
|
writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32);
|
|
|
|
|
return;
|
|
|
|
|
} else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) {
|
|
|
|
|
mmu_perm = writelookupp[addr >> 12];
|
|
|
|
|
*(uint64_t *) (writelookup2[addr >> 12] + addr) = val;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) {
|
|
|
|
|
mmu_perm = page_lookupp[addr >> 12];
|
|
|
|
|
page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]);
|
|
|
|
|
page_lookup[addr >> 12]->write_l(addr + 4, val >> 32, page_lookup[addr >> 12]);
|
|
|
|
|
return;
|
|
|
|
|
@@ -1702,8 +1660,7 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write)
|
|
|
|
|
a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff));
|
|
|
|
|
a64[i] = (uint32_t) a;
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
mmu_perm = page_lookupp[addr >> 12];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addr++;
|
|
|
|
|
}
|
|
|
|
|
@@ -2914,7 +2871,6 @@ mem_reset(void)
|
|
|
|
|
pages = (page_t *) malloc(m * sizeof(page_t));
|
|
|
|
|
|
|
|
|
|
memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *));
|
|
|
|
|
memset(page_lookupp, 0x04, (1 << 20) * sizeof(uint8_t));
|
|
|
|
|
|
|
|
|
|
memset(pages, 0x00, pages_sz * sizeof(page_t));
|
|
|
|
|
|
|
|
|
|
@@ -3033,11 +2989,8 @@ mem_init(void)
|
|
|
|
|
|
|
|
|
|
/* Allocate the lookup tables. */
|
|
|
|
|
page_lookup = (page_t **) malloc((1 << 20) * sizeof(page_t *));
|
|
|
|
|
page_lookupp = (uint8_t *) malloc((1 << 20) * sizeof(uint8_t));
|
|
|
|
|
readlookup2 = malloc((1 << 20) * sizeof(uintptr_t));
|
|
|
|
|
readlookupp = malloc((1 << 20) * sizeof(uint8_t));
|
|
|
|
|
writelookup2 = malloc((1 << 20) * sizeof(uintptr_t));
|
|
|
|
|
writelookupp = malloc((1 << 20) * sizeof(uint8_t));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|