57#include "debug/Arm.hh"
58#include "debug/LLSC.hh"
59#include "debug/MatRegs.hh"
60#include "debug/VecPredRegs.hh"
61#include "debug/VecRegs.hh"
65#include "params/ArmISA.hh"
160 if (
release->has(ArmExtension::TME)) {
162 tc->setHtmCheckpointPtr(std::move(cpt));
170 pmu->setThreadContext(
tc);
178 gicv3_ifc->setISA(
this);
179 gicv3_ifc->setThreadContext(
tc);
239 bool sec_el2 = scr.eel2 &&
release->has(ArmExtension::FEAT_SEL2);
405 int lower = map.first, upper = map.second;
411 DPRINTF(MiscRegs,
"Reading MiscReg %s with set res0 bits: %#x\n",
415 DPRINTF(MiscRegs,
"Reading MiscReg %s with clear res1 bits: %#x\n",
431 cpsr.t =
pc.thumb() ? 1 : 0;
439 warn(
"Unimplemented system register %s read.\n",
442 panic(
"Unimplemented system register %s read.\n",
451 const uint32_t ones = (uint32_t)(-1);
455 cpacrMask.cp10 = ones;
456 cpacrMask.cp11 = ones;
457 cpacrMask.asedis = ones;
460 if (
release->has(ArmExtension::SECURITY)) {
466 if (!nsacr.cp10) cpacrMask.cp10 = 0;
467 if (!nsacr.cp11) cpacrMask.cp11 = 0;
472 DPRINTF(MiscRegs,
"Reading misc reg %s: %#x\n",
491 warn_once(
"The clidr register always reports 0 caches.\n");
492 warn_once(
"clidr LoUIS field of 0b001 to match current "
493 "ARM implementations.\n");
496 warn_once(
"The ccsidr register isn't implemented and "
497 "always reads as 0.\n");
500 warn(
"Not doing anything for miscreg ACTLR\n");
507 return pmu->readMiscReg(idx);
510 panic(
"shouldn't be reading this register seperately\n");
514 if (!
release->has(ArmExtension::FEAT_AFP)) {
519 if (!
release->has(ArmExtension::FEAT_EBF16)) {
592 l2ctlr.numCPUs =
tc->getSystemPtr()->threads.size() - 1;
599 tc->getCpuPtr()->getInterruptController(
tc->threadId()));
608 bool secure_lookup =
release->has(ArmExtension::SECURITY) &&
610 if (!secure_lookup) {
662 warn(
"Call to %s attempts to access a system timer which is "
663 "inaccessible within SE mode. Divergent behaviour is "
687 int lower = map.first, upper = map.second;
693 DPRINTF(MiscRegs,
"Writing MiscReg %s (%d %d:%d) : %#x\n",
697 DPRINTF(MiscRegs,
"Writing MiscReg %s (%d %d) : %#x\n",
715 int old_mode = old_cpsr.mode;
717 if (cpsr.pan != old_cpsr.pan || cpsr.il != old_cpsr.il) {
721 DPRINTF(Arm,
"Updating CPSR from %#x to %#x f:%d i:%d a:%d d:%d "
722 "mode:%#x\n",
miscRegs[idx], cpsr, cpsr.f, cpsr.i, cpsr.a,
725 pc.nextThumb(cpsr.t);
726 pc.illegalExec(cpsr.il == 1);
729 tc->getDecoderPtr()->as<
Decoder>().setSveLen(
731 tc->getDecoderPtr()->as<
Decoder>().setSmeLen(
738 tc->pcStateNoRecord(
pc);
745 if (old_mode != cpsr.mode) {
765 warn(
"Unimplemented system register %s write with %#x.\n",
768 panic(
"Unimplemented system register %s write with %#x.\n",
778 const uint32_t ones = (uint32_t)(-1);
782 cpacrMask.cp10 = ones;
783 cpacrMask.cp11 = ones;
784 cpacrMask.asedis = ones;
787 if (
release->has(ArmExtension::SECURITY)) {
793 if (!nsacr.cp10) cpacrMask.cp10 = 0;
794 if (!nsacr.cp11) cpacrMask.cp11 = 0;
800 newVal |= old_val & ~cpacrMask;
801 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
807 const uint32_t ones = (uint32_t)(-1);
809 cpacrMask.tta = ones;
810 cpacrMask.fpen = ones;
811 if (
release->has(ArmExtension::FEAT_SVE)) {
812 cpacrMask.zen = ones;
814 if (
release->has(ArmExtension::FEAT_SME)) {
815 cpacrMask.smen = ones;
818 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
825 const uint32_t ones = (uint32_t)(-1);
827 cptrMask.tcpac = ones;
830 if (
release->has(ArmExtension::FEAT_SVE)) {
832 cptrMask.zen = hcr.e2h ? ones : 0;
834 if (
release->has(ArmExtension::FEAT_SME)) {
836 cptrMask.smen = hcr.e2h ? ones : 0;
838 cptrMask.fpen = hcr.e2h ? ones : 0;
841 cptrMask.res1_13_el2 = ones;
842 cptrMask.res1_7_0_el2 = ones;
843 if (!
release->has(ArmExtension::FEAT_SVE)) {
844 cptrMask.res1_8_el2 = ones;
846 if (!
release->has(ArmExtension::FEAT_SME)) {
847 cptrMask.res1_12_el2 = ones;
849 cptrMask.res1_9_el2 = ones;
851 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
857 const uint32_t ones = (uint32_t)(-1);
859 cptrMask.tcpac = ones;
862 if (
release->has(ArmExtension::FEAT_SVE)) {
865 if (
release->has(ArmExtension::FEAT_SME)) {
869 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
874 warn_once(
"The csselr register isn't implemented.\n");
878 warn(
"Calling DC ZVA! Not Implemeted! Expect WEIRD results\n");
883 FPCR fpcr_val = (FPCR)newVal;
884 if (!
release->has(ArmExtension::FEAT_AFP)) {
889 if (!
release->has(ArmExtension::FEAT_EBF16)) {
896 tc->getDecoderPtr()->as<
Decoder>().setContext(newVal);
933 const uint32_t fpexcMask = 0x60000000;
934 newVal = (newVal & fpexcMask) |
954 const uint32_t temp = (
val == 0xC5ACCE55)? 0x1 : 0x0;
956 r.oslk =
bits(temp,0);
985 r.udccdis =
v.udccdis;
1019 DPRINTF(MiscRegs,
"Writing SCTLR: %#x\n", newVal);
1023 if (
release->has(ArmExtension::SECURITY) &&
1031 SCTLR new_sctlr = newVal;
1032 new_sctlr.nmfi = ((bool)sctlr.nmfi) &&
1033 !
release->has(ArmExtension::VIRTUALIZATION);
1076 warn(
"Not doing anything for write of miscreg ACTLR\n");
1083 pmu->setMiscReg(idx, newVal);
1091 newVal &= ~((uint32_t) hstrMask);
1098 secure_lookup =
release->has(ArmExtension::SECURITY) &&
1100 if (!secure_lookup) {
1104 newVal = (newVal &
~mask) | (oldValue &
mask);
1129 if (!
release->has(ArmExtension::SECURITY))
1130 panic(
"Security Extensions required for ATS12NSOPR");
1134 if (!
release->has(ArmExtension::SECURITY))
1135 panic(
"Security Extensions required for ATS12NSOPW");
1139 if (!
release->has(ArmExtension::SECURITY))
1140 panic(
"Security Extensions required for ATS12NSOUR");
1145 if (!
release->has(ArmExtension::SECURITY))
1146 panic(
"Security Extensions required for ATS12NSOUW");
1159 const uint32_t ones = (uint32_t)(-1);
1160 TTBCR ttbcrMask = 0;
1161 TTBCR ttbcrNew = newVal;
1165 if (
release->has(ArmExtension::SECURITY)) {
1166 ttbcrMask.pd0 = ones;
1167 ttbcrMask.pd1 = ones;
1169 ttbcrMask.epd0 = ones;
1170 ttbcrMask.irgn0 = ones;
1171 ttbcrMask.orgn0 = ones;
1172 ttbcrMask.sh0 = ones;
1173 ttbcrMask.ps = ones;
1174 ttbcrMask.a1 = ones;
1175 ttbcrMask.epd1 = ones;
1176 ttbcrMask.irgn1 = ones;
1177 ttbcrMask.orgn1 = ones;
1178 ttbcrMask.sh1 = ones;
1179 if (
release->has(ArmExtension::LPAE))
1180 ttbcrMask.eae = ones;
1182 if (
release->has(ArmExtension::LPAE) && ttbcrNew.eae) {
1183 newVal = newVal & ttbcrMask;
1185 newVal = (newVal & ttbcrMask) | (ttbcr & (~ttbcrMask));
1195 if (
release->has(ArmExtension::LPAE)) {
1199 uint64_t ttbrMask =
mask(63,56) |
mask(47,40);
1200 newVal = (newVal & (~ttbrMask));
1257 cpsr.daif = (uint8_t) ((CPSR) newVal).daif;
1274 cpsr.sp = (uint8_t) ((CPSR) newVal).sp;
1282 cpsr.el = (uint8_t) ((CPSR) newVal).el;
1293 cpsr.pan = (uint8_t) ((CPSR) newVal).pan;
1304 cpsr.uao = (uint8_t) ((CPSR) newVal).uao;
1310 warn(
"miscreg L2CTLR (%s) written with %#x. ignored...\n",
1331 tc->getDecoderPtr()->as<
Decoder>().setSveLen(
1341 tc->getDecoderPtr()->as<
Decoder>().setSmeLen(
1369 return *
timer.get();
1373 if (!generic_timer) {
1374 panic(
"Trying to get a generic timer from a system that hasn't "
1375 "been configured to use a generic timer.\n");
1381 return *
timer.get();
1391 panic_if(!gicv3_ifc,
"The system does not have a GICv3 irq controller\n");
1412 if (!
release->has(ArmExtension::SECURITY)) {
1456 "A ThreadContext is needed to determine the SVE vector length "
1457 "in full-system mode");
1474 static_cast<unsigned>(
1480 }
else if (
release->has(ArmExtension::SECURITY)) {
1483 static_cast<unsigned>(
1489 return (
len + 1) * 128;
1500 "A ThreadContext is needed to determine the SME vector length "
1501 "in full-system mode");
1518 static_cast<unsigned>(
1524 }
else if (
release->has(ArmExtension::SECURITY)) {
1527 static_cast<unsigned>(
1535 static const unsigned LUT[16] = {0, 1, 1, 3, 3, 3, 3, 7,
1536 7, 7, 7, 7, 7, 7, 7, 15};
1539 return (
len + 1) * 128;
1547 DPRINTF(Checkpoint,
"Serializing Arm Misc Registers\n");
1554 DPRINTF(Checkpoint,
"Unserializing Arm Misc Registers\n");
1560 warn(
"Checkpoint value for register %s does not match "
1561 "current configuration (checkpointed: %#x, current: %#x)",
1582 warn_once(
"Doing AT (address translation) in functional mode! Fix Me!\n");
1584 auto req = std::make_shared<Request>(
1586 tc->pcState().instAddr(),
tc->contextId());
1589 req,
tc,
mode, tran_type);
1593 Addr paddr = req->getPaddr();
1597 uint8_t max_paddr_bit = 0;
1598 if (
release->has(ArmExtension::LPAE) &&
1607 par = (paddr &
mask(max_paddr_bit, 12)) |
1611 "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
1620 par.lpae = fsr.lpae;
1621 par.ptw = (arm_fault->
iss() >> 7) & 0x1;
1622 par.s = arm_fault->
isStage2() ? 1 : 0;
1626 par.fst = fsr.status;
1629 par.fs4_0 = fsr.fsLow | (fsr.fsHigh << 5);
1633 "MISCREG: Translated addr 0x%08x fault fsr %#x: PAR: 0x%08x\n",
1643 Addr cacheBlockMask)
1648 DPRINTF(LLSC,
"%s: handling snoop for address: %#x locked: %d\n",
1656 Addr snoop_addr = pkt->
getAddr() & cacheBlockMask;
1658 DPRINTF(LLSC,
"%s: handling snoop for address: %#x locked addr: %#x\n",
1660 if (locked_addr == snoop_addr) {
1661 DPRINTF(LLSC,
"%s: address match, clearing lock and signaling sev\n",
1687 DPRINTF(LLSC,
"%s: Placing address %#x in monitor\n",
1688 tc->getCpuPtr()->name(), req->getPaddr());
1696 DPRINTF(LLSC,
"%s: Placing address %#x in monitor\n",
1703 DPRINTF(LLSC,
"%s: handling snoop lock hit address: %#x\n",
1712 DPRINTF(LLSC,
"%s: handling snoop lock hit address: %#x\n",
1722 Addr cacheBlockMask)
1727 DPRINTF(LLSC,
"Handling locked write for address %#x in monitor.\n",
1733 if (!lock_flag || (req->getPaddr() & cacheBlockMask) != lock_addr) {
1736 req->setExtraData(0);
1738 DPRINTF(LLSC,
"clearing lock flag in handle locked write\n",
1744 int stCondFailures = xc->readStCondFailures();
1746 xc->setStCondFailures(stCondFailures);
1747 if (stCondFailures % 100000 == 0) {
1748 warn(
"context %d: %d consecutive "
1749 "store conditional failures\n",
1767 Addr cacheBlockMask)
1779 DPRINTF(LLSC,
"Clearing lock and signaling sev\n");
1793 DPRINTF(LLSC,
"Clearing lock and signaling sev\n");
ISA-specific types for hardware transactional memory.
virtual FSR getFsr(ThreadContext *tc) const
virtual uint32_t iss() const =0
virtual void update(ThreadContext *tc)
virtual bool isStage2() const
Base class for devices that use the MiscReg interfaces.
virtual void setMiscReg(int misc_reg, RegVal val)=0
Write to a system register belonging to this device.
virtual RegVal readMiscReg(int misc_reg)=0
Read a system register belonging to this device.
bool inSecureState() const
Return true if the PE is in Secure state.
void setMiscRegReset(RegIndex, RegVal val)
unsigned getCurSveVecLenInBits() const
ExceptionLevel currEL() const
Returns the current Exception Level (EL) of the ISA object.
void takeOverFrom(ThreadContext *new_tc, ThreadContext *old_tc) override
void serialize(CheckpointOut &cp) const override
Serialize an object.
void copyRegsFrom(ThreadContext *src) override
const enums::DecoderFlavor _decoderFlavor
DummyISADevice dummyDevice
Dummy device for to handle non-existing ISA devices.
RegVal readMiscRegReset(RegIndex) const
void setupThreadContext()
void setMiscRegNoEffect(RegIndex idx, RegVal val) override
void handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask) override
int flattenMiscIndex(int reg) const
std::pair< int, int > getMiscIndices(int misc_reg) const
RegVal miscRegs[NUM_MISCREGS]
unsigned smeVL
SME vector length in quadwords.
std::unique_ptr< BaseISADevice > timer
bool handleLockedWrite(const RequestPtr &req, Addr cacheBlockMask) override
void globalClearExclusive() override
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void updateRegMap(CPSR cpsr)
void startup() override
startup() is the final initialization call before simulation.
int redirectRegVHE(int misc_reg)
Returns the enconcing equivalent when VHE is implemented and HCR_EL2.E2H is enabled and executing at ...
BaseISADevice & getGICv3CPUInterface()
BaseISADevice & getGenericTimer()
RegVal readMiscRegNoEffect(RegIndex idx) const override
bool impdefAsNop
If true, accesses to IMPLEMENTATION DEFINED registers are treated as NOP hence not causing UNDEFINED ...
void setMiscReg(RegIndex, RegVal val) override
unsigned sveVL
SVE vector length in quadwords.
const MiscRegLUTEntryInitializer InitReg(uint32_t reg)
void handleLockedRead(const RequestPtr &req) override
enums::DecoderFlavor decoderFlavor() const
void addressTranslation(MMU::ArmTranslationType tran_type, BaseMMU::Mode mode, Request::Flags flags, RegVal val)
void initializeMiscRegMetadata()
const ArmRelease * release
This could be either a FS or a SE release.
RegVal readMiscReg(RegIndex idx) override
void handleLockedSnoopHit() override
std::unique_ptr< BaseISADevice > gicv3CpuInterface
unsigned getCurSmeVecLenInBits() const
TranslationGenPtr translateFunctional(Addr start, Addr size, ThreadContext *tc, Mode mode, Request::Flags flags) override
Returns a translation generator for a region of virtual addresses, instead of directly translating a ...
chain reset(uint64_t res_val) const
void serialize(CheckpointOut &cp) const override
Serialize an object.
BaseISA(const SimObjectParams &p, const std::string &name)
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
virtual ThreadContext * tcBase() const =0
Returns a pointer to the ThreadContext.
virtual RegVal readMiscReg(int misc_reg)=0
Reads a miscellaneous register, handling any architectural side effects due to reading that register.
virtual void setMiscReg(int misc_reg, RegVal val)=0
Sets a miscellaneous register, handling any architectural side effects due to writing that register.
Gicv3CPUInterface * getCPUInterface(int cpu_id) const
virtual std::string name() const
bool isInvalidate() const
@ funcRequestorId
This requestor id is used for functional requests that don't come from a particular device.
gem5::Flags< FlagsType > Flags
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal getReg(const RegId ®) const
virtual BaseCPU * getCpuPtr()=0
virtual const PCStateBase & pcState() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual ContextID contextId() const =0
This module implements the global system counter and the local per-CPU architected timers as specifie...
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
#define panic(...)
This implements a cprintf based panic() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual void startup()
startup() is the final initialization call before simulation.
RegAccessor::type readRegisterNoEffect(ThreadContext *tc, ExceptionLevel el)
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
static const uint32_t FpscrQcMask
bool ELIsInHost(ThreadContext *tc, ExceptionLevel el)
Returns true if the current exception level el is executing a Host OS or an application of a Host OS ...
bool isSecure(ThreadContext *tc)
static const uint32_t FpscrExcMask
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn't already a pending event.
constexpr RegClass matRegClass
constexpr RegClass vecElemClass
const RegClass flatIntRegClass
static const uint32_t CpsrMaskQ
bool EL2Enabled(ThreadContext *tc)
void preUnflattenMiscReg()
gem5::MatStore< MaxSmeVecLenInBytes, MaxSmeVecLenInBytes > MatRegContainer
constexpr RegClass vecPredRegClass
static const uint32_t FpscrFpcrMask
constexpr RegClass ccRegClass
@ MISCREG_ID_AA64PFR0_EL1
@ MISCREG_ICC_IGRPEN1_EL3
@ MISCREG_ID_AA64DFR0_EL1
@ MISCREG_ID_AA64DFR1_EL1
@ MISCREG_ID_AA64ISAR1_EL1
@ MISCREG_ID_AA64MMFR1_EL1
@ MISCREG_CNTHPS_CVAL_EL2
@ MISCREG_CNTHPS_TVAL_EL2
@ MISCREG_ID_AA64MMFR0_EL1
@ MISCREG_CNTHVS_TVAL_EL2
@ MISCREG_CNTHVS_CVAL_EL2
@ MISCREG_ID_AA64MMFR2_EL1
@ MISCREG_ID_AA64AFR1_EL1
@ MISCREG_ID_AA64AFR0_EL1
@ MISCREG_ID_AA64ISAR0_EL1
@ MISCREG_CONTEXTIDR_EL12
@ MISCREG_PMXEVTYPER_PMCCFILTR
@ MISCREG_ID_AA64PFR1_EL1
gem5::VecRegContainer< NumVecElemPerVecReg *sizeof(VecElem)> VecRegContainer
int unflattenMiscReg(int reg)
static bool lockedWriteHandler(ThreadContext *tc, XC *xc, const RequestPtr &req, Addr cacheBlockMask)
static const uint32_t FpscrFpsrMask
static ExceptionLevel opModeToEL(OperatingMode mode)
constexpr RegClass miscRegClass
const char *const miscRegName[]
RegVal readMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is either returing the value of MPIDR_EL1 (by calling getMPIDR),...
static void lockedSnoopHandler(ThreadContext *tc, XC *xc, PacketPtr pkt, Addr cacheBlockMask)
std::vector< struct MiscRegLUTEntry > lookUpMiscReg(NUM_MISCREGS)
constexpr RegClass vecRegClass
constexpr RegClass floatRegClass
Copyright (c) 2024 Arm Limited All rights reserved.
std::shared_ptr< FaultBase > Fault
std::shared_ptr< Request > RequestPtr
std::ostream CheckpointOut
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
constexpr decltype(nullptr) NoFault
@ FloatRegClass
Floating-point register.
constexpr char FloatRegClassName[]
#define UNSERIALIZE_MAPPING(member, names, size)
#define SERIALIZE_MAPPING(member, names, size)