m68kmmu: factor out atc lookup into pmmu_atc_lookup()

This commit is contained in:
Sven Schnelle 2018-10-20 20:40:24 +02:00
parent 6e5965a939
commit 5fce6d4273

View File

@ -234,6 +234,48 @@ inline uint32_t get_dt3_table_entry(uint32_t tptr, uint8_t fc, uint8_t ptest)
return (tbl_entry & ~M68K_MMU_DF_DT) | dt;
}
bool pmmu_atc_lookup(const uint32_t addr_in, int fc, const bool ptest, uint32_t& addr_out)
{
int ps = (m_mmu_tc >> 20) & 0xf;
uint32_t atc_tag = M68K_MMU_ATC_VALID | ((fc &7) << 24) | addr_in >> ps;
// first see if this is already in the ATC
for (int i = 0; i < MMU_ATC_ENTRIES; i++)
{
if (m_mmu_atc_tag[i] != atc_tag)
{
// tag bits and function code don't match
}
else if (!m_mmu_tmp_rw && (m_mmu_atc_data[i] & M68K_MMU_ATC_WRITE_PR))
{
// write mode, but write protected
}
else if (!m_mmu_tmp_rw && !(m_mmu_atc_data[i] & M68K_MMU_ATC_MODIFIED))
{
// first write; must set modified in PMMU tables as well
}
else
{
// read access or write access and not write protected
if (!m_mmu_tmp_rw && !ptest)
{
// FIXME: must set modified in PMMU tables as well
m_mmu_atc_data[i] |= M68K_MMU_ATC_MODIFIED;
}
else
{
// FIXME: supervisor mode?
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++;
return true;
}
}
return false;
}
/*
pmmu_translate_addr_with_fc: perform 68851/68030-style PMMU address translation
*/
@ -242,8 +284,6 @@ 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 i;
uint32_t atc_tag;
// int verbose = 0;
// static uint32_t pmmu_access_count = 0;
@ -289,42 +329,9 @@ uint32_t pmmu_translate_addr_with_fc(uint32_t addr_in, uint8_t fc, uint8_t ptest
// get page size (i.e. # of bits to ignore); ps is 10 or 12 for Apollo, 8 otherwise
ps = (m_mmu_tc >> 20) & 0xf;
atc_tag = M68K_MMU_ATC_VALID | ((fc &7) << 24) | addr_in >> ps;
// first see if this is already in the ATC
for (i = 0; i < MMU_ATC_ENTRIES; i++)
{
if (m_mmu_atc_tag[i] != atc_tag)
{
// tag bits and function code don't match
}
else if (!m_mmu_tmp_rw && (m_mmu_atc_data[i] & M68K_MMU_ATC_WRITE_PR))
{
// write mode, but write protected
}
else if (!m_mmu_tmp_rw && !(m_mmu_atc_data[i] & M68K_MMU_ATC_MODIFIED))
{
// first write; must set modified in PMMU tables as well
}
else
{
// read access or write access and not write protected
if (!m_mmu_tmp_rw && !ptest)
{
// FIXME: must set modified in PMMU tables as well
m_mmu_atc_data[i] |= M68K_MMU_ATC_MODIFIED;
}
else
{
// FIXME: supervisor mode?
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++;
return addr_out;
}
}
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))