summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/i386/i386.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/i386/i386.h')
-rw-r--r--src/devices/cpu/i386/i386.h52
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
};