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:
Giacomo Travaglini
2018-12-18 14:20:44 +00:00
parent 671840615b
commit cba75858ab
3 changed files with 40 additions and 12 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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,