arch-arm: Add the FAR_EL* register accessor

Use it accordingly in the faulting/exception logic

Change-Id: I2f6360d04698b6fb7188e776f1d6966e99ce19b1
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Richard Cooper <richard.cooper@arm.com>
This commit is contained in:
Giacomo Travaglini
2024-01-26 16:10:08 +00:00
parent 19628e746d
commit a3d030d161
3 changed files with 18 additions and 26 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2012-2014, 2016-2019, 2022 Arm Limited
* Copyright (c) 2010, 2012-2014, 2016-2019, 2022, 2024 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -44,6 +44,7 @@
#include "arch/arm/insts/static_inst.hh"
#include "arch/arm/interrupts.hh"
#include "arch/arm/isa.hh"
#include "arch/arm/regs/misc_accessors.hh"
#include "arch/arm/self_debug.hh"
#include "arch/arm/system.hh"
#include "arch/arm/utility.hh"
@@ -378,22 +379,6 @@ ArmFault::getSyndromeReg64() const
}
}
MiscRegIndex
ArmFault::getFaultAddrReg64() const
{
switch (toEL) {
case EL1:
return MISCREG_FAR_EL1;
case EL2:
return MISCREG_FAR_EL2;
case EL3:
return MISCREG_FAR_EL3;
default:
panic("Invalid exception level");
break;
}
}
void
ArmFault::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg)
{
@@ -1113,13 +1098,15 @@ AbortFault<T>::invoke(ThreadContext *tc, const StaticInstPtr &inst)
if (stage2) {
// stage 2 fault, set HPFAR_EL2 to the faulting IPA
// and FAR_EL2 to the Original VA
tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), OVAddr);
misc_regs::writeRegister<misc_regs::FarAccessor>(
tc, OVAddr, this->toEL);
tc->setMiscReg(MISCREG_HPFAR_EL2, bits(faultAddr, 47, 12) << 4);
DPRINTF(Faults, "Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n",
OVAddr, faultAddr);
} else {
tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), faultAddr);
misc_regs::writeRegister<misc_regs::FarAccessor>(
tc, faultAddr, this->toEL);
}
}
}
@@ -1517,7 +1504,7 @@ PCAlignmentFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
ArmFaultVals<PCAlignmentFault>::invoke(tc, inst);
assert(from64);
// Set the FAR
tc->setMiscReg(getFaultAddrReg64(), faultPC);
misc_regs::writeRegister<misc_regs::FarAccessor>(tc, faultPC, toEL);
}
bool
@@ -1661,8 +1648,7 @@ Watchpoint::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
ArmFaultVals<Watchpoint>::invoke(tc, inst);
// Set the FAR
tc->setMiscReg(getFaultAddrReg64(), vAddr);
misc_regs::writeRegister<misc_regs::FarAccessor>(tc, vAddr, toEL);
}
bool

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2012-2013, 2016-2019, 2022 Arm Limited
* Copyright (c) 2010, 2012-2013, 2016-2019, 2022, 2024 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -220,9 +220,6 @@ class ArmFault : public FaultBase
// Returns the actual syndrome register to use based on the target
// exception level
MiscRegIndex getSyndromeReg64() const;
// Returns the actual fault address register to use based on the target
// exception level
MiscRegIndex getFaultAddrReg64() const;
void invoke(ThreadContext *tc, const StaticInstPtr &inst =
nullStaticInstPtr) override;

View File

@@ -50,6 +50,15 @@ namespace ArmISA
namespace misc_regs
{
struct FarAccessor
{
using type = RegVal;
static const MiscRegIndex el0 = NUM_MISCREGS;
static const MiscRegIndex el1 = MISCREG_FAR_EL1;
static const MiscRegIndex el2 = MISCREG_FAR_EL2;
static const MiscRegIndex el3 = MISCREG_FAR_EL3;
};
template <typename RegAccessor>
MiscRegIndex
getRegVersion(ExceptionLevel el)