mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
m68kmmu: cleanups (#4172)
* m68kmmu: factor out TT register matching into pmmu_match_tt() * m68kmmu: simplify tt/fc matching * m68kmmu: remove dead code * m68kmmu: factor out table walking code * m68kmmu: replace printf by logerror This should be switched over to use LOG(), but can't right now because the header file is included directly in C++ classes.
This commit is contained in:
parent
5dba426a7c
commit
3f19591995
@ -9,6 +9,13 @@
|
||||
|
||||
// MMU status register bit definitions
|
||||
|
||||
|
||||
#if 0
|
||||
#define MMULOG logerror
|
||||
#else
|
||||
#define MMULOG(...)
|
||||
#endif
|
||||
|
||||
static constexpr int M68K_MMU_SR_BUS_ERROR = 0x8000;
|
||||
static constexpr int M68K_MMU_SR_SUPERVISOR_ONLY = 0x2000;
|
||||
static constexpr int M68K_MMU_SR_WRITE_PROTECT = 0x0800;
|
||||
@ -158,7 +165,7 @@ void pmmu_atc_add(uint32_t logical, uint32_t physical, int fc)
|
||||
}
|
||||
|
||||
// add the entry
|
||||
// printf("ATC[%2d] add: log %08x -> phys %08x (fc=%d)\n", found, (logical>>ps) << ps, (physical >> ps) << ps, fc);
|
||||
MMULOG("ATC[%2d] add: log %08x -> phys %08x (fc=%d)\n", found, (logical>>ps) << ps, (physical >> ps) << ps, fc);
|
||||
m_mmu_atc_tag[found] = atc_tag;
|
||||
m_mmu_atc_data[found] = (physical >> ps) << (ps-8);
|
||||
|
||||
@ -176,7 +183,7 @@ void pmmu_atc_add(uint32_t logical, uint32_t physical, int fc)
|
||||
void pmmu_atc_flush()
|
||||
{
|
||||
int i;
|
||||
// printf("ATC flush: pc=%08x\n", m_ppc);
|
||||
MMULOG("ATC flush: pc=%08x\n", m_ppc);
|
||||
|
||||
for (i = 0; i < MMU_ATC_ENTRIES; i++)
|
||||
{
|
||||
@ -269,233 +276,109 @@ bool pmmu_atc_lookup(const uint32_t addr_in, int fc, const bool ptest, uint32_t&
|
||||
m_mmu_tmp_sr = M68K_MMU_SR_MODIFIED;
|
||||
}
|
||||
addr_out = (m_mmu_atc_data[i] << 8) | (addr_in & ~(~0 << ps));
|
||||
// printf("ATC[%2d] hit: log %08x -> phys %08x pc=%08x fc=%d\n", i, addr_in, addr_out, m_ppc, fc);
|
||||
// pmmu_atc_count++;
|
||||
MMULOG("ATC[%2d] hit: log %08x -> phys %08x pc=%08x fc=%d\n", i, addr_in, addr_out, m_ppc, fc);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pmmu_match_tt(uint32_t addr_in, int fc, uint32_t tt)
|
||||
{
|
||||
if (!(tt & 0x8000))
|
||||
return false;
|
||||
|
||||
// transparent translation enabled
|
||||
uint32_t address_base = tt & 0xff000000;
|
||||
uint32_t address_mask = ((tt << 8) & 0xff000000) ^ 0xff000000;
|
||||
return (addr_in & address_mask) == address_base && (fc & ~tt) == ((tt >> 4) & 7);
|
||||
}
|
||||
|
||||
bool pmmu_walk_table(uint32_t& tbl_entry, uint32_t addr_in, int shift, int bits, bool ptest, int fc, int level, uint32_t &addr_out)
|
||||
{
|
||||
// get table offset
|
||||
uint32_t tofs;
|
||||
uint32_t tptr = tbl_entry & 0xfffffff0;
|
||||
int ps = (m_mmu_tc >> 20) & 0xf;
|
||||
// get initial shift (# of top bits to ignore)
|
||||
int is = (m_mmu_tc >> 16) & 0xf;
|
||||
|
||||
shift += is;
|
||||
tofs = (addr_in << shift) >> (32 - bits);
|
||||
|
||||
MMULOG("walk_table: addr_in %08x, table %08x, offset %08x is %d, bits %d\n", addr_in, tptr, tofs, shift, bits);
|
||||
|
||||
switch (tbl_entry & M68K_MMU_DF_DT)
|
||||
{
|
||||
case M68K_MMU_DF_DT0: // invalid, will cause MMU exception
|
||||
m_mmu_tmp_sr |= M68K_MMU_SR_INVALID | level;
|
||||
addr_out = tbl_entry;
|
||||
return true;
|
||||
|
||||
case M68K_MMU_DF_DT1: // page descriptor, will cause direct mapping
|
||||
tbl_entry &= (~0 << ps);
|
||||
addr_out = ((addr_in << shift) >> shift) + tbl_entry;
|
||||
MMULOG("PMMU: DT1 PC=%x (addr_in %08x -> %08x)\n", m_ppc, addr_in, addr_out);
|
||||
return true;
|
||||
|
||||
case M68K_MMU_DF_DT2: // valid 4 byte descriptors
|
||||
tofs *= 4;
|
||||
tbl_entry = get_dt2_table_entry(tptr + tofs, ptest);
|
||||
MMULOG("PMMU: DT2 read table entry at %08x: %08x\n", tofs + tptr, tbl_entry);
|
||||
return false;
|
||||
|
||||
case M68K_MMU_DF_DT3: // valid 8 byte descriptors
|
||||
tofs *= 8;
|
||||
tbl_entry = get_dt3_table_entry(tofs + tptr, fc, ptest);
|
||||
MMULOG("PMMU: DT3 read table A entries at %08x\n", tofs + tptr, tbl_entry);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
pmmu_translate_addr_with_fc: perform 68851/68030-style PMMU address translation
|
||||
*/
|
||||
uint32_t pmmu_translate_addr_with_fc(uint32_t addr_in, uint8_t fc, uint8_t ptest)
|
||||
{
|
||||
uint32_t addr_out, tbl_entry = 0, tamode = 0, tbmode = 0, tcmode = 0;
|
||||
uint32_t root_aptr, root_limit, tofs, ps, is, abits, bbits, cbits;
|
||||
uint32_t resolved, tptr, shift, last_entry_ptr;
|
||||
// int verbose = 0;
|
||||
uint32_t addr_out, tbl_entry;
|
||||
uint32_t abits, bbits, cbits, dbits;
|
||||
|
||||
// static uint32_t pmmu_access_count = 0;
|
||||
// static uint32_t pmmu_atc_count = 0;
|
||||
|
||||
resolved = 0;
|
||||
addr_out = addr_in;
|
||||
m_mmu_tmp_sr = 0;
|
||||
|
||||
if (fc == 7)
|
||||
if (fc == 7 ||
|
||||
pmmu_match_tt(addr_in, fc, m_mmu_tt0) ||
|
||||
pmmu_match_tt(addr_in, fc, m_mmu_tt1))
|
||||
{
|
||||
return addr_in;
|
||||
}
|
||||
|
||||
if (m_mmu_tt0 & 0x8000)
|
||||
{
|
||||
// transparent translation register 0 enabled
|
||||
uint32_t address_base = m_mmu_tt0 & 0xff000000;
|
||||
uint32_t address_mask = ((m_mmu_tt0 << 8) & 0xff000000) ^ 0xff000000;
|
||||
if ((addr_in & address_mask) == address_base && (fc & ~m_mmu_tt0) == ((m_mmu_tt0 >> 4) & 7))
|
||||
{
|
||||
// printf("PMMU: pc=%x TT0 fc=%x addr_in=%08x address_mask=%08x address_base=%08x\n", m_ppc, fc, addr_in, address_mask, address_base);
|
||||
return addr_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_mmu_tt1 & 0x8000)
|
||||
{
|
||||
// transparent translation register 1 enabled
|
||||
uint32_t address_base = m_mmu_tt1 & 0xff000000;
|
||||
uint32_t address_mask = ((m_mmu_tt1 << 8) & 0xff000000) ^ 0xff000000;
|
||||
if ((addr_in & address_mask) == address_base && (fc & ~m_mmu_tt1) == ((m_mmu_tt1 >> 4) & 7))
|
||||
{
|
||||
// printf("PMMU: pc=%x TT1 fc=%x addr_in=%08x address_mask=%08x address_base=%08x\n", m_ppc, fc, addr_in, address_mask, address_base);
|
||||
return addr_in;
|
||||
}
|
||||
}
|
||||
|
||||
// if ((++pmmu_access_count % 10000000) == 0) {
|
||||
// printf("pmmu_translate_addr_with_fc: atc usage = %d%%\n", pmmu_atc_count*100/pmmu_access_count);
|
||||
// pmmu_atc_count = pmmu_access_count = 0;
|
||||
// }
|
||||
|
||||
// get page size (i.e. # of bits to ignore); ps is 10 or 12 for Apollo, 8 otherwise
|
||||
ps = (m_mmu_tc >> 20) & 0xf;
|
||||
|
||||
if (pmmu_atc_lookup(addr_in, fc, ptest, addr_out))
|
||||
{
|
||||
return addr_out;
|
||||
}
|
||||
|
||||
// if SRP is enabled and we're in supervisor mode, use it
|
||||
if ((m_mmu_tc & M68K_MMU_TC_SRE) && (fc & 4))
|
||||
{
|
||||
root_aptr = m_mmu_srp_aptr;
|
||||
root_limit = m_mmu_srp_limit;
|
||||
tbl_entry = (m_mmu_srp_aptr & 0xfffffff0) | (m_mmu_srp_limit & M68K_MMU_DF_DT);
|
||||
}
|
||||
else // else use the CRP
|
||||
{
|
||||
root_aptr = m_mmu_crp_aptr;
|
||||
root_limit = m_mmu_crp_limit;
|
||||
tbl_entry = (m_mmu_crp_aptr & 0xfffffff0) | (m_mmu_crp_limit & M68K_MMU_DF_DT);
|
||||
}
|
||||
|
||||
// get initial shift (# of top bits to ignore)
|
||||
is = (m_mmu_tc >> 16) & 0xf;
|
||||
ps = (m_mmu_tc >> 20) & 0xf;
|
||||
abits = (m_mmu_tc >> 12) & 0xf;
|
||||
bbits = (m_mmu_tc >> 8) & 0xf;
|
||||
cbits = (m_mmu_tc >> 4) & 0xf;
|
||||
dbits = m_mmu_tc & 0x0f;
|
||||
|
||||
// printf("PMMU: tcr %08x limit %08x aptr %08x is %x abits %d bbits %d cbits %d\n", m_mmu_tc, root_limit, root_aptr, is, abits, bbits, cbits);
|
||||
|
||||
// get table A offset
|
||||
tofs = (addr_in<<is)>>(32-abits);
|
||||
tptr = root_aptr & 0xfffffff0;
|
||||
|
||||
// find out what format table A is
|
||||
switch (root_limit & M68K_MMU_DF_DT)
|
||||
if (!pmmu_walk_table(tbl_entry, addr_in, 0 , abits, ptest, fc, 0, addr_out) &&
|
||||
!pmmu_walk_table(tbl_entry, addr_in, abits , bbits, ptest, fc, 1, addr_out) &&
|
||||
!pmmu_walk_table(tbl_entry, addr_in, abits + bbits , cbits, ptest, fc, 2, addr_out) &&
|
||||
!pmmu_walk_table(tbl_entry, addr_in, abits + bbits + cbits, dbits, ptest, fc, 3, addr_out))
|
||||
{
|
||||
case M68K_MMU_DF_DT0: // invalid, will cause MMU exception
|
||||
m_mmu_tmp_sr |= M68K_MMU_SR_INVALID;
|
||||
return root_aptr;
|
||||
|
||||
case M68K_MMU_DF_DT1: // page descriptor, will cause direct mapping
|
||||
addr_out = tptr + addr_in;
|
||||
// printf("PMMU: PC=%x root mode %d (addr_in %08x -> %08x)\n", m_ppc, M68K_MMU_DF_DT1, addr_in, addr_out);
|
||||
return addr_out;
|
||||
|
||||
case M68K_MMU_DF_DT2: // valid 4 byte descriptors
|
||||
tofs *= 4;
|
||||
// if (verbose) printf("PMMU: reading table A entry at %08x\n", tofs + tptr);
|
||||
tbl_entry = get_dt2_table_entry(tptr + tofs, ptest);
|
||||
tamode = tbl_entry & M68K_MMU_DF_DT;
|
||||
// if (verbose) printf("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tamode, tofs);
|
||||
break;
|
||||
|
||||
case M68K_MMU_DF_DT3: // valid 8 byte descriptors
|
||||
tofs *= 8;
|
||||
// if (verbose) printf("PMMU: reading table A entries at %08x\n", tofs + tptr);
|
||||
tbl_entry = get_dt3_table_entry(tofs + tptr, fc, ptest);
|
||||
tamode = tbl_entry & M68K_MMU_DF_DT;
|
||||
// if (verbose) printf("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tamode, tofs);
|
||||
break;
|
||||
}
|
||||
|
||||
last_entry_ptr = tptr + tofs;
|
||||
|
||||
// get table B offset and pointer
|
||||
tofs = (addr_in<<(is+abits))>>(32-bbits);
|
||||
tptr = tbl_entry & 0xfffffff0;
|
||||
|
||||
// find out what format table B is, if any
|
||||
switch (tamode)
|
||||
{
|
||||
case M68K_MMU_DF_DT0: // invalid, will cause MMU exception (but not for ptest)
|
||||
m_mmu_tmp_sr |= (M68K_MMU_SR_INVALID | M68K_MMU_SR_LEVEL_1);
|
||||
// last valid pointer (for ptest)
|
||||
addr_out = last_entry_ptr;
|
||||
resolved = 1;
|
||||
break;
|
||||
|
||||
case M68K_MMU_DF_DT2: // 4-byte table B descriptor
|
||||
tofs *= 4;
|
||||
// if (verbose) printf("PMMU: reading table B entry at %08x\n", tofs + tptr);
|
||||
tbl_entry = get_dt2_table_entry(tptr + tofs, ptest);
|
||||
tbmode = tbl_entry & M68K_MMU_DF_DT;
|
||||
// if (verbose) printf("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs);
|
||||
break;
|
||||
|
||||
case M68K_MMU_DF_DT3: // 8-byte table B descriptor
|
||||
tofs *= 8;
|
||||
// if (verbose) printf("PMMU: reading table B entries at %08x\n", tofs + tptr);
|
||||
tbl_entry = get_dt3_table_entry(tptr + tofs, fc, ptest);
|
||||
tbmode = tbl_entry & M68K_MMU_DF_DT;
|
||||
tbl_entry &= ~M68K_MMU_DF_DT;
|
||||
// if (verbose) printf("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tbmode, tofs);
|
||||
break;
|
||||
|
||||
case M68K_MMU_DF_DT1: // early termination descriptor
|
||||
tbl_entry &= (~0 << ps);
|
||||
|
||||
shift = is+abits;
|
||||
addr_out = ((addr_in<<shift)>>shift) + tbl_entry;
|
||||
resolved = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// if table A wasn't early-out, continue to process table B
|
||||
if (!resolved)
|
||||
{
|
||||
last_entry_ptr = tptr + tofs;
|
||||
|
||||
// get table C offset and pointer
|
||||
tofs = (addr_in<<(is+abits+bbits))>>(32-cbits);
|
||||
tptr = tbl_entry & 0xfffffff0;
|
||||
|
||||
switch (tbmode)
|
||||
{
|
||||
case M68K_MMU_DF_DT0: // invalid, will cause MMU exception (but not for ptest)
|
||||
m_mmu_tmp_sr |= (M68K_MMU_SR_INVALID | M68K_MMU_SR_LEVEL_2);
|
||||
// last valid pointer (for ptest)
|
||||
addr_out = last_entry_ptr;
|
||||
resolved = 1;
|
||||
break;
|
||||
|
||||
case M68K_MMU_DF_DT2: // 4-byte table C descriptor
|
||||
tofs *= 4;
|
||||
// if (verbose) printf("PMMU: reading table C entry at %08x\n", tofs + tptr);
|
||||
tbl_entry = get_dt2_table_entry(tptr + tofs, ptest);
|
||||
tcmode = tbl_entry & M68K_MMU_DF_DT;
|
||||
// if (verbose) printf("PMMU: addr %08x entry %08x mode %x tofs %x\n", addr_in, tbl_entry, tbmode, tofs);
|
||||
break;
|
||||
|
||||
case M68K_MMU_DF_DT3: // 8-byte table C descriptor
|
||||
tofs *= 8;
|
||||
// if (verbose) printf("PMMU: reading table C entries at %08x\n", tofs + tptr);
|
||||
tbl_entry = get_dt3_table_entry(tptr+ tofs, fc, ptest);
|
||||
tcmode = tbl_entry & M68K_MMU_DF_DT;
|
||||
// if (verbose) printf("PMMU: addr %08x entry %08x entry2 %08x mode %x tofs %x\n", addr_in, tbl_entry, tbl_entry2, tcmode, tofs);
|
||||
break;
|
||||
|
||||
case M68K_MMU_DF_DT1: // termination descriptor
|
||||
tbl_entry &= (~0 << ps);
|
||||
|
||||
shift = is+abits+bbits;
|
||||
addr_out = ((addr_in<<shift)>>shift) + tbl_entry;
|
||||
resolved = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!resolved)
|
||||
{
|
||||
switch (tcmode)
|
||||
{
|
||||
case M68K_MMU_DF_DT0: // invalid, will cause MMU exception (unless ptest)
|
||||
m_mmu_tmp_sr |= (M68K_MMU_SR_INVALID | M68K_MMU_SR_LEVEL_3);
|
||||
addr_out = tptr + tofs;
|
||||
resolved = 1;
|
||||
break;
|
||||
|
||||
case M68K_MMU_DF_DT2: // 4-byte (short-form) indirect descriptor
|
||||
case M68K_MMU_DF_DT3: // 8-byte (long-form) indirect descriptor
|
||||
fatalerror("PMMU: pc=%08x Unhandled Table C mode %d (addr_in %08x)\n", m_ppc, tcmode, addr_in);
|
||||
break;
|
||||
|
||||
case M68K_MMU_DF_DT1: // termination descriptor
|
||||
tbl_entry &= (~0 << ps);
|
||||
|
||||
shift = is+abits+bbits+cbits;
|
||||
addr_out = ((addr_in<<shift)>>shift) + tbl_entry;
|
||||
resolved = 1;
|
||||
break;
|
||||
}
|
||||
fatalerror("Table walk did not resolve\n");
|
||||
}
|
||||
|
||||
if (!ptest)
|
||||
@ -514,7 +397,7 @@ uint32_t pmmu_translate_addr_with_fc(uint32_t addr_in, uint8_t fc, uint8_t ptest
|
||||
}
|
||||
}
|
||||
|
||||
//printf("PMMU: [%08x] => [%08x]\n", addr_in, addr_out);
|
||||
MMULOG("PMMU: [%08x] => [%08x]\n", addr_in, addr_out);
|
||||
|
||||
return addr_out;
|
||||
}
|
||||
@ -557,7 +440,7 @@ uint32_t pmmu_translate_addr_with_fc_040(uint32_t addr_in, uint8_t fc, uint8_t p
|
||||
|
||||
if ((addr_in & mask) == (tt0 & mask) && (fc & fcmask[(tt0 >> 13) & 3]) == fcmatch[(tt0 >> 13) & 3])
|
||||
{
|
||||
// fprintf(stderr, "TT0 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt0, mask);
|
||||
MMULOG("TT0 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt0, mask);
|
||||
if ((tt0 & 4) && !m_mmu_tmp_rw && !ptest) // write protect?
|
||||
{
|
||||
pmmu_set_buserror(addr_in);
|
||||
@ -577,7 +460,7 @@ uint32_t pmmu_translate_addr_with_fc_040(uint32_t addr_in, uint8_t fc, uint8_t p
|
||||
|
||||
if ((addr_in & mask) == (tt1 & mask) && (fc & fcmask[(tt1 >> 13) & 3]) == fcmatch[(tt1 >> 13) & 3])
|
||||
{
|
||||
// fprintf(stderr, "TT1 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt1, mask);
|
||||
MMULOG("TT1 match on address %08x (TT0 = %08x, mask = %08x)\n", addr_in, tt1, mask);
|
||||
if ((tt1 & 4) && !m_mmu_tmp_rw && !ptest) // write protect?
|
||||
{
|
||||
pmmu_set_buserror(addr_in);
|
||||
@ -640,7 +523,7 @@ uint32_t pmmu_translate_addr_with_fc_040(uint32_t addr_in, uint8_t fc, uint8_t p
|
||||
m_program->write_dword(pointer_ptr, pointer_entry);
|
||||
}
|
||||
|
||||
// logerror("pointer entry = %08x\n", pointer_entry);
|
||||
MMULOG("pointer entry = %08x\n", pointer_entry);
|
||||
|
||||
// write protected by the root or pointer entries?
|
||||
if ((((root_entry & 4) && !m_mmu_tmp_rw) || ((pointer_entry & 4) && !m_mmu_tmp_rw)) && !ptest)
|
||||
@ -652,7 +535,7 @@ uint32_t pmmu_translate_addr_with_fc_040(uint32_t addr_in, uint8_t fc, uint8_t p
|
||||
// is UDT valid on the pointer entry?
|
||||
if (!(pointer_entry & 2) && !ptest)
|
||||
{
|
||||
// fprintf(stderr, "Invalid pointer entry! PC=%x, addr=%x\n", m_ppc, addr_in);
|
||||
logerror("Invalid pointer entry! PC=%x, addr=%x\n", m_ppc, addr_in);
|
||||
pmmu_set_buserror(addr_in);
|
||||
return addr_in;
|
||||
}
|
||||
@ -661,7 +544,7 @@ uint32_t pmmu_translate_addr_with_fc_040(uint32_t addr_in, uint8_t fc, uint8_t p
|
||||
}
|
||||
else // throw an error
|
||||
{
|
||||
// fprintf(stderr, "Invalid root entry! PC=%x, addr=%x\n", m_ppc, addr_in);
|
||||
logerror("Invalid root entry! PC=%x, addr=%x\n", m_ppc, addr_in);
|
||||
|
||||
if (!ptest)
|
||||
{
|
||||
@ -677,21 +560,21 @@ uint32_t pmmu_translate_addr_with_fc_040(uint32_t addr_in, uint8_t fc, uint8_t p
|
||||
page_idx = (addr_in >> 13) & 0x1f;
|
||||
page = addr_in & 0x1fff;
|
||||
pointer_entry &= ~0x7f;
|
||||
// logerror("8k pages: index %x page %x\n", page_idx, page);
|
||||
MMULOG("8k pages: index %x page %x\n", page_idx, page);
|
||||
}
|
||||
else // 4k pages
|
||||
{
|
||||
page_idx = (addr_in >> 12) & 0x3f;
|
||||
page = addr_in & 0xfff;
|
||||
pointer_entry &= ~0xff;
|
||||
// logerror("4k pages: index %x page %x\n", page_idx, page);
|
||||
MMULOG("4k pages: index %x page %x\n", page_idx, page);
|
||||
}
|
||||
|
||||
page_ptr = pointer_entry + (page_idx<<2);
|
||||
page_entry = m_program->read_dword(page_ptr);
|
||||
m_mmu_last_page_entry_addr = page_ptr;
|
||||
|
||||
// logerror("page_entry = %08x\n", page_entry);
|
||||
MMULOG("page_entry = %08x\n", page_entry);
|
||||
|
||||
// resolve indirect page pointers
|
||||
while ((page_entry & 3) == 2)
|
||||
@ -711,7 +594,7 @@ uint32_t pmmu_translate_addr_with_fc_040(uint32_t addr_in, uint8_t fc, uint8_t p
|
||||
switch (page_entry & 3)
|
||||
{
|
||||
case 0: // invalid
|
||||
// fprintf(stderr, "Invalid page entry! PC=%x, addr=%x\n", m_ppc, addr_in);
|
||||
MMULOG("Invalid page entry! PC=%x, addr=%x\n", m_ppc, addr_in);
|
||||
if (!ptest)
|
||||
{
|
||||
pmmu_set_buserror(addr_in);
|
||||
@ -759,7 +642,7 @@ uint32_t pmmu_translate_addr_with_fc_040(uint32_t addr_in, uint8_t fc, uint8_t p
|
||||
fatalerror("68040: got indirect final page pointer, shouldn't be possible\n");
|
||||
break;
|
||||
}
|
||||
// if (addr_in != addr_out) fprintf(stderr, "040MMU: [%08x] => [%08x]\n", addr_in, addr_out);
|
||||
// if (addr_in != addr_out) MMULOG("040MMU: [%08x] => [%08x]\n", addr_in, addr_out);
|
||||
}
|
||||
|
||||
return addr_out;
|
||||
@ -782,7 +665,7 @@ uint32_t pmmu_translate_addr(uint32_t addr_in)
|
||||
}
|
||||
|
||||
// if (m_mmu_tmp_buserror_occurred > 0) {
|
||||
// printf("PMMU: pc=%08x sp=%08x va=%08x pa=%08x - invalid Table mode for level=%d (buserror %d)\n",
|
||||
// MMULOG("PMMU: pc=%08x sp=%08x va=%08x pa=%08x - invalid Table mode for level=%d (buserror %d)\n",
|
||||
// m_ppc, REG_A()[7], addr_in, addr_out, m_mmu_tmp_sr & M68K_MMU_SR_LEVEL_3,
|
||||
// m_mmu_tmp_buserror_occurred);
|
||||
// }
|
||||
@ -804,17 +687,17 @@ void m68881_mmu_ops()
|
||||
// catch the 2 "weird" encodings up front (PBcc)
|
||||
if ((m_ir & 0xffc0) == 0xf0c0)
|
||||
{
|
||||
printf("680x0: unhandled PBcc\n");
|
||||
logerror("680x0: unhandled PBcc\n");
|
||||
return;
|
||||
}
|
||||
else if ((m_ir & 0xffc0) == 0xf080)
|
||||
{
|
||||
printf("680x0: unhandled PBcc\n");
|
||||
logerror("680x0: unhandled PBcc\n");
|
||||
return;
|
||||
}
|
||||
else if ((m_ir & 0xffe0) == 0xf500)
|
||||
{
|
||||
// logerror("68040 pflush: pc=%08x ir=%04x opmode=%d register=%d\n", m_ppc, m_ir, (m_ir >> 3) & 3, m_ir & 7);
|
||||
MMULOG("68040 pflush: pc=%08x ir=%04x opmode=%d register=%d\n", m_ppc, m_ir, (m_ir >> 3) & 3, m_ir & 7);
|
||||
pmmu_atc_flush();
|
||||
}
|
||||
else // the rest are 1111000xxxXXXXXX where xxx is the instruction family
|
||||
@ -842,7 +725,7 @@ void m68881_mmu_ops()
|
||||
}
|
||||
}
|
||||
|
||||
// printf("680x0: PLOADing ATC with logical %08x => phys %08x\n", ltmp, ptmp);
|
||||
MMULOG("680x0: PLOADing ATC with logical %08x => phys %08x\n", ltmp, ptmp);
|
||||
// FIXME: rw bit?
|
||||
pmmu_atc_add(ltmp, ptmp, modes & 0x07);
|
||||
return;
|
||||
@ -859,12 +742,12 @@ void m68881_mmu_ops()
|
||||
}
|
||||
else if (modes == 0x2800) // PVALID (FORMAT 1)
|
||||
{
|
||||
printf("680x0: unhandled PVALID1\n");
|
||||
logerror("680x0: unhandled PVALID1\n");
|
||||
return;
|
||||
}
|
||||
else if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2)
|
||||
{
|
||||
printf("680x0: unhandled PVALID2\n");
|
||||
logerror("680x0: unhandled PVALID2\n");
|
||||
return;
|
||||
}
|
||||
else if ((modes & 0xe000) == 0x8000) // PTEST
|
||||
@ -894,8 +777,8 @@ void m68881_mmu_ops()
|
||||
}
|
||||
m_mmu_sr = m_mmu_tmp_sr;
|
||||
|
||||
// printf("PMMU: pc=%08x sp=%08x va=%08x pa=%08x PTEST fc=%x level=%x mmu_sr=%04x\n",
|
||||
// m_ppc, REG_A()[7], v_addr, p_addr, fc, (modes >> 10) & 0x07, m_mmu_sr);
|
||||
MMULOG("PMMU: pc=%08x sp=%08x va=%08x pa=%08x PTEST fc=%x level=%x mmu_sr=%04x\n",
|
||||
m_ppc, REG_A()[7], v_addr, p_addr, fc, (modes >> 10) & 0x07, m_mmu_sr);
|
||||
|
||||
if (modes & 0x100)
|
||||
{
|
||||
@ -916,29 +799,29 @@ void m68881_mmu_ops()
|
||||
{
|
||||
case 0x02: // transparent translation register 0
|
||||
WRITE_EA_32(ea, m_mmu_tt0);
|
||||
// printf("PMMU: pc=%x PMOVE from mmu_tt0=%08x\n", m_ppc, m_mmu_tt0);
|
||||
MMULOG("PMMU: pc=%x PMOVE from mmu_tt0=%08x\n", m_ppc, m_mmu_tt0);
|
||||
break;
|
||||
case 0x03: // transparent translation register 1
|
||||
WRITE_EA_32(ea, m_mmu_tt1);
|
||||
// printf("PMMU: pc=%x PMOVE from mmu_tt1=%08x\n", m_ppc, m_mmu_tt1);
|
||||
MMULOG("PMMU: pc=%x PMOVE from mmu_tt1=%08x\n", m_ppc, m_mmu_tt1);
|
||||
break;
|
||||
case 0x10: // translation control register
|
||||
WRITE_EA_32(ea, m_mmu_tc);
|
||||
// printf("PMMU: pc=%x PMOVE from mmu_tc=%08x\n", m_ppc, m_mmu_tc);
|
||||
MMULOG("PMMU: pc=%x PMOVE from mmu_tc=%08x\n", m_ppc, m_mmu_tc);
|
||||
break;
|
||||
|
||||
case 0x12: // supervisor root pointer
|
||||
WRITE_EA_64(ea, (uint64_t)m_mmu_srp_limit<<32 | (uint64_t)m_mmu_srp_aptr);
|
||||
// printf("PMMU: pc=%x PMOVE from SRP limit = %08x, aptr = %08x\n", m_ppc, m_mmu_srp_limit, m_mmu_srp_aptr);
|
||||
MMULOG("PMMU: pc=%x PMOVE from SRP limit = %08x, aptr = %08x\n", m_ppc, m_mmu_srp_limit, m_mmu_srp_aptr);
|
||||
break;
|
||||
|
||||
case 0x13: // CPU root pointer
|
||||
WRITE_EA_64(ea, (uint64_t)m_mmu_crp_limit<<32 | (uint64_t)m_mmu_crp_aptr);
|
||||
// printf("PMMU: pc=%x PMOVE from CRP limit = %08x, aptr = %08x\n", m_ppc, m_mmu_crp_limit, m_mmu_crp_aptr);
|
||||
MMULOG("PMMU: pc=%x PMOVE from CRP limit = %08x, aptr = %08x\n", m_ppc, m_mmu_crp_limit, m_mmu_crp_aptr);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, m_pc);
|
||||
logerror("680x0: PMOVE from unknown MMU register %x, PC %x\n", (modes>>10) & 7, m_pc);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -963,7 +846,7 @@ void m68881_mmu_ops()
|
||||
break;
|
||||
|
||||
case 1:
|
||||
printf("680x0: unknown PMOVE case 1, PC %x\n", m_pc);
|
||||
logerror("680x0: unknown PMOVE case 1, PC %x\n", m_pc);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@ -971,7 +854,7 @@ void m68881_mmu_ops()
|
||||
{
|
||||
case 0: // translation control register
|
||||
m_mmu_tc = READ_EA_32(ea);
|
||||
// printf("PMMU: TC = %08x\n", m_mmu_tc);
|
||||
MMULOG("PMMU: TC = %08x\n", m_mmu_tc);
|
||||
|
||||
if (m_mmu_tc & 0x80000000)
|
||||
{
|
||||
@ -987,12 +870,12 @@ void m68881_mmu_ops()
|
||||
} else {
|
||||
m_pmmu_enabled = 1;
|
||||
}
|
||||
// printf("PMMU enabled\n");
|
||||
MMULOG("PMMU enabled\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pmmu_enabled = 0;
|
||||
// printf("PMMU disabled\n");
|
||||
MMULOG("PMMU disabled\n");
|
||||
}
|
||||
|
||||
if (!(modes & 0x100)) // flush ATC on moves to TC, SRP, CRP with FD bit clear
|
||||
@ -1005,7 +888,7 @@ void m68881_mmu_ops()
|
||||
temp64 = READ_EA_64(ea);
|
||||
m_mmu_srp_limit = (temp64>>32) & 0xffffffff;
|
||||
m_mmu_srp_aptr = temp64 & 0xffffffff;
|
||||
// printf("PMMU: SRP limit = %08x aptr = %08x\n", m_mmu_srp_limit, m_mmu_srp_aptr);
|
||||
MMULOG("PMMU: SRP limit = %08x aptr = %08x\n", m_mmu_srp_limit, m_mmu_srp_aptr);
|
||||
// SRP type 0 is not allowed
|
||||
if ((m_mmu_srp_limit & 3) == 0) {
|
||||
m68ki_exception_trap(EXCEPTION_MMU_CONFIGURATION);
|
||||
@ -1022,7 +905,7 @@ void m68881_mmu_ops()
|
||||
temp64 = READ_EA_64(ea);
|
||||
m_mmu_crp_limit = (temp64>>32) & 0xffffffff;
|
||||
m_mmu_crp_aptr = temp64 & 0xffffffff;
|
||||
// printf("PMMU: CRP limit = %08x aptr = %08x\n", m_mmu_crp_limit, m_mmu_crp_aptr);
|
||||
MMULOG("PMMU: CRP limit = %08x aptr = %08x\n", m_mmu_crp_limit, m_mmu_crp_aptr);
|
||||
// CRP type 0 is not allowed
|
||||
if ((m_mmu_crp_limit & 3) == 0) {
|
||||
m68ki_exception_trap(EXCEPTION_MMU_CONFIGURATION);
|
||||
@ -1043,7 +926,7 @@ void m68881_mmu_ops()
|
||||
uint16_t mmu_ac = READ_EA_16(ea);
|
||||
if (mmu_ac != 0)
|
||||
{
|
||||
printf("680x0 PMMU: pc=%x PMOVE to mmu_ac=%08x\n",
|
||||
MMULOG("680x0 PMMU: pc=%x PMOVE to mmu_ac=%08x\n",
|
||||
m_ppc, mmu_ac);
|
||||
}
|
||||
break;
|
||||
@ -1051,7 +934,7 @@ void m68881_mmu_ops()
|
||||
// fall through; unknown PMOVE mode unless MC68020 with MC68851
|
||||
|
||||
default:
|
||||
printf("680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, m_pc);
|
||||
logerror("680x0: PMOVE to unknown MMU register %x, PC %x\n", (modes>>10) & 7, m_pc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1059,7 +942,7 @@ void m68881_mmu_ops()
|
||||
case 3: // MMU status
|
||||
{
|
||||
uint32_t temp = READ_EA_32(ea);
|
||||
printf("680x0: unsupported PMOVE %x to MMU status, PC %x\n", temp, m_pc);
|
||||
logerror("680x0: unsupported PMOVE %x to MMU status, PC %x\n", temp, m_pc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1078,7 +961,7 @@ void m68881_mmu_ops()
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes>>13) & 0x7, modes, m_pc);
|
||||
logerror("680x0: unknown PMOVE mode %x (modes %04x) (PC %x)\n", (modes>>13) & 0x7, modes, m_pc);
|
||||
break;
|
||||
|
||||
}
|
||||
@ -1086,7 +969,7 @@ void m68881_mmu_ops()
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("680x0: unknown PMMU instruction group %d\n", (m_ir>>9) & 0x7);
|
||||
logerror("680x0: unknown PMMU instruction group %d\n", (m_ir>>9) & 0x7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user