arch-arm: Implement Armv8.2 FEAT_UAO
Change-Id: I87b25a65e706ed6486347806a540b1dbf25231cb Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/50390 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -116,8 +116,8 @@ class ArmISA(BaseISA):
|
||||
# PAN | HPDS | !VHE | VMIDBits
|
||||
id_aa64mmfr1_el1 = Param.UInt64(0x0000000000101020,
|
||||
"AArch64 Memory Model Feature Register 1")
|
||||
# |VARANGE
|
||||
id_aa64mmfr2_el1 = Param.UInt64(0x0000000000010000,
|
||||
# |VARANGE | UAO
|
||||
id_aa64mmfr2_el1 = Param.UInt64(0x0000000000010010,
|
||||
"AArch64 Memory Model Feature Register 2")
|
||||
|
||||
# Any access (read/write) to an unimplemented
|
||||
|
||||
@@ -682,6 +682,7 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
ITSTATE it = tc->pcState().itstate();
|
||||
spsr.it2 = it.top6;
|
||||
spsr.it1 = it.bottom2;
|
||||
spsr.uao = 0;
|
||||
}
|
||||
tc->setMiscReg(spsr_idx, spsr);
|
||||
|
||||
@@ -706,6 +707,7 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
cpsr.il = 0;
|
||||
cpsr.ss = 0;
|
||||
cpsr.pan = span ? 1 : spsr.pan;
|
||||
cpsr.uao = 0;
|
||||
tc->setMiscReg(MISCREG_CPSR, cpsr);
|
||||
|
||||
// If we have a valid instruction then use it to annotate this fault with
|
||||
|
||||
@@ -800,11 +800,14 @@ MiscRegOp64::checkEL3Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
|
||||
RegVal
|
||||
MiscRegImmOp64::miscRegImm() const
|
||||
{
|
||||
if (dest == MISCREG_SPSEL) {
|
||||
switch (dest) {
|
||||
case MISCREG_SPSEL:
|
||||
return imm & 0x1;
|
||||
} else if (dest == MISCREG_PAN) {
|
||||
case MISCREG_PAN:
|
||||
return (imm & 0x1) << 22;
|
||||
} else {
|
||||
case MISCREG_UAO:
|
||||
return (imm & 0x1) << 23;
|
||||
default:
|
||||
panic("Not a valid PSTATE field register\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1192,6 +1192,7 @@ ArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
|
||||
} else {
|
||||
// aarch64
|
||||
new_cpsr.daif = spsr.daif;
|
||||
new_cpsr.uao = spsr.uao;
|
||||
}
|
||||
|
||||
SelfDebug *sd = ArmISA::ISA::getSelfDebug(tc);
|
||||
|
||||
@@ -773,6 +773,10 @@ ISA::readMiscReg(int misc_reg)
|
||||
{
|
||||
return miscRegs[MISCREG_CPSR] & 0x400000;
|
||||
}
|
||||
case MISCREG_UAO:
|
||||
{
|
||||
return miscRegs[MISCREG_CPSR] & 0x800000;
|
||||
}
|
||||
case MISCREG_L2CTLR:
|
||||
{
|
||||
// mostly unimplemented, just set NumCPUs field from sim and return
|
||||
@@ -2276,6 +2280,17 @@ ISA::setMiscReg(int misc_reg, RegVal val)
|
||||
misc_reg = MISCREG_CPSR;
|
||||
}
|
||||
break;
|
||||
case MISCREG_UAO:
|
||||
{
|
||||
// UAO is affecting data accesses
|
||||
getMMUPtr(tc)->invalidateMiscReg();
|
||||
|
||||
CPSR cpsr = miscRegs[MISCREG_CPSR];
|
||||
cpsr.uao = (uint8_t) ((CPSR) newVal).uao;
|
||||
newVal = cpsr;
|
||||
misc_reg = MISCREG_CPSR;
|
||||
}
|
||||
break;
|
||||
case MISCREG_AT_S1E1R_Xt:
|
||||
addressTranslation64(MMU::S1E1Tran, BaseMMU::Read, 0, val);
|
||||
return;
|
||||
|
||||
@@ -413,6 +413,10 @@ namespace Aarch64
|
||||
// MSR immediate: moving immediate value to selected
|
||||
// bits of the PSTATE
|
||||
switch (op1 << 3 | op2) {
|
||||
case 0x3:
|
||||
// UAO
|
||||
return new MsrImm64(
|
||||
machInst, MISCREG_UAO, crm);
|
||||
case 0x4:
|
||||
// PAN
|
||||
return new MsrImm64(
|
||||
|
||||
@@ -2451,6 +2451,8 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
|
||||
return MISCREG_CURRENTEL;
|
||||
case 3:
|
||||
return MISCREG_PAN;
|
||||
case 4:
|
||||
return MISCREG_UAO;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
@@ -4945,6 +4947,8 @@ ISA::initializeMiscRegMetadata()
|
||||
InitReg(MISCREG_PAN)
|
||||
.allPrivileges().exceptUserMode()
|
||||
.implemented(havePAN);
|
||||
InitReg(MISCREG_UAO)
|
||||
.allPrivileges().exceptUserMode();
|
||||
InitReg(MISCREG_NZCV)
|
||||
.allPrivileges();
|
||||
InitReg(MISCREG_DAIF)
|
||||
|
||||
@@ -1091,6 +1091,7 @@ namespace ArmISA
|
||||
|
||||
// PSTATE
|
||||
MISCREG_PAN,
|
||||
MISCREG_UAO,
|
||||
|
||||
// Total number of Misc Registers: Physical + Dummy
|
||||
NUM_MISCREGS
|
||||
@@ -2181,6 +2182,7 @@ namespace ArmISA
|
||||
|
||||
// PSTATE
|
||||
"pan",
|
||||
"uao",
|
||||
};
|
||||
|
||||
static_assert(sizeof(miscRegName) / sizeof(*miscRegName) == NUM_MISCREGS,
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace ArmISA
|
||||
Bitfield<27> q;
|
||||
Bitfield<26, 25> it1;
|
||||
Bitfield<24> j;
|
||||
Bitfield<23> uao; // AArch64
|
||||
Bitfield<22> pan;
|
||||
Bitfield<21> ss; // AArch64
|
||||
Bitfield<20> il; // AArch64
|
||||
|
||||
@@ -1245,6 +1245,8 @@ bool
|
||||
isUnpriviledgeAccess(ThreadContext *tc)
|
||||
{
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
|
||||
|
||||
// NV Extension not implemented yet
|
||||
bool have_nv_ext = false;
|
||||
bool unpriv_el1 = currEL(tc) == EL1 &&
|
||||
@@ -1253,9 +1255,7 @@ isUnpriviledgeAccess(ThreadContext *tc)
|
||||
bool unpriv_el2 = ArmSystem::haveEL(tc, EL2) && HaveVirtHostExt(tc) &&
|
||||
currEL(tc) == EL2 && hcr.e2h == 1 && hcr.tge == 1;
|
||||
|
||||
// User Access override, or UAO not implemented yet.
|
||||
bool user_access_override = false;
|
||||
return (unpriv_el1 || unpriv_el2) && !user_access_override;
|
||||
return (unpriv_el1 || unpriv_el2) && !cpsr.uao;
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
Reference in New Issue
Block a user