From 8ce5aa566f3f8faac454ee875c6495bf475cb6bd Mon Sep 17 00:00:00 2001 From: arbee Date: Sat, 25 Mar 2017 17:08:21 -0400 Subject: MIPS: initial support for VR5500 and TX4925 CPUs. [R. Belmont] --- src/devices/cpu/mips/mips3.cpp | 74 +++++++++++++++++++++++++++++++++++++++ src/devices/cpu/mips/mips3.h | 42 ++++++++++++++++++++++ src/devices/cpu/mips/mips3com.cpp | 24 +++++++++++++ src/devices/cpu/mips/mips3drc.cpp | 63 +++++++++++++++++++++++++++++++++ 4 files changed, 203 insertions(+) diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp index 13e6f00715f..bf262bd1476 100644 --- a/src/devices/cpu/mips/mips3.cpp +++ b/src/devices/cpu/mips/mips3.cpp @@ -108,8 +108,12 @@ const device_type R4650BE = device_creator; const device_type R4650LE = device_creator; const device_type R4700BE = device_creator; const device_type R4700LE = device_creator; +const device_type TX4925BE = device_creator; +const device_type TX4925LE = device_creator; const device_type R5000BE = device_creator; const device_type R5000LE = device_creator; +const device_type VR5500BE = device_creator; +const device_type VR5500LE = device_creator; const device_type QED5271BE = device_creator; const device_type QED5271LE = device_creator; const device_type RM7000BE = device_creator; @@ -974,6 +978,12 @@ offs_t mips3_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u inline bool mips3_device::RBYTE(offs_t address, uint32_t *result) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + *result = (*m_memory.read_byte)(*m_program, address); + return true; + } + const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1007,6 +1017,12 @@ inline bool mips3_device::RBYTE(offs_t address, uint32_t *result) inline bool mips3_device::RHALF(offs_t address, uint32_t *result) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + *result = (*m_memory.read_word)(*m_program, address); + return true; + } + const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1040,6 +1056,12 @@ inline bool mips3_device::RHALF(offs_t address, uint32_t *result) inline bool mips3_device::RWORD(offs_t address, uint32_t *result) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + *result = (*m_memory.read_dword)(*m_program, address); + return true; + } + const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1073,6 +1095,12 @@ inline bool mips3_device::RWORD(offs_t address, uint32_t *result) inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_t mem_mask) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + *result = (*m_memory.read_dword_masked)(*m_program, address, mem_mask); + return true; + } + const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1096,6 +1124,11 @@ inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_ inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + *result = (*m_memory.read_qword)(*m_program, address); + return true; + } const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1119,6 +1152,12 @@ inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result) inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint64_t mem_mask) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + *result = (*m_memory.read_qword_masked)(*m_program, address, mem_mask); + return true; + } + const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1142,6 +1181,12 @@ inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6 inline void mips3_device::WBYTE(offs_t address, uint8_t data) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + (*m_memory.write_byte)(*m_program, address, data); + return; + } + const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1176,6 +1221,11 @@ inline void mips3_device::WBYTE(offs_t address, uint8_t data) inline void mips3_device::WHALF(offs_t address, uint16_t data) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + (*m_memory.write_word)(*m_program, address, data); + return; + } const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1210,6 +1260,12 @@ inline void mips3_device::WHALF(offs_t address, uint16_t data) inline void mips3_device::WWORD(offs_t address, uint32_t data) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + (*m_memory.write_dword)(*m_program, address, data); + return; + } + const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1244,6 +1300,12 @@ inline void mips3_device::WWORD(offs_t address, uint32_t data) inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + (*m_memory.write_dword_masked)(*m_program, address, data, mem_mask); + return; + } + const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1268,6 +1330,12 @@ inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t m inline void mips3_device::WDOUBLE(offs_t address, uint64_t data) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + (*m_memory.write_qword)(*m_program, address, data); + return; + } + const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1292,6 +1360,12 @@ inline void mips3_device::WDOUBLE(offs_t address, uint64_t data) inline void mips3_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask) { + if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) + { + (*m_memory.write_qword_masked)(*m_program, address, data, mem_mask); + return; + } + const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h index 18cb6557e91..f3e2ef52c74 100644 --- a/src/devices/cpu/mips/mips3.h +++ b/src/devices/cpu/mips/mips3.h @@ -33,8 +33,12 @@ extern const device_type R4650BE; extern const device_type R4650LE; extern const device_type R4700BE; extern const device_type R4700LE; +extern const device_type TX4925BE; +extern const device_type TX4925LE; extern const device_type R5000BE; extern const device_type R5000LE; +extern const device_type VR5500BE; +extern const device_type VR5500LE; extern const device_type QED5271BE; extern const device_type QED5271LE; extern const device_type RM7000BE; @@ -259,10 +263,12 @@ protected: MIPS3_TYPE_R4600, MIPS3_TYPE_R4650, MIPS3_TYPE_R4700, + MIPS3_TYPE_TX4925, /* MIPS IV variants */ MIPS3_TYPE_MIPS_IV, MIPS3_TYPE_R5000, + MIPS3_TYPE_VR5500, MIPS3_TYPE_QED5271, MIPS3_TYPE_RM7000 }; @@ -662,6 +668,24 @@ public: { } }; +class tx4925be_device : public mips3_device +{ +public: + // construction/destruction + tx4925be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mips3_device(mconfig, TX4925BE, "TX4925 (big)", tag, owner, clock, "tx4925be", MIPS3_TYPE_TX4925, ENDIANNESS_BIG) + { } +}; + +class tx4925le_device : public mips3_device +{ +public: + // construction/destruction + tx4925le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mips3_device(mconfig, TX4925LE, "TX4925 (little)", tag, owner, clock, "tx4925le", MIPS3_TYPE_TX4925, ENDIANNESS_LITTLE) + { } +}; + class r5000be_device : public mips3_device { public: @@ -680,6 +704,24 @@ public: { } }; +class vr5500be_device : public mips3_device +{ +public: + // construction/destruction + vr5500be_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mips3_device(mconfig, VR5500BE, "VR5500 (big)", tag, owner, clock, "vr5500be", MIPS3_TYPE_R5000, ENDIANNESS_BIG) + { } +}; + +class vr5500le_device : public mips3_device +{ +public: + // construction/destruction + vr5500le_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : mips3_device(mconfig, VR5500LE, "VR5500 (little)", tag, owner, clock, "r5500le", MIPS3_TYPE_R5000, ENDIANNESS_LITTLE) + { } +}; + class qed5271be_device : public mips3_device { public: diff --git a/src/devices/cpu/mips/mips3com.cpp b/src/devices/cpu/mips/mips3com.cpp index f01f27925fe..d5260a8b05e 100644 --- a/src/devices/cpu/mips/mips3com.cpp +++ b/src/devices/cpu/mips/mips3com.cpp @@ -230,6 +230,24 @@ uint32_t mips3_device::compute_config_register() configreg = 0x6460; } + else if (m_flavor == MIPS3_TYPE_VR5500) + { + /* + For VR55xx, Config is as follows: + bit 31 = always 0 + bits 28-30 = EC + bits 24-27 = EP + bits 23-22 = EM + bits 21-20 = always b11 + bits 19-18 = EW + bits 17-16 = always b10 + bit 15 = endian indicator as standard MIPS III + bits 3-14 = always b110011011110 + bits 0-2 = K0 ("Coherency algorithm of kseg0") + */ + + configreg = 0x6460; + } else { /* set the data cache size */ @@ -287,6 +305,9 @@ uint32_t mips3_device::compute_prid_register() case MIPS3_TYPE_VR4300: return 0x0b00; + case MIPS3_TYPE_VR5500: + return 0x5500; + case MIPS3_TYPE_R4600: case MIPS3_TYPE_R4650: return 0x2000; @@ -294,6 +315,9 @@ uint32_t mips3_device::compute_prid_register() case MIPS3_TYPE_R4700: return 0x2100; + case MIPS3_TYPE_TX4925: + return 0x2d23; + case MIPS3_TYPE_R5000: case MIPS3_TYPE_QED5271: return 0x2300; diff --git a/src/devices/cpu/mips/mips3drc.cpp b/src/devices/cpu/mips/mips3drc.cpp index 96bab73faef..defef4c486b 100644 --- a/src/devices/cpu/mips/mips3drc.cpp +++ b/src/devices/cpu/mips/mips3drc.cpp @@ -840,6 +840,69 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri UML_LABEL(block, addrok); // addrok: } + /* TX4925 on-board peripherals pass-through */ + if (m_flavor == MIPS3_TYPE_TX4925) + { + int addrok; + UML_AND(block, I3, I0, 0xffff0000); // and i3, i0, 0xffff0000 + UML_CMP(block, I3, 0xff1f0000); // cmp i3, 0xff1f0000 + UML_JMPc(block, COND_NZ, addrok = label++); + + switch (size) + { + case 1: + if (iswrite) + UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM); // write i0,i1,program_byte + else + UML_READ(block, I0, I0, SIZE_BYTE, SPACE_PROGRAM); // read i0,i0,program_byte + break; + + case 2: + if (iswrite) + UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM); // write i0,i1,program_word + else + UML_READ(block, I0, I0, SIZE_WORD, SPACE_PROGRAM); // read i0,i0,program_word + break; + + case 4: + if (iswrite) + { + if (!ismasked) + UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM); // write i0,i1,program_dword + else + UML_WRITEM(block, I0, I1, I2, SIZE_DWORD, SPACE_PROGRAM); // writem i0,i1,i2,program_dword + } + else + { + if (!ismasked) + UML_READ(block, I0, I0, SIZE_DWORD, SPACE_PROGRAM); // read i0,i0,program_dword + else + UML_READM(block, I0, I0, I2, SIZE_DWORD, SPACE_PROGRAM); // readm i0,i0,i2,program_dword + } + break; + + case 8: + if (iswrite) + { + if (!ismasked) + UML_DWRITE(block, I0, I1, SIZE_QWORD, SPACE_PROGRAM); // dwrite i0,i1,program_qword + else + UML_DWRITEM(block, I0, I1, I2, SIZE_QWORD, SPACE_PROGRAM); // dwritem i0,i1,i2,program_qword + } + else + { + if (!ismasked) + UML_DREAD(block, I0, I0, SIZE_QWORD, SPACE_PROGRAM); // dread i0,i0,program_qword + else + UML_DREADM(block, I0, I0, I2, SIZE_QWORD, SPACE_PROGRAM); // dreadm i0,i0,i2,program_qword + } + break; + } + UML_RET(block); + + UML_LABEL(block, addrok); + } + /* general case: assume paging and perform a translation */ UML_SHR(block, I3, I0, 12); // shr i3,i0,12 UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb_table],i3,dword -- cgit v1.2.3