summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Ryan Holtz <ryan.holtz@arrowheadgs.com>2020-05-20 00:02:14 +0200
committer Ryan Holtz <ryan.holtz@arrowheadgs.com>2020-05-20 00:02:43 +0200
commit0ec3865b9990c96341160a967fb2013c324a5cf2 (patch)
tree92ca4c1dacb0402daa97b4b8427626f360b3f913
parentcec2fd71bc414c1f51fbadb772d845240819c1a7 (diff)
-sun4: Make use of multiple address spaces in the SPARC core rather than having the MMU handle it all. [Ryan Holtz]
-rw-r--r--src/devices/cpu/m68000/m68kmake.exebin0 -> 415010 bytes
-rw-r--r--src/devices/cpu/m68000/m68kmake.obin0 -> 26355 bytes
-rw-r--r--src/devices/cpu/sparc/sparc.cpp111
-rw-r--r--src/devices/cpu/sparc/sparc.h8
-rw-r--r--src/devices/cpu/sparc/sparc_intf.h2
-rw-r--r--src/devices/machine/sun4c_mmu.cpp382
-rw-r--r--src/devices/machine/sun4c_mmu.h59
-rw-r--r--src/mame/drivers/sun4.cpp121
8 files changed, 358 insertions, 325 deletions
diff --git a/src/devices/cpu/m68000/m68kmake.exe b/src/devices/cpu/m68000/m68kmake.exe
new file mode 100644
index 00000000000..7b2a36e5413
--- /dev/null
+++ b/src/devices/cpu/m68000/m68kmake.exe
Binary files differ
diff --git a/src/devices/cpu/m68000/m68kmake.o b/src/devices/cpu/m68000/m68kmake.o
new file mode 100644
index 00000000000..b4621ccc99a
--- /dev/null
+++ b/src/devices/cpu/m68000/m68kmake.o
Binary files differ
diff --git a/src/devices/cpu/sparc/sparc.cpp b/src/devices/cpu/sparc/sparc.cpp
index 07765a7ef19..f24a4f6a93c 100644
--- a/src/devices/cpu/sparc/sparc.cpp
+++ b/src/devices/cpu/sparc/sparc.cpp
@@ -45,7 +45,13 @@ sparc_base_device::sparc_base_device(const machine_config &mconfig, device_type
: cpu_device(mconfig, type, tag, owner, clock)
, m_mmu(*this, finder_base::DUMMY_TAG)
{
- m_default_config = address_space_config("program", ENDIANNESS_BIG, 32, 32);
+ char asi_buf[10];
+ m_debugger_config = address_space_config("debug", ENDIANNESS_BIG, 32, 32);
+ for (int i = 0; i < 0x10; i++)
+ {
+ snprintf(asi_buf, ARRAY_LENGTH(asi_buf), "asi%X", i);
+ m_asi_config[i] = address_space_config(asi_buf, ENDIANNESS_BIG, 32, 32);
+ }
}
@@ -162,6 +168,15 @@ void sparc_base_device::device_start()
m_bp_irl = 0;
m_irq_state = 0;
+ for (int i = 0; i < 0x20; i++)
+ {
+ if (i > 0 && i < 0x10)
+ {
+ continue;
+ }
+ m_asi[i] = &space(i);
+ }
+
memset(m_dbgregs, 0, 24 * sizeof(uint32_t));
memset(m_illegal_instruction_asr, 0, 32 * sizeof(bool));
@@ -522,38 +537,24 @@ void sparc_base_device::device_post_load()
device_memory_interface::space_config_vector sparc_base_device::memory_space_config() const
{
space_config_vector config_vector;
- config_vector.push_back(std::make_pair(AS_PROGRAM, &m_default_config));
+ config_vector.push_back(std::make_pair(0, &m_debugger_config));
+ for (int i = 0; i < 0x10; i++)
+ {
+ config_vector.push_back(std::make_pair(0x10 + i, &m_asi_config[i]));
+ }
return config_vector;
}
-
-//-------------------------------------------------
-// read_sized_word - read a value from a given
-// address space and address, shifting the data
-// that is read into the appropriate location of
-// a 32-bit word in a big-endian system.
-//-------------------------------------------------
-
-uint32_t sparc_base_device::read_sized_word(const uint8_t asi, const uint32_t address, const uint32_t mem_mask)
+inline uint32_t sparc_base_device::read_word(const uint8_t asi, const uint32_t address, const uint32_t mem_mask)
{
- assert(asi < 0x20); // We do not currently support ASIs outside the range used by actual Sun machines.
- return m_mmu->read_asi(asi, address >> 2, mem_mask);
+ assert(asi < 0x10); // We do not currently support ASIs outside the range used by actual Sun machines.
+ return m_asi[asi | 0x10]->read_dword(address, mem_mask);
}
-
-//-------------------------------------------------
-// write_sized_word - write a value to a given
-// address space and address, shifting the data
-// that is written into the least significant
-// bits as appropriate in order to write the
-// value to a memory system with separate data
-// size handlers
-//-------------------------------------------------
-
-void sparc_base_device::write_sized_word(const uint8_t asi, const uint32_t address, const uint32_t data, const uint32_t mem_mask)
+inline void sparc_base_device::write_word(const uint8_t asi, const uint32_t address, const uint32_t data, const uint32_t mem_mask)
{
- assert(asi < 0x20); // We do not currently support ASIs outside the range used by actual Sun machines.
- m_mmu->write_asi(asi, address >> 2, data, mem_mask);
+ assert(asi < 0x10); // We do not currently support ASIs outside the range used by actual Sun machines.
+ return m_asi[asi | 0x10]->write_dword(address, data, mem_mask);
}
@@ -2165,7 +2166,7 @@ void sparc_base_device::execute_store(uint32_t op)
static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
- m_mmu->write_asi(addr_space, address >> 2, data0, (ST || STA || STD || STDA || STF || STDF || STDFQ || STFSR || STC || STDC || STDCQ || STCSR) ? 0xffffffff : ((STH || STHA) ? mask16[address & 2] : mask8[address & 3]));
+ write_word(addr_space, address, data0, (ST || STA || STD || STDA || STF || STDF || STDFQ || STFSR || STC || STDC || STDCQ || STCSR) ? 0xffffffff : ((STH || STHA) ? mask16[address & 2] : mask8[address & 3]));
if (MAE)
{
m_trap = 1;
@@ -2177,7 +2178,7 @@ void sparc_base_device::execute_store(uint32_t op)
if (STD || STDA || STDF || STDC || STDFQ || STDCQ)
{
- m_mmu->write_asi(addr_space, (address + 4) >> 2, data1, 0xffffffff);
+ write_word(addr_space, address + 4, data1);
if (MAE)
{
m_trap = 1;
@@ -2304,7 +2305,7 @@ inline void sparc_base_device::execute_ldd(uint32_t op)
m_icount = 0;
}
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ const uint32_t data = read_word(m_data_space, address);
if (MAE)
{
@@ -2318,7 +2319,7 @@ inline void sparc_base_device::execute_ldd(uint32_t op)
if (RDBITS)
RDREG = data;
- const uint32_t word1 = m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
+ const uint32_t word1 = read_word(m_data_space, address + 4);
if (MAE)
{
m_trap = 1;
@@ -2347,7 +2348,7 @@ inline void sparc_base_device::execute_ld(uint32_t op)
return;
}
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ const uint32_t data = read_word(m_data_space, address);
if (m_mae)
{
@@ -2379,7 +2380,7 @@ inline void sparc_base_device::execute_ldsh(uint32_t op)
}
static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask16[address & 2]);
+ const uint32_t data = read_word(m_data_space, address, mask16[address & 2]);
if (m_mae)
{
@@ -2414,7 +2415,7 @@ inline void sparc_base_device::execute_lduh(uint32_t op)
}
static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask16[address & 2]);
+ const uint32_t data = read_word(m_data_space, address, mask16[address & 2]);
if (m_mae)
{
@@ -2440,7 +2441,7 @@ inline void sparc_base_device::execute_ldsb(uint32_t op)
const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask8[address & 3]);
+ const uint32_t data = read_word(m_data_space, address, mask8[address & 3]);
if (m_mae)
{
@@ -2469,7 +2470,7 @@ inline void sparc_base_device::execute_ldub(uint32_t op)
static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
const uint32_t byte_idx = address & 3;
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask8[byte_idx]);
+ const uint32_t data = read_word(m_data_space, address, mask8[byte_idx]);
if (m_mae)
{
@@ -2512,7 +2513,7 @@ inline void sparc_base_device::execute_lddfpr(uint32_t op)
return;
}
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ const uint32_t data = read_word(m_data_space, address);
if (m_mae)
{
@@ -2528,7 +2529,7 @@ inline void sparc_base_device::execute_lddfpr(uint32_t op)
return;
}
- const uint32_t word1 = m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
+ const uint32_t word1 = read_word(m_data_space, address + 4);
if (MAE)
{
m_trap = 1;
@@ -2572,7 +2573,7 @@ inline void sparc_base_device::execute_ldfpr(uint32_t op)
return;
}
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ const uint32_t data = read_word(m_data_space, address);
if (m_mae)
{
@@ -2616,7 +2617,7 @@ inline void sparc_base_device::execute_ldfsr(uint32_t op)
return;
}
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ const uint32_t data = read_word(m_data_space, address);
if (m_mae)
{
@@ -2673,7 +2674,7 @@ inline void sparc_base_device::execute_lddcpr(uint32_t op)
return;
}
- m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ read_word(m_data_space, address);
if (MAE)
{
m_trap = 1;
@@ -2685,7 +2686,7 @@ inline void sparc_base_device::execute_lddcpr(uint32_t op)
// implementation-dependent actions
- m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
+ read_word(m_data_space, address + 4);
if (MAE)
{
m_trap = 1;
@@ -2733,7 +2734,7 @@ inline void sparc_base_device::execute_ldcpr(uint32_t op)
return;
}
- m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ read_word(m_data_space, address);
if (MAE)
{
@@ -2782,7 +2783,7 @@ inline void sparc_base_device::execute_ldcsr(uint32_t op)
return;
}
- m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ read_word(m_data_space, address);
if (MAE)
{
@@ -2830,7 +2831,7 @@ inline void sparc_base_device::execute_ldda(uint32_t op)
return;
}
- const uint32_t data = m_mmu->read_asi(addr_space, address >> 2, 0xffffffff);
+ const uint32_t data = read_word(addr_space, address);
if (m_mae)
{
@@ -2844,7 +2845,7 @@ inline void sparc_base_device::execute_ldda(uint32_t op)
if (RDBITS)
RDREG = data;
- uint32_t word1 = m_mmu->read_asi(addr_space, (address + 4) >> 2, 0xffffffff);
+ uint32_t word1 = read_word(addr_space, address + 4);
if (MAE)
{
m_trap = 1;
@@ -2890,7 +2891,7 @@ inline void sparc_base_device::execute_lda(uint32_t op)
return;
}
- const uint32_t data = m_mmu->read_asi(ASI, address >> 2, 0xffffffff);
+ const uint32_t data = read_word(ASI, address);
if (m_mae)
{
@@ -2939,7 +2940,7 @@ inline void sparc_base_device::execute_ldsha(uint32_t op)
}
static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
- const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask16[address & 2]);
+ const uint32_t data = read_word(ASI, address, mask16[address & 2]);
if (m_mae)
{
@@ -2990,7 +2991,7 @@ inline void sparc_base_device::execute_lduha(uint32_t op)
}
static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
- const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask16[address & 2]);
+ const uint32_t data = read_word(ASI, address, mask16[address & 2]);
if (m_mae)
{
@@ -3032,7 +3033,7 @@ inline void sparc_base_device::execute_ldsba(uint32_t op)
static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
const uint32_t address = RS1REG + RS2REG;
- const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask8[address & 3]);
+ const uint32_t data = read_word(ASI, address, mask8[address & 3]);
if (m_mae)
{
@@ -3076,7 +3077,7 @@ inline void sparc_base_device::execute_lduba(uint32_t op)
static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
const uint32_t address = RS1REG + RS2REG;
- const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask8[address & 3]);
+ const uint32_t data = read_word(ASI, address, mask8[address & 3]);
if (m_mae)
{
@@ -3210,7 +3211,7 @@ void sparc_base_device::execute_ldstub(uint32_t op)
m_pb_block_ldst_byte = 1;
static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
- data = m_mmu->read_asi(addr_space, address >> 2, mask8[address & 3]);
+ data = read_word(addr_space, address, mask8[address & 3]);
if (MAE)
{
@@ -3221,7 +3222,7 @@ void sparc_base_device::execute_ldstub(uint32_t op)
return;
}
- m_mmu->write_asi(addr_space, address >> 2, 0xffffffff, mask8[address & 3]);
+ write_word(addr_space, address, 0xffffffff, mask8[address & 3]);
m_pb_block_ldst_byte = 0;
@@ -4555,7 +4556,7 @@ void sparcv8_device::execute_swap(uint32_t op)
m_pb_block_ldst_word = 1;
- word = read_sized_word(addr_space, address, 4);
+ word = read_word(addr_space, address);
if (MAE)
{
@@ -4565,7 +4566,7 @@ void sparcv8_device::execute_swap(uint32_t op)
}
if (!m_trap)
{
- write_sized_word(addr_space, address, temp, 4);
+ write_word(addr_space, address, temp);
m_pb_block_ldst_word = 0;
if (MAE)
@@ -4807,7 +4808,7 @@ inline void sparc_base_device::execute_step()
// write-state-register delay not yet implemented
- const uint32_t op = m_mmu->fetch_insn(m_s, PC >> 2);
+ const uint32_t op = read_word(8 + (IS_SUPERVISOR ? 1 : 0), PC);
#if LOG_FCODES
//if (m_log_fcodes)
diff --git a/src/devices/cpu/sparc/sparc.h b/src/devices/cpu/sparc/sparc.h
index 8e16c8bc3f5..de7fa3d3797 100644
--- a/src/devices/cpu/sparc/sparc.h
+++ b/src/devices/cpu/sparc/sparc.h
@@ -155,11 +155,13 @@ protected:
required_device<sparc_mmu_interface> m_mmu;
// address spaces
- address_space_config m_default_config;
+ address_space_config m_debugger_config;
+ address_space_config m_asi_config[0x10];
+ address_space *m_asi[0x20];
// memory access
- uint32_t read_sized_word(const uint8_t asi, const uint32_t address, const uint32_t mem_mask);
- void write_sized_word(const uint8_t asi, const uint32_t address, const uint32_t data, const uint32_t mem_mask);
+ inline uint32_t read_word(const uint8_t asi, const uint32_t address, const uint32_t mem_mask = 0xffffffff);
+ inline void write_word(const uint8_t asi, const uint32_t address, const uint32_t data, const uint32_t mem_mask = 0xffffffff);
// helpers for the disassembler
virtual uint64_t get_reg_r(unsigned index) const override;
diff --git a/src/devices/cpu/sparc/sparc_intf.h b/src/devices/cpu/sparc/sparc_intf.h
index b1fad3ad9a9..f84219be8fd 100644
--- a/src/devices/cpu/sparc/sparc_intf.h
+++ b/src/devices/cpu/sparc/sparc_intf.h
@@ -23,8 +23,6 @@ class sparc_mmu_interface
public:
virtual ~sparc_mmu_interface() { }
virtual uint32_t fetch_insn(const bool supervisor, const uint32_t offset) = 0;
- virtual uint32_t read_asi(uint8_t asi, uint32_t offset, uint32_t mem_mask) = 0;
- virtual void write_asi(uint8_t asi, uint32_t offset, uint32_t data, uint32_t mem_mask) = 0;
virtual void set_host(sparc_mmu_host_interface *host) = 0;
};
diff --git a/src/devices/machine/sun4c_mmu.cpp b/src/devices/machine/sun4c_mmu.cpp
index 8e55308adbd..7cc673cb9d1 100644
--- a/src/devices/machine/sun4c_mmu.cpp
+++ b/src/devices/machine/sun4c_mmu.cpp
@@ -230,107 +230,45 @@ void sun4_mmu_base_device::device_timer(emu_timer &timer, device_timer_id id, in
}
}
-uint32_t sun4_mmu_base_device::fetch_insn(const bool supervisor, const uint32_t offset)
+uint32_t sun4_mmu_base_device::fetch_insn(const bool supervisor, uint32_t offset)
{
if (supervisor)
- return insn_data_r<SUPER_INSN, SUPER_MODE>(offset, 0xffffffff);
+ return insn_data_r<SUPER_INSN>(offset, 0xffffffff);
else
- return insn_data_r<USER_INSN, USER_MODE>(offset, 0xffffffff);
+ return insn_data_r<USER_INSN>(offset, 0xffffffff);
}
-uint32_t sun4_mmu_base_device::read_asi(uint8_t asi, 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)
{
- LOGMASKED(LOG_ALL_ASI, "read_asi %d: %08x & %08x\n", asi, offset << 2, mem_mask);
- switch (asi)
+ for (uint32_t i = 0x0000; i < (0x1000 >> (m_cache_tag_shift + 2)); i++)
{
- case 2:
- return system_r(offset, mem_mask);
- case 3:
- return segment_map_r(offset, mem_mask);
- case 4:
- return page_map_r(offset, mem_mask);
- case 8:
- return insn_data_r<USER_INSN, USER_MODE>(offset, mem_mask);
- case 9:
- return insn_data_r<SUPER_INSN, SUPER_MODE>(offset, mem_mask);
- case 10:
- return insn_data_r<USER_DATA, USER_MODE>(offset, mem_mask);
- case 11:
- return insn_data_r<SUPER_DATA, SUPER_MODE>(offset, mem_mask);
- case 12:
- case 13:
- case 14:
- return 0;
- default:
- LOGMASKED(LOG_UNKNOWN_ASI, "Unknown ASI read: %d, %08x & %08x\n", asi, offset << 2, mem_mask);
- return ~0;
+ segment_flush_w(offset | (i << m_cache_tag_shift), data, mem_mask);
}
}
-void sun4_mmu_base_device::write_asi(uint8_t asi, 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)
{
- LOGMASKED(LOG_ALL_ASI, "write_asi %d: %08x = %08x & %08x\n", asi, offset << 2, data, mem_mask);
- switch (asi)
+ for (uint32_t i = 0x0000; i < (0x1000 >> (m_cache_tag_shift + 2)); i++)
{
- case 2:
- system_w(offset, data, mem_mask);
- return;
- case 3:
- segment_map_w(offset, data, mem_mask);
- return;
- case 4:
- page_map_w(offset, data, mem_mask);
- return;
- case 5:
- for (uint32_t i = 0x0000; i < (0x1000 >> (m_cache_tag_shift + 2)); i++)
- {
- segment_flush_w(offset | (i << m_cache_tag_shift));
- }
- break;
- case 6:
- for (uint32_t i = 0x0000; i < (0x1000 >> (m_cache_tag_shift + 2)); i++)
- {
- page_flush_w(offset | (i << m_cache_tag_shift));
- }
- break;
- case 7:
- for (uint32_t i = 0x0000; i < (0x1000 >> (m_cache_tag_shift + 2)); i++)
- {
- context_flush_w(offset | (i << m_cache_tag_shift));
- }
- break;
- case 8:
- insn_data_w<USER_INSN, USER_MODE>(offset, data, mem_mask);
- return;
- case 9:
- insn_data_w<SUPER_INSN, SUPER_MODE>(offset, data, mem_mask);
- return;
- case 10:
- insn_data_w<USER_DATA, USER_MODE>(offset, data, mem_mask);
- return;
- case 11:
- insn_data_w<SUPER_DATA, SUPER_MODE>(offset, data, mem_mask);
- return;
- case 12:
- segment_flush_w(offset);
- break;
- case 13:
- page_flush_w(offset);
- break;
- case 14:
- context_flush_w(offset);
- return;
- case 15:
- 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);
- }
- break;
- default:
- LOGMASKED(LOG_UNKNOWN_ASI, "Unknown ASI write: %d, %08x = %08x & %08x\n", asi, offset << 2, data, mem_mask);
- return;
+ page_flush_w(offset | (i << m_cache_tag_shift), data, mem_mask);
+ }
+}
+
+void sun4_mmu_base_device::hw_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);
+ }
+}
+
+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);
}
}
@@ -365,7 +303,7 @@ void sun4_mmu_base_device::parity_w(uint32_t offset, uint32_t data, uint32_t mem
}
}
-void sun4_mmu_base_device::segment_flush_w(const uint32_t vaddr)
+void sun4_mmu_base_device::segment_flush_w(uint32_t vaddr, 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);
@@ -393,7 +331,7 @@ void sun4_mmu_base_device::segment_flush_w(const uint32_t vaddr)
}
}
-void sun4_mmu_base_device::context_flush_w(const uint32_t vaddr)
+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);
@@ -413,7 +351,7 @@ void sun4_mmu_base_device::context_flush_w(const uint32_t vaddr)
}
}
-void sun4_mmu_base_device::page_flush_w(const uint32_t vaddr)
+void sun4_mmu_base_device::page_flush_w(uint32_t vaddr, 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);
@@ -443,133 +381,115 @@ void sun4_mmu_base_device::page_flush_w(const uint32_t vaddr)
}
}
-uint32_t sun4_mmu_base_device::system_r(const uint32_t offset, const uint32_t mem_mask)
+uint32_t sun4_mmu_base_device::context_reg_r(uint32_t offset, uint32_t mem_mask)
{
- LOGMASKED(LOG_SYSTEM, "%s: system_r: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask);
- switch (offset >> 26)
+ if (mem_mask == 0x00ff0000)
{
- case 3: // context reg
- {
- 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;
- }
-
- case 4: // system enable reg
- 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;
-
- case 6: // bus error register
- {
- 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;
- }
+ 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;
+}
- case 8: // (d-)cache tags
- 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::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;
+}
- case 9: // (d-)cache data
- 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::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;
+}
- case 0xf: // UART bypass
- 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;
+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)];
+}
- case 0: // IDPROM - SPARCstation-1 does not have an ID prom and a timeout should occur.
- default:
- LOGMASKED(LOG_UNKNOWN_SYSTEM, "read unhandled ASI 2 space %08x & %08x\n", offset << 2, mem_mask);
- return 0;
- }
+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];
}
-void sun4_mmu_base_device::system_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
+uint32_t sun4_mmu_base_device::uart_r(uint32_t offset, uint32_t mem_mask)
{
- LOGMASKED(LOG_SYSTEM, "system_w: %08x = %08x & %08x\n", offset << 2, data, mem_mask);
- switch (offset >> 26)
+ switch (offset & 3)
{
- case 3: // context reg
- LOGMASKED(LOG_CONTEXT, "write context = %08x & %08x\n", data, mem_mask);
- 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][0];
- m_curr_segmap_masked = &m_segmap_masked[m_context_masked][0];
- return;
+ 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;
+}
- case 4: // system enable reg
- {
- LOGMASKED(LOG_SYSTEM_ENABLE, "write system enable = %08x & %08x\n", data, mem_mask);
- m_system_enable = data >> 24;
- m_fetch_bootrom = !(m_system_enable & ENA_NOTBOOT);
+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);
+ 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][0];
+ m_curr_segmap_masked = &m_segmap_masked[m_context_masked][0];
+}
- if (m_system_enable & ENA_RESET)
- {
- m_reset_timer->adjust(attotime::from_usec(1));
- m_cpu->set_input_line(SPARC_RESET, ASSERT_LINE);
- }
- if (m_system_enable & ENA_RESET)
- {
- m_system_enable = 0;
- m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
- m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
- }
- return;
- }
+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);
+ m_system_enable = data >> 24;
+ m_fetch_bootrom = !(m_system_enable & ENA_NOTBOOT);
- case 6: // bus error
- {
- const uint32_t masked_offset = offset & 0xf;
- LOGMASKED(LOG_BUSERROR, "write bus error %08x = %08x & %08x\n", offset << 2, data, mem_mask);
- if (masked_offset == 0)
- m_buserr[0] = (data & 0x000000ff) | 0x00008000;
- else
- m_buserr[masked_offset] = data;
- return;
- }
+ if (m_system_enable & ENA_RESET)
+ {
+ m_reset_timer->adjust(attotime::from_usec(1));
+ m_cpu->set_input_line(SPARC_RESET, ASSERT_LINE);
+ }
+ if (m_system_enable & ENA_RESET)
+ {
+ m_system_enable = 0;
+ m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
+ m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
+ }
+}
- case 8: // cache tags
- 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;
- /*if (m_cpu->pc() == 0xFFE8B4F8)
- {
- m_log_mem = true;
- }*/
- return;
+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);
+ if (masked_offset == 0)
+ m_buserr[0] = (data & 0x000000ff) | 0x00008000;
+ else
+ m_buserr[masked_offset] = data;
+}
- case 9: // cache data
- 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);
- return;
+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;
+}
- case 0xf: // UART bypass
- 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;
- }
- return;
+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);
+}
- case 0: // IDPROM
- default:
- LOGMASKED(LOG_UNKNOWN_SYSTEM, "write unhandled ASI 2 space %08x = %08x & %08x, PC=%08x\n", offset << 2, data, mem_mask, m_cpu->pc());
- return;
+void sun4_mmu_base_device::uart_w(uint32_t offset, uint32_t data, uint32_t 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;
}
}
-uint32_t sun4_mmu_base_device::segment_map_r(const uint32_t offset, const uint32_t mem_mask)
+uint32_t sun4_mmu_base_device::segment_map_r(uint32_t offset, uint32_t mem_mask)
{
uint32_t ret = 0;
if (mem_mask == 0xffff0000)
@@ -584,7 +504,7 @@ uint32_t sun4_mmu_base_device::segment_map_r(const uint32_t offset, const uint32
return ret;
}
-void sun4_mmu_base_device::segment_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
+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);
@@ -599,7 +519,7 @@ void sun4_mmu_base_device::segment_map_w(const uint32_t offset, const uint32_t d
m_curr_segmap_masked[seg] = (segdata & m_pmeg_mask) << 6;
}
-uint32_t sun4_mmu_base_device::page_map_r(const uint32_t offset, const uint32_t mem_mask)
+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);
@@ -607,7 +527,7 @@ uint32_t sun4_mmu_base_device::page_map_r(const uint32_t offset, const uint32_t
return ret;
}
-void sun4_mmu_base_device::page_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
+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);
@@ -615,7 +535,7 @@ void sun4_mmu_base_device::page_map_w(const uint32_t offset, const uint32_t data
m_page_valid[page] = m_pagemap[page].valid;
}
-void sun4_mmu_base_device::type0_timeout_r(const uint32_t offset)
+void sun4_mmu_base_device::type0_timeout_r(uint32_t offset)
{
LOGMASKED(LOG_TYPE0_TIMEOUT, "type 0 read timeout %08x, PC=%08x\n", offset << 2, m_cpu->pc());
m_buserr[0] = 0x20; // read timeout
@@ -623,7 +543,7 @@ void sun4_mmu_base_device::type0_timeout_r(const uint32_t offset)
m_host->set_mae();
}
-void sun4_mmu_base_device::type0_timeout_w(const uint32_t offset)
+void sun4_mmu_base_device::type0_timeout_w(uint32_t offset)
{
LOGMASKED(LOG_TYPE0_TIMEOUT, "type 0 write timeout %08x, PC=%08x\n", offset << 2, m_cpu->pc());
m_buserr[0] = 0x8020; // write timeout
@@ -703,10 +623,12 @@ void sun4_mmu_base_device::cache_fill(page_entry &entry, uint32_t vaddr, uint32_
}
}
-template bool sun4_mmu_base_device::cache_fetch<sun4_mmu_base_device::USER_MODE>(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_MODE>(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_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::perm_mode PERM_MODE>
+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);
@@ -725,7 +647,7 @@ bool sun4_mmu_base_device::cache_fetch(page_entry &entry, uint32_t vaddr, uint32
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 (PERM_MODE == USER_MODE)
+ 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)))
@@ -750,17 +672,13 @@ bool sun4_mmu_base_device::cache_fetch(page_entry &entry, uint32_t vaddr, uint32
}
}
-template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_INSN, sun4_mmu_base_device::USER_MODE>(const uint32_t, const uint32_t);
-template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::SUPER_INSN, sun4_mmu_base_device::USER_MODE>(const uint32_t, const uint32_t);
-template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_DATA, sun4_mmu_base_device::USER_MODE>(const uint32_t, const uint32_t);
-template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::SUPER_DATA, sun4_mmu_base_device::USER_MODE>(const uint32_t, const uint32_t);
-template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_INSN, sun4_mmu_base_device::SUPER_MODE>(const uint32_t, const uint32_t);
-template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::SUPER_INSN, sun4_mmu_base_device::SUPER_MODE>(const uint32_t, const uint32_t);
-template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_DATA, sun4_mmu_base_device::SUPER_MODE>(const uint32_t, const uint32_t);
-template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::SUPER_DATA, sun4_mmu_base_device::SUPER_MODE>(const uint32_t, const uint32_t);
-
-template <sun4_mmu_base_device::insn_data_mode MODE, sun4_mmu_base_device::perm_mode PERM_MODE>
-uint32_t sun4_mmu_base_device::insn_data_r(const uint32_t offset, const uint32_t mem_mask)
+template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_INSN>(const uint32_t, const uint32_t);
+template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::SUPER_INSN>(const uint32_t, const uint32_t);
+template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_DATA>(const uint32_t, const uint32_t);
+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)
{
// supervisor program fetches in boot state are special
if (MODE == SUPER_INSN && m_fetch_bootrom)
@@ -785,7 +703,7 @@ uint32_t sun4_mmu_base_device::insn_data_r(const uint32_t offset, const uint32_t
{
uint32_t tag_entry = vaddr_to_cache_line(offset);
uint32_t tag = m_cachetags[tag_entry];
- bool user_mode = (PERM_MODE == USER_MODE);
+ 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);
@@ -845,7 +763,7 @@ uint32_t sun4_mmu_base_device::insn_data_r(const uint32_t offset, const uint32_t
const uint32_t masked_addr = m_ram_set_base[set] + (paddr & addr_mask);
if (!entry.uncached && (m_system_enable & ENA_CACHE))
{
- if (cache_fetch<PERM_MODE>(entry, offset, masked_addr, cached_data, entry_index))
+ if (cache_fetch<MODE>(entry, offset, masked_addr, cached_data, entry_index))
{
#if SUN4CMMU_LOG_MEM_ACCESSES
uint32_t value = masked_addr | 0x80000000;
@@ -886,7 +804,7 @@ uint32_t sun4_mmu_base_device::insn_data_r(const uint32_t offset, const uint32_t
{
if (!machine().side_effects_disabled())
{
- if ((m_system_enable & ENA_CACHE) && cache_fetch<PERM_MODE>(entry, offset, 0, cached_data, entry_index))
+ if ((m_system_enable & ENA_CACHE) && cache_fetch<MODE>(entry, offset, 0, cached_data, entry_index))
{
return cached_data;
}
@@ -915,17 +833,13 @@ uint32_t sun4_mmu_base_device::insn_data_r(const uint32_t offset, const uint32_t
}
}
-template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_INSN, sun4_mmu_base_device::USER_MODE>(const uint32_t, const uint32_t, const uint32_t);
-template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::SUPER_INSN, sun4_mmu_base_device::USER_MODE>(const uint32_t, const uint32_t, const uint32_t);
-template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_DATA, sun4_mmu_base_device::USER_MODE>(const uint32_t, const uint32_t, const uint32_t);
-template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::SUPER_DATA, sun4_mmu_base_device::USER_MODE>(const uint32_t, const uint32_t, const uint32_t);
-template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_INSN, sun4_mmu_base_device::SUPER_MODE>(const uint32_t, const uint32_t, const uint32_t);
-template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::SUPER_INSN, sun4_mmu_base_device::SUPER_MODE>(const uint32_t, const uint32_t, const uint32_t);
-template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_DATA, sun4_mmu_base_device::SUPER_MODE>(const uint32_t, const uint32_t, const uint32_t);
-template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::SUPER_DATA, sun4_mmu_base_device::SUPER_MODE>(const uint32_t, const uint32_t, const uint32_t);
-
-template <sun4_mmu_base_device::insn_data_mode MODE, sun4_mmu_base_device::perm_mode PERM_MODE>
-void sun4_mmu_base_device::insn_data_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
+template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_INSN>(const uint32_t, const uint32_t, const uint32_t);
+template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::SUPER_INSN>(const uint32_t, const uint32_t, const uint32_t);
+template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_DATA>(const uint32_t, const uint32_t, const uint32_t);
+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)
{
// it's translation time
const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];// & m_pmeg_mask;
@@ -939,7 +853,7 @@ void sun4_mmu_base_device::insn_data_w(const uint32_t offset, const uint32_t dat
{
uint32_t tag_entry = vaddr_to_cache_line(offset);
uint32_t tag = m_cachetags[tag_entry];
- bool user_mode = PERM_MODE == USER_MODE;
+ 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);
diff --git a/src/devices/machine/sun4c_mmu.h b/src/devices/machine/sun4c_mmu.h
index 32623a36769..7ab00c8798a 100644
--- a/src/devices/machine/sun4c_mmu.h
+++ b/src/devices/machine/sun4c_mmu.h
@@ -52,22 +52,22 @@ public:
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
+ };
+
enum insn_data_mode
{
USER_INSN,
- SUPER_INSN,
USER_DATA,
+ SUPER_INSN,
SUPER_DATA
};
- enum perm_mode
- {
- USER_MODE,
- SUPER_MODE
- };
-
- template <insn_data_mode MODE, perm_mode PERM_MODE> uint32_t insn_data_r(const uint32_t offset, const uint32_t mem_mask);
- template <insn_data_mode MODE, perm_mode PERM_MODE> void insn_data_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask);
+ 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);
uint32_t type1_timeout_r(uint32_t offset);
void type1_timeout_w(uint32_t offset, uint32_t data);
@@ -75,11 +75,35 @@ public:
void parity_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
// sparc_mmu_device overrides
- uint32_t fetch_insn(const bool supervisor, const uint32_t offset) override;
- uint32_t read_asi(uint8_t asi, uint32_t offset, uint32_t mem_mask) override;
- void write_asi(uint8_t asi, uint32_t offset, uint32_t data, uint32_t mem_mask) override;
+ uint32_t fetch_insn(const bool supervisor, 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);
+ void context_reg_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ uint32_t system_enable_r(uint32_t offset, uint32_t mem_mask);
+ void system_enable_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ uint32_t bus_error_r(uint32_t offset, uint32_t mem_mask);
+ void bus_error_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ uint32_t cache_tag_r(uint32_t offset, uint32_t mem_mask);
+ void cache_tag_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ uint32_t cache_data_r(uint32_t offset, uint32_t mem_mask);
+ void cache_data_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ uint32_t uart_r(uint32_t offset, uint32_t mem_mask);
+ void uart_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ uint32_t segment_map_r(uint32_t offset, uint32_t mem_mask);
+ void segment_map_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ uint32_t page_map_r(uint32_t offset, uint32_t mem_mask);
+ void page_map_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+
+ void segment_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ void page_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ void context_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+
+ void hw_segment_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ void hw_page_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ void hw_context_flush_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+ void hw_flush_all_w(uint32_t offset, uint32_t data, uint32_t mem_mask);
+
protected:
sun4_mmu_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@@ -108,18 +132,9 @@ protected:
uint32_t page_entry_to_uint(uint32_t index);
void merge_page_entry(uint32_t index, uint32_t data, uint32_t mem_mask);
- template <perm_mode MODE> bool cache_fetch(page_entry &entry, uint32_t vaddr, uint32_t paddr, uint32_t &cached_data, uint32_t entry_index);
+ 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 segment_flush_w(const uint32_t vaddr);
- void context_flush_w(const uint32_t vaddr);
- void page_flush_w(const uint32_t vaddr);
- uint32_t system_r(const uint32_t offset, const uint32_t mem_mask);
- void system_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask);
- uint32_t segment_map_r(const uint32_t offset, const uint32_t mem_mask);
- void segment_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask);
- uint32_t page_map_r(const uint32_t offset, const uint32_t mem_mask);
- void page_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask);
void type0_timeout_r(const uint32_t offset);
void type0_timeout_w(const uint32_t offset);
bool translate(uint32_t &addr);
diff --git a/src/mame/drivers/sun4.cpp b/src/mame/drivers/sun4.cpp
index 1089cc9d8ec..45a53f5ead9 100644
--- a/src/mame/drivers/sun4.cpp
+++ b/src/mame/drivers/sun4.cpp
@@ -580,6 +580,20 @@ protected:
void ncr53c90a(device_t *device);
void debugger_map(address_map &map);
+ void system_asi_map(address_map &map);
+ void segment_asi_map(address_map &map);
+ void page_asi_map(address_map &map);
+ void hw_segment_flush_asi_map(address_map &map);
+ void hw_page_flush_asi_map(address_map &map);
+ void hw_context_flush_asi_map(address_map &map);
+ void user_insn_asi_map(address_map &map);
+ void super_insn_asi_map(address_map &map);
+ void user_data_asi_map(address_map &map);
+ void super_data_asi_map(address_map &map);
+ void sw_segment_flush_asi_map(address_map &map);
+ void sw_page_flush_asi_map(address_map &map);
+ void sw_context_flush_asi_map(address_map &map);
+ void hw_flush_all_asi_map(address_map &map);
void type1space_base_map(address_map &map);
@@ -673,12 +687,12 @@ private:
READ32_MEMBER( sun4_base_state::debugger_r )
{
- return m_mmu->insn_data_r<sun4_mmu_base_device::SUPER_INSN, sun4_mmu_base_device::SUPER_MODE>(offset, mem_mask);
+ return m_mmu->insn_data_r<sun4_mmu_base_device::SUPER_INSN>(offset, mem_mask);
}
WRITE32_MEMBER( sun4_base_state::debugger_w )
{
- m_mmu->insn_data_w<sun4_mmu_base_device::SUPER_INSN, sun4_mmu_base_device::SUPER_MODE>(offset, data, mem_mask);
+ m_mmu->insn_data_w<sun4_mmu_base_device::SUPER_INSN>(offset, data, mem_mask);
}
void sun4_base_state::fcodes_command(int ref, const std::vector<std::string> &params)
@@ -738,6 +752,81 @@ void sun4_state::type1space_map(address_map &map)
type1space_base_map(map);
}
+void sun4_base_state::system_asi_map(address_map &map)
+{
+ map(0x30000000, 0x3fffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::context_reg_r), FUNC(sun4_mmu_base_device::context_reg_w));
+ map(0x40000000, 0x4fffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::system_enable_r), FUNC(sun4_mmu_base_device::system_enable_w));
+ map(0x60000000, 0x6fffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::bus_error_r), FUNC(sun4_mmu_base_device::bus_error_w));
+ map(0x80000000, 0x8fffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::cache_tag_r), FUNC(sun4_mmu_base_device::cache_tag_w));
+ map(0x90000000, 0x9fffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::cache_data_r), FUNC(sun4_mmu_base_device::cache_data_w));
+ map(0xf0000000, 0xffffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::uart_r), FUNC(sun4_mmu_base_device::uart_w));
+}
+
+void sun4_base_state::segment_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::segment_map_r), FUNC(sun4_mmu_base_device::segment_map_w));
+}
+
+void sun4_base_state::page_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::page_map_r), FUNC(sun4_mmu_base_device::page_map_w));
+}
+
+void sun4_base_state::hw_segment_flush_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).w(m_mmu, FUNC(sun4_mmu_base_device::hw_segment_flush_w));
+}
+
+void sun4_base_state::hw_page_flush_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).w(m_mmu, FUNC(sun4_mmu_base_device::hw_page_flush_w));
+}
+
+void sun4_base_state::hw_context_flush_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).w(m_mmu, FUNC(sun4_mmu_base_device::hw_context_flush_w));
+}
+
+void sun4_base_state::user_insn_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_INSN>), FUNC(sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_INSN>));
+}
+
+void sun4_base_state::super_insn_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::SUPER_INSN>), FUNC(sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::SUPER_INSN>));
+}
+
+void sun4_base_state::user_data_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_DATA>), FUNC(sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_DATA>));
+}
+
+void sun4_base_state::super_data_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).rw(m_mmu, FUNC(sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::SUPER_DATA>), FUNC(sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::SUPER_DATA>));
+}
+
+void sun4_base_state::sw_segment_flush_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).w(m_mmu, FUNC(sun4_mmu_base_device::segment_flush_w));
+}
+
+void sun4_base_state::sw_page_flush_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).w(m_mmu, FUNC(sun4_mmu_base_device::page_flush_w));
+}
+
+void sun4_base_state::sw_context_flush_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).w(m_mmu, FUNC(sun4_mmu_base_device::context_flush_w));
+}
+
+void sun4_base_state::hw_flush_all_asi_map(address_map &map)
+{
+ map(0x00000000, 0xffffffff).w(m_mmu, FUNC(sun4_mmu_base_device::hw_flush_all_w));
+}
+
/* Input ports */
static INPUT_PORTS_START( sun4 )
INPUT_PORTS_END
@@ -1078,7 +1167,7 @@ void sun4_base_state::dma_transfer_write()
pack_cnt++;
if (pack_cnt == 4)
{
- m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA, sun4_mmu_base_device::SUPER_MODE>(m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0);
+ m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0);
pack_cnt = 0;
m_dma_pack_register = 0;
m_dma[DMA_ADDR] += 4;
@@ -1099,7 +1188,7 @@ void sun4_base_state::dma_transfer_read()
{
if (!word_cached)
{
- current_word = m_mmu->insn_data_r<sun4c_mmu_device::SUPER_DATA, sun4_mmu_base_device::SUPER_MODE>(m_dma[DMA_ADDR] >> 2, ~0);
+ current_word = m_mmu->insn_data_r<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, ~0);
word_cached = true;
//logerror("Current word: %08x\n", current_word);
}
@@ -1176,7 +1265,7 @@ WRITE32_MEMBER( sun4_base_state::dma_w )
const uint32_t bit_index = (3 - i) * 8;
//const uint32_t value = m_dma_pack_register & (0xff << bit_index);
//logerror("dma_w: draining %02x to RAM address %08x & %08x\n", value >> bit_index, m_dma[DMA_ADDR], 0xff << (24 - bit_index));
- m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA, sun4_mmu_base_device::SUPER_MODE>(m_dma[DMA_ADDR] >> 2, m_dma_pack_register, 0xff << bit_index);
+ m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, m_dma_pack_register, 0xff << bit_index);
m_dma[DMA_ADDR]++;
}
m_dma_pack_register = 0;
@@ -1301,16 +1390,16 @@ void sun4_base_state::sun4_base(machine_config &config)
AM79C90(config, m_lance);
m_lance->dma_in().set([this](offs_t offset)
{
- u32 const data = m_mmu->insn_data_r<sun4c_mmu_device::SUPER_DATA, sun4_mmu_base_device::SUPER_MODE>((0xff000000U | offset) >> 2, 0xffffffffU);
+ u32 const data = m_mmu->insn_data_r<sun4c_mmu_device::SUPER_DATA>((0xff000000U | offset) >> 2, 0xffffffffU);
return (offset & 2) ? u16(data) : u16(data >> 16);
});
m_lance->dma_out().set([this](offs_t offset, u16 data, u16 mem_mask)
{
if (offset & 2)
- m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA, sun4_mmu_base_device::SUPER_MODE>((0xff000000U | offset) >> 2, data, mem_mask);
+ m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>((0xff000000U | offset) >> 2, data, mem_mask);
else
- m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA, sun4_mmu_base_device::SUPER_MODE>((0xff000000U | offset) >> 2, u32(data) << 16, u32(mem_mask) << 16);
+ m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>((0xff000000U | offset) >> 2, u32(data) << 16, u32(mem_mask) << 16);
});
// Keyboard/mouse
@@ -1376,7 +1465,21 @@ void sun4c_state::sun4c(machine_config &config)
/* basic machine hardware */
SPARCV7(config, m_maincpu, 20'000'000);
m_maincpu->add_asi_desc([](sparc_disassembler *dasm) { dasm->add_asi_desc(sun4c_asi_desc); });
- m_maincpu->set_addrmap(0, &sun4c_state::debugger_map);
+ m_maincpu->set_addrmap(0x00, &sun4c_state::debugger_map);
+ m_maincpu->set_addrmap(0x12, &sun4c_state::system_asi_map);
+ m_maincpu->set_addrmap(0x13, &sun4c_state::segment_asi_map);
+ m_maincpu->set_addrmap(0x14, &sun4c_state::page_asi_map);
+ m_maincpu->set_addrmap(0x15, &sun4c_state::hw_segment_flush_asi_map);
+ m_maincpu->set_addrmap(0x16, &sun4c_state::hw_page_flush_asi_map);
+ m_maincpu->set_addrmap(0x17, &sun4c_state::hw_context_flush_asi_map);
+ m_maincpu->set_addrmap(0x18, &sun4c_state::user_insn_asi_map);
+ m_maincpu->set_addrmap(0x19, &sun4c_state::super_insn_asi_map);
+ m_maincpu->set_addrmap(0x1a, &sun4c_state::user_data_asi_map);
+ m_maincpu->set_addrmap(0x1b, &sun4c_state::super_data_asi_map);
+ m_maincpu->set_addrmap(0x1c, &sun4c_state::sw_segment_flush_asi_map);
+ m_maincpu->set_addrmap(0x1d, &sun4c_state::sw_page_flush_asi_map);
+ m_maincpu->set_addrmap(0x1e, &sun4c_state::sw_context_flush_asi_map);
+ m_maincpu->set_addrmap(0x1f, &sun4c_state::hw_flush_all_asi_map);
sun4_base(config);