diff options
Diffstat (limited to 'src/devices/machine/sun4c_mmu.h')
-rw-r--r-- | src/devices/machine/sun4c_mmu.h | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/devices/machine/sun4c_mmu.h b/src/devices/machine/sun4c_mmu.h new file mode 100644 index 00000000000..0beafb73c29 --- /dev/null +++ b/src/devices/machine/sun4c_mmu.h @@ -0,0 +1,149 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/*************************************************************************** + + sun4c_mmu.h - Sun 4c MMU emulation + +***************************************************************************/ + +#ifndef MAME_MACHINE_SUN4C_MMU_H +#define MAME_MACHINE_SUN4C_MMU_H + +#pragma once + +#include "cpu/sparc/sparc_intf.h" +#include "machine/ram.h" +#include "machine/z80scc.h" + +class sun4c_mmu_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) + { + m_ctx_mask = ctx_mask; + m_pmeg_mask = pmeg_mask; + } + + 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)); } + template <typename T> void set_scc(T &&scc_tag) { m_scc.set_tag(std::forward<T>(scc_tag)); } + + enum insn_data_mode + { + USER_INSN, + SUPER_INSN, + USER_DATA, + SUPER_DATA + }; + + 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); + + auto type1_r() { return m_type1_r.bind(); } + auto type1_w() { return m_type1_w.bind(); } + + // sparc_mmu_device overrides + 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 { logerror("Setting host\n"); m_host = host; } + +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); + void type0_timeout_r(const uint32_t offset); + void type0_timeout_w(const uint32_t offset); + + enum + { + // system enable constants + ENA_NOTBOOT = 0x80, + ENA_SDVMA = 0x20, + ENA_CACHE = 0x10, + ENA_RESET = 0x04, + ENA_DIAG = 0x01, + + // page table entry constants + PM_VALID = 0x80000000, // page is valid + PM_WRITEMASK = 0x40000000, // writable? + PM_SYSMASK = 0x20000000, // system use only? + PM_CACHE = 0x10000000, // cachable? + PM_TYPEMASK = 0x0c000000, // type mask + PM_ACCESSED = 0x02000000, // accessed flag + PM_MODIFIED = 0x01000000 // modified flag + }; + + struct page_entry_t + { + 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]; + + uint32_t to_uint(); + void merge_uint(uint32_t data, uint32_t mem_mask); + }; + + required_device<cpu_device> m_cpu; + required_device<ram_device> m_ram; + required_memory_region m_rom; + required_device<z80scc_device> m_scc; + + sparc_mmu_host_interface *m_host; + + // Bus access callbacks + devcb_read32 m_type1_r; + 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]; + + uint32_t *m_rom_ptr; + uint32_t *m_ram_ptr; + uint32_t m_ram_size; + uint32_t m_ram_size_words; + uint32_t m_context; + uint32_t m_context_masked; + uint8_t m_system_enable; + bool m_fetch_bootrom; + uint32_t m_buserr[4]; + + // Pre-computed data for optimization purposes + uint32_t m_segmap_masked[16][4096]; + uint8_t *m_curr_segmap; + uint32_t *m_curr_segmap_masked; + bool m_page_valid[16384]; + + // 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 + emu_timer *m_reset_timer; +}; + + +DECLARE_DEVICE_TYPE(SUN4C_MMU, sun4c_mmu_device) + +#endif // MAME_MACHINE_SUN4C_MMU_H
\ No newline at end of file |