From f33de36e7450f38ee3e414a36307c4f2d991db8e Mon Sep 17 00:00:00 2001 From: David Haywood Date: Wed, 23 Nov 2016 19:33:33 +0000 Subject: [PATCH] SH4MMU: allow table upload by LDTLB opcode. --- src/devices/cpu/sh4/sh4.cpp | 27 ++++++++++++++++++- src/devices/cpu/sh4/sh4.h | 4 ++- src/devices/cpu/sh4/sh4comn.cpp | 48 ++++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/devices/cpu/sh4/sh4.cpp b/src/devices/cpu/sh4/sh4.cpp index ce1a3fedf91..637929121ec 100644 --- a/src/devices/cpu/sh4/sh4.cpp +++ b/src/devices/cpu/sh4/sh4.cpp @@ -186,9 +186,34 @@ void sh34_base_device::TODO(const uint16_t opcode) void sh34_base_device::LDTLB(const uint16_t opcode) { - logerror("unhandled LDTLB\n"); + logerror("unhandled LDTLB for this CPU type\n"); } +void sh4_base_device::LDTLB(const uint16_t opcode) +{ + int replace = (m_m[MMUCR] & 0x0000fc00) >> 10; + + logerror("using LDTLB to replace UTLB entry %02x\n", replace); + + // these come from PTEH + m_utlb[replace].VPN = (m_m[PTEH] & 0xfffffc00) >> 10; +// m_utlb[replace].D = (m_m[PTEH] & 0x00000200) >> 9; // from PTEL +// m_utlb[replace].V = (m_m[PTEH] & 0x00000100) >> 8; // from PTEL + m_utlb[replace].ASID = (m_m[PTEH] & 0x000000ff) >> 0; + // these come from PTEL + m_utlb[replace].PPN = (m_m[PTEL] & 0x1ffffc00) >> 10; + m_utlb[replace].V = (m_m[PTEL] & 0x00000100) >> 8; + m_utlb[replace].PSZ = (m_m[PTEL] & 0x00000080) >> 6; + m_utlb[replace].PSZ |=(m_m[PTEL] & 0x00000010) >> 4; + m_utlb[replace].PPR= (m_m[PTEL] & 0x00000060) >> 5; + m_utlb[replace].C = (m_m[PTEL] & 0x00000008) >> 3; + m_utlb[replace].D = (m_m[PTEL] & 0x00000004) >> 2; + m_utlb[replace].SH = (m_m[PTEL] & 0x00000002) >> 1; + m_utlb[replace].WT = (m_m[PTEL] & 0x00000001) >> 0; + // these come from PTEA + m_utlb[replace].TC = (m_m[PTEA] & 0x00000008) >> 3; + m_utlb[replace].SA = (m_m[PTEA] & 0x00000007) >> 0; +} #if 0 int sign_of(int n) diff --git a/src/devices/cpu/sh4/sh4.h b/src/devices/cpu/sh4/sh4.h index 0cb92ae6b5e..2b9d10bfed4 100644 --- a/src/devices/cpu/sh4/sh4.h +++ b/src/devices/cpu/sh4/sh4.h @@ -469,7 +469,7 @@ protected: void LDSMMACH(const uint16_t opcode); void LDSMMACL(const uint16_t opcode); void LDSMPR(const uint16_t opcode); - void LDTLB(const uint16_t opcode); + virtual void LDTLB(const uint16_t opcode); void MAC_L(const uint16_t opcode); void MAC_W(const uint16_t opcode); void MOV(const uint16_t opcode); @@ -762,6 +762,8 @@ public: DECLARE_READ64_MEMBER( sh4_utlb_data_array2_r ); DECLARE_WRITE64_MEMBER( sh4_utlb_data_array2_w ); + virtual void LDTLB(const uint16_t opcode) override; + virtual uint32_t sh4_getsqremap(uint32_t address) override; sh4_utlb m_utlb[64]; diff --git a/src/devices/cpu/sh4/sh4comn.cpp b/src/devices/cpu/sh4/sh4comn.cpp index 069498cde74..f02c9f50242 100644 --- a/src/devices/cpu/sh4/sh4comn.cpp +++ b/src/devices/cpu/sh4/sh4comn.cpp @@ -676,10 +676,56 @@ WRITE32_MEMBER( sh4_base_device::sh4_internal_w ) // printf("sh4_internal_w: Write %08x (%x), %08x @ %08x\n", 0xfe000000+((offset & 0x3fc0) << 11)+((offset & 0x3f) << 2), offset, data, mem_mask); - switch( offset ) + switch( offset ) { + case PTEH: // for use with LDTLB opcode + m_m[PTEH] &= 0xffffffff; + /* + NNNN NNNN NNNN NNNN NNNN NN-- AAAA AAAA + + N = VPM = Virtual Page Number + A = ASID = Address Space Identifier + + same as the address table part of the utlb but with 2 unused bits (these are sourced from PTEL instead when LDTLB is called) + */ + + + break; + + case PTEL: + m_m[PTEL] &= 0xffffffff; + /* + ---P PPPP PPPP PPPP PPPP PP-V zRRz CDHW + + same format as data array 1 of the utlb + */ + break; + + case PTEA: + m_m[PTEA] &= 0xffffffff; + /* + ---- ---- ---- ---- ---- ---- ---- TSSS + + same format as data array 2 of the utlb + */ + break; + case MMUCR: // MMU Control logerror("MMUCR %08x\n", data); + m_m[MMUCR] &= 0xffffffff; + /* + LLLL LL-- BBBB BB-- CCCC CCQV ---- -T-A + + L = LRUI = Least recently used ITLB + B = URB = UTLB replace boundary + C = URC = UTLB replace counter + Q = SQMD = Store Queue Mode Bit + V = SV = Single Virtual Mode Bit + T = TI = TLB invaldiate + A = AT = Address translation bit (enable) + */ + + if (data & MMUCR_AT) {