sun4c: More MMU fixes, makes SPARCstation SLC, IPX and 1+ happier, though not yet completely. [Ryan Holtz]

This commit is contained in:
mooglyguy 2018-09-29 10:56:29 +02:00
parent ab28690b71
commit fc37ac35b0
3 changed files with 36 additions and 19 deletions

View File

@ -230,15 +230,15 @@ uint32_t sun4c_mmu_device::system_r(const uint32_t offset, const uint32_t mem_ma
case 6: // bus error register
{
//printf("sun4c_mmu: read buserror %08x, PC=%x (mask %08x)\n", 0x60000000 | (offset << 2), m_cpu->pc(), mem_mask);
const uint32_t retval = m_buserr[offset & 0xf];
//logerror("sun4c_mmu: read buserror %08x & %08x = %08x, PC=%x\n", 0x60000000 | (offset << 2), mem_mask, retval, m_cpu->pc());
m_buserr[offset & 0xf] = 0; // clear on reading
return retval;
}
case 8: // (d-)cache tags
//logerror("sun4_mmu: read dcache tags @ %x, PC = %x\n", offset, m_cpu->pc());
return m_cachetags[(offset >> 3) & 0x3fff];
return m_cachetags[offset & 0x3fff];
case 9: // (d-)cache data
//logerror("sun4c_mmu: read dcache data @ %x, PC = %x\n", offset, m_cpu->pc());
@ -255,7 +255,7 @@ uint32_t sun4c_mmu_device::system_r(const uint32_t offset, const uint32_t mem_ma
case 0: // IDPROM - SPARCstation-1 does not have an ID prom and a timeout should occur.
default:
logerror("%s: sun4c_mmu: ASI 2 space unhandled read @ %x\n", machine().describe_context(), offset<<2);
//logerror("%s: sun4c_mmu: ASI 2 space unhandled read @ %x\n", machine().describe_context(), offset<<2);
return 0;
}
}
@ -269,6 +269,7 @@ void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, cons
//printf("%08x to context, mask %08x, offset %x\n", data, mem_mask, offset);
m_context = data >> 24;
m_context_masked = m_context & m_ctx_mask;
m_cache_context = m_context & m_ctx_mask;
m_curr_segmap = m_segmap[m_context_masked];
m_curr_segmap_masked = m_segmap_masked[m_context_masked];
return;
@ -295,22 +296,32 @@ void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, cons
}
case 6: // bus error
//logerror("%08x to bus error @ %x, mask %08x\n", data, offset, mem_mask);
m_buserr[offset & 0xf] = data;
{
const uint32_t masked_offset = offset & 0xf;
//logerror("%08x to bus error @ %x, mask %08x\n", data, offset << 2, mem_mask);
if (masked_offset == 0)
m_buserr[0] = (data & 0x000000ff) | 0x00008000;
else if (masked_offset == 1)
m_buserr[1] = data;
else if (masked_offset == 2)
m_buserr[2] = data & 0x000000b0;
else if (masked_offset == 3)
m_buserr[3] = (data & 0x3fffffff) | ((data & 0x20000000) << 1) | ((data & 0x20000000) << 2);
return;
}
case 8: // cache tags
//logerror("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_cpu->pc());
m_cachetags[(offset>>3)&0x3fff] = data & 0x03f8fffc;
m_cachetags[offset&0x3fff] = data & 0x03f8fffc;
return;
case 9: // cache data
//logerror("sun4c: %08x to cache data @ %x, PC = %x\n", data, offset, m_cpu->pc());
m_cachedata[offset&0x3fff] = data;
m_cachedata[offset&0x3fff] = data | (1 << 19);
return;
case 0xf: // UART bypass
//printf("%08x to UART bypass @ %x, mask %08x\n", data, offset<<2, mem_mask);
logerror("%08x to UART bypass @ %x, mask %08x\n", data, offset<<2, mem_mask);
switch (offset & 3)
{
case 0: if (mem_mask == 0xff000000) m_scc->cb_w(0, data>>24); else m_scc->db_w(0, data>>8); break;
@ -320,7 +331,7 @@ void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, cons
case 0: // IDPROM
default:
logerror("sun4c: ASI 2 space unhandled write %x @ %x (mask %08x, PC=%x, shift %x)\n", data, offset<<2, mem_mask, m_cpu->pc(), offset>>26);
//logerror("sun4c: ASI 2 space unhandled write %x @ %x (mask %08x, PC=%x, shift %x)\n", data, offset<<2, mem_mask, m_cpu->pc(), offset>>26);
return;
}
}
@ -353,15 +364,16 @@ void sun4c_mmu_device::segment_map_w(const uint32_t offset, const uint32_t data,
uint32_t sun4c_mmu_device::page_map_r(const uint32_t offset, const uint32_t mem_mask)
{
//logerror("%s: page_map_r: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask);
const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f);
return m_pagemap[page].to_uint();
const uint32_t retval = m_pagemap[page].to_uint();
logerror("%s: page_map_r: %08x (%x, %x) & %08x = %08x\n", machine().describe_context(), offset << 2, page, (m_curr_segmap[(offset >> 16) & 0xfff] << 6) | ((offset >> 10) & 0x3f), mem_mask, retval);
return retval;
}
void sun4c_mmu_device::page_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
{
//logerror("%s: page_map_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f);
uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f);
logerror("%s: page_map_w: %08x (%x, %x) = %08x & %08x\n", machine().describe_context(), offset << 2, page, (m_curr_segmap[(offset >> 16) & 0xfff] << 6) | ((offset >> 10) & 0x3f), data, mem_mask);
m_pagemap[page].merge_uint(data, mem_mask);
m_page_valid[page] = m_pagemap[page].valid;
}
@ -413,7 +425,7 @@ uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem
}
// it's translation time
const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];// & m_pmeg_mask;
const uint32_t entry_index = pmeg | ((offset >> 10) & 0x3f);
if (m_page_valid[entry_index])
@ -447,7 +459,7 @@ uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem
return m_type1_r(tmp, mem_mask);
default:
//logerror("sun4c_mmu: access to memory type not defined in sun4c\n");
//logerror("sun4c_mmu: read from to memory type not defined in sun4c, %d, %08x & %08x\n", entry.type, tmp << 2, mem_mask);
m_host->set_mae();
m_buserr[0] = 0x20;
m_buserr[1] = offset << 2;
@ -458,7 +470,7 @@ uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem
{
if (!machine().side_effects_disabled())
{
//logerror("sun4c: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), offset <<2, m_cpu->pc());
//logerror("sun4c: INVALID PTE entry %d %08x read! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), offset << 2, m_cpu->pc());
m_host->set_mae();
m_buserr[0] |= 0x80; // invalid PTE
m_buserr[0] &= ~0x8000; // read
@ -492,7 +504,7 @@ template <sun4c_mmu_device::insn_data_mode MODE>
void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
{
// it's translation time
const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];// & m_pmeg_mask;
const uint32_t entry_index = pmeg | ((offset >> 10) & 0x3f);
if (m_page_valid[entry_index])
@ -537,7 +549,7 @@ void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, c
return;
default:
//logerror("sun4c_mmu: access to memory type not defined\n");
//logerror("sun4c_mmu: access to memory type not defined, %d %08x = %08x & %08x\n", entry.type, tmp, data, mem_mask);
m_host->set_mae();
m_buserr[0] = 0x8020;
m_buserr[1] = offset << 2;
@ -546,7 +558,7 @@ void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, c
}
else
{
//logerror("sun4c: INVALID PTE entry %d %08x accessed! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), data, offset <<2, m_cpu->pc());
//logerror("sun4c: INVALID PTE entry %d %08x written! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), data, offset << 2, m_cpu->pc());
m_host->set_mae();
m_buserr[0] |= 0x8080; // write cycle, invalid PTE
m_buserr[1] = offset << 2;

View File

@ -131,6 +131,7 @@ protected:
uint32_t m_ram_size_words;
uint32_t m_context;
uint32_t m_context_masked;
uint32_t m_cache_context;
uint8_t m_system_enable;
bool m_fetch_bootrom;
uint32_t m_buserr[4];

View File

@ -2048,6 +2048,9 @@ void sun4_state::sun4_50(machine_config &config)
{
sun4c(config);
m_mmu->set_ctx_mask(0xf);
m_mmu->set_pmeg_mask(0xff);
m_mmu->set_clock(40'000'000);
m_maincpu->set_clock(40'000'000);
@ -2075,6 +2078,7 @@ void sun4_state::sun4_65(machine_config &config)
m_sbus_slot[0]->set_clock(25'000'000);
m_sbus_slot[1]->set_clock(25'000'000);
m_sbus_slot[2]->set_clock(25'000'000);
m_sbus_slot[2]->set_default_option("bwtwo");
}
void sun4_state::sun4_75(machine_config &config)