On 27/10/26 11:41, Kirill A. Korinsky wrote:
Octeon firmware programs contiguous PageMask values that do not follow the generic R4K even maskbits rule.Keep the generic validation rule for other MIPS CPUs, while allowing Octeon CPUs to use the contiguous masks accepted by hardware. --- target/mips/tcg/system/cp0_helper.c | 15 ++++++++++----- target/mips/tcg/system/tlb_helper.c | 2 +- target/mips/tcg/tcg-internal.h | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/target/mips/tcg/system/cp0_helper.c b/target/mips/tcg/system/cp0_helper.c index 33fb7365d7..046fea6234 100644 --- a/target/mips/tcg/system/cp0_helper.c +++ b/target/mips/tcg/system/cp0_helper.c @@ -882,14 +882,19 @@ void HELPER(mtc0_memorymapid)(CPUMIPSState *env, target_ulong arg1) } }-uint32_t compute_pagemask(uint32_t val)+uint32_t compute_pagemask(CPUMIPSState *env, uint32_t val) { /* Don't care MASKX as we don't support 1KB page */ - uint32_t mask = extract32(val, CP0PM_MASK, 16); + uint32_t mask = val >> CP0PM_MASK;
This changes behaviour for every CPU, not just Octeon.
int maskbits = cto32(mask);- /* Ensure no more set bit after first zero, and maskbits even. */- if ((mask >> maskbits) == 0 && maskbits % 2 == 0) { + /* + * Generic R4K PageMask values use two mask bits per size step. + * Octeon accepts contiguous byte masks such as 0x003fffff for + * two 2 MiB pages. + */ + if ((mask & (mask + 1)) == 0 && + ((env->insn_flags & INSN_OCTEON) || maskbits % 2 == 0)) { return mask << CP0PM_MASK; } else { /* When invalid, set to default target page size. */ @@ -899,7 +904,7 @@ uint32_t compute_pagemask(uint32_t val)void HELPER(mtc0_pagemask)(CPUMIPSState *env, target_ulong arg1){ - env->CP0_PageMask = compute_pagemask(arg1); + env->CP0_PageMask = compute_pagemask(env, arg1); }
Preferrably pass @env to compute_pagemask() in a preliminary patch.
