diff options
Diffstat (limited to 'src/devices/machine/sun4c_mmu.h')
-rw-r--r-- | src/devices/machine/sun4c_mmu.h | 123 |
1 files changed, 90 insertions, 33 deletions
diff --git a/src/devices/machine/sun4c_mmu.h b/src/devices/machine/sun4c_mmu.h index b97ec362181..423d866ec80 100644 --- a/src/devices/machine/sun4c_mmu.h +++ b/src/devices/machine/sun4c_mmu.h @@ -2,7 +2,7 @@ // copyright-holders:Ryan Holtz /*************************************************************************** - sun4c_mmu.h - Sun 4c MMU emulation + sun4c_mmu.h - Sun 4/4c MMU emulation ***************************************************************************/ @@ -15,18 +15,24 @@ #include "machine/ram.h" #include "machine/z80scc.h" -class sun4c_mmu_device : public device_t, public sparc_mmu_interface +class sun4_mmu_base_device : public device_t, public sparc_mmu_interface { public: - sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint8_t ctx_mask, uint8_t pmeg_mask) - : sun4c_mmu_device(mconfig, tag, owner, clock) + sun4_mmu_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock + , uint8_t ctx_mask, uint8_t pmeg_mask, uint32_t page_mask, uint32_t seg_entry_shift, uint32_t seg_entry_mask + , uint32_t page_entry_mask, uint32_t cache_mask) + : sun4_mmu_base_device(mconfig, type, tag, owner, clock) { set_ctx_mask(ctx_mask); set_pmeg_mask(pmeg_mask); + set_page_mask(page_mask); + set_seg_entry_shift(seg_entry_shift); + set_seg_entry_mask(seg_entry_mask); + set_page_entry_mask(page_entry_mask); + set_cache_mask(cache_mask); + set_cache_line_size(16); } - sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <typename T> void set_cpu(T &&cpu_tag) { m_cpu.set_tag(std::forward<T>(cpu_tag)); } 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)); } @@ -37,6 +43,12 @@ public: void set_ctx_mask(uint8_t ctx_mask) { m_ctx_mask = ctx_mask; } void set_pmeg_mask(uint8_t pmeg_mask) { m_pmeg_mask = pmeg_mask; } + void set_page_mask(uint32_t page_mask) { m_page_mask = page_mask; } + void set_seg_entry_shift(uint32_t seg_entry_shift) { m_seg_entry_shift = seg_entry_shift; } + 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; } + void set_cache_line_size(uint32_t cache_line_size) { m_cache_line_size = cache_line_size; } enum insn_data_mode { @@ -49,29 +61,55 @@ public: 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); - // sparc_mmu_device overrides + 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_interface 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; 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: - static const device_timer_id TIMER_RESET = 0; - - virtual void device_start() override; - virtual void device_reset() override; - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - - uint32_t cache_flush_r(); - void cache_flush_w(); - 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); + sun4_mmu_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + + 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); + void type0_timeout_r(const uint32_t offset); void type0_timeout_w(const uint32_t offset); + void l2p_command(const std::vector<std::string_view> ¶ms); enum { @@ -92,7 +130,7 @@ protected: PM_MODIFIED = 0x01000000 // modified flag }; - struct page_entry_t + struct page_entry { uint32_t valid; uint32_t writable; @@ -103,9 +141,6 @@ protected: uint32_t page; uint8_t type; uint8_t pad[3]; - - uint32_t to_uint(); - void merge_uint(uint32_t data, uint32_t mem_mask); }; required_device<cpu_device> m_cpu; @@ -120,10 +155,10 @@ protected: devcb_write32 m_type1_w; // Actual SRAM - uint8_t m_segmap[16][4096]; - page_entry_t m_pagemap[16384]; - uint32_t m_cachetags[16384]; - uint32_t m_cachedata[16384]; + std::unique_ptr<std::unique_ptr<uint8_t[]>[]> m_segmap; + std::unique_ptr<page_entry[]> m_pagemap; + std::unique_ptr<uint32_t[]> m_cachetags; + std::unique_ptr<uint32_t[]> m_cachedata; uint32_t *m_rom_ptr; uint32_t *m_ram_ptr; @@ -135,23 +170,45 @@ protected: uint8_t m_system_enable; bool m_fetch_bootrom; uint32_t m_buserr[4]; + uint32_t m_type1_offset; + uint32_t m_parity_err_reg; + uint32_t m_memory_err_reg; + uint32_t m_parity_err; // Pre-computed data for optimization purposes - uint32_t m_segmap_masked[16][4096]; + std::unique_ptr<std::unique_ptr<uint32_t[]>[]> m_segmap_masked; uint8_t *m_curr_segmap; uint32_t *m_curr_segmap_masked; - bool m_page_valid[16384]; + std::unique_ptr<bool[]> m_page_valid; // Internal MAME device state uint8_t m_ctx_mask; // SS2 is sun4c but has 16 contexts; most have 8 uint8_t m_pmeg_mask; // SS2 is sun4c but has 16384 PTEs; most have 8192 + uint32_t m_page_mask; + uint32_t m_seg_entry_shift; + uint32_t m_seg_entry_mask; + uint32_t m_page_entry_mask; + uint32_t m_cache_mask; + uint32_t m_cache_line_size; 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; emu_timer *m_reset_timer; }; +class sun4_mmu_device : public sun4_mmu_base_device +{ +public: + sun4_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + +class sun4c_mmu_device : public sun4_mmu_base_device +{ +public: + sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; +DECLARE_DEVICE_TYPE(SUN4_MMU, sun4_mmu_device) DECLARE_DEVICE_TYPE(SUN4C_MMU, sun4c_mmu_device) #endif // MAME_MACHINE_SUN4C_MMU_H |