target/mips: Fix PageMask with variable page size

Our current code assumed the target page size is always 4k
when handling PageMask and VPN2, however, variable page size
was just added to mips target and that's no longer true.

Fixes: ee3863b9d4 ("target/mips: Support variable page size")
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhc@lemote.com>
Message-Id: <1604636510-8347-2-git-send-email-chenhc@lemote.com>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
[PMD: Replaced find_first_zero_bit() by cto32()]
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
master
Jiaxun Yang 2020-11-06 12:21:45 +08:00 committed by Philippe Mathieu-Daudé
parent a60442eb8d
commit d40b55bc1b
2 changed files with 22 additions and 6 deletions

View File

@ -892,13 +892,28 @@ void helper_mtc0_memorymapid(CPUMIPSState *env, target_ulong arg1)
void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask)
{
uint64_t mask = arg1 >> (TARGET_PAGE_BITS + 1);
if (!(env->insn_flags & ISA_MIPS32R6) || (arg1 == ~0) ||
(mask == 0x0000 || mask == 0x0003 || mask == 0x000F ||
mask == 0x003F || mask == 0x00FF || mask == 0x03FF ||
mask == 0x0FFF || mask == 0x3FFF || mask == 0xFFFF)) {
env->CP0_PageMask = arg1 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
uint32_t mask;
int maskbits;
/* Don't care MASKX as we don't support 1KB page */
mask = extract32((uint32_t)arg1, CP0PM_MASK, 16);
maskbits = cto32(mask);
/* Ensure no more set bit after first zero */
if ((mask >> maskbits) != 0) {
goto invalid;
}
/* We don't support VTLB entry smaller than target page */
if ((maskbits + 12) < TARGET_PAGE_BITS) {
goto invalid;
}
env->CP0_PageMask = mask << CP0PM_MASK;
return;
invalid:
/* When invalid, set to default target page size. */
env->CP0_PageMask = (~TARGET_PAGE_MASK >> 12) << CP0PM_MASK;
}
void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)

View File

@ -619,6 +619,7 @@ struct CPUMIPSState {
* CP0 Register 5
*/
int32_t CP0_PageMask;
#define CP0PM_MASK 13
int32_t CP0_PageGrain_rw_bitmask;
int32_t CP0_PageGrain;
#define CP0PG_RIE 31