Go to the documentation of this file.
56 #include "debug/Arm.hh"
57 #include "debug/LLSC.hh"
58 #include "debug/MatRegs.hh"
59 #include "debug/VecPredRegs.hh"
60 #include "debug/VecRegs.hh"
64 #include "params/ArmISA.hh"
84 _decoderFlavor(
p.decoderFlavor), pmu(
p.pmu), impdefAsNop(
p.impdef_nop)
173 gicv3_ifc->setISA(
this);
174 gicv3_ifc->setThreadContext(
tc);
234 bool sec_el2 = scr.eel2 &&
release->
has(ArmExtension::FEAT_SEL2);
380 int lower = map.first, upper = map.second;
386 DPRINTF(MiscRegs,
"Reading MiscReg %s with set res0 bits: %#x\n",
390 DPRINTF(MiscRegs,
"Reading MiscReg %s with clear res1 bits: %#x\n",
406 cpsr.j =
pc.jazelle() ? 1 : 0;
407 cpsr.t =
pc.thumb() ? 1 : 0;
415 warn(
"Unimplemented system register %s read.\n",
418 panic(
"Unimplemented system register %s read.\n",
427 const uint32_t ones = (uint32_t)(-1);
431 cpacrMask.cp10 = ones;
432 cpacrMask.cp11 = ones;
433 cpacrMask.asedis = ones;
442 if (!nsacr.cp10) cpacrMask.cp10 = 0;
443 if (!nsacr.cp11) cpacrMask.cp11 = 0;
448 DPRINTF(MiscRegs,
"Reading misc reg %s: %#x\n",
467 warn_once(
"The clidr register always reports 0 caches.\n");
468 warn_once(
"clidr LoUIS field of 0b001 to match current "
469 "ARM implementations.\n");
472 warn_once(
"The ccsidr register isn't implemented and "
473 "always reads as 0.\n");
476 warn(
"Not doing anything for miscreg ACTLR\n");
486 panic(
"shouldn't be reading this register seperately\n");
493 const uint32_t ones = (uint32_t)(-1);
495 fpscrMask.ioc = ones;
496 fpscrMask.dzc = ones;
497 fpscrMask.ofc = ones;
498 fpscrMask.ufc = ones;
499 fpscrMask.ixc = ones;
500 fpscrMask.idc = ones;
510 const uint32_t ones = (uint32_t)(-1);
512 fpscrMask.len = ones;
513 fpscrMask.fz16 = ones;
514 fpscrMask.stride = ones;
515 fpscrMask.rMode = ones;
518 fpscrMask.ahp = ones;
584 bool secure_lookup =
release->
has(ArmExtension::SECURITY) &&
586 if (!secure_lookup) {
639 int lower = map.first, upper = map.second;
645 DPRINTF(MiscRegs,
"Writing MiscReg %s (%d %d:%d) : %#x\n",
649 DPRINTF(MiscRegs,
"Writing MiscReg %s (%d %d) : %#x\n",
667 int old_mode = old_cpsr.mode;
669 if (cpsr.pan != old_cpsr.pan || cpsr.il != old_cpsr.il) {
673 DPRINTF(
Arm,
"Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
674 miscRegs[idx], cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
676 pc.nextThumb(cpsr.t);
677 pc.nextJazelle(cpsr.j);
678 pc.illegalExec(cpsr.il == 1);
697 if (old_mode != cpsr.mode) {
717 warn(
"Unimplemented system register %s write with %#x.\n",
720 panic(
"Unimplemented system register %s write with %#x.\n",
730 const uint32_t ones = (uint32_t)(-1);
734 cpacrMask.cp10 = ones;
735 cpacrMask.cp11 = ones;
736 cpacrMask.asedis = ones;
745 if (!nsacr.cp10) cpacrMask.cp10 = 0;
746 if (!nsacr.cp11) cpacrMask.cp11 = 0;
752 newVal |= old_val & ~cpacrMask;
753 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
759 const uint32_t ones = (uint32_t)(-1);
761 cpacrMask.tta = ones;
762 cpacrMask.fpen = ones;
764 cpacrMask.zen = ones;
767 cpacrMask.smen = ones;
770 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
777 const uint32_t ones = (uint32_t)(-1);
779 cptrMask.tcpac = ones;
784 cptrMask.zen = hcr.e2h ? ones : 0;
788 cptrMask.smen = hcr.e2h ? ones : 0;
790 cptrMask.fpen = hcr.e2h ? ones : 0;
793 cptrMask.res1_13_el2 = ones;
794 cptrMask.res1_7_0_el2 = ones;
796 cptrMask.res1_8_el2 = ones;
799 cptrMask.res1_12_el2 = ones;
801 cptrMask.res1_9_el2 = ones;
803 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
809 const uint32_t ones = (uint32_t)(-1);
811 cptrMask.tcpac = ones;
821 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
826 warn_once(
"The csselr register isn't implemented.\n");
830 warn(
"Calling DC ZVA! Not Implemeted! Expect WEIRD results\n");
838 const uint32_t ones = (uint32_t)(-1);
840 fpscrMask.ioc = ones;
841 fpscrMask.dzc = ones;
842 fpscrMask.ofc = ones;
843 fpscrMask.ufc = ones;
844 fpscrMask.ixc = ones;
845 fpscrMask.idc = ones;
851 newVal = (newVal & (uint32_t)fpscrMask) |
853 ~(uint32_t)fpscrMask);
859 const uint32_t ones = (uint32_t)(-1);
861 fpscrMask.len = ones;
862 fpscrMask.fz16 = ones;
863 fpscrMask.stride = ones;
864 fpscrMask.rMode = ones;
867 fpscrMask.ahp = ones;
868 newVal = (newVal & (uint32_t)fpscrMask) |
870 ~(uint32_t)fpscrMask);
899 const uint32_t fpexcMask = 0x60000000;
900 newVal = (newVal & fpexcMask) |
920 const uint32_t temp = (
val == 0xC5ACCE55)? 0x1 : 0x0;
922 r.oslk =
bits(temp,0);
951 r.udccdis =
v.udccdis;
985 DPRINTF(MiscRegs,
"Writing SCTLR: %#x\n", newVal);
997 SCTLR new_sctlr = newVal;
998 new_sctlr.nmfi = ((bool)sctlr.nmfi) &&
1041 warn(
"Not doing anything for write of miscreg ACTLR\n");
1056 newVal &= ~((uint32_t) hstrMask);
1063 secure_lookup =
release->
has(ArmExtension::SECURITY) &&
1065 if (!secure_lookup) {
1069 newVal = (newVal & ~
mask) | (oldValue &
mask);
1095 panic(
"Security Extensions required for ATS12NSOPR");
1100 panic(
"Security Extensions required for ATS12NSOPW");
1105 panic(
"Security Extensions required for ATS12NSOUR");
1111 panic(
"Security Extensions required for ATS12NSOUW");
1124 const uint32_t ones = (uint32_t)(-1);
1125 TTBCR ttbcrMask = 0;
1126 TTBCR ttbcrNew = newVal;
1131 ttbcrMask.pd0 = ones;
1132 ttbcrMask.pd1 = ones;
1134 ttbcrMask.epd0 = ones;
1135 ttbcrMask.irgn0 = ones;
1136 ttbcrMask.orgn0 = ones;
1137 ttbcrMask.sh0 = ones;
1138 ttbcrMask.ps = ones;
1139 ttbcrMask.a1 = ones;
1140 ttbcrMask.epd1 = ones;
1141 ttbcrMask.irgn1 = ones;
1142 ttbcrMask.orgn1 = ones;
1143 ttbcrMask.sh1 = ones;
1145 ttbcrMask.eae = ones;
1147 if (
release->
has(ArmExtension::LPAE) && ttbcrNew.eae) {
1148 newVal = newVal & ttbcrMask;
1150 newVal = (newVal & ttbcrMask) | (ttbcr & (~ttbcrMask));
1164 uint64_t ttbrMask =
mask(63,56) |
mask(47,40);
1165 newVal = (newVal & (~ttbrMask));
1214 cpsr.daif = (uint8_t) ((CPSR) newVal).
daif;
1231 cpsr.sp = (uint8_t) ((CPSR) newVal).
sp;
1239 cpsr.el = (uint8_t) ((CPSR) newVal).
el;
1250 cpsr.pan = (uint8_t) ((CPSR) newVal).
pan;
1261 cpsr.uao = (uint8_t) ((CPSR) newVal).
uao;
1307 warn(
"miscreg L2CTLR (%s) written with %#x. ignored...\n",
1366 return *
timer.get();
1370 if (!generic_timer) {
1371 panic(
"Trying to get a generic timer from a system that hasn't "
1372 "been configured to use a generic timer.\n");
1378 return *
timer.get();
1388 panic_if(!gicv3_ifc,
"The system does not have a GICv3 irq controller\n");
1453 "A ThreadContext is needed to determine the SVE vector length "
1454 "in full-system mode");
1471 static_cast<unsigned>(
1477 }
else if (
release->
has(ArmExtension::SECURITY)) {
1480 static_cast<unsigned>(
1486 return (
len + 1) * 128;
1497 "A ThreadContext is needed to determine the SME vector length "
1498 "in full-system mode");
1515 static_cast<unsigned>(
1521 }
else if (
release->
has(ArmExtension::SECURITY)) {
1524 static_cast<unsigned>(
1532 static const unsigned LUT[16] = {0, 1, 1, 3, 3, 3, 3, 7,
1533 7, 7, 7, 7, 7, 7, 7, 15};
1536 return (
len + 1) * 128;
1542 DPRINTF(Checkpoint,
"Serializing Arm Misc Registers\n");
1549 DPRINTF(Checkpoint,
"Unserializing Arm Misc Registers\n");
1555 warn(
"Checkpoint value for register %s does not match "
1556 "current configuration (checkpointed: %#x, current: %#x)",
1577 warn_once(
"Doing AT (address translation) in functional mode! Fix Me!\n");
1579 auto req = std::make_shared<Request>(
1584 req,
tc,
mode, tran_type);
1588 Addr paddr = req->getPaddr();
1590 uint64_t attr1 =
attr >> 56;
1591 if (!attr1 || attr1 ==0x44) {
1593 attr &= ~ uint64_t(0x80);
1595 par = (paddr &
mask(47, 12)) |
attr;
1597 "MISCREG: Translated addr %#x: PAR_EL1: %#xx\n",
1606 par.fst = fsr.status;
1607 par.ptw = (arm_fault->
iss() >> 7) & 0x1;
1608 par.s = arm_fault->
isStage2() ? 1 : 0;
1611 "MISCREG: Translated addr %#x fault fsr %#x: PAR: %#x\n",
1628 warn_once(
"Doing AT (address translation) in functional mode! Fix Me!\n");
1630 auto req = std::make_shared<Request>(
1635 req,
tc,
mode, tran_type);
1639 Addr paddr = req->getPaddr();
1643 uint8_t max_paddr_bit = 0;
1653 par = (paddr &
mask(max_paddr_bit, 12)) |
1657 "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
1666 par.lpae = fsr.lpae;
1667 par.ptw = (arm_fault->
iss() >> 7) & 0x1;
1668 par.s = arm_fault->
isStage2() ? 1 : 0;
1672 par.fst = fsr.status;
1675 par.fs4_0 = fsr.fsLow | (fsr.fsHigh << 5);
1679 "MISCREG: Translated addr 0x%08x fault fsr %#x: PAR: 0x%08x\n",
1689 Addr cacheBlockMask)
1694 DPRINTF(LLSC,
"%s: handling snoop for address: %#x locked: %d\n",
1702 Addr snoop_addr = pkt->
getAddr() & cacheBlockMask;
1704 DPRINTF(LLSC,
"%s: handling snoop for address: %#x locked addr: %#x\n",
1706 if (locked_addr == snoop_addr) {
1707 DPRINTF(LLSC,
"%s: address match, clearing lock and signaling sev\n",
1733 DPRINTF(LLSC,
"%s: Placing address %#x in monitor\n",
1742 DPRINTF(LLSC,
"%s: Placing address %#x in monitor\n",
1749 DPRINTF(LLSC,
"%s: handling snoop lock hit address: %#x\n",
1758 DPRINTF(LLSC,
"%s: handling snoop lock hit address: %#x\n",
1768 Addr cacheBlockMask)
1773 DPRINTF(LLSC,
"Handling locked write for address %#x in monitor.\n",
1779 if (!lock_flag || (req->getPaddr() & cacheBlockMask) != lock_addr) {
1782 req->setExtraData(0);
1784 DPRINTF(LLSC,
"clearing lock flag in handle locked write\n",
1790 int stCondFailures = xc->readStCondFailures();
1792 xc->setStCondFailures(stCondFailures);
1793 if (stCondFailures % 100000 == 0) {
1794 warn(
"context %d: %d consecutive "
1795 "store conditional failures\n",
1813 Addr cacheBlockMask)
1825 DPRINTF(LLSC,
"Clearing lock and signaling sev\n");
1839 DPRINTF(LLSC,
"Clearing lock and signaling sev\n");
void setMiscReg(RegIndex, RegVal val) override
@ funcRequestorId
This requestor id is used for functional requests that don't come from a particular device.
virtual void setISA(ISA *isa)
uint8_t physAddrRange() const
Returns the supported physical address range in bits.
void addressTranslation64(MMU::ArmTranslationType tran_type, BaseMMU::Mode mode, Request::Flags flags, RegVal val)
void setenableTDETGE(HCR hcr, HDCR mdcr)
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
void init(ThreadContext *tc)
DummyISADevice dummyDevice
Dummy device for to handle non-existing ISA devices.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
@ MISCREG_CNTHVS_TVAL_EL2
constexpr decltype(nullptr) NoFault
virtual System * getSystemPtr()=0
ExceptionLevel currEL() const
Returns the current Exception Level (EL) of the ISA object.
virtual RegVal readMiscReg(int misc_reg)=0
Read a system register belonging to this device.
virtual void setMiscReg(int misc_reg, RegVal val)=0
Sets a miscellaneous register, handling any architectural side effects due to writing that register.
unsigned getCurSveVecLenInBits() const
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8)
std::unique_ptr< BaseISADevice > gicv3CpuInterface
Gicv3CPUInterface * getCPUInterface(int cpu_id) const
@ MISCREG_CNTHPS_TVAL_EL2
@ MISCREG_CNTHVS_CVAL_EL2
Backing store for matrices.
BaseInterrupts * getInterruptController(ThreadID tid)
virtual RegVal getReg(const RegId ®) const
void takeOverFrom(ThreadContext *new_tc, ThreadContext *old_tc) override
void handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask) override
static bool lockedWriteHandler(ThreadContext *tc, XC *xc, const RequestPtr &req, Addr cacheBlockMask)
void updateRegMap(CPSR cpsr)
const ArmRelease * release
This could be either a FS or a SE release.
virtual BaseMMU * getMMUPtr()=0
virtual const PCStateBase & pcState() const =0
std::unique_ptr< BaseISADevice > timer
void updateOSLock(RegVal val)
unsigned smeVL() const
Returns the SME vector length at reset, in quadwords.
bool haveLargeAsid64() const
Returns true if ASID is 16 bits in AArch64 (ARMv8)
@ MISCREG_ID_AA64AFR1_EL1
const char *const miscRegName[]
virtual ContextID contextId() const =0
void copyRegsFrom(ThreadContext *src) override
@ MISCREG_ID_AA64MMFR0_EL1
static ExceptionLevel opModeToEL(OperatingMode mode)
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 ...
static const uint32_t CpsrMaskQ
void serialize(CheckpointOut &cp) const override
Serialize an object.
#define SERIALIZE_MAPPING(member, names, size)
virtual RegVal readMiscReg(int misc_reg)=0
Reads a miscellaneous register, handling any architectural side effects due to reading that register.
static const uint32_t FpscrQcMask
unsigned sveVL
SVE vector length in quadwords.
@ MISCREG_ID_AA64DFR1_EL1
static const uint32_t FpscrExcMask
void updateDBGBCR(int index, DBGBCR val)
BaseGic * getGIC() const
Get a pointer to the system's GIC.
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
void handleLockedRead(const RequestPtr &req) override
virtual uint32_t iss() const =0
@ FloatRegClass
Floating-point register.
chain reset(uint64_t res_val) const
bool has(ArmExtension ext) const
void setMDBGen(RegVal val)
virtual void setHtmCheckpointPtr(BaseHTMCheckpointPtr cpt)=0
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
void handleLockedSnoopHit() override
@ MISCREG_ID_AA64PFR1_EL1
void setMDSCRvals(RegVal val)
ThreadContext is the external interface to all thread state for anything outside of the CPU.
@ MISCREG_ID_AA64MMFR2_EL1
virtual std::string name() const
std::shared_ptr< FaultBase > Fault
@ MISCREG_CONTEXTIDR_EL12
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
std::vector< struct MiscRegLUTEntry > lookUpMiscReg(NUM_MISCREGS)
virtual InstDecoder * getDecoderPtr()=0
void globalClearExclusive() override
@ MISCREG_ID_AA64AFR0_EL1
std::pair< int, int > getMiscIndices(int misc_reg) const
void unserialize(CheckpointIn &cp) override
Unserialize an object.
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
void update(ThreadContext *tc)
std::shared_ptr< Request > RequestPtr
void addressTranslation(MMU::ArmTranslationType tran_type, BaseMMU::Mode mode, Request::Flags flags, RegVal val)
@ MISCREG_PMXEVTYPER_PMCCFILTR
virtual ThreadContext * tcBase() const =0
Returns a pointer to the ThreadContext.
@ MISCREG_ICC_IGRPEN1_EL3
bool EL2Enabled(ThreadContext *tc)
void setMiscRegReset(RegIndex, RegVal val)
bool handleLockedWrite(const RequestPtr &req, Addr cacheBlockMask) override
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
BaseISADevice & getGICv3CPUInterface()
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
void startup() override
startup() is the final initialization call before simulation.
@ MISCREG_ID_AA64DFR0_EL1
BaseISADevice & getGenericTimer()
RegVal readMiscReg(RegIndex idx) override
@ MISCREG_ID_AA64MMFR1_EL1
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
constexpr RegClass floatRegClass
constexpr RegClass flatIntRegClass
bool isSecure(ThreadContext *tc)
void initializeMiscRegMetadata()
unsigned getCurSmeVecLenInBits() const
@ MISCREG_ID_AA64ISAR1_EL1
virtual FSR getFsr(ThreadContext *tc) const
constexpr RegClass vecRegClass
void setupThreadContext()
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
constexpr RegClass miscRegClass
virtual void pcStateNoRecord(const PCStateBase &val)=0
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual void setThreadContext(ThreadContext *tc)
constexpr RegClass vecElemClass
unsigned sveVL() const
Returns the SVE vector length at reset, in quadwords.
void setMiscRegNoEffect(RegIndex idx, RegVal val) override
const MiscRegLUTEntryInitializer InitReg(uint32_t reg)
virtual void startup()
startup() is the final initialization call before simulation.
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 ...
RegVal readMiscRegReset(RegIndex) const
RegVal miscRegs[NUM_MISCREGS]
static void lockedSnoopHandler(ThreadContext *tc, XC *xc, PacketPtr pkt, Addr cacheBlockMask)
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn't already a pending event.
unsigned smeVL
SME vector length in quadwords.
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
The ExecContext is an abstract base class the provides the interface used by the ISA to manipulate th...
const ArmRelease * releaseFS() const
GenericTimer * getGenericTimer() const
Get a pointer to the system's generic timer model.
@ MISCREG_CNTHPS_CVAL_EL2
virtual void setMiscReg(int misc_reg, RegVal val)=0
Write to a system register belonging to this device.
std::ostream CheckpointOut
virtual BaseCPU * getCpuPtr()=0
virtual int threadId() const =0
int redirectRegVHE(int misc_reg)
Returns the enconcing equivalent when VHE is implemented and HCR_EL2.E2H is enabled and executing at ...
void updateDBGWCR(int index, DBGWCR val)
constexpr RegClass vecPredRegClass
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
@ MISCREG_ID_AA64PFR0_EL1
void setDebugMask(bool mask)
RegVal readMiscRegNoEffect(RegIndex idx) const override
virtual bool isStage2() const
constexpr RegClass matRegClass
constexpr char FloatRegClassName[]
#define UNSERIALIZE_MAPPING(member, names, size)
virtual CheckerCPU * getCheckerCpuPtr()=0
constexpr RegClass ccRegClass
void preUnflattenMiscReg()
@ MISCREG_ID_AA64ISAR0_EL1
RegVal readMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is either returing the value of MPIDR_EL1 (by calling getMPIDR),...
bool inSecureState() const
Return true if the PE is in Secure state.
int unflattenMiscReg(int reg)
bool isInvalidate() const
#define panic(...)
This implements a cprintf based panic() function.
Base class for devices that use the MiscReg interfaces.
int flattenMiscIndex(int reg) const
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
virtual void setReg(const RegId ®, RegVal val)
Generated on Sun Jul 30 2023 01:56:46 for gem5 by doxygen 1.8.17