summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author MooglyGuy <MooglyGuy@users.noreply.github.com>2023-01-05 09:59:26 +0100
committer GitHub <noreply@github.com>2023-01-05 19:59:26 +1100
commit9d34edf37c63e155db105821c108bdcdee21f24d (patch)
tree45e1dca82bf3da84814233d0630e6601608c63dd
parent94b1e168b2b97b48b81f7a8f64406b0a6f64184e (diff)
machine/sun4c_mmu.cpp: Removed non-functional cache emulation. (#10788) [Ryan Holtz]
sun4_60 can install and boot SunOS 4.1.4 again.
-rw-r--r--src/devices/machine/sun4c_mmu.cpp734
-rw-r--r--src/devices/machine/sun4c_mmu.h66
2 files changed, 239 insertions, 561 deletions
diff --git a/src/devices/machine/sun4c_mmu.cpp b/src/devices/machine/sun4c_mmu.cpp
index 91686a42fdf..6e2b4ce36de 100644
--- a/src/devices/machine/sun4c_mmu.cpp
+++ b/src/devices/machine/sun4c_mmu.cpp
@@ -32,23 +32,19 @@ DEFINE_DEVICE_TYPE(SUN4C_MMU, sun4c_mmu_device, "sun4c_mmu", "Sun 4c MMU")
#define LOG_TYPE1_TIMEOUT (1U << 12)
#define LOG_UNKNOWN_SPACE (1U << 13)
#define LOG_WRITE_PROTECT (1U << 14)
-#define LOG_READ_PROTECT (1U << 15)
-#define LOG_PARITY (1U << 16)
-#define LOG_ALL_ASI (1U << 17) // WARNING: Heavy!
-#define LOG_UNKNOWN_ASI (1U << 18)
-#define LOG_SEGMENT_FLUSH (1U << 19)
-#define LOG_PAGE_FLUSH (1U << 20)
-#define LOG_CONTEXT_FLUSH (1U << 21)
-#define LOG_CACHE_FILLS (1U << 22)
-#define LOG_PAGE_ENTRIES (1U << 23)
-
-#if SUN4CMMU_LOG_MEM_ACCESSES
-static FILE* s_mem_log = nullptr;
-#endif
+#define LOG_SEGMENT_FLUSH (1U << 15)
+#define LOG_PAGE_FLUSH (1U << 16)
+#define LOG_CONTEXT_FLUSH (1U << 17)
+#define LOG_ALL_FLUSH (1U << 18)
+#define LOG_UART (1U << 19)
+#define LOG_PARITY (1U << 20)
+#define LOG_ALL_ASI (1U << 21) // WARNING: Heavy!
#define VERBOSE (0)
#include "logmacro.h"
+#define PRINT_UART_DATA (0)
+
sun4_mmu_base_device::sun4_mmu_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
, m_cpu(*this, finder_base::DUMMY_TAG)
@@ -81,20 +77,8 @@ sun4c_mmu_device::sun4c_mmu_device(const machine_config &mconfig, const char *ta
{
}
-void sun4_mmu_base_device::device_stop()
-{
-#if SUN4CMMU_LOG_MEM_ACCESSES
- fclose(s_mem_log);
-#endif
-}
-
void sun4_mmu_base_device::device_start()
{
-#if SUN4CMMU_LOG_MEM_ACCESSES
- s_mem_log = fopen("sun4c_mem.bin", "wb");
- m_fpos = 0;
-#endif
-
m_type1_r.resolve_safe(0xffffffff);
m_type1_w.resolve_safe();
@@ -152,29 +136,10 @@ void sun4_mmu_base_device::device_start()
using namespace std::placeholders;
machine().debugger().console().register_command("l2p", CMDFLAG_NONE, 1, 1, std::bind(&sun4_mmu_base_device::l2p_command, this, _1));
}
-
- m_cache_word_size = m_cache_line_size >> 2;
- m_cache_tag_shift = 0;
- while ((m_cache_word_size & (1 << m_cache_tag_shift)) == 0)
- {
- m_cache_tag_shift++;
- }
- m_cache_vaddr_shift = 14;
- m_cache_tag_id_mask = 0xfffc;
- m_cache_tag_id_shift = 12;//13 + (m_cache_tag_shift - 2);
- m_cache_tag_mask = m_cache_mask >> m_cache_tag_shift;
-
- printf("m_cache_tag_shift %d\n", m_cache_tag_shift);
- printf("m_page_mask %08x\n", m_page_mask);
- printf("m_seg_entry_shift %08x\n", m_seg_entry_shift);
- printf("m_seg_entry_mask %08x\n", m_seg_entry_mask);
- printf("m_page_entry_mask %08x\n", m_page_entry_mask);
- printf("m_cache_mask %08x\n", m_cache_mask);
}
void sun4_mmu_base_device::device_reset()
{
- m_log_mem = false;
m_rom_ptr = (uint32_t *)m_rom->base();
m_ram_ptr = (uint32_t *)m_ram->pointer();
m_ram_size = m_ram->size();
@@ -209,8 +174,12 @@ void sun4_mmu_base_device::device_reset()
m_curr_segmap_masked = &m_segmap_masked[0][0];
m_system_enable = 0;
m_fetch_bootrom = true;
+ m_type1_offset = 0;
+ m_parity_err_reg = 0;
+ m_memory_err_reg = 0;
+ m_parity_err = 0;
- memset(m_buserr, 0, sizeof(uint32_t) * 16);
+ memset(m_buserr, 0, sizeof(uint32_t) * 4);
for (int i = 0; i < 16; i++)
{
memset(&m_segmap[i][0], 0, 4096);
@@ -226,7 +195,7 @@ TIMER_CALLBACK_MEMBER(sun4_mmu_base_device::reset_off_tick)
m_cpu->set_input_line(SPARC_RESET, CLEAR_LINE);
}
-uint32_t sun4_mmu_base_device::fetch_insn(const bool supervisor, uint32_t offset)
+uint32_t sun4_mmu_base_device::fetch_insn(const bool supervisor, const uint32_t offset)
{
if (supervisor)
return insn_data_r<SUPER_INSN>(offset, 0xffffffff);
@@ -234,199 +203,58 @@ uint32_t sun4_mmu_base_device::fetch_insn(const bool supervisor, uint32_t offset
return insn_data_r<USER_INSN>(offset, 0xffffffff);
}
-void sun4_mmu_base_device::hw_segment_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
+void sun4_mmu_base_device::segment_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- for (uint32_t i = 0x0000; i < (0x1000 >> (m_cache_tag_shift + 2)); i++)
- {
- segment_flush_w(offset | (i << m_cache_tag_shift), data, mem_mask);
- }
+ // Do nothing for now
+ LOGMASKED(LOG_SEGMENT_FLUSH, "%s: segment_flush_w %08x & %08x: %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
}
-void sun4_mmu_base_device::hw_page_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
+void sun4_mmu_base_device::page_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- for (uint32_t i = 0x0000; i < (0x1000 >> (m_cache_tag_shift + 2)); i++)
- {
- page_flush_w(offset | (i << m_cache_tag_shift), data, mem_mask);
- }
+ // Do nothing for now
+ LOGMASKED(LOG_PAGE_FLUSH, "%s: page_flush_w %08x & %08x: %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
}
-void sun4_mmu_base_device::hw_context_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
+void sun4_mmu_base_device::context_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- for (uint32_t i = 0x0000; i < (0x1000 >> (m_cache_tag_shift + 2)); i++)
- {
- context_flush_w(offset | (i << m_cache_tag_shift), data, mem_mask);
- }
+ // Do nothing for now
+ LOGMASKED(LOG_CONTEXT_FLUSH, "%s: context_flush_w %08x & %08x: %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
}
-void sun4_mmu_base_device::hw_flush_all_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
-{
- for (uint32_t i = 0x0000; i < (0x1000 >> (m_cache_tag_shift + 2)); i++)
- {
- const uint32_t vaddr = offset | (i << m_cache_tag_shift);
- const uint32_t tag_addr = vaddr_to_cache_line(vaddr);
- m_cachetags[tag_addr] &= ~(1 << 19);
- }
-}
-
-uint32_t sun4_mmu_base_device::parity_r(uint32_t offset, uint32_t mem_mask)
+void sun4_mmu_base_device::hw_segment_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- if (offset == 0)
- {
- const uint32_t data = m_parity_err_reg;
- LOGMASKED(LOG_PARITY, "%s: parity_err_reg read: %08x & %08x\n", machine().describe_context(), m_parity_err_reg, mem_mask);
- m_parity_err_reg &= ~0xcf;
- return data;
- }
- else if (offset == 1)
- {
- LOGMASKED(LOG_PARITY, "%s: memory_err_reg read: %08x & %08x\n", machine().describe_context(), m_memory_err_reg, mem_mask);
- return m_memory_err_reg;
- }
- return 0;
+ // Do nothing for now
+ LOGMASKED(LOG_SEGMENT_FLUSH, "%s: segment_flush_w %08x & %08x: %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
}
-void sun4_mmu_base_device::parity_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
+void sun4_mmu_base_device::hw_page_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- if (offset == 0)
- {
- LOGMASKED(LOG_PARITY, "%s: parity_err_reg write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
- COMBINE_DATA(&m_parity_err_reg);
- }
- else
- {
- LOGMASKED(LOG_PARITY, "%s: memory_err_reg write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
- COMBINE_DATA(&m_memory_err_reg);
- }
+ // Do nothing for now
+ LOGMASKED(LOG_PAGE_FLUSH, "%s: page_flush_w %08x & %08x: %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
}
-void sun4_mmu_base_device::segment_flush_w(uint32_t vaddr, uint32_t data, uint32_t mem_mask)
+void sun4_mmu_base_device::hw_context_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- LOGMASKED(LOG_SEGMENT_FLUSH, "%s: segment_flush_w %08x\n", machine().describe_context(), vaddr);
- const uint32_t tag_addr = vaddr_to_cache_line(vaddr);
- const uint32_t tag = m_cachetags[tag_addr];
- if ((tag & (1 << 19)) != 0 && ((tag >> 22) & m_ctx_mask) == m_context_masked)
- {
- // Unshifted
- // 00SS|SSSS|SSSS|SSPP|PPPP|BBBB|BBBB|BBBB
- // 00TT|TTTT|TTTT|TTTT|LLLL|LLLL|LLLL|bbbb
- //
- // 00ss|ssss|ssss|ss--|LLLL|LLLL|LLLL|----
-
- // Shifted
- // SSSS|SSSS|SSSS|PPPP|PPBB|BBBB|BBBB
- // TTTT|TTTT|TTTT|TTLL|LLLL|LLLL|LLww
- //
- // ssss|ssss|ssss|--LL|LLLL|LLLL|LL--
-
- const uint32_t tag_id = (tag >> 4) & m_cache_tag_mask;
- if (tag_id == ((vaddr >> 16) & 0xfff))
- {
- m_cachetags[tag_addr] &= ~(1 << 19);
- LOGMASKED(LOG_SEGMENT_FLUSH, "flushing line with tag %08x from vaddr %08x\n", tag, vaddr << 2);
- }
- }
+ // Do nothing for now
+ LOGMASKED(LOG_CONTEXT_FLUSH, "%s: context_flush_w %08x & %08x: %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
}
-void sun4_mmu_base_device::context_flush_w(uint32_t vaddr, uint32_t data, uint32_t mem_mask)
-{
- LOGMASKED(LOG_CONTEXT_FLUSH, "%s: context_flush_w %08x\n", machine().describe_context(), vaddr << 2);
- const uint32_t tag_addr = vaddr_to_cache_line(vaddr);
- const uint32_t tag = m_cachetags[tag_addr];
- if ((tag & (1 << 19)) != 0)
- {
- LOGMASKED(LOG_CONTEXT_FLUSH, "tag is valid: %08x (%d vs. %d)\n", tag, ((tag >> 22) & m_ctx_mask), m_context_masked);
- if (((tag >> 22) & m_ctx_mask) == m_context_masked && !BIT(tag, 20))
- {
- const uint32_t tag_id = (tag >> 2) & m_cache_tag_mask;
- if (tag_id == ((vaddr >> 14) & 0xfff))
- {
- LOGMASKED(LOG_CONTEXT_FLUSH, "flushing line with tag %08x from vaddr %08x\n", tag, vaddr << 2);
- m_cachetags[tag_addr] &= ~(1 << 19);
- }
- }
- }
-}
-
-void sun4_mmu_base_device::page_flush_w(uint32_t vaddr, uint32_t data, uint32_t mem_mask)
+void sun4_mmu_base_device::hw_flush_all_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- LOGMASKED(LOG_PAGE_FLUSH, "%s: page_flush_w %08x\n", machine().describe_context(), vaddr << 2);
- const uint32_t tag_addr = vaddr_to_cache_line(vaddr);
- const uint32_t tag = m_cachetags[tag_addr];
- if ((tag & (1 << 19)) != 0 && ((tag >> 22) & m_ctx_mask) == m_context_masked)
- {
- // Unshifted
- // 00SS|SSSS|SSSS|SSPP|PPPP|BBBB|BBBB|BBBB
- // 00TT|TTTT|TTTT|TTTT|LLLL|LLLL|LLLL|bbbb
- //
- // 00pp|pppp|pppp|pppp|pppp|LLLL|LLLL|---- ff1dc000
- // 1111|1111|0001|1101|1100|0000|0000|---- 0000fc70
-
- // Shifted
- // SSSS|SSSS|SSSS|PPPP|PPBB|BBBB|BBBB
- // TTTT|TTTT|TTTT|TTLL|LLLL|LLLL|LLww
- //
- // pppp|pppp|pppp|pppp|ppLL|LLLL|LL--
-
- const uint32_t tag_id = tag & m_cache_tag_id_mask;
- LOGMASKED(LOG_PAGE_FLUSH, "tag is valid: %08x (%04x vs. %04x)\n", tag, tag_id, (vaddr >> (m_cache_tag_id_shift + 2)) & 0x3fff);
- if (tag_id == ((vaddr >> m_cache_tag_id_shift) & 0xfffc))
- {
- m_cachetags[tag_addr] &= ~(1 << 19);
- LOGMASKED(LOG_PAGE_FLUSH, "flushing line with tag %08x from vaddr %08x\n", tag, vaddr << 2);
- }
- }
+ // Do nothing for now
+ LOGMASKED(LOG_ALL_FLUSH, "%s: hw_flush_all_w %08x = %08x: %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
}
uint32_t sun4_mmu_base_device::context_reg_r(uint32_t offset, uint32_t mem_mask)
{
- if (mem_mask == 0x00ff0000)
- {
- LOGMASKED(LOG_CONTEXT, "sun4c_mmu: read context %08x & %08x = %08x\n", offset << 2, mem_mask, m_context<<16);
- return m_context<<16;
- }
- LOGMASKED(LOG_CONTEXT, "sun4c_mmu: read context %08x & %08x = %08x\n", offset << 2, mem_mask, m_context<<24);
- return m_context<<24;
-}
-
-uint32_t sun4_mmu_base_device::system_enable_r(uint32_t offset, uint32_t mem_mask)
-{
- LOGMASKED(LOG_SYSTEM_ENABLE, "sun4c_mmu: read system enable %08x & %08x = %08x\n", offset << 2, mem_mask, m_system_enable<<24);
- return m_system_enable<<24;
-}
-
-uint32_t sun4_mmu_base_device::bus_error_r(uint32_t offset, uint32_t mem_mask)
-{
- const uint32_t ret = m_buserr[offset & 0xf];
- LOGMASKED(LOG_BUSERROR, "sun4c_mmu: read buserror %08x & %08x = %08x, PC=%x\n", 0x60000000 | (offset << 2), mem_mask, ret, m_cpu->pc());
- m_buserr[offset & 0xf] = 0; // clear on reading
- return ret;
-}
-
-uint32_t sun4_mmu_base_device::cache_tag_r(uint32_t offset, uint32_t mem_mask)
-{
- LOGMASKED(LOG_CACHE_TAGS, "%s: sun4c_mmu: read dcache tags @ %x, %08x\n", machine().describe_context(), offset << 2, m_cachetags[vaddr_to_cache_line(offset)]);
- return m_cachetags[vaddr_to_cache_line(offset)];
-}
-
-uint32_t sun4_mmu_base_device::cache_data_r(uint32_t offset, uint32_t mem_mask)
-{
- LOGMASKED(LOG_CACHE_DATA, "%s: sun4c_mmu: read dcache data @ %x, PC = %x\n", machine().describe_context(), offset << 2, m_cpu->pc());
- return m_cachedata[offset & 0x3fff];
-}
-
-uint32_t sun4_mmu_base_device::uart_r(uint32_t offset, uint32_t mem_mask)
-{
- switch (offset & 3)
- {
- case 0: if (mem_mask == 0xff000000) return m_scc->cb_r(0)<<24; else return m_scc->db_r(0)<<8; break;
- case 1: if (mem_mask == 0xff000000) return m_scc->ca_r(0)<<24; else return m_scc->da_r(0)<<8; break;
- }
- return 0xffffffff;
+ const uint32_t data = m_context << (mem_mask == 0x00ff0000 ? 16 : 24);
+ LOGMASKED(LOG_CONTEXT, "%s: context_reg_r %08x & %08x: %08x\n", machine().describe_context(), offset << 2, mem_mask, data);
+ return data;
}
void sun4_mmu_base_device::context_reg_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- LOGMASKED(LOG_CONTEXT, "write context = %08x & %08x\n", data, mem_mask);
+ LOGMASKED(LOG_CONTEXT, "%s: context_reg_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
m_context = data >> 24;
m_context_masked = m_context & m_ctx_mask;
m_cache_context = m_context & m_ctx_mask;
@@ -434,9 +262,16 @@ void sun4_mmu_base_device::context_reg_w(uint32_t offset, uint32_t data, uint32_
m_curr_segmap_masked = &m_segmap_masked[m_context_masked][0];
}
+uint32_t sun4_mmu_base_device::system_enable_r(uint32_t offset, uint32_t mem_mask)
+{
+ const uint32_t data = m_system_enable << 24;
+ LOGMASKED(LOG_SYSTEM_ENABLE, "%s: system_enable_r %08x & %08x: %08x\n", machine().describe_context(), offset << 2, mem_mask, data);
+ return data;
+}
+
void sun4_mmu_base_device::system_enable_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- LOGMASKED(LOG_SYSTEM_ENABLE, "write system enable = %08x & %08x\n", data, mem_mask);
+ LOGMASKED(LOG_SYSTEM_ENABLE, "%s: system_enable_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
m_system_enable = data >> 24;
m_fetch_bootrom = !(m_system_enable & ENA_NOTBOOT);
@@ -453,64 +288,132 @@ void sun4_mmu_base_device::system_enable_w(uint32_t offset, uint32_t data, uint3
}
}
+uint32_t sun4_mmu_base_device::bus_error_r(uint32_t offset, uint32_t mem_mask)
+{
+ const uint32_t data = m_buserr[offset & 0xf];
+ LOGMASKED(LOG_BUSERROR, "%s: bus_error_r %08x & %08x: %08x\n", machine().describe_context(), 0x60000000 | (offset << 2), mem_mask, data);
+ m_buserr[offset & 0xf] = 0; // clear on reading
+ return data;
+}
+
void sun4_mmu_base_device::bus_error_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
const uint32_t masked_offset = offset & 0xf;
- LOGMASKED(LOG_BUSERROR, "write bus error %08x = %08x & %08x\n", offset << 2, data, mem_mask);
+ LOGMASKED(LOG_BUSERROR, "%s: bus_error_w: %08x = %08x & %08x\n", machine().describe_context(), 0x60000000 | (offset << 2), data, mem_mask);
if (masked_offset == 0)
m_buserr[0] = (data & 0x000000ff) | 0x00008000;
- else
- m_buserr[masked_offset] = data;
+ 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);
+}
+
+uint32_t sun4_mmu_base_device::cache_tag_r(uint32_t offset, uint32_t mem_mask)
+{
+ const uint32_t data = m_cachetags[offset & m_cache_mask];
+ LOGMASKED(LOG_CACHE_TAGS, "%s: cache_tag_r %08x & %08x: %08x\n", machine().describe_context(), offset, mem_mask, data);
+ return data;
}
void sun4_mmu_base_device::cache_tag_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- LOGMASKED(LOG_CACHE_TAGS, "%s: write dcache tags %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
- m_cachetags[vaddr_to_cache_line(offset)] = data & 0x03f8fffc;
+ LOGMASKED(LOG_CACHE_TAGS, "%s: cache_tag_w: %08x = %08x & %08x\n", machine().describe_context(), offset, data, mem_mask);
+ m_cachetags[offset & m_cache_mask] = data & 0x03f8fffc;
+}
+
+uint32_t sun4_mmu_base_device::cache_data_r(uint32_t offset, uint32_t mem_mask)
+{
+ const uint32_t data = m_cachedata[offset & m_cache_mask];
+ LOGMASKED(LOG_CACHE_DATA, "%s: cache_data_r %08x & %08x: %08x\n", machine().describe_context(), offset, mem_mask, data);
+ return data;
}
void sun4_mmu_base_device::cache_data_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- LOGMASKED(LOG_CACHE_DATA, "write cache data %08x = %08x & %08x\n", offset << 2, data, mem_mask);
- COMBINE_DATA(&m_cachedata[offset & 0x3fff]);
- m_cachetags[vaddr_to_cache_line(offset)] &= ~(1 << 19);
+ LOGMASKED(LOG_CACHE_DATA, "%s: cache_data_w: %08x = %08x & %08x\n", machine().describe_context(), offset, data, mem_mask);
+ m_cachedata[offset & m_cache_mask] = data | (1 << 19);
+}
+
+uint32_t sun4_mmu_base_device::uart_r(uint32_t offset, uint32_t mem_mask)
+{
+ uint32_t data = 0xffffffff;
+ switch (offset & 3)
+ {
+ case 0:
+ if (mem_mask == 0xff000000)
+ data = m_scc->cb_r(0) << 24;
+ else
+ data = m_scc->db_r(0) << 8;
+ break;
+ case 1:
+ if (mem_mask == 0xff000000)
+ data = m_scc->ca_r(0) << 24;
+ else
+ data = m_scc->da_r(0) << 8;
+ break;
+ }
+ LOGMASKED(LOG_UART, "%s: uart_r %08x & %08x: %08x\n", machine().describe_context(), offset, mem_mask, data);
+ return data;
}
void sun4_mmu_base_device::uart_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
+ LOGMASKED(LOG_UART, "%s: uart_w: %08x = %08x & %08x\n", machine().describe_context(), offset, data, 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;
- case 1: if (mem_mask == 0xff000000) m_scc->ca_w(0, data>>24); else { m_scc->da_w(0, data>>8); logerror("%c\n", data>>8); printf("%c", data>>8); } break;
+ case 0:
+ if (mem_mask == 0xff000000)
+ m_scc->cb_w(0, data >> 24);
+ else
+ m_scc->db_w(0, data >> 8);
+ return;
+ case 1:
+ if (mem_mask == 0xff000000)
+ m_scc->ca_w(0, data >> 24);
+ else
+ {
+ m_scc->da_w(0, data >> 8);
+ if (PRINT_UART_DATA)
+ {
+ printf("%c", data >> 8);
+ }
+ }
+ return;
}
}
uint32_t sun4_mmu_base_device::segment_map_r(uint32_t offset, uint32_t mem_mask)
{
- uint32_t ret = 0;
+ uint32_t data = 0;
if (mem_mask == 0xffff0000)
- ret = m_curr_segmap[(offset>>16) & 0xfff]<<16;
+ data = m_curr_segmap[(offset >> 16) & 0xfff] << 16;
else if (mem_mask == 0xff000000)
- ret = m_curr_segmap[(offset>>16) & 0xfff]<<24;
+ data = m_curr_segmap[(offset >> 16) & 0xfff] << 24;
else if (mem_mask == 0xffffffff)
- ret = m_curr_segmap[(offset>>16) & 0xfff];
+ data = m_curr_segmap[(offset >> 16) & 0xfff];
else
- LOGMASKED(LOG_UNKNOWN_SEGMENT, "read segment map w/ unknown mask %08x & %08x\n", offset << 2, mem_mask);
- LOGMASKED(LOG_SEGMENT_MAP, "read segment map %08x & %08x = %08x\n", offset << 2, mem_mask, ret);
- return ret;
+ LOGMASKED(LOG_UNKNOWN_SEGMENT, "%s: segment_map_r: %08x & %08x (unknown mask)\n", machine().describe_context(), offset << 2, mem_mask);
+ LOGMASKED(LOG_SEGMENT_MAP, "%s: segment_map_r: %08x & %08x: %08x\n", machine().describe_context(), offset << 2, mem_mask, data);
+ return data;
}
void sun4_mmu_base_device::segment_map_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- LOGMASKED(LOG_SEGMENT_MAP, "write segment map %08x = %08x & %08x\n", offset << 2, data, mem_mask);
+ LOGMASKED(LOG_SEGMENT_MAP, "%s: segment_map_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
uint8_t segdata = 0;
- if (mem_mask == 0xffff0000) segdata = (data >> 16) & 0xff;
- else if (mem_mask == 0xff000000) segdata = (data >> 24) & 0xff;
- else if (mem_mask == 0xffffffff) segdata = data & 0xff;
- else LOGMASKED(LOG_UNKNOWN_SEGMENT, "write segment map w/ unknown mask %08x = %08x & %08x, PC=%08x\n", offset << 2, data, mem_mask, m_cpu->pc());
+ if (mem_mask == 0xffff0000)
+ segdata = (data >> 16) & 0xff;
+ else if (mem_mask == 0xff000000)
+ segdata = (data >> 24) & 0xff;
+ else if (mem_mask == 0xffffffff)
+ segdata = data & 0xff;
+ else
+ LOGMASKED(LOG_UNKNOWN_SEGMENT, "%s: segment_map_w: %08x = %08x & %08x (unknown mask)\n", machine().describe_context(), offset << 2, data, mem_mask);
- const uint32_t seg = (offset>>16) & 0xfff;
+ const uint32_t seg = (offset >> 16) & 0xfff;
m_curr_segmap[seg] = segdata;
m_curr_segmap_masked[seg] = (segdata & m_pmeg_mask) << 6;
}
@@ -518,30 +421,30 @@ void sun4_mmu_base_device::segment_map_w(uint32_t offset, uint32_t data, uint32_
uint32_t sun4_mmu_base_device::page_map_r(uint32_t offset, uint32_t mem_mask)
{
const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
- const uint32_t ret = page_entry_to_uint(page);
- LOGMASKED(LOG_PAGE_MAP, "read page map %08x & %08x (%x) = %08x\n", offset << 2, mem_mask, page, ret);
- return ret;
+ const uint32_t data = page_entry_to_uint(page);
+ LOGMASKED(LOG_PAGE_MAP, "%s: page_map_r: %08x (%x) & %08x: %08x\n", machine().describe_context(), offset << 2, page, mem_mask, data);
+ return data;
}
void sun4_mmu_base_device::page_map_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
{
- uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
- LOGMASKED(LOG_PAGE_MAP, "write page map %08x (%x) = %08x & %08x\n", offset << 2, page, data, mem_mask);
+ const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
+ LOGMASKED(LOG_PAGE_MAP, "%s: page_map_w: %08x (%x) = %08x & %08x\n", offset << 2, page, data, mem_mask);
merge_page_entry(page, data, mem_mask);
m_page_valid[page] = m_pagemap[page].valid;
}
-void sun4_mmu_base_device::type0_timeout_r(uint32_t offset)
+void sun4_mmu_base_device::type0_timeout_r(const uint32_t offset)
{
- LOGMASKED(LOG_TYPE0_TIMEOUT, "type 0 read timeout %08x, PC=%08x\n", offset << 2, m_cpu->pc());
+ LOGMASKED(LOG_TYPE0_TIMEOUT, "%s: type0_timeout_r (%08x)\n", machine().describe_context(), offset << 2);
m_buserr[0] = 0x20; // read timeout
m_buserr[1] = 0x04000000 + (offset << 2);
m_host->set_mae();
}
-void sun4_mmu_base_device::type0_timeout_w(uint32_t offset)
+void sun4_mmu_base_device::type0_timeout_w(const uint32_t offset)
{
- LOGMASKED(LOG_TYPE0_TIMEOUT, "type 0 write timeout %08x, PC=%08x\n", offset << 2, m_cpu->pc());
+ LOGMASKED(LOG_TYPE0_TIMEOUT, "%s: type0_timeout_w (%08x)\n", machine().describe_context(), offset << 2);
m_buserr[0] = 0x8020; // write timeout
m_buserr[1] = 0x04000000 + (offset << 2);
m_host->set_mae();
@@ -549,7 +452,7 @@ void sun4_mmu_base_device::type0_timeout_w(uint32_t offset)
uint32_t sun4_mmu_base_device::type1_timeout_r(uint32_t offset)
{
- LOGMASKED(LOG_TYPE1_TIMEOUT, "type 1 read timeout %08x, PC=%08x\n", offset << 2, m_cpu->pc());
+ LOGMASKED(LOG_TYPE1_TIMEOUT, "%s: type1_timeout_r (%08x)\n", machine().describe_context(), offset << 2);
m_buserr[2] = 0x20; // read timeout
m_buserr[3] = m_type1_offset << 2;
return 0;
@@ -557,11 +460,42 @@ uint32_t sun4_mmu_base_device::type1_timeout_r(uint32_t offset)
void sun4_mmu_base_device::type1_timeout_w(uint32_t offset, uint32_t data)
{
- LOGMASKED(LOG_TYPE1_TIMEOUT, "type 1 write timeout %08x = %08x, PC=%08x\n", offset << 2, data, m_cpu->pc());
+ LOGMASKED(LOG_TYPE1_TIMEOUT, "%s: type1_timeout_w (%08x)\n", machine().describe_context(), offset << 2);
m_buserr[2] = 0x120; // write timeout
m_buserr[3] = m_type1_offset << 2;
}
+uint32_t sun4_mmu_base_device::parity_r(uint32_t offset, uint32_t mem_mask)
+{
+ uint32_t data = 0;
+ if (offset == 0)
+ {
+ data = m_parity_err_reg;
+ LOGMASKED(LOG_PARITY, "%s: parity_r (parity error register): %08x & %08x: %08x\n", machine().describe_context(), offset << 2, mem_mask, data);
+ m_parity_err_reg &= ~0xcf;
+ }
+ else if (offset == 1)
+ {
+ data = m_memory_err_reg;
+ LOGMASKED(LOG_PARITY, "%s: parity_r (memory error register): %08x & %08x: %08x\n", machine().describe_context(), offset << 2, mem_mask, data);
+ }
+ return data;
+}
+
+void sun4_mmu_base_device::parity_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
+{
+ if (offset == 0)
+ {
+ LOGMASKED(LOG_PARITY, "%s: parity_w (parity error register): %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
+ COMBINE_DATA(&m_parity_err_reg);
+ }
+ else
+ {
+ LOGMASKED(LOG_PARITY, "%s: parity_w (memory error register): %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
+ COMBINE_DATA(&m_memory_err_reg);
+ }
+}
+
uint32_t sun4_mmu_base_device::page_entry_to_uint(uint32_t index)
{
const page_entry &pe = m_pagemap[index];
@@ -580,92 +514,6 @@ void sun4_mmu_base_device::merge_page_entry(uint32_t index, uint32_t data, uint3
pe.accessed = new_value & PM_ACCESSED;
pe.modified = new_value & PM_MODIFIED;
pe.page = (new_value & m_page_entry_mask) << m_seg_entry_shift;
- pe.raw = new_value;
- pe.index = index;
- LOGMASKED(LOG_PAGE_ENTRIES, "page entry %05x: data %08x, sanity %08x, mem_mask %08x, valid %d, write %d, super %d, cached %d\n", index, new_value, page_entry_to_uint(index), mem_mask, pe.valid ? 1 : 0, pe.writable ? 1 : 0, pe.supervisor ? 1 : 0, pe.uncached ? 0 : 1);
-}
-
-uint32_t sun4_mmu_base_device::vaddr_to_cache_line(uint32_t vaddr)
-{
- return (vaddr >> m_cache_tag_shift) & m_cache_tag_mask;
-}
-
-void sun4_mmu_base_device::cache_fill(page_entry &entry, uint32_t vaddr, uint32_t paddr, uint32_t entry_index)
-{
- const uint32_t cache_line = vaddr_to_cache_line(vaddr);
- m_cachetags[cache_line] = (1 << 19);
- m_cachetags[cache_line] |= entry.supervisor ? (1 << 20) : (0 << 20);
- m_cachetags[cache_line] |= entry.writable ? (1 << 21) : (0 << 21);
- m_cachetags[cache_line] |= (vaddr >> m_cache_tag_id_shift) & m_cache_tag_id_mask;
- m_cachetags[cache_line] |= (m_context_masked) << 22;
- const uint32_t cache_line_start = cache_line << m_cache_tag_shift;
- const uint32_t mem_line_mask = (1 << m_cache_tag_shift) - 1;
- const uint32_t mem_line_start = paddr & ~mem_line_mask;
-
- if (paddr < m_populated_ram_words)
- {
- LOGMASKED(LOG_CACHE_FILLS, "Filling cache line %04x (%08x) with data from paddr %08x, vaddr %08x, cache_line %04x, mem_line %08x, tag entry %04x\n",
- cache_line, 0x80000000 | (cache_line << m_cache_tag_shift), paddr << 2, vaddr << 2, cache_line_start << 2, mem_line_start << 2,
- (m_cachetags[cache_line] >> m_cache_line_size) & (0xfffc >> m_cache_tag_shift));
- LOGMASKED(LOG_CACHE_FILLS, "Tag: %08x, valid %d, super %d, write %d, ctx %d\n", m_cachetags[cache_line], BIT(m_cachetags[cache_line], 19),
- BIT(m_cachetags[cache_line], 20), BIT(m_cachetags[cache_line], 21), (m_cachetags[cache_line] >> 22) & 7);
- LOGMASKED(LOG_CACHE_FILLS, "Entry %05x: raw: %08x, valid %d, super %d, write %d, cache %d\n", entry_index, page_entry_to_uint(entry_index),
- entry.valid ? 1 : 0, entry.supervisor ? 1 : 0, entry.writable ? 1 : 0, entry.uncached ? 0 : 1);
- memcpy(&m_cachedata[cache_line_start], m_ram_ptr + mem_line_start, sizeof(uint32_t) * m_cache_word_size);
- }
- else
- {
- LOGMASKED(LOG_CACHE_FILLS, "Unable to fill cache line, paddr %08x exceeds populated RAM range\n", paddr << 2);
- }
-}
-
-template bool sun4_mmu_base_device::cache_fetch<sun4_mmu_base_device::USER_INSN>(page_entry &entry, uint32_t vaddr, uint32_t paddr, uint32_t &cached_data, uint32_t entry_index);
-template bool sun4_mmu_base_device::cache_fetch<sun4_mmu_base_device::USER_DATA>(page_entry &entry, uint32_t vaddr, uint32_t paddr, uint32_t &cached_data, uint32_t entry_index);
-template bool sun4_mmu_base_device::cache_fetch<sun4_mmu_base_device::SUPER_INSN>(page_entry &entry, uint32_t vaddr, uint32_t paddr, uint32_t &cached_data, uint32_t entry_index);
-template bool sun4_mmu_base_device::cache_fetch<sun4_mmu_base_device::SUPER_DATA>(page_entry &entry, uint32_t vaddr, uint32_t paddr, uint32_t &cached_data, uint32_t entry_index);
-
-template <sun4_mmu_base_device::insn_data_mode MODE>
-bool sun4_mmu_base_device::cache_fetch(page_entry &entry, uint32_t vaddr, uint32_t paddr, uint32_t &cached_data, uint32_t entry_index)
-{
- const uint32_t cache_line = vaddr_to_cache_line(vaddr);
- const uint32_t tag = m_cachetags[cache_line];
- if (!(tag & (1 << 19)))
- {
- // If the current tag is invalid, bail if the corresponding entry is invalid
- if (!entry.valid)
- {
- return false;
- }
- cache_fill(entry, vaddr, paddr, entry_index);
- cached_data = m_cachedata[vaddr & 0x3fff];
- return true;
- }
- else if ((tag & m_cache_tag_id_mask) == ((vaddr >> m_cache_tag_id_shift) & m_cache_tag_id_mask))
- {
- // If the current tag is valid and the tag IDs match, fetch from the cache
- if ((MODE >> 1) == USER_MODE)
- {
- // If we're in user mode and the context does not match, this is a miss
- if (((tag >> 22) & m_ctx_mask) != m_context_masked && (tag & (1 << 20)))
- {
- return false;
- }
- }
- cached_data = m_cachedata[vaddr & 0x3fff];
- return true;
- }
- else if (!entry.valid)
- {
- // If the current tag is valid, the tag IDs don't match, and the memory entry is invalid, miss
- return false;
- }
- else
- {
- // If the current tag is valid, the tag IDs don't match, and the memory entry is valid, it's a miss
- cache_fill(entry, vaddr, paddr, entry_index);
- cached_data = m_cachedata[vaddr & 0x3fff];
- return true;
- }
}
template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_INSN>(const uint32_t, const uint32_t);
@@ -674,122 +522,47 @@ template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_D
template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::SUPER_DATA>(const uint32_t, const uint32_t);
template <sun4_mmu_base_device::insn_data_mode MODE>
-uint32_t sun4_mmu_base_device::insn_data_r(uint32_t offset, uint32_t mem_mask)
+uint32_t sun4_mmu_base_device::insn_data_r(const uint32_t offset, const uint32_t mem_mask)
{
// supervisor program fetches in boot state are special
if (MODE == SUPER_INSN && m_fetch_bootrom)
{
- if (!machine().side_effects_disabled())
- m_cpu->eat_cycles(50); // !?
return m_rom_ptr[offset & 0x1ffff];
}
// it's translation time
const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];// & m_pmeg_mask;
const uint32_t entry_index = pmeg | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
- page_entry &entry = m_pagemap[entry_index];
- uint32_t cached_data = 0;
- if (entry.valid)
+ if (m_page_valid[entry_index])
{
- const uint32_t paddr = entry.page | (offset & m_page_mask);
-
+ page_entry &entry = m_pagemap[entry_index];
entry.accessed = PM_ACCESSED;
- {
- uint32_t tag_entry = vaddr_to_cache_line(offset);
- uint32_t tag = m_cachetags[tag_entry];
- bool user_mode = ((MODE >> 1) == USER_MODE);
- bool cache_hit = (tag & m_cache_tag_id_mask) == ((offset >> m_cache_tag_id_shift) & m_cache_tag_id_mask);
- bool cacheable = entry.type == 0 && !entry.uncached;
- bool check_cache = cacheable && cache_hit && (m_system_enable & ENA_CACHE);
- bool cache_valid = BIT(tag, 19);
- bool cache_protected = user_mode && BIT(tag, 20) && (((m_cachetags[tag_entry] >> 22) & m_ctx_mask) != m_context_masked);
-
- if (check_cache && cache_valid && cache_protected)
- {
- LOGMASKED(LOG_READ_PROTECT, "%s: read protect error with PTE %04x (%08x), %08x & %08x\n", machine().describe_context(),
- entry_index, page_entry_to_uint(entry_index), offset << 2, mem_mask);
- LOGMASKED(LOG_WRITE_PROTECT, "%s: tag %08x, line %04x, writable %d, check %d, valid %d, super %d, tag ctx %d, ctx reg %d\n",
- machine().describe_context(), m_cachetags[tag_entry], tag_entry, BIT(m_cachetags[tag_entry], 21), check_cache ? 1 : 0, cache_valid ? 1 : 0,
- BIT(m_cachetags[tag_entry], 20), (m_cachetags[tag_entry] >> 22) & 7, m_context_masked);
- LOGMASKED(LOG_WRITE_PROTECT, "%s: entry cached %d, entry writable %d, entry super %d\n",
- machine().describe_context(), entry.uncached ? 0 : 1, entry.writable ? 1 : 0, entry.supervisor ? 1 : 0);
- LOGMASKED(LOG_WRITE_PROTECT, "%s: pmeg %08x, seg entry %08x\n", machine().describe_context(), pmeg, ((offset >> m_seg_entry_shift) & m_seg_entry_mask));
- m_buserr[0] |= 0x0040; // read protection error
- m_buserr[1] = offset << 2;
- m_host->set_mae();
- m_cachetags[tag_entry] &= ~(1 << 19);
- return 0;
- }
- }
+ const uint32_t tmp = entry.page | (offset & m_page_mask);
switch (entry.type)
{
case 0: // type 0 space
- if (paddr < m_populated_ram_words)
+ if (tmp < m_populated_ram_words)
{
- if (BIT(m_parity_err_reg, 4) && m_parity_err)
- {
- LOGMASKED(LOG_PARITY, "%s: ram read with parity %08x: %08x & %08x\n", machine().describe_context(), m_parity_err_reg, offset, mem_mask);
- m_parity_err_reg |= m_parity_err;
- if (BIT(m_parity_err_reg, 7))
- {
- m_parity_err_reg |= (1 << 6);
- }
- uint8_t boffs = 0;
-
- if (ACCESSING_BITS_24_31)
- boffs = 0;
- else if (ACCESSING_BITS_16_23)
- boffs = 1;
- else if (ACCESSING_BITS_8_15)
- boffs = 2;
- else if (ACCESSING_BITS_0_7)
- boffs = 3;
-
- m_parity_err_reg |= (1 << 7);
- m_parity_err = 0;
- m_buserr[0] = 0x8; // Read cycle, memory error
- m_buserr[1] = (offset << 2) | boffs;
- m_host->set_mae();
- }
- const uint32_t set = (paddr >> 22) & 3;
+ const uint32_t set = (tmp >> 22) & 3;
const uint32_t addr_mask = m_ram_set_mask[set];
- const uint32_t masked_addr = m_ram_set_base[set] + (paddr & addr_mask);
- if (!entry.uncached && (m_system_enable & ENA_CACHE))
- {
- if (cache_fetch<MODE>(entry, offset, masked_addr, cached_data, entry_index))
- {
-#if SUN4CMMU_LOG_MEM_ACCESSES
- uint32_t value = masked_addr | 0x80000000;
- fwrite(&value, 1, 4, s_mem_log);
- fwrite(&cached_data, 1, 4, s_mem_log);
- m_fpos += 8;
-#endif
- return cached_data;
- }
- }
-#if SUN4CMMU_LOG_MEM_ACCESSES
- uint32_t value = masked_addr | 0x80000000;
- fwrite(&value, 1, 4, s_mem_log);
- fwrite(&m_ram_ptr[masked_addr], 1, 4, s_mem_log);
- m_fpos += 8;
-#endif
+ const uint32_t masked_addr = m_ram_set_base[set] + (tmp & addr_mask);
return m_ram_ptr[masked_addr];
}
- else if (paddr >= 0x4000000 >> 2 && paddr < 0x10000000 >> 2)
+ else if (tmp >= 0x4000000 >> 2 && tmp < 0x10000000 >> 2)
{
- type0_timeout_r(paddr);
+ type0_timeout_r(tmp);
}
return ~0;
case 1: // type 1 space
m_type1_offset = offset;
- return m_type1_r(paddr, mem_mask);
+ return m_type1_r(tmp, mem_mask);
default:
- LOGMASKED(LOG_UNKNOWN_SPACE, "read unknown space type %d, %08x & %08x, PC=%08x\n", entry.type, paddr << 2, mem_mask, m_cpu->pc());
+ LOGMASKED(LOG_UNKNOWN_SPACE, "read unknown space type %d, %08x & %08x, PC=%08x\n", entry.type, tmp << 2, mem_mask, m_cpu->pc());
m_host->set_mae();
m_buserr[0] = 0x20;
m_buserr[1] = offset << 2;
@@ -800,10 +573,6 @@ uint32_t sun4_mmu_base_device::insn_data_r(uint32_t offset, uint32_t mem_mask)
{
if (!machine().side_effects_disabled())
{
- if ((m_system_enable & ENA_CACHE) && cache_fetch<MODE>(entry, offset, 0, cached_data, entry_index))
- {
- return cached_data;
- }
LOGMASKED(LOG_INVALID_PTE, "read invalid PTE %d (%08x), %08x & %08x, PC=%08x\n", entry_index, page_entry_to_uint(entry_index), offset << 2, mem_mask, m_cpu->pc());
m_host->set_mae();
m_buserr[0] |= 0x80; // invalid PTE
@@ -835,7 +604,7 @@ template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_DATA>
template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::SUPER_DATA>(const uint32_t, const uint32_t, const uint32_t);
template <sun4_mmu_base_device::insn_data_mode MODE>
-void sun4_mmu_base_device::insn_data_w(uint32_t offset, uint32_t data, uint32_t mem_mask)
+void sun4_mmu_base_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];// & m_pmeg_mask;
@@ -844,104 +613,43 @@ void sun4_mmu_base_device::insn_data_w(uint32_t offset, uint32_t data, uint32_t
if (m_page_valid[entry_index])
{
page_entry &entry = m_pagemap[entry_index];
- const uint32_t paddr = entry.page | (offset & m_page_mask);
-
+ if ((!entry.writable) || (entry.supervisor && MODE != SUPER_DATA && MODE != SUPER_INSN))
{
- uint32_t tag_entry = vaddr_to_cache_line(offset);
- uint32_t tag = m_cachetags[tag_entry];
- bool user_mode = (MODE >> 1) == USER_MODE;
- bool cacheable = entry.type == 0 && !entry.uncached;
- bool check_cache = cacheable && (m_system_enable & ENA_CACHE);
- bool cache_valid = BIT(tag, 19);
- bool cache_hit = (tag & m_cache_tag_id_mask) == ((offset >> m_cache_tag_id_shift) & m_cache_tag_id_mask);
- bool cache_writable = BIT(tag, 21);
- bool cache_protected = user_mode && BIT(tag, 20) && (((tag >> 22) & m_ctx_mask) != m_context_masked);
-
- if (cacheable && (!cache_valid || !cache_hit || !cache_writable || cache_protected))
- {
- m_cachetags[tag_entry] &= ~(1 << 19);
- }
-
- if ((check_cache && cache_hit && cache_valid && (!cache_writable || cache_protected)) ||
- (!check_cache && (!entry.writable || (user_mode && entry.supervisor))))
- {
- LOGMASKED(LOG_WRITE_PROTECT, "%s: write protect error with PTE %04x (%08x), %08x = %08x & %08x, mode %c\n", machine().describe_context(),
- entry_index, page_entry_to_uint(entry_index), offset << 2, data, mem_mask, user_mode ? 'U' : 'S');
- LOGMASKED(LOG_WRITE_PROTECT, "%s: tag %08x, line %04x, writable %d, check %d, valid %d, super %d, tag ctx %d, ctx reg %d\n",
- machine().describe_context(), m_cachetags[tag_entry], tag_entry, BIT(m_cachetags[tag_entry], 21), check_cache ? 1 : 0, cache_valid ? 1 : 0,
- BIT(m_cachetags[tag_entry], 20), (m_cachetags[tag_entry] >> 22) & 7, m_context_masked);
- LOGMASKED(LOG_WRITE_PROTECT, "%s: entry cached %d, entry writable %d, entry super %d\n",
- machine().describe_context(), entry.uncached ? 0 : 1, entry.writable ? 1 : 0, entry.supervisor ? 1 : 0);
- LOGMASKED(LOG_WRITE_PROTECT, "%s: pmeg %08x, seg entry %08x\n", machine().describe_context(), pmeg, ((offset >> m_seg_entry_shift) & m_seg_entry_mask));
- m_buserr[0] |= 0x8040; // write protection error
- m_buserr[1] = offset << 2;
- m_host->set_mae();
- return;
- }
+ LOGMASKED(LOG_WRITE_PROTECT, "write protect error with PTE %d (%08x), %08x = %08x & %08x, PC=%08x\n", entry_index, page_entry_to_uint(entry_index), offset << 2, data, mem_mask, m_cpu->pc());
+ m_buserr[0] |= 0x8040; // write, protection error
+ m_buserr[1] = offset << 2;
+ m_host->set_mae();
+ return;
}
entry.accessed = PM_ACCESSED;
entry.modified = PM_MODIFIED;
+ const uint32_t tmp = entry.page | (offset & m_page_mask);
+
switch (entry.type)
{
case 0: // type 0
- if (paddr < m_populated_ram_words)
+ if (tmp < m_populated_ram_words)
{
- if (BIT(m_parity_err_reg, 5))
- {
- LOGMASKED(LOG_PARITY, "%s: ram write with parity %08x: %08x = %08x & %08x\n", machine().describe_context(), m_parity_err_reg,
- offset, data, mem_mask);
- if (ACCESSING_BITS_24_31)
- m_parity_err |= (1 << 0);
- if (ACCESSING_BITS_16_23)
- m_parity_err |= (1 << 1);
- if (ACCESSING_BITS_8_15)
- m_parity_err |= (1 << 2);
- if (ACCESSING_BITS_0_7)
- m_parity_err |= (1 << 3);
- }
- const uint32_t set = (paddr >> 22) & 3;
+ const uint32_t set = (tmp >> 22) & 3;
const uint32_t addr_mask = m_ram_set_mask[set];
- const uint32_t masked_addr = m_ram_set_base[set] + (paddr & addr_mask);
- if (!entry.uncached && (m_system_enable & ENA_CACHE))
- {
- const uint32_t cache_entry = vaddr_to_cache_line(offset);
- const uint32_t tag = m_cachetags[cache_entry];
- if (tag & (1 << 19))
- {
- if ((m_cachetags[cache_entry] & m_cache_tag_id_mask) == ((offset >> m_cache_tag_id_shift) & m_cache_tag_id_mask))
- {
- COMBINE_DATA(&m_cachedata[offset & 0x3fff]);
- }
- else
- {
- //m_cachetags[cache_entry] &= ~(1 << 19);
- //cache_fill(entry, offset, masked_addr, entry_index);
- //COMBINE_DATA(&m_cachedata[offset & 0x3fff]);
- }
- }
- }
+ const uint32_t masked_addr = m_ram_set_base[set] + (tmp & addr_mask);
COMBINE_DATA((m_ram_ptr + masked_addr));
-#if SUN4CMMU_LOG_MEM_ACCESSES
- fwrite(&masked_addr, 1, 4, s_mem_log);
- fwrite(&m_ram_ptr[masked_addr], 1, 4, s_mem_log);
- m_fpos += 8;
-#endif
}
- else if (paddr >= 0x4000000 >> 2 && paddr < 0x10000000 >> 2)
+ else if (tmp >= 0x4000000 >> 2 && tmp < 0x10000000 >> 2)
{
- type0_timeout_w(paddr);
+ type0_timeout_w(tmp);
}
return;
case 1: // type 1
m_type1_offset = offset;
- m_type1_w(paddr, data, mem_mask);
+ m_type1_w(tmp, data, mem_mask);
return;
default:
- LOGMASKED(LOG_UNKNOWN_SPACE, "write unknown space type %d, %08x = %08x & %08x, PC=%08x\n", entry.type, paddr << 2, data, mem_mask, m_cpu->pc());
+ LOGMASKED(LOG_UNKNOWN_SPACE, "write unknown space type %d, %08x = %08x & %08x, PC=%08x\n", entry.type, tmp << 2, data, mem_mask, m_cpu->pc());
m_host->set_mae();
m_buserr[0] = 0x8020;
m_buserr[1] = offset << 2;
@@ -972,15 +680,6 @@ void sun4_mmu_base_device::insn_data_w(uint32_t offset, uint32_t data, uint32_t
}
}
-bool sun4_mmu_base_device::translate(uint32_t &addr)
-{
- const uint32_t pmeg = m_curr_segmap_masked[(addr >> 16) & 0xfff];// & m_pmeg_mask;
- const uint32_t entry_index = pmeg | ((addr >> m_seg_entry_shift) & m_seg_entry_mask);
- const page_entry &entry = m_pagemap[entry_index];
- addr = entry.page | (addr & m_page_mask);
- return entry.valid;
-}
-
void sun4_mmu_base_device::l2p_command(const std::vector<std::string_view> &params)
{
uint64_t addr, offset;
@@ -990,17 +689,22 @@ void sun4_mmu_base_device::l2p_command(const std::vector<std::string_view> &para
addr &= 0xffffffff;
offset = addr >> 2;
- uint8_t pmeg = m_curr_segmap_masked[(addr >> 18) & 0xfff];
- uint32_t entry_index = pmeg | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
- uint32_t paddr = m_pagemap[entry_index].page | (offset & m_page_mask);
- uint32_t entry_value = page_entry_to_uint(entry_index);
+ uint8_t pmeg = 0;
+ uint32_t entry_index = 0, tmp = 0;
+ uint32_t entry_value = 0;
+
+ pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
+ entry_index = pmeg | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
+ tmp = m_pagemap[entry_index].page | (offset & m_page_mask);
+ entry_value = page_entry_to_uint(entry_index);
if (m_page_valid[entry_index])
{
- machine().debugger().console().printf("logical %08x => phys %08x, type %d (pmeg %d, entry %d PTE %08x)\n", addr, paddr << 2, m_pagemap[entry_index].type, pmeg, entry_index, entry_value);
+ machine().debugger().console().printf("logical %08x => phys %08x, type %d (pmeg %d, entry %d PTE %08x)\n", addr, tmp << 2, m_pagemap[entry_index].type, pmeg, entry_index, entry_value);
}
else
{
- machine().debugger().console().printf("logical %08x points to an invalid PTE! (pmeg %d, entry %d PTE %08x)\n", addr, paddr << 2, pmeg, entry_index, entry_value);
+ machine().debugger().console().printf("logical %08x points to an invalid PTE! (pmeg %d, entry %d PTE %08x)\n", addr, tmp << 2, pmeg, entry_index, entry_value);
}
}
+
diff --git a/src/devices/machine/sun4c_mmu.h b/src/devices/machine/sun4c_mmu.h
index bd9b1201fbf..87db83ec4a7 100644
--- a/src/devices/machine/sun4c_mmu.h
+++ b/src/devices/machine/sun4c_mmu.h
@@ -15,8 +15,6 @@
#include "machine/ram.h"
#include "machine/z80scc.h"
-#define SUN4CMMU_LOG_MEM_ACCESSES (0)
-
class sun4_mmu_base_device : public device_t, public sparc_mmu_interface
{
public:
@@ -39,7 +37,6 @@ public:
template <typename T> void set_ram(T &&ram_tag) { m_ram.set_tag(std::forward<T>(ram_tag)); }
template <typename T> void set_rom(T &&rom_tag) { m_rom.set_tag(std::forward<T>(rom_tag)); }
template <typename T> void set_scc(T &&scc_tag) { m_scc.set_tag(std::forward<T>(scc_tag)); }
- void set_cache_line_size(uint32_t line_size) { m_cache_line_size = line_size; }
auto type1_r() { return m_type1_r.bind(); }
auto type1_w() { return m_type1_w.bind(); }
@@ -51,31 +48,26 @@ public:
void set_seg_entry_mask(uint32_t seg_entry_mask) { m_seg_entry_mask = seg_entry_mask; }
void set_page_entry_mask(uint32_t page_entry_mask) { m_page_entry_mask = page_entry_mask; }
void set_cache_mask(uint32_t cache_mask) { m_cache_mask = cache_mask; }
-
- enum perm_mode
- {
- USER_MODE,
- SUPER_MODE
- };
+ void set_cache_line_size(uint32_t cache_line_size) { m_cache_line_size = cache_line_size; }
enum insn_data_mode
{
USER_INSN,
- USER_DATA,
SUPER_INSN,
+ USER_DATA,
SUPER_DATA
};
- template <insn_data_mode MODE> uint32_t insn_data_r(uint32_t offset, uint32_t mem_mask);
- template <insn_data_mode MODE> void insn_data_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ template <insn_data_mode MODE> uint32_t insn_data_r(const uint32_t offset, const uint32_t mem_mask);
+ template <insn_data_mode MODE> void insn_data_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask);
uint32_t type1_timeout_r(uint32_t offset);
void type1_timeout_w(uint32_t offset, uint32_t data);
uint32_t parity_r(uint32_t offset, uint32_t mem_mask);
void parity_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
- // sparc_mmu_device overrides
- uint32_t fetch_insn(const bool supervisor, uint32_t offset) override;
+ // sparc_mmu_interface overrides
+ uint32_t fetch_insn(const bool supervisor, const uint32_t offset) override;
void set_host(sparc_mmu_host_interface *host) override { m_host = host; }
uint32_t context_reg_r(uint32_t offset, uint32_t mem_mask);
@@ -107,38 +99,17 @@ public:
protected:
sun4_mmu_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
- struct page_entry
- {
- uint32_t index;
- uint32_t raw;
- uint32_t valid;
- uint32_t writable;
- uint32_t supervisor;
- uint32_t uncached;
- uint32_t accessed;
- uint32_t modified;
- uint32_t page;
- uint8_t type;
- uint8_t pad[3];
- };
-
virtual void device_start() override;
virtual void device_reset() override;
- virtual void device_stop() override;
TIMER_CALLBACK_MEMBER(reset_off_tick);
uint32_t page_entry_to_uint(uint32_t index);
void merge_page_entry(uint32_t index, uint32_t data, uint32_t mem_mask);
- template <insn_data_mode MODE> bool cache_fetch(page_entry &entry, uint32_t vaddr, uint32_t paddr, uint32_t &cached_data, uint32_t entry_index);
- void cache_fill(page_entry &entry, uint32_t vaddr, uint32_t paddr, uint32_t entry_index);
-
void type0_timeout_r(const uint32_t offset);
void type0_timeout_w(const uint32_t offset);
- bool translate(uint32_t &addr);
void l2p_command(const std::vector<std::string_view> &params);
- uint32_t vaddr_to_cache_line(uint32_t vaddr);
enum
{
@@ -159,6 +130,19 @@ protected:
PM_MODIFIED = 0x01000000 // modified flag
};
+ struct page_entry
+ {
+ uint32_t valid;
+ uint32_t writable;
+ uint32_t supervisor;
+ uint32_t uncached;
+ uint32_t accessed;
+ uint32_t modified;
+ uint32_t page;
+ uint8_t type;
+ uint8_t pad[3];
+ };
+
required_device<cpu_device> m_cpu;
required_device<ram_device> m_ram;
required_memory_region m_rom;
@@ -185,7 +169,7 @@ protected:
uint32_t m_cache_context;
uint8_t m_system_enable;
bool m_fetch_bootrom;
- uint32_t m_buserr[16];
+ uint32_t m_buserr[4];
uint32_t m_type1_offset;
uint32_t m_parity_err_reg;
uint32_t m_memory_err_reg;
@@ -205,21 +189,11 @@ protected:
uint32_t m_seg_entry_mask;
uint32_t m_page_entry_mask;
uint32_t m_cache_mask;
- uint32_t m_cache_tag_mask;
uint32_t m_cache_line_size;
- uint32_t m_cache_word_size;
- uint32_t m_cache_tag_shift;
- uint32_t m_cache_tag_id_mask;
- uint32_t m_cache_tag_id_shift;
- uint32_t m_cache_vaddr_shift;
uint32_t m_ram_set_mask[4]; // Used for mirroring within 4 megabyte sets
uint32_t m_ram_set_base[4];
uint32_t m_populated_ram_words;
-#if SUN4CMMU_LOG_MEM_ACCESSES
- uint64_t m_fpos;
-#endif
emu_timer *m_reset_timer;
- bool m_log_mem;
};
class sun4_mmu_device : public sun4_mmu_base_device