diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2020-01-30 14:18:45 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2020-01-30 14:18:45 +0000 |
| commit | 204aa60b37c23a89e690d418f49787d274303ca7 (patch) | |
| tree | 902d059da93888c408d17ede0d92a1038cd4ff67 /target/mips/helper.c | |
| parent | a09a2b5a4d85d4bf2f04b0e503d7dd7905967148 (diff) | |
| parent | 99029be1c2875cd857614397674bbf563ddb6f91 (diff) | |
| download | focaccia-qemu-204aa60b37c23a89e690d418f49787d274303ca7.tar.gz focaccia-qemu-204aa60b37c23a89e690d418f49787d274303ca7.zip | |
Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-jan-29-2020' into staging
MIPS queue for January 29th, 2020 # gpg: Signature made Wed 29 Jan 2020 18:29:43 GMT # gpg: using RSA key D4972A8967F75A65 # gpg: Good signature from "Aleksandar Markovic <amarkovic@wavecomp.com>" [full] # Primary key fingerprint: 8526 FBF1 5DA3 811F 4A01 DD75 D497 2A89 67F7 5A65 * remotes/amarkovic/tags/mips-queue-jan-29-2020: target/mips: Add implementation of GINVT instruction target/mips: Amend CP0 WatchHi register implementation hw/core/loader: Let load_elf() populate a field with CPU-specific flags target/mips: semihosting: Remove 'uhi_done' label in helper_do_semihosting() disas: Add a field for target-dependant data to disassemble_info target/mips: Rectify documentation on deprecating MIPS r4k machine Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/mips/helper.c')
| -rw-r--r-- | target/mips/helper.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/target/mips/helper.c b/target/mips/helper.c index 781930a7dd..afd78b1990 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -72,8 +72,13 @@ int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type) { uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; + uint32_t MMID = env->CP0_MemoryMapID; + bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); + uint32_t tlb_mmid; int i; + MMID = mi ? MMID : (uint32_t) ASID; + for (i = 0; i < env->tlb->tlb_in_use; i++) { r4k_tlb_t *tlb = &env->tlb->mmu.r4k.tlb[i]; /* 1k pages are not supported. */ @@ -84,8 +89,9 @@ int r4k_map_address(CPUMIPSState *env, hwaddr *physical, int *prot, tag &= env->SEGMask; #endif - /* Check ASID, virtual page number & size */ - if ((tlb->G == 1 || tlb->ASID == ASID) && VPN == tag && !tlb->EHINV) { + /* Check ASID/MMID, virtual page number & size */ + tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; + if ((tlb->G == 1 || tlb_mmid == MMID) && VPN == tag && !tlb->EHINV) { /* TLB match */ int n = !!(address & mask & ~(mask >> 1)); /* Check access rights */ @@ -1418,14 +1424,20 @@ void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra) target_ulong addr; target_ulong end; uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; + uint32_t MMID = env->CP0_MemoryMapID; + bool mi = !!((env->CP0_Config5 >> CP0C5_MI) & 1); + uint32_t tlb_mmid; target_ulong mask; + MMID = mi ? MMID : (uint32_t) ASID; + tlb = &env->tlb->mmu.r4k.tlb[idx]; /* - * The qemu TLB is flushed when the ASID changes, so no need to + * The qemu TLB is flushed when the ASID/MMID changes, so no need to * flush these entries again. */ - if (tlb->G == 0 && tlb->ASID != ASID) { + tlb_mmid = mi ? tlb->MMID : (uint32_t) tlb->ASID; + if (tlb->G == 0 && tlb_mmid != MMID) { return; } |