mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
i386.cpp: add virtual methods for cpuid and msr instructions (nw)
- add virtual methods opcode_cpuid opcode_rdmsr opcode_wrmsr - default implementations in class i386_device log an error message - derive Pentium MMX, Pentium II, Pentium III classes from pentium_pro_device - remove pentium_msr_* p6_msr_* piv_msr_* MSR_READ MSR_WRITE routines and call virtual methods instead - the routine pentium_rdmsr modifies the registers only if the msr is valid
This commit is contained in:
parent
99e50b3d41
commit
95c50fed36
@ -99,26 +99,31 @@ mediagx_device::mediagx_device(const machine_config &mconfig, const char *tag, d
|
||||
}
|
||||
|
||||
pentium_pro_device::pentium_pro_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: pentium_device(mconfig, PENTIUM_PRO, tag, owner, clock)
|
||||
: pentium_pro_device(mconfig, PENTIUM_PRO, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
pentium_pro_device::pentium_pro_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: pentium_device(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
pentium_mmx_device::pentium_mmx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: pentium_device(mconfig, PENTIUM_MMX, tag, owner, clock)
|
||||
: pentium_pro_device(mconfig, PENTIUM_MMX, tag, owner, clock)
|
||||
{
|
||||
// 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
|
||||
set_vtlb_dynamic_entries(96);
|
||||
}
|
||||
|
||||
pentium2_device::pentium2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: pentium_device(mconfig, PENTIUM2, tag, owner, clock)
|
||||
: pentium_pro_device(mconfig, PENTIUM2, tag, owner, clock)
|
||||
{
|
||||
// 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
|
||||
set_vtlb_dynamic_entries(96);
|
||||
}
|
||||
|
||||
pentium3_device::pentium3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: pentium_device(mconfig, PENTIUM3, tag, owner, clock)
|
||||
: pentium_pro_device(mconfig, PENTIUM3, tag, owner, clock)
|
||||
{
|
||||
// 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
|
||||
set_vtlb_dynamic_entries(96);
|
||||
@ -4039,6 +4044,24 @@ std::unique_ptr<util::disasm_interface> i386_device::create_disassembler()
|
||||
return std::make_unique<i386_disassembler>(this);
|
||||
}
|
||||
|
||||
void i386_device::opcode_cpuid()
|
||||
{
|
||||
logerror("CPUID called with unsupported EAX=%08x at %08x!\n", REG32(EAX), m_eip);
|
||||
}
|
||||
|
||||
uint64_t i386_device::opcode_rdmsr(bool &valid_msr)
|
||||
{
|
||||
valid_msr = false;
|
||||
logerror("RDMSR called with unsupported ECX=%08x at %08x!\n", REG32(ECX), m_eip);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void i386_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
|
||||
{
|
||||
valid_msr = false;
|
||||
logerror("WRMSR called with unsupported ECX=%08x (%08x%08x) at %08x!\n", REG32(ECX), (uint32_t)(data >> 32), (uint32_t)data, m_eip);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Intel 486 */
|
||||
|
||||
@ -4177,6 +4200,98 @@ void pentium_device::device_reset()
|
||||
CHANGE_PC(m_eip);
|
||||
}
|
||||
|
||||
uint64_t pentium_device::opcode_rdmsr(bool &valid_msr)
|
||||
{
|
||||
uint32_t offset = REG32(ECX);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
// Machine Check Exception (TODO)
|
||||
case 0x00:
|
||||
valid_msr = true;
|
||||
popmessage("RDMSR: Reading P5_MC_ADDR");
|
||||
return 0;
|
||||
case 0x01:
|
||||
valid_msr = true;
|
||||
popmessage("RDMSR: Reading P5_MC_TYPE");
|
||||
return 0;
|
||||
// Time Stamp Counter
|
||||
case 0x10:
|
||||
valid_msr = true;
|
||||
popmessage("RDMSR: Reading TSC");
|
||||
return m_tsc;
|
||||
// Event Counters (TODO)
|
||||
case 0x11: // CESR
|
||||
valid_msr = true;
|
||||
popmessage("RDMSR: Reading CESR");
|
||||
return 0;
|
||||
case 0x12: // CTR0
|
||||
valid_msr = true;
|
||||
return m_perfctr[0];
|
||||
case 0x13: // CTR1
|
||||
valid_msr = true;
|
||||
return m_perfctr[1];
|
||||
default:
|
||||
if (!(offset & ~0xf)) // 2-f are test registers
|
||||
{
|
||||
valid_msr = true;
|
||||
logerror("RDMSR: Reading test MSR %x", offset);
|
||||
return 0;
|
||||
}
|
||||
logerror("RDMSR: invalid P5 MSR read %08x at %08x\n", offset, m_pc - 2);
|
||||
valid_msr = false;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pentium_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
|
||||
{
|
||||
uint32_t offset = REG32(ECX);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
// Machine Check Exception (TODO)
|
||||
case 0x00:
|
||||
popmessage("WRMSR: Writing P5_MC_ADDR");
|
||||
valid_msr = true;
|
||||
break;
|
||||
case 0x01:
|
||||
popmessage("WRMSR: Writing P5_MC_TYPE");
|
||||
valid_msr = true;
|
||||
break;
|
||||
// Time Stamp Counter
|
||||
case 0x10:
|
||||
m_tsc = data;
|
||||
popmessage("WRMSR: Writing to TSC");
|
||||
valid_msr = true;
|
||||
break;
|
||||
// Event Counters (TODO)
|
||||
case 0x11: // CESR
|
||||
popmessage("WRMSR: Writing to CESR");
|
||||
valid_msr = true;
|
||||
break;
|
||||
case 0x12: // CTR0
|
||||
m_perfctr[0] = data;
|
||||
valid_msr = true;
|
||||
break;
|
||||
case 0x13: // CTR1
|
||||
m_perfctr[1] = data;
|
||||
valid_msr = true;
|
||||
break;
|
||||
default:
|
||||
if (!(offset & ~0xf)) // 2-f are test registers
|
||||
{
|
||||
valid_msr = true;
|
||||
logerror("WRMSR: Writing test MSR %x", offset);
|
||||
break;
|
||||
}
|
||||
logerror("WRMSR: invalid MSR write %08x (%08x%08x) at %08x\n", offset, (uint32_t)(data >> 32), (uint32_t)data, m_pc - 2);
|
||||
valid_msr = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Cyrix MediaGX */
|
||||
@ -4314,6 +4429,69 @@ void pentium_pro_device::device_reset()
|
||||
CHANGE_PC(m_eip);
|
||||
}
|
||||
|
||||
uint64_t pentium_pro_device::opcode_rdmsr(bool &valid_msr)
|
||||
{
|
||||
uint32_t offset = REG32(ECX);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
// Machine Check Exception (TODO)
|
||||
case 0x00:
|
||||
valid_msr = true;
|
||||
popmessage("RDMSR: Reading P5_MC_ADDR");
|
||||
return 0;
|
||||
case 0x01:
|
||||
valid_msr = true;
|
||||
popmessage("RDMSR: Reading P5_MC_TYPE");
|
||||
return 0;
|
||||
// Time Stamp Counter
|
||||
case 0x10:
|
||||
valid_msr = true;
|
||||
popmessage("RDMSR: Reading TSC");
|
||||
return m_tsc;
|
||||
// Performance Counters (TODO)
|
||||
case 0xc1: // PerfCtr0
|
||||
valid_msr = true;
|
||||
return m_perfctr[0];
|
||||
case 0xc2: // PerfCtr1
|
||||
valid_msr = true;
|
||||
return m_perfctr[1];
|
||||
default:
|
||||
logerror("RDMSR: unimplemented register called %08x at %08x\n", offset, m_pc - 2);
|
||||
valid_msr = true;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pentium_pro_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
|
||||
{
|
||||
uint32_t offset = REG32(ECX);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
// Time Stamp Counter
|
||||
case 0x10:
|
||||
m_tsc = data;
|
||||
popmessage("WRMSR: Writing to TSC");
|
||||
valid_msr = true;
|
||||
break;
|
||||
// Performance Counters (TODO)
|
||||
case 0xc1: // PerfCtr0
|
||||
m_perfctr[0] = data;
|
||||
valid_msr = true;
|
||||
break;
|
||||
case 0xc2: // PerfCtr1
|
||||
m_perfctr[1] = data;
|
||||
valid_msr = true;
|
||||
break;
|
||||
default:
|
||||
logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n", offset, (uint32_t)(data >> 32), (uint32_t)data, m_pc - 2);
|
||||
valid_msr = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Intel Pentium MMX */
|
||||
@ -4655,3 +4833,26 @@ void pentium4_device::device_reset()
|
||||
|
||||
CHANGE_PC(m_eip);
|
||||
}
|
||||
|
||||
uint64_t pentium4_device::opcode_rdmsr(bool &valid_msr)
|
||||
{
|
||||
switch (REG32(ECX))
|
||||
{
|
||||
default:
|
||||
logerror("RDMSR: unimplemented register called %08x at %08x\n", REG32(ECX), m_pc - 2);
|
||||
valid_msr = true;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pentium4_device::opcode_wrmsr(uint64_t data, bool &valid_msr)
|
||||
{
|
||||
switch (REG32(ECX))
|
||||
{
|
||||
default:
|
||||
logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n", REG32(ECX), (uint32_t)(data >> 32), (uint32_t)data, m_pc - 2);
|
||||
valid_msr = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,12 @@ protected:
|
||||
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
|
||||
// default implementations 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);
|
||||
|
||||
address_space_config m_program_config;
|
||||
address_space_config m_io_config;
|
||||
|
||||
@ -425,14 +431,6 @@ protected:
|
||||
inline void WRITEPORT16(offs_t port, uint16_t value);
|
||||
inline uint32_t READPORT32(offs_t port);
|
||||
inline void WRITEPORT32(offs_t port, uint32_t value);
|
||||
uint64_t pentium_msr_read(uint32_t offset,uint8_t *valid_msr);
|
||||
void pentium_msr_write(uint32_t offset, uint64_t data, uint8_t *valid_msr);
|
||||
uint64_t p6_msr_read(uint32_t offset,uint8_t *valid_msr);
|
||||
void p6_msr_write(uint32_t offset, uint64_t data, uint8_t *valid_msr);
|
||||
uint64_t piv_msr_read(uint32_t offset,uint8_t *valid_msr);
|
||||
void piv_msr_write(uint32_t offset, uint64_t data, uint8_t *valid_msr);
|
||||
inline uint64_t MSR_READ(uint32_t offset,uint8_t *valid_msr);
|
||||
inline void MSR_WRITE(uint32_t offset, uint64_t data, uint8_t *valid_msr);
|
||||
uint32_t i386_load_protected_mode_segment(I386_SREG *seg, uint64_t *desc );
|
||||
void i386_load_call_gate(I386_CALL_GATE *gate);
|
||||
void i386_set_descriptor_accessed(uint16_t selector);
|
||||
@ -1542,6 +1540,8 @@ 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 uint64_t opcode_rdmsr(bool &valid_msr) override;
|
||||
virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
};
|
||||
@ -1566,12 +1566,16 @@ public:
|
||||
pentium_pro_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
pentium_pro_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual uint64_t opcode_rdmsr(bool &valid_msr) override;
|
||||
virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
};
|
||||
|
||||
|
||||
class pentium_mmx_device : public pentium_device
|
||||
class pentium_mmx_device : public pentium_pro_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
@ -1583,7 +1587,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
class pentium2_device : public pentium_device
|
||||
class pentium2_device : public pentium_pro_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
@ -1595,7 +1599,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
class pentium3_device : public pentium_device
|
||||
class pentium3_device : public pentium_pro_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
@ -1626,6 +1630,8 @@ public:
|
||||
pentium4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
virtual uint64_t opcode_rdmsr(bool &valid_msr) override;
|
||||
virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
};
|
||||
|
@ -1200,227 +1200,4 @@ void i386_device::WRITEPORT32(offs_t port, uint32_t value)
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
MSR ACCESS
|
||||
***********************************************************************************/
|
||||
|
||||
// Pentium MSR handling
|
||||
uint64_t i386_device::pentium_msr_read(uint32_t offset,uint8_t *valid_msr)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
// Machine Check Exception (TODO)
|
||||
case 0x00:
|
||||
*valid_msr = 1;
|
||||
popmessage("RDMSR: Reading P5_MC_ADDR");
|
||||
return 0;
|
||||
case 0x01:
|
||||
*valid_msr = 1;
|
||||
popmessage("RDMSR: Reading P5_MC_TYPE");
|
||||
return 0;
|
||||
// Time Stamp Counter
|
||||
case 0x10:
|
||||
*valid_msr = 1;
|
||||
popmessage("RDMSR: Reading TSC");
|
||||
return m_tsc;
|
||||
// Event Counters (TODO)
|
||||
case 0x11: // CESR
|
||||
*valid_msr = 1;
|
||||
popmessage("RDMSR: Reading CESR");
|
||||
return 0;
|
||||
case 0x12: // CTR0
|
||||
*valid_msr = 1;
|
||||
return m_perfctr[0];
|
||||
case 0x13: // CTR1
|
||||
*valid_msr = 1;
|
||||
return m_perfctr[1];
|
||||
default:
|
||||
if(!(offset & ~0xf)) // 2-f are test registers
|
||||
{
|
||||
*valid_msr = 1;
|
||||
logerror("RDMSR: Reading test MSR %x", offset);
|
||||
return 0;
|
||||
}
|
||||
logerror("RDMSR: invalid P5 MSR read %08x at %08x\n",offset,m_pc-2);
|
||||
*valid_msr = 0;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void i386_device::pentium_msr_write(uint32_t offset, uint64_t data, uint8_t *valid_msr)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
// Machine Check Exception (TODO)
|
||||
case 0x00:
|
||||
popmessage("WRMSR: Writing P5_MC_ADDR");
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
case 0x01:
|
||||
popmessage("WRMSR: Writing P5_MC_TYPE");
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
// Time Stamp Counter
|
||||
case 0x10:
|
||||
m_tsc = data;
|
||||
popmessage("WRMSR: Writing to TSC");
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
// Event Counters (TODO)
|
||||
case 0x11: // CESR
|
||||
popmessage("WRMSR: Writing to CESR");
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
case 0x12: // CTR0
|
||||
m_perfctr[0] = data;
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
case 0x13: // CTR1
|
||||
m_perfctr[1] = data;
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
default:
|
||||
if(!(offset & ~0xf)) // 2-f are test registers
|
||||
{
|
||||
*valid_msr = 1;
|
||||
logerror("WRMSR: Writing test MSR %x", offset);
|
||||
break;
|
||||
}
|
||||
logerror("WRMSR: invalid MSR write %08x (%08x%08x) at %08x\n",offset,(uint32_t)(data >> 32),(uint32_t)data,m_pc-2);
|
||||
*valid_msr = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// P6 (Pentium Pro, Pentium II, Pentium III) MSR handling
|
||||
uint64_t i386_device::p6_msr_read(uint32_t offset,uint8_t *valid_msr)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
// Machine Check Exception (TODO)
|
||||
case 0x00:
|
||||
*valid_msr = 1;
|
||||
popmessage("RDMSR: Reading P5_MC_ADDR");
|
||||
return 0;
|
||||
case 0x01:
|
||||
*valid_msr = 1;
|
||||
popmessage("RDMSR: Reading P5_MC_TYPE");
|
||||
return 0;
|
||||
// Time Stamp Counter
|
||||
case 0x10:
|
||||
*valid_msr = 1;
|
||||
popmessage("RDMSR: Reading TSC");
|
||||
return m_tsc;
|
||||
// Performance Counters (TODO)
|
||||
case 0xc1: // PerfCtr0
|
||||
*valid_msr = 1;
|
||||
return m_perfctr[0];
|
||||
case 0xc2: // PerfCtr1
|
||||
*valid_msr = 1;
|
||||
return m_perfctr[1];
|
||||
default:
|
||||
logerror("RDMSR: unimplemented register called %08x at %08x\n",offset,m_pc-2);
|
||||
*valid_msr = 1;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void i386_device::p6_msr_write(uint32_t offset, uint64_t data, uint8_t *valid_msr)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
// Time Stamp Counter
|
||||
case 0x10:
|
||||
m_tsc = data;
|
||||
popmessage("WRMSR: Writing to TSC");
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
// Performance Counters (TODO)
|
||||
case 0xc1: // PerfCtr0
|
||||
m_perfctr[0] = data;
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
case 0xc2: // PerfCtr1
|
||||
m_perfctr[1] = data;
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
default:
|
||||
logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n",offset,(uint32_t)(data >> 32),(uint32_t)data,m_pc-2);
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// PIV (Pentium 4+)
|
||||
uint64_t i386_device::piv_msr_read(uint32_t offset,uint8_t *valid_msr)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
default:
|
||||
logerror("RDMSR: unimplemented register called %08x at %08x\n",offset,m_pc-2);
|
||||
*valid_msr = 1;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void i386_device::piv_msr_write(uint32_t offset, uint64_t data, uint8_t *valid_msr)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
default:
|
||||
logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n",offset,(uint32_t)(data >> 32),(uint32_t)data,m_pc-2);
|
||||
*valid_msr = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t i386_device::MSR_READ(uint32_t offset,uint8_t *valid_msr)
|
||||
{
|
||||
uint64_t res;
|
||||
uint8_t cpu_type = (m_cpu_version >> 8) & 0x0f;
|
||||
|
||||
*valid_msr = 0;
|
||||
|
||||
switch(cpu_type)
|
||||
{
|
||||
case 5: // Pentium
|
||||
res = pentium_msr_read(offset,valid_msr);
|
||||
break;
|
||||
case 6: // Pentium Pro, Pentium II, Pentium III
|
||||
res = p6_msr_read(offset,valid_msr);
|
||||
break;
|
||||
case 15: // Pentium 4+
|
||||
res = piv_msr_read(offset,valid_msr);
|
||||
break;
|
||||
default:
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void i386_device::MSR_WRITE(uint32_t offset, uint64_t data, uint8_t *valid_msr)
|
||||
{
|
||||
*valid_msr = 0;
|
||||
uint8_t cpu_type = (m_cpu_version >> 8) & 0x0f;
|
||||
|
||||
switch(cpu_type)
|
||||
{
|
||||
case 5: // Pentium
|
||||
pentium_msr_write(offset,data,valid_msr);
|
||||
break;
|
||||
case 6: // Pentium Pro, Pentium II, Pentium III
|
||||
p6_msr_write(offset,data,valid_msr);
|
||||
break;
|
||||
case 15: // Pentium 4+
|
||||
piv_msr_write(offset,data,valid_msr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __I386_H__ */
|
||||
|
@ -34,7 +34,8 @@ void i386_device::i486_cpuid() // Opcode 0x0F A2
|
||||
|
||||
default:
|
||||
{
|
||||
logerror("CPUID called with unsupported EAX=%08x at %08x!\n", REG32(EAX), m_eip);
|
||||
// call the model specific implementation
|
||||
opcode_cpuid();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -56,14 +56,17 @@ void i386_device::WRITEXMM_HI64(uint32_t ea,i386_device::XMM_REG &r)
|
||||
void i386_device::pentium_rdmsr() // Opcode 0x0f 32
|
||||
{
|
||||
uint64_t data;
|
||||
uint8_t valid_msr = 0;
|
||||
bool valid_msr = false;
|
||||
|
||||
data = MSR_READ(REG32(ECX),&valid_msr);
|
||||
REG32(EDX) = data >> 32;
|
||||
REG32(EAX) = data & 0xffffffff;
|
||||
|
||||
if(m_CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized ...
|
||||
FAULT(FAULT_GP,0) // ... throw a general exception fault
|
||||
// call the model specific implementation
|
||||
data = opcode_rdmsr(valid_msr);
|
||||
if (m_CPL != 0 || valid_msr == false) // if current privilege level isn't 0 or the register isn't recognized ...
|
||||
FAULT(FAULT_GP, 0) // ... throw a general exception fault
|
||||
else
|
||||
{
|
||||
REG32(EDX) = data >> 32;
|
||||
REG32(EAX) = data & 0xffffffff;
|
||||
}
|
||||
|
||||
CYCLES(CYCLES_RDMSR);
|
||||
}
|
||||
@ -71,12 +74,13 @@ void i386_device::pentium_rdmsr() // Opcode 0x0f 32
|
||||
void i386_device::pentium_wrmsr() // Opcode 0x0f 30
|
||||
{
|
||||
uint64_t data;
|
||||
uint8_t valid_msr = 0;
|
||||
bool valid_msr = false;
|
||||
|
||||
data = (uint64_t)REG32(EAX);
|
||||
data |= (uint64_t)(REG32(EDX)) << 32;
|
||||
|
||||
MSR_WRITE(REG32(ECX),data,&valid_msr);
|
||||
// call the model specific implementation
|
||||
opcode_wrmsr(data, valid_msr);
|
||||
|
||||
if(m_CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized
|
||||
FAULT(FAULT_GP,0) // ... throw a general exception fault
|
||||
|
Loading…
Reference in New Issue
Block a user