diff options
author | Leon Alrae <leon.alrae@imgtec.com> | 2014-09-11 16:28:16 +0100 |
---|---|---|
committer | Leon Alrae <leon.alrae@imgtec.com> | 2015-06-12 09:05:14 +0100 |
commit | cd0d45c40133ef8b409aede5ad8a99aeaf6a70fe (patch) | |
tree | 2988b940dc0b36a8086cc52ac8779bc34f28ee8f /target-mips/op_helper.c | |
parent | 284b731a6ae47b9ebabb9613e753c4d83cf75dd3 (diff) | |
download | qemu-cd0d45c40133ef8b409aede5ad8a99aeaf6a70fe.zip |
target-mips: support Page Frame Number Extension field
Update tlb->PFN to contain PFN concatenated with PFNX. PFNX is 0 if large
physical address is not supported.
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-mips/op_helper.c')
-rw-r--r-- | target-mips/op_helper.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 4dc4970d80..31bafcf954 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1826,6 +1826,16 @@ static void r4k_mips_tlb_flush_extra (CPUMIPSState *env, int first) } } +static inline uint64_t get_tlb_pfn_from_entrylo(uint64_t entrylo) +{ +#if defined(TARGET_MIPS64) + return extract64(entrylo, 6, 54); +#else + return extract64(entrylo, 6, 24) | /* PFN */ + (extract64(entrylo, 32, 32) << 24); /* PFNX */ +#endif +} + static void r4k_fill_tlb(CPUMIPSState *env, int idx) { r4k_tlb_t *tlb; @@ -1849,13 +1859,13 @@ static void r4k_fill_tlb(CPUMIPSState *env, int idx) tlb->C0 = (env->CP0_EntryLo0 >> 3) & 0x7; tlb->XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) & 1; tlb->RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) & 1; - tlb->PFN[0] = (env->CP0_EntryLo0 >> 6) << 12; + tlb->PFN[0] = get_tlb_pfn_from_entrylo(env->CP0_EntryLo0) << 12; tlb->V1 = (env->CP0_EntryLo1 & 2) != 0; tlb->D1 = (env->CP0_EntryLo1 & 4) != 0; tlb->C1 = (env->CP0_EntryLo1 >> 3) & 0x7; tlb->XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) & 1; tlb->RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) & 1; - tlb->PFN[1] = (env->CP0_EntryLo1 >> 6) << 12; + tlb->PFN[1] = get_tlb_pfn_from_entrylo(env->CP0_EntryLo1) << 12; } void r4k_helper_tlbinv(CPUMIPSState *env) @@ -1972,6 +1982,16 @@ void r4k_helper_tlbp(CPUMIPSState *env) } } +static inline uint64_t get_entrylo_pfn_from_tlb(uint64_t tlb_pfn) +{ +#if defined(TARGET_MIPS64) + return tlb_pfn << 6; +#else + return (extract64(tlb_pfn, 0, 24) << 6) | /* PFN */ + (extract64(tlb_pfn, 24, 32) << 32); /* PFNX */ +#endif +} + void r4k_helper_tlbr(CPUMIPSState *env) { r4k_tlb_t *tlb; @@ -1998,12 +2018,12 @@ void r4k_helper_tlbr(CPUMIPSState *env) env->CP0_PageMask = tlb->PageMask; env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) | ((uint64_t)tlb->RI0 << CP0EnLo_RI) | - ((uint64_t)tlb->XI0 << CP0EnLo_XI) | - (tlb->C0 << 3) | (tlb->PFN[0] >> 6); + ((uint64_t)tlb->XI0 << CP0EnLo_XI) | (tlb->C0 << 3) | + get_entrylo_pfn_from_tlb(tlb->PFN[0] >> 12); env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) | ((uint64_t)tlb->RI1 << CP0EnLo_RI) | - ((uint64_t)tlb->XI1 << CP0EnLo_XI) | - (tlb->C1 << 3) | (tlb->PFN[1] >> 6); + ((uint64_t)tlb->XI1 << CP0EnLo_XI) | (tlb->C1 << 3) | + get_entrylo_pfn_from_tlb(tlb->PFN[1] >> 12); } } |