diff options
Diffstat (limited to 'src/devices/cpu/i386/i386.h')
-rw-r--r-- | src/devices/cpu/i386/i386.h | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/src/devices/cpu/i386/i386.h b/src/devices/cpu/i386/i386.h index e7a460488c0..90aab9f0667 100644 --- a/src/devices/cpu/i386/i386.h +++ b/src/devices/cpu/i386/i386.h @@ -16,6 +16,7 @@ #include "divtlb.h" #include "i386dasm.h" +#include "cache.h" #define INPUT_LINE_A20 1 #define INPUT_LINE_SMI 2 @@ -71,10 +72,24 @@ protected: virtual int get_mode() const override; // routines for opcodes whose operation can vary between cpu models - // default implementations just log an error message + // default implementations usually just log an error message virtual void opcode_cpuid(); virtual uint64_t opcode_rdmsr(bool &valid_msr); virtual void opcode_wrmsr(uint64_t data, bool &valid_msr); + virtual void opcode_invd() {} + virtual void opcode_wbinvd() {} + + // routine to access memory + virtual u8 mem_pr8(offs_t address) { return macache32->read_byte(address); } + virtual u16 mem_pr16(offs_t address) { return macache32->read_word(address); } + virtual u32 mem_pr32(offs_t address) { return macache32->read_dword(address); } + + virtual u8 mem_prd8(offs_t address) { return m_program->read_byte(address); } + virtual u16 mem_prd16(offs_t address) { return m_program->read_word(address); } + virtual u32 mem_prd32(offs_t address) { return m_program->read_dword(address); } + virtual void mem_pwd8(offs_t address, u8 data) { m_program->write_byte(address, data); } + virtual void mem_pwd16(offs_t address, u16 data) { m_program->write_word(address, data); } + virtual void mem_pwd32(offs_t address, u32 data) { m_program->write_dword(address, data); } address_space_config m_program_config; address_space_config m_io_config; @@ -280,11 +295,10 @@ protected: uint8_t m_irq_state; address_space *m_program; - std::function<u8 (offs_t)> m_pr8; - std::function<u16 (offs_t)> m_pr16; - std::function<u32 (offs_t)> m_pr32; address_space *m_io; uint32_t m_a20_mask; + memory_access_cache<1, 0, ENDIANNESS_LITTLE> *macache16; + memory_access_cache<2, 0, ENDIANNESS_LITTLE> *macache32; int m_cpuid_max_input_value_eax; // Highest CPUID standard function available uint32_t m_cpuid_id0, m_cpuid_id1, m_cpuid_id2; @@ -1495,8 +1509,12 @@ class i386sx_device : public i386_device public: // construction/destruction i386sx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); -}; +protected: + virtual u8 mem_pr8(offs_t address) override { return macache16->read_byte(address); }; + virtual u16 mem_pr16(offs_t address) override { return macache16->read_word(address); }; + virtual u32 mem_pr32(offs_t address) override { return macache16->read_dword(address); }; +}; class i486_device : public i386_device { @@ -1614,10 +1632,34 @@ protected: virtual void opcode_cpuid() override; virtual uint64_t opcode_rdmsr(bool &valid_msr) override; virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override; + virtual void opcode_invd() override; + virtual void opcode_wbinvd() override; virtual void device_start() override; virtual void device_reset() override; + virtual u8 mem_pr8(offs_t address) override { return opcode_read_cache<u8, NATIVE_ENDIAN_VALUE_LE_BE(0, 3)>(address); } + virtual u16 mem_pr16(offs_t address) override { return opcode_read_cache<u16, NATIVE_ENDIAN_VALUE_LE_BE(0, 2)>(address); } + virtual u32 mem_pr32(offs_t address) override { return opcode_read_cache<u32, 0>(address); } + virtual u8 mem_prd8(offs_t address) override { return program_read_cache<u8, NATIVE_ENDIAN_VALUE_LE_BE(0, 3)>(address); } + virtual u16 mem_prd16(offs_t address) override { return program_read_cache<u16, NATIVE_ENDIAN_VALUE_LE_BE(0, 2)>(address); } + virtual u32 mem_prd32(offs_t address) override { return program_read_cache<u32, 0>(address); } + virtual void mem_pwd8(offs_t address, u8 data) override { program_write_cache<u8, NATIVE_ENDIAN_VALUE_LE_BE(0, 3)>(address, data); } + virtual void mem_pwd16(offs_t address, u16 data) override { program_write_cache<u16, NATIVE_ENDIAN_VALUE_LE_BE(0, 2)>(address, data); } + virtual void mem_pwd32(offs_t address, u32 data) override { program_write_cache<u32, 0>(address, data); } + +private: + void parse_mtrrfix(u64 mtrr, offs_t base, int kblock); + int check_cacheable(offs_t address); + void invalidate_cache(bool writeback); + + template <class dt, offs_t xorle> dt opcode_read_cache(offs_t address); + template <class dt, offs_t xorle> dt program_read_cache(offs_t address); + template <class dt, offs_t xorle> void program_write_cache(offs_t address, dt data); + uint8_t m_processor_name_string[48]; + uint64_t m_msr_mtrrfix[11]; + uint8_t m_memory_ranges_1m[1024 / 4]; + cpucache<17, 9, Cache2Way, CacheLineBytes64> cache; // 512 sets, 2 ways (cachelines per set), 64 bytes per cacheline }; |