OSDN Git Service

[VM][NEWDEV][I386] .
authorK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 24 Apr 2019 10:03:33 +0000 (19:03 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 24 Apr 2019 10:03:33 +0000 (19:03 +0900)
source/src/vm/libcpu_newdev/i386/cpuidmsrs.hxx
source/src/vm/libcpu_newdev/i386/i386_device.cpp
source/src/vm/libcpu_newdev/i386/i386_device.h
source/src/vm/libcpu_newdev/i386/i386ops.hxx

index 842ff85..7db7325 100644 (file)
@@ -178,7 +178,7 @@ void pentium4_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
                break;
        }
 }
-
+#if 0
 void athlonxp_device::opcode_cpuid()
 {
        switch (REG32(EAX))
@@ -449,3 +449,4 @@ void athlonxp_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
        }
        valid_msr = true;
 }
+#endif
index f017204..d70605f 100644 (file)
@@ -72,6 +72,8 @@ i386_device::i386_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
 
        m_ferr_err_value = 0;
        data_width = 32;
+
+       cache_data.clear();
        set_device_name(_T("i386 DX CPU"));
 
        
@@ -165,14 +167,6 @@ pentium4_device::pentium4_device(VM_TEMPLATE* parent_vm, EMU* parent_emu)
        set_device_name(_T("Intel Pentium4"));
 }
 
-device_memory_interface::space_config_vector i386_device::memory_space_config() const
-{
-       return space_config_vector {
-               std::make_pair(AS_PROGRAM, &m_program_config),
-               std::make_pair(AS_IO,      &m_io_config)
-       };
-}
-
 int i386_parity_table[256];
 MODRM_TABLE i386_MODRM_table[256];
 
@@ -3334,10 +3328,10 @@ uint8_t i386_device::read8_debug(uint32_t ea, uint8_t *data)
                return 0;
 
        address &= m_a20_mask;
-       *data = m_program->read_byte(address);
+       *data = this->read_debug_data8(address);
        return 1;
 }
-
+#if 0
 uint32_t i386_device::i386_get_debug_desc(I386_SREG *seg)
 {
        uint32_t base, limit, address;
@@ -3478,7 +3472,7 @@ void i386_device::device_debug_setup()
        debug()->symtable().add("segofftovirt", 2, 2, std::bind(&i386_device::debug_segofftovirt, this, _1, _2, _3));
        debug()->symtable().add("virttophys", 1, 1, std::bind(&i386_device::debug_virttophys, this, _1, _2, _3));
 }
-
+#endif
 /*************************************************************************/
 
 void i386_device::i386_postload()
@@ -3520,14 +3514,14 @@ void i386_device::i386_common_init()
                i386_MODRM_table[i].rm.d = regs32[i & 0x7];
        }
 
-       m_program = &space(AS_PROGRAM);
-       if(data_width == 16) {
-               // for the 386sx
-               macache16 = m_program->cache<1, 0, ENDIANNESS_LITTLE>();
-       } else {
-               macache32 = m_program->cache<2, 0, ENDIANNESS_LITTLE>();
-       }
-
+//     m_program = &space(AS_PROGRAM);
+//     if(data_width == 16) {
+//             // for the 386sx
+//             macache16 = m_program->cache<1, 0, ENDIANNESS_LITTLE>();
+//     } else {
+//             macache32 = m_program->cache<2, 0, ENDIANNESS_LITTLE>();
+//     }
+       cache_mem.clear();
        m_io = &space(AS_IO);
        m_smi = false;
        m_debugger_temp = 0;
@@ -3823,6 +3817,7 @@ bool athlonxp_device::process_state(FILEIO* state_fio, bool loading)
        return process_state_i386_x87_xmm(state_fio, loading);
 }
 #endif
+#if 0
 void i386_device::state_import(int index)
 {
        switch (index)
@@ -3864,6 +3859,7 @@ void i386_device::state_export(int index)
                        break;
        }
 }
+#endif
 
 void i386_device::build_opcode_table(uint32_t features)
 {
@@ -4174,46 +4170,11 @@ void i386_device::pentium_smi()
        CHANGE_PC(m_eip);
 }
 
-void i386_device::execute_set_input(int irqline, int state)
-{
-       if ( irqline == INPUT_LINE_A20 )
-       {
-               i386_set_a20_line( state );
-               return;
-       }
-       if ( irqline == INPUT_LINE_NMI )
-       {
-               if ( state != CLEAR_LINE && m_halted)
-               {
-                       m_halted = 0;
-               }
-
-               /* NMI (I do not think that this is 100% right) */
-               if(m_nmi_masked)
-               {
-                       m_nmi_latched = true;
-                       return;
-               }
-               if ( state )
-                       i386_trap(2, 1, 0);
-       }
-       else
-       {
-               if (irqline >= 0 && irqline <= MAX_INPUT_LINES)
-               {
-                       if ( state != CLEAR_LINE && m_halted )
-                       {
-                               m_halted = 0;
-                       }
 
-                       m_irq_state = state;
-               }
-       }
-}
-
-void pentium_device::execute_set_input(int irqline, int state)
+void pentium_device::write_signal(int id, uint32_t data, uint32_t mask)
 {
-       if ( irqline == INPUT_LINE_SMI )
+       bool state = ((data & mask) != 0);
+       if ( id == SIG_I386_SMI )
        {
                if ( !m_smi && state && m_smm )
                {
@@ -4223,7 +4184,7 @@ void pentium_device::execute_set_input(int irqline, int state)
        }
        else
        {
-               i386_device::execute_set_input(irqline, state);
+               i386_device::write_signal(id, data, mask);
        }
 }
 
@@ -4251,6 +4212,10 @@ void i386_device::write_signal(int id, uint32_t data, uint32_t mask)
                m_busreq = (data & mask) ? 1 : 0;
        } else if(id == SIG_I386_A20) {
                i386_set_a20_line(data & mask);
+       } else if(id == SIG_CPU_ADDRESS_DIRTY) {
+               // ToDo: clear cache.
+               uint32_t target_address = data;
+               uint32_t target_bytes = mask;
        }
 }
 
@@ -4478,30 +4443,35 @@ uint32_t i386_device::get_next_pc()
 void i386_device::write_debug_data8(uint32_t addr, uint32_t data)
 {
        int wait;
+       // ToDo: cache
        d_mem->write_data8w(addr, data, &wait);
 }
 
 void i386_device::write_debug_data16(uint32_t addr, uint32_t data)
 {
        int wait;
+       // ToDo: cache
        d_mem->write_data16w(addr, data, &wait);
 }
 
 void i386_device::write_debug_data32(uint32_t addr, uint32_t data)
 {
        int wait;
+       // ToDo: cache
        d_mem->write_data32w(addr, data, &wait);
 }
 
 uint32_t i386_device::read_debug_data8(uint32_t addr)
 {
        int wait;
+       // ToDo: cache
        return d_mem->read_data8w(addr, &wait);
 }
 
 uint32_t i386_device::read_debug_data16(uint32_t addr)
 {
        int wait;
+       // ToDo: cache
        return d_mem->read_data16w(addr, &wait);
 }
 
@@ -4548,11 +4518,12 @@ int i386_device::get_mode() const
 {
        return m_sreg[CS].d ? 32 : 16;
 }
-
+#if 0
 std::unique_ptr<util::disasm_interface> i386_device::create_disassembler()
 {
        return std::make_unique<i386_disassembler>(this);
 }
+#endif
 
 void i386_device::opcode_cpuid()
 {
index badd42b..078bea7 100644 (file)
 #include "./i386dasm.h"
 #include "./cache.h"
 
-#define INPUT_LINE_A20      1
-#define INPUT_LINE_SMI      2
+#define SIG_I386_A20   1
+#define SIG_I386_SMI   2
+enum
+{
+       INPUT_LINE_IRQ = 0,
+       INPUT_LINE_NMI
+};
 
 typedef u8 uint8_t;
 typedef u16 uint16_t;
@@ -60,6 +65,8 @@ protected:
        
        DEBUGGER* d_debugger;
        DEVICE* d_program_stored, d_io_stored;
+
+       int m_wait;
 public:
        // construction/destruction
        i386_device(VM_TEMPLATE* parent_vm, EMU* parent_emu);
@@ -67,6 +74,26 @@ public:
        virtual bool process_state(FILEIO* state_fio, bool loading);
        virtual void initialize() override;
        virtual void reset() override;
+       virtual int run(int clocks);
+       
+       virtual void write_signal(int ch, uint32_t data, uint32_t mask);
+       virtual void set_intr_line(bool line, bool pending, uint32_t bit);
+       virtual void set_extra_clock(int cycles);
+       virtual int get_extra_clock();
+       uint32_t get_pc();
+       uint32_t get_next_pc();
+       void write_debug_data8(uint32_t addr, uint32_t data);
+       void write_debug_data16(uint32_t addr, uint32_t data);
+       void write_debug_data32(uint32_t addr, uint32_t data);
+       uint32_t read_debug_data8(uint32_t addr);
+       uint32_t read_debug_data16(uint32_t addr);
+       uint32_t read_debug_data32(uint32_t addr);
+       void write_debug_io8(uint32_t addr, uint32_t data);
+       uint32_t read_debug_io8(uint32_t addr);
+       void write_debug_io16(uint32_t addr, uint32_t data);
+       uint32_t read_debug_io16(uint32_t addr);
+       void write_debug_io32(uint32_t addr, uint32_t data);
+       
        void set_address_mask(uint32_t mask)
        {
                m_a20_mask = mask;
@@ -113,14 +140,48 @@ public:
        {
                register_output_signal(&outputs_reset, dev, id, mask);
        }
-       
+       void set_cachable_region(uint32_t start, uint32_t end, DEVICE* dev = NULL, int type = CACHE_LINE_READ_WRITE)
+       {
+               cache_line *p;
+               if(dev == NULL) {
+                       p = new cache_line(start, end, d_device, type);
+               } else {
+                       p = new cache_line(start, end, dev, type);
+               }
+               if(p != NULL) {
+                       cache_mem.push_back(p);
+               }
+       }
+       void delete_cachable_region(uint32_t start, uint32_t end)
+       {
+               for(auto pp = cache_mem.begin(); pp != cache_mem.end(); ++pp) {
+                       cache_line* p = *pp;
+                       if(p != NULL) {
+                               if((p->get_start_address() == start) && (p->get_end_address() == end)) {
+                                       delete p;
+                                       pcache_mem.erace(pp);
+                               }
+                       }
+               }
+       }
+       void change_cache_type(uint32_t start, uint32_t end, int new_mode)
+       {
+               for(auto pp = cache_mem.begin(); pp != cache_mem.end(); ++pp) {
+                       cache_line* p = *pp;
+                       if(p != NULL) {
+                               if((p->get_start_address() == start) && (p->get_end_address() == end)) {
+                                       p->change_access_mode(new_mode);
+                               }
+                       }
+               }
+       }
        // configuration helpers
-
+#if 0
        uint64_t debug_segbase(symbol_table &table, int params, const uint64_t *param);
        uint64_t debug_seglimit(symbol_table &table, int params, const uint64_t *param);
        uint64_t debug_segofftovirt(symbol_table &table, int params, const uint64_t *param);
        uint64_t debug_virttophys(symbol_table &table, int params, const uint64_t *param);
-
+#endif
 protected:
        device_vtlb_interface* d_vtlb;
        bool process_state_segment(int num, FILEIO* state_fio, bool loading);
@@ -133,27 +194,23 @@ protected:
        bool bios_trap_x86(uint32_t address, int &stat);
 
        // device-level overrides
-       virtual void device_debug_setup() override;
+       //virtual void device_debug_setup() override;
 
        // device_execute_interface overrides
        virtual uint32_t execute_min_cycles() const override { return 1; }
        virtual uint32_t execute_max_cycles() const override { return 40; }
        virtual uint32_t execute_input_lines() const override { return 32; }
-       virtual bool execute_input_edge_triggered(int inputnum) const override { return inputnum == INPUT_LINE_NMI; }
-       virtual void execute_run() override;
-       virtual void execute_set_input(int inputnum, int state) override;
 
        // device_memory_interface overrides
-       virtual space_config_vector memory_space_config() const override;
        virtual bool memory_translate(int spacenum, int intention, offs_t &address) override;
 
        // device_state_interface overrides
-       virtual void state_import(const device_state_entry &entry) override;
-       virtual void state_export(const device_state_entry &entry) override;
-       virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
+       //virtual void state_import(const device_state_entry &entry) override;
+       //virtual void state_export(const device_state_entry &entry) override;
+       //virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
 
        // device_disasm_interface overrides
-       virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+       //virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
        virtual int get_mode() const override;
 
        // routines for opcodes whose operation can vary between cpu models
@@ -167,30 +224,63 @@ protected:
        // routine to access memory
        // ToDo: Memory cache
 #if 1
-       virtual u8 mem_pr8(offs_t address) { return m_program->read_data8(address); }
-       virtual u16 mem_pr16(offs_t address) { return m_program->read_data16(address); }
-       virtual u32 mem_pr32(offs_t address) { return m_program->read_data32(address); }
-
-       virtual u8 mem_prd8(offs_t address) { return m_program->read_data8(address); }
-       virtual u16 mem_prd16(offs_t address) { return m_program->read_data16(address); }
-       virtual u32 mem_prd32(offs_t address) { return m_program->read_data32(address); }
-       virtual void mem_pwd8(offs_t address, u8 data) { m_program->write_data8(address, data); }
-       virtual void mem_pwd16(offs_t address, u16 data) { m_program->write_data16(address, data); }
-       virtual void mem_pwd32(offs_t address, u32 data) { m_program->write_data32(address, data); }
+       virtual u8 mem_pr8(offs_t address) { return d_mem->read_data8(address); }
+       virtual u16 mem_pr16(offs_t address) { return d_mem->read_data16(address); }
+       virtual u32 mem_pr32(offs_t address) { return d_mem->read_data32(address); }
+
+       virtual u8 mem_prd8(offs_t address) { return d_mem->read_data8(address); }
+       virtual u16 mem_prd16(offs_t address) { return d_mem->read_data16(address); }
+       virtual u32 mem_prd32(offs_t address) { return d_mem->read_data32(address); }
+       virtual void mem_pwd8(offs_t address, u8 data) { d_mem->write_data8(address, data); }
+       virtual void mem_pwd16(offs_t address, u16 data) { d_mem->write_data16(address, data); }
+       virtual void mem_pwd32(offs_t address, u32 data) { d_mem->write_data32(address, data); }
 #else
-       virtual u8 mem_pr8(offs_t address) { return macache32->read_data8(address); }
-       virtual u16 mem_pr16(offs_t address) { return macache32->read_data16(address); }
-       virtual u32 mem_pr32(offs_t address) { return macache32->read_data32(address); }
-
-       virtual u8 mem_prd8(offs_t address) { return m_program->read_data8(address); }
-       virtual u16 mem_prd16(offs_t address) { return m_program->read_data16(address); }
-       virtual u32 mem_prd32(offs_t address) { return m_program->read_data32(address); }
-       virtual void mem_pwd8(offs_t address, u8 data) { m_program->write_data8(address, data); }
-       virtual void mem_pwd16(offs_t address, u16 data) { m_program->write_data16(address, data); }
-       virtual void mem_pwd32(offs_t address, u32 data) { m_program->write_data32(address, data); }
+       virtual u8 mem_pr8(offs_t address) {
+               int n = cache_mem.size();
+               for(int i = 0; i < n; i++) {
+                       cache_line* p = cache_mem[i];
+                       if(p != NULL) {
+                               if(p->region_check(address)) {
+                                       return p->read_data8w(addr, &m_wait);
+                               }
+                       }
+               }
+               return d_device->read_data8w(address, &m_wait);
+       }
+       virtual u16 mem_pr16(offs_t address) {
+               int n = cache_mem.size();
+               for(int i = 0; i < n; i++) {
+                       cache_line* p = cache_mem[i];
+                       if(p != NULL) {
+                               if(p->region_check_range(address, 2)) {
+                                       return p->read_data16w(addr, &m_wait);
+                               }
+                       }
+               }
+               return d_device->read_data16w(address, &m_wait);
+       }
+       virtual u32 mem_pr32(offs_t address) {
+               int n = cache_mem.size();
+               for(int i = 0; i < n; i++) {
+                       cache_line* p = cache_mem[i];
+                       if(p != NULL) {
+                               if(p->region_check_range(address, 4)) {
+                                       return p->read_data32w(addr, &m_wait);
+                               }
+                       }
+               }
+               return d_device->read_data32w(address, &m_wait);
+       }
+
+       virtual u8 mem_prd8(offs_t address) { return d_mem->read_data8(address); }
+       virtual u16 mem_prd16(offs_t address) { return d_mem->read_data16(address); }
+       virtual u32 mem_prd32(offs_t address) { return d_mem->read_data32(address); }
+       virtual void mem_pwd8(offs_t address, u8 data) { d_mem->write_data8(address, data); }
+       virtual void mem_pwd16(offs_t address, u16 data) { d_mem->write_data16(address, data); }
+       virtual void mem_pwd32(offs_t address, u32 data) { d_mem->write_data32(address, data); }
 #endif 
-       address_space_config m_program_config;
-       address_space_config m_io_config;
+       //address_space_config m_mem_config;
+       //address_space_config m_io_config;
 
        std::unique_ptr<uint8_t[]> cycle_table_rm[X86_NUM_CPUS];
        std::unique_ptr<uint8_t[]> cycle_table_pm[X86_NUM_CPUS];
@@ -397,13 +487,12 @@ protected:
        uint8_t m_opcode;
 
        uint8_t m_irq_state;
-       DEVICE *m_program;
-       DEVICE *m_io;
        uint32_t m_a20_mask;
        bool m_shutdown;
        // ToDo: Memory Cache.
        //memory_access_cache<1, 0, ENDIANNESS_LITTLE> *macache16;
        //memory_access_cache<2, 0, ENDIANNESS_LITTLE> *macache32;
+       std::vector<cache_line *>cache_data; 
 
        int m_cpuid_max_input_value_eax; // Highest CPUID standard function available
        uint32_t m_cpuid_id0, m_cpuid_id1, m_cpuid_id2;
@@ -585,7 +674,7 @@ protected:
        void i386_decode_four_byte3af2();
        void i386_decode_four_byte38f3();
        uint8_t read8_debug(uint32_t ea, uint8_t *data);
-       uint32_t i386_get_debug_desc(I386_SREG *seg);
+       //uint32_t i386_get_debug_desc(I386_SREG *seg);
        inline void CYCLES(int x);
        inline void CYCLES_RM(int modrm, int r, int m);
        uint8_t i386_shift_rotate8(uint8_t modrm, uint32_t value, uint8_t shift);
@@ -1623,9 +1712,9 @@ protected:
        virtual u16 mem_pr16(offs_t address) override { return macache16->read_data16(address); };
        virtual u32 mem_pr32(offs_t address) override { return macache16->read_data32(address); };
 #else
-       virtual u8 mem_pr8(offs_t address) override { return m_program->read_data8(address); };
-       virtual u16 mem_pr16(offs_t address) override { return m_program->read_data16(address); };
-       virtual u32 mem_pr32(offs_t address) override { return m_program->read_data32(address); };
+       virtual u8 mem_pr8(offs_t address) override { return d_mem->read_data8(address); };
+       virtual u16 mem_pr16(offs_t address) override { return d_mem->read_data16(address); };
+       virtual u32 mem_pr32(offs_t address) override { return d_mem->read_data32(address); };
 #endif 
 };
 
@@ -1661,8 +1750,8 @@ public:
 
 protected:
 
-       virtual bool execute_input_edge_triggered(int inputnum) const override { return inputnum == INPUT_LINE_NMI || inputnum == INPUT_LINE_SMI; }
-       virtual void execute_set_input(int inputnum, int state) override;
+       virtual bool execute_input_edge_triggered(int inputnum) const override { return inputnum == SIG_CPU_NMI || inputnum == SIG_CPU_SMI; }
+       virtual void write_signal(int ch, uint32_t data, uint32_t mask) override;
        virtual uint64_t opcode_rdmsr(bool &valid_msr) override;
        virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override;
 };
index 58bef3c..9932057 100644 (file)
@@ -2542,6 +2542,8 @@ void i386_device::i386_loadall()       // Opcode 0x0f 0x07 (0x0f 0x05 on 80286),
        m_idtr.limit = READ32(ea + 0x68);
        m_gdtr.base = READ32(ea + 0x70);
        m_gdtr.limit = READ32(ea + 0x74);
+       logerror("LOADALL PC=%08X GDTR:BASE=%08X GDTR:LIMIT=%04X\n", cpustate->prev_pc, cpustate->gdtr.base, cpustate->gdtr.limit);
+
        m_ldtr.flags = READ32(ea + 0x78) >> 8;
        m_ldtr.base = READ32(ea + 0x7c);
        m_ldtr.limit = READ32(ea + 0x80);