arch-arm: Read VMPIDR instead of MPIDR when EL2 is Enabled
Trying to read MPIDR(_EL1) from EL1, should return the value of VMPIDR_EL2 if EL2 is enabled. This patch is modifying the utility function for reading MPIDR in order to match this behaviour for both AArch32 and AArch64. Change-Id: I32c2d4d5052f509e6e0542a5314844164221c6a3 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/15617 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
@@ -477,18 +477,10 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
|
||||
return val;
|
||||
}
|
||||
case MISCREG_MPIDR:
|
||||
cpsr = readMiscRegNoEffect(MISCREG_CPSR);
|
||||
scr = readMiscRegNoEffect(MISCREG_SCR);
|
||||
if ((cpsr.mode == MODE_HYP) || inSecureState(scr, cpsr)) {
|
||||
return getMPIDR(system, tc);
|
||||
} else {
|
||||
return readMiscReg(MISCREG_VMPIDR, tc);
|
||||
}
|
||||
break;
|
||||
case MISCREG_MPIDR_EL1:
|
||||
// @todo in the absence of v8 virtualization support just return MPIDR_EL1
|
||||
return getMPIDR(system, tc) & 0xffffffff;
|
||||
return readMPIDR(system, tc);
|
||||
case MISCREG_VMPIDR:
|
||||
case MISCREG_VMPIDR_EL2:
|
||||
// top bit defined as RES1
|
||||
return readMiscRegNoEffect(misc_reg) | 0x80000000;
|
||||
case MISCREG_ID_AFR0: // not implemented, so alias MIDR
|
||||
|
||||
@@ -205,7 +205,37 @@ longDescFormatInUse(ThreadContext *tc)
|
||||
return ArmSystem::haveLPAE(tc) && ttbcr.eae;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
MiscReg
|
||||
readMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
|
||||
{
|
||||
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
|
||||
const ExceptionLevel current_el =
|
||||
opModeToEL((OperatingMode) (uint8_t) cpsr.mode);
|
||||
|
||||
const bool is_secure = isSecureBelowEL3(tc);
|
||||
|
||||
switch (current_el) {
|
||||
case EL0:
|
||||
// Note: in MsrMrs instruction we read the register value before
|
||||
// checking access permissions. This means that EL0 entry must
|
||||
// be part of the table even if MPIDR is not accessible in user
|
||||
// mode.
|
||||
warn_once("Trying to read MPIDR at EL0\n");
|
||||
M5_FALLTHROUGH;
|
||||
case EL1:
|
||||
if (ArmSystem::haveEL(tc, EL2) && !is_secure)
|
||||
return tc->readMiscReg(MISCREG_VMPIDR_EL2);
|
||||
else
|
||||
return getMPIDR(arm_sys, tc);
|
||||
case EL2:
|
||||
case EL3:
|
||||
return getMPIDR(arm_sys, tc);
|
||||
default:
|
||||
panic("Invalid EL for reading MPIDR register\n");
|
||||
}
|
||||
}
|
||||
|
||||
MiscReg
|
||||
getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
|
||||
{
|
||||
// Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical
|
||||
|
||||
@@ -250,7 +250,13 @@ inline bool isSecureBelowEL3(ThreadContext *tc);
|
||||
|
||||
bool longDescFormatInUse(ThreadContext *tc);
|
||||
|
||||
uint32_t getMPIDR(ArmSystem *arm_sys, ThreadContext *tc);
|
||||
/** This helper function is either returing the value of
|
||||
* MPIDR_EL1 (by calling getMPIDR), or it is issuing a read
|
||||
* to VMPIDR_EL2 (as it happens in virtualized systems) */
|
||||
MiscReg readMPIDR(ArmSystem *arm_sys, ThreadContext *tc);
|
||||
|
||||
/** This helper function is returing the value of MPIDR_EL1 */
|
||||
MiscReg getMPIDR(ArmSystem *arm_sys, ThreadContext *tc);
|
||||
|
||||
static inline uint32_t
|
||||
mcrMrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, uint32_t crn,
|
||||
|
||||
Reference in New Issue
Block a user