arch-arm: Add misc_accessor templated functions to read/write regs at different ELs (#1072)
A usual system register read/write pattern is something like the
following
```
switch(el) {
case EL1:
tc->readMiscReg(REG_EL1);
case EL2:
tc->readMiscReg(REG_EL2);
case EL3:
tc->readMiscReg(REG_EL3);
}
```
To avoid repeating these switch statements all over gem5, we define
templated functions which have
an accessor struct as a template parameter. These accessor will help
populating the templated switch
construct. We provide the FAR register accessor as an example. The
accessor should define the following
fields: (type, el0, el1, el2, el3)
Example:
```
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;
};
```
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
105
src/arch/arm/regs/misc_accessors.hh
Normal file
105
src/arch/arm/regs/misc_accessors.hh
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_REGS_MISC_ACCESSORS_HH__
|
||||
#define __ARCH_ARM_REGS_MISC_ACCESSORS_HH__
|
||||
|
||||
#include "arch/arm/regs/misc_types.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
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)
|
||||
{
|
||||
switch (el) {
|
||||
case EL0:
|
||||
return RegAccessor::el0;
|
||||
case EL1:
|
||||
return RegAccessor::el1;
|
||||
case EL2:
|
||||
return RegAccessor::el2;
|
||||
case EL3:
|
||||
return RegAccessor::el3;
|
||||
default:
|
||||
panic("Invalid EL\n");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RegAccessor>
|
||||
typename RegAccessor::type
|
||||
readRegister(ThreadContext *tc, ExceptionLevel el)
|
||||
{
|
||||
return tc->readMiscReg(getRegVersion<RegAccessor>(el));
|
||||
}
|
||||
|
||||
template <typename RegAccessor>
|
||||
typename RegAccessor::type
|
||||
readRegisterNoEffect(ThreadContext *tc, ExceptionLevel el)
|
||||
{
|
||||
return tc->readMiscRegNoEffect(getRegVersion<RegAccessor>(el));
|
||||
}
|
||||
|
||||
template <typename RegAccessor>
|
||||
void
|
||||
writeRegister(ThreadContext *tc, RegVal val, ExceptionLevel el)
|
||||
{
|
||||
tc->setMiscReg(getRegVersion<RegAccessor>(el), val);
|
||||
}
|
||||
|
||||
} // namespace misc_regs
|
||||
} // namespace ArmISA
|
||||
} // namespace gem5
|
||||
|
||||
#endif // __ARCH_ARM_REGS_MISC_ACCESSORS_HH__
|
||||
Reference in New Issue
Block a user