target/arm: Correct handling of PMCR_EL0.LC bit
The LC bit in the PMCR_EL0 register is supposed to be: * read/write * RES1 on an AArch64-only implementation * an architecturally UNKNOWN value on reset (and use of LC==0 by software is deprecated). We were implementing it incorrectly as read-only always zero, though we do have all the code needed to test it and behave accordingly. Instead make it a read-write bit which resets to 1 always, which satisfies all the architectural requirements above. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20200214175116.9164-18-peter.maydell@linaro.org
This commit is contained in:
parent
a1ed04dd79
commit
62d96ff485
@ -1023,6 +1023,11 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
|
|||||||
#define PMCRC 0x4
|
#define PMCRC 0x4
|
||||||
#define PMCRP 0x2
|
#define PMCRP 0x2
|
||||||
#define PMCRE 0x1
|
#define PMCRE 0x1
|
||||||
|
/*
|
||||||
|
* Mask of PMCR bits writeable by guest (not including WO bits like C, P,
|
||||||
|
* which can be written as 1 to trigger behaviour but which stay RAZ).
|
||||||
|
*/
|
||||||
|
#define PMCR_WRITEABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
|
||||||
|
|
||||||
#define PMXEVTYPER_P 0x80000000
|
#define PMXEVTYPER_P 0x80000000
|
||||||
#define PMXEVTYPER_U 0x40000000
|
#define PMXEVTYPER_U 0x40000000
|
||||||
@ -1577,9 +1582,8 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only the DP, X, D and E bits are writable */
|
env->cp15.c9_pmcr &= ~PMCR_WRITEABLE_MASK;
|
||||||
env->cp15.c9_pmcr &= ~0x39;
|
env->cp15.c9_pmcr |= (value & PMCR_WRITEABLE_MASK);
|
||||||
env->cp15.c9_pmcr |= (value & 0x39);
|
|
||||||
|
|
||||||
pmu_op_finish(env);
|
pmu_op_finish(env);
|
||||||
}
|
}
|
||||||
@ -6370,7 +6374,8 @@ static void define_pmu_regs(ARMCPU *cpu)
|
|||||||
.access = PL0_RW, .accessfn = pmreg_access,
|
.access = PL0_RW, .accessfn = pmreg_access,
|
||||||
.type = ARM_CP_IO,
|
.type = ARM_CP_IO,
|
||||||
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
|
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
|
||||||
.resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
|
.resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
|
||||||
|
PMCRLC,
|
||||||
.writefn = pmcr_write, .raw_writefn = raw_write,
|
.writefn = pmcr_write, .raw_writefn = raw_write,
|
||||||
};
|
};
|
||||||
define_one_arm_cp_reg(cpu, &pmcr);
|
define_one_arm_cp_reg(cpu, &pmcr);
|
||||||
|
Loading…
Reference in New Issue
Block a user