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"
76using namespace misc_regs;
87 _decoderFlavor(
p.decoderFlavor), pmu(
p.pmu), impdefAsNop(
p.impdef_nop)
178 gicv3_ifc->setISA(
this);
179 gicv3_ifc->setThreadContext(
tc);
239 bool sec_el2 = scr.eel2 &&
release->
has(ArmExtension::FEAT_SEL2);
393 int lower = map.first, upper = map.second;
399 DPRINTF(MiscRegs,
"Reading MiscReg %s with set res0 bits: %#x\n",
403 DPRINTF(MiscRegs,
"Reading MiscReg %s with clear res1 bits: %#x\n",
419 cpsr.t =
pc.thumb() ? 1 : 0;
427 warn(
"Unimplemented system register %s read.\n",
430 panic(
"Unimplemented system register %s read.\n",
439 const uint32_t ones = (uint32_t)(-1);
443 cpacrMask.cp10 = ones;
444 cpacrMask.cp11 = ones;
445 cpacrMask.asedis = ones;
454 if (!nsacr.cp10) cpacrMask.cp10 = 0;
455 if (!nsacr.cp11) cpacrMask.cp11 = 0;
460 DPRINTF(MiscRegs,
"Reading misc reg %s: %#x\n",
479 warn_once(
"The clidr register always reports 0 caches.\n");
480 warn_once(
"clidr LoUIS field of 0b001 to match current "
481 "ARM implementations.\n");
484 warn_once(
"The ccsidr register isn't implemented and "
485 "always reads as 0.\n");
488 warn(
"Not doing anything for miscreg ACTLR\n");
498 panic(
"shouldn't be reading this register seperately\n");
505 const uint32_t ones = (uint32_t)(-1);
507 fpscrMask.ioc = ones;
508 fpscrMask.dzc = ones;
509 fpscrMask.ofc = ones;
510 fpscrMask.ufc = ones;
511 fpscrMask.ixc = ones;
512 fpscrMask.idc = ones;
522 const uint32_t ones = (uint32_t)(-1);
524 fpscrMask.len = ones;
525 fpscrMask.fz16 = ones;
526 fpscrMask.stride = ones;
527 fpscrMask.rMode = ones;
530 fpscrMask.ahp = ones;
596 bool secure_lookup =
release->
has(ArmExtension::SECURITY) &&
598 if (!secure_lookup) {
668 int lower = map.first, upper = map.second;
670 auto v = (
val & ~reg.wi()) |
reg.rao();
674 DPRINTF(MiscRegs,
"Writing MiscReg %s (%d %d:%d) : %#x\n",
678 DPRINTF(MiscRegs,
"Writing MiscReg %s (%d %d) : %#x\n",
696 int old_mode = old_cpsr.mode;
698 if (cpsr.pan != old_cpsr.pan || cpsr.il != old_cpsr.il) {
702 DPRINTF(Arm,
"Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
703 miscRegs[idx], cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
705 pc.nextThumb(cpsr.t);
706 pc.illegalExec(cpsr.il == 1);
725 if (old_mode != cpsr.mode) {
745 warn(
"Unimplemented system register %s write with %#x.\n",
748 panic(
"Unimplemented system register %s write with %#x.\n",
758 const uint32_t ones = (uint32_t)(-1);
762 cpacrMask.cp10 = ones;
763 cpacrMask.cp11 = ones;
764 cpacrMask.asedis = ones;
773 if (!nsacr.cp10) cpacrMask.cp10 = 0;
774 if (!nsacr.cp11) cpacrMask.cp11 = 0;
780 newVal |= old_val & ~cpacrMask;
781 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
787 const uint32_t ones = (uint32_t)(-1);
789 cpacrMask.tta = ones;
790 cpacrMask.fpen = ones;
792 cpacrMask.zen = ones;
795 cpacrMask.smen = ones;
798 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
805 const uint32_t ones = (uint32_t)(-1);
807 cptrMask.tcpac = ones;
812 cptrMask.zen = hcr.e2h ? ones : 0;
816 cptrMask.smen = hcr.e2h ? ones : 0;
818 cptrMask.fpen = hcr.e2h ? ones : 0;
821 cptrMask.res1_13_el2 = ones;
822 cptrMask.res1_7_0_el2 = ones;
824 cptrMask.res1_8_el2 = ones;
827 cptrMask.res1_12_el2 = ones;
829 cptrMask.res1_9_el2 = ones;
831 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
837 const uint32_t ones = (uint32_t)(-1);
839 cptrMask.tcpac = ones;
849 DPRINTF(MiscRegs,
"Writing misc reg %s: %#x\n",
854 warn_once(
"The csselr register isn't implemented.\n");
858 warn(
"Calling DC ZVA! Not Implemeted! Expect WEIRD results\n");
866 const uint32_t ones = (uint32_t)(-1);
868 fpscrMask.ioc = ones;
869 fpscrMask.dzc = ones;
870 fpscrMask.ofc = ones;
871 fpscrMask.ufc = ones;
872 fpscrMask.ixc = ones;
873 fpscrMask.idc = ones;
879 newVal = (newVal & (uint32_t)fpscrMask) |
881 ~(uint32_t)fpscrMask);
887 const uint32_t ones = (uint32_t)(-1);
889 fpscrMask.len = ones;
890 fpscrMask.fz16 = ones;
891 fpscrMask.stride = ones;
892 fpscrMask.rMode = ones;
895 fpscrMask.ahp = ones;
896 newVal = (newVal & (uint32_t)fpscrMask) |
898 ~(uint32_t)fpscrMask);
927 const uint32_t fpexcMask = 0x60000000;
928 newVal = (newVal & fpexcMask) |
948 const uint32_t temp = (
val == 0xC5ACCE55)? 0x1 : 0x0;
950 r.oslk =
bits(temp,0);
979 r.udccdis =
v.udccdis;
1013 DPRINTF(MiscRegs,
"Writing SCTLR: %#x\n", newVal);
1025 SCTLR new_sctlr = newVal;
1026 new_sctlr.nmfi = ((bool)sctlr.nmfi) &&
1069 warn(
"Not doing anything for write of miscreg ACTLR\n");
1084 newVal &= ~((uint32_t) hstrMask);
1091 secure_lookup =
release->
has(ArmExtension::SECURITY) &&
1093 if (!secure_lookup) {
1097 newVal = (newVal & ~mask) | (oldValue &
mask);
1123 panic(
"Security Extensions required for ATS12NSOPR");
1128 panic(
"Security Extensions required for ATS12NSOPW");
1133 panic(
"Security Extensions required for ATS12NSOUR");
1139 panic(
"Security Extensions required for ATS12NSOUW");
1152 const uint32_t ones = (uint32_t)(-1);
1153 TTBCR ttbcrMask = 0;
1154 TTBCR ttbcrNew = newVal;
1159 ttbcrMask.pd0 = ones;
1160 ttbcrMask.pd1 = ones;
1162 ttbcrMask.epd0 = ones;
1163 ttbcrMask.irgn0 = ones;
1164 ttbcrMask.orgn0 = ones;
1165 ttbcrMask.sh0 = ones;
1166 ttbcrMask.ps = ones;
1167 ttbcrMask.a1 = ones;
1168 ttbcrMask.epd1 = ones;
1169 ttbcrMask.irgn1 = ones;
1170 ttbcrMask.orgn1 = ones;
1171 ttbcrMask.sh1 = ones;
1173 ttbcrMask.eae = ones;
1175 if (
release->
has(ArmExtension::LPAE) && ttbcrNew.eae) {
1176 newVal = newVal & ttbcrMask;
1178 newVal = (newVal & ttbcrMask) | (ttbcr & (~ttbcrMask));
1192 uint64_t ttbrMask =
mask(63,56) |
mask(47,40);
1193 newVal = (newVal & (~ttbrMask));
1242 cpsr.daif = (uint8_t) ((CPSR) newVal).
daif;
1259 cpsr.sp = (uint8_t) ((CPSR) newVal).
sp;
1267 cpsr.el = (uint8_t) ((CPSR) newVal).
el;
1278 cpsr.pan = (uint8_t) ((CPSR) newVal).
pan;
1289 cpsr.uao = (uint8_t) ((CPSR) newVal).
uao;
1335 warn(
"miscreg L2CTLR (%s) written with %#x. ignored...\n",
1394 return *
timer.get();
1398 if (!generic_timer) {
1399 panic(
"Trying to get a generic timer from a system that hasn't "
1400 "been configured to use a generic timer.\n");
1406 return *
timer.get();
1416 panic_if(!gicv3_ifc,
"The system does not have a GICv3 irq controller\n");
1481 "A ThreadContext is needed to determine the SVE vector length "
1482 "in full-system mode");
1499 static_cast<unsigned>(
1505 }
else if (
release->
has(ArmExtension::SECURITY)) {
1508 static_cast<unsigned>(
1514 return (
len + 1) * 128;
1525 "A ThreadContext is needed to determine the SME vector length "
1526 "in full-system mode");
1543 static_cast<unsigned>(
1549 }
else if (
release->
has(ArmExtension::SECURITY)) {
1552 static_cast<unsigned>(
1560 static const unsigned LUT[16] = {0, 1, 1, 3, 3, 3, 3, 7,
1561 7, 7, 7, 7, 7, 7, 7, 15};
1564 return (
len + 1) * 128;
1572 DPRINTF(Checkpoint,
"Serializing Arm Misc Registers\n");
1579 DPRINTF(Checkpoint,
"Unserializing Arm Misc Registers\n");
1585 warn(
"Checkpoint value for register %s does not match "
1586 "current configuration (checkpointed: %#x, current: %#x)",
1607 warn_once(
"Doing AT (address translation) in functional mode! Fix Me!\n");
1609 auto req = std::make_shared<Request>(
1614 req,
tc,
mode, tran_type);
1618 Addr paddr = req->getPaddr();
1620 uint64_t attr1 =
attr >> 56;
1621 if (!attr1 || attr1 ==0x44) {
1623 attr &= ~ uint64_t(0x80);
1625 par = (paddr &
mask(47, 12)) |
attr;
1627 "MISCREG: Translated addr %#x: PAR_EL1: %#xx\n",
1636 par.fst = fsr.status;
1637 par.ptw = (arm_fault->
iss() >> 7) & 0x1;
1638 par.s = arm_fault->
isStage2() ? 1 : 0;
1641 "MISCREG: Translated addr %#x fault fsr %#x: PAR: %#x\n",
1658 warn_once(
"Doing AT (address translation) in functional mode! Fix Me!\n");
1660 auto req = std::make_shared<Request>(
1665 req,
tc,
mode, tran_type);
1669 Addr paddr = req->getPaddr();
1673 uint8_t max_paddr_bit = 0;
1683 par = (paddr &
mask(max_paddr_bit, 12)) |
1687 "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
1696 par.lpae = fsr.lpae;
1697 par.ptw = (arm_fault->
iss() >> 7) & 0x1;
1698 par.s = arm_fault->
isStage2() ? 1 : 0;
1702 par.fst = fsr.status;
1705 par.fs4_0 = fsr.fsLow | (fsr.fsHigh << 5);
1709 "MISCREG: Translated addr 0x%08x fault fsr %#x: PAR: 0x%08x\n",
1719 Addr cacheBlockMask)
1724 DPRINTF(LLSC,
"%s: handling snoop for address: %#x locked: %d\n",
1732 Addr snoop_addr = pkt->
getAddr() & cacheBlockMask;
1734 DPRINTF(LLSC,
"%s: handling snoop for address: %#x locked addr: %#x\n",
1736 if (locked_addr == snoop_addr) {
1737 DPRINTF(LLSC,
"%s: address match, clearing lock and signaling sev\n",
1763 DPRINTF(LLSC,
"%s: Placing address %#x in monitor\n",
1772 DPRINTF(LLSC,
"%s: Placing address %#x in monitor\n",
1779 DPRINTF(LLSC,
"%s: handling snoop lock hit address: %#x\n",
1788 DPRINTF(LLSC,
"%s: handling snoop lock hit address: %#x\n",
1798 Addr cacheBlockMask)
1803 DPRINTF(LLSC,
"Handling locked write for address %#x in monitor.\n",
1809 if (!lock_flag || (req->getPaddr() & cacheBlockMask) != lock_addr) {
1812 req->setExtraData(0);
1814 DPRINTF(LLSC,
"clearing lock flag in handle locked write\n",
1820 int stCondFailures = xc->readStCondFailures();
1822 xc->setStCondFailures(stCondFailures);
1823 if (stCondFailures % 100000 == 0) {
1824 warn(
"context %d: %d consecutive "
1825 "store conditional failures\n",
1843 Addr cacheBlockMask)
1855 DPRINTF(LLSC,
"Clearing lock and signaling sev\n");
1869 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
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 void setISA(ISA *isa)
virtual void setThreadContext(ThreadContext *tc)
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
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 addressTranslation64(MMU::ArmTranslationType tran_type, BaseMMU::Mode mode, Request::Flags flags, RegVal val)
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
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
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 setenableTDETGE(HCR hcr, HDCR mdcr)
void init(ThreadContext *tc)
void updateOSLock(RegVal val)
void setMDSCRvals(RegVal val)
void updateDBGBCR(int index, DBGBCR val)
void updateDBGWCR(int index, DBGWCR val)
void setMDBGen(RegVal val)
void setDebugMask(bool mask)
bool has(ArmExtension ext) const
GenericTimer * getGenericTimer() const
Get a pointer to the system's generic timer model.
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8)
ArmISA::ExceptionLevel highestEL() const
Returns the highest implemented exception level.
unsigned smeVL() const
Returns the SME vector length at reset, in quadwords.
BaseGic * getGIC() const
Get a pointer to the system's GIC.
uint8_t physAddrRange() const
Returns the supported physical address range in bits.
bool haveLargeAsid64() const
Returns true if ASID is 16 bits in AArch64 (ARMv8)
const ArmRelease * releaseFS() const
unsigned sveVL() const
Returns the SVE vector length at reset, in quadwords.
BaseInterrupts * getInterruptController(ThreadID tid)
void serialize(CheckpointOut &cp) const override
Serialize an object.
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
Backing store for matrices.
virtual std::string name() const
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
bool isInvalidate() const
@ funcRequestorId
This requestor id is used for functional requests that don't come from a particular device.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual void setHtmCheckpointPtr(BaseHTMCheckpointPtr cpt)=0
virtual void pcStateNoRecord(const PCStateBase &val)=0
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual RegVal getReg(const RegId ®) const
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
virtual System * getSystemPtr()=0
virtual BaseCPU * getCpuPtr()=0
virtual void setReg(const RegId ®, RegVal val)
virtual CheckerCPU * getCheckerCpuPtr()=0
virtual InstDecoder * getDecoderPtr()=0
virtual const PCStateBase & pcState() const =0
virtual int threadId() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual BaseMMU * getMMUPtr()=0
virtual ContextID contextId() const =0
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
This module implements the global system counter and the local per-CPU architected timers as specifie...
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...
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)
constexpr RegClass flatIntRegClass
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
static const uint32_t CpsrMaskQ
bool EL2Enabled(ThreadContext *tc)
void preUnflattenMiscReg()
constexpr RegClass vecPredRegClass
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
int unflattenMiscReg(int reg)
static bool lockedWriteHandler(ThreadContext *tc, XC *xc, const RequestPtr &req, Addr cacheBlockMask)
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 - Pranith Kumar Copyright (c) 2020 Inria 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)