arch-arm: Define ESR.ISS field as a SubBitUnion
This will make it easier for an ArmFault to setup the ISS field of the syndrome register Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Change-Id: I970dfea474f2de0a696bef27712bc42daed9f1a0 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/57489 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2014, 2016-2019 ARM Limited
|
||||
* Copyright (c) 2010, 2012-2014, 2016-2019, 2022 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -397,42 +397,41 @@ ArmFault::getFaultAddrReg64() const
|
||||
void
|
||||
ArmFault::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg)
|
||||
{
|
||||
uint32_t value;
|
||||
ESR esr = 0;
|
||||
uint32_t exc_class = (uint32_t) ec(tc);
|
||||
uint32_t issVal = iss();
|
||||
uint32_t iss_val = iss();
|
||||
|
||||
assert(!from64 || ArmSystem::highestELIs64(tc));
|
||||
|
||||
value = exc_class << 26;
|
||||
esr.ec = exc_class;
|
||||
|
||||
// HSR.IL not valid for Prefetch Aborts (0x20, 0x21) and Data Aborts (0x24,
|
||||
// 0x25) for which the ISS information is not valid (ARMv7).
|
||||
// @todo: ARMv8 revises AArch32 functionality: when HSR.IL is not
|
||||
// valid it is treated as RES1.
|
||||
if (to64) {
|
||||
value |= 1 << 25;
|
||||
esr.il = 1;
|
||||
} else if ((bits(exc_class, 5, 3) != 4) ||
|
||||
(bits(exc_class, 2) && bits(issVal, 24))) {
|
||||
(bits(exc_class, 2) && bits(iss_val, 24))) {
|
||||
if (!machInst.thumb || machInst.bigThumb)
|
||||
value |= 1 << 25;
|
||||
esr.il = 1;
|
||||
}
|
||||
// Condition code valid for EC[5:4] nonzero
|
||||
if (!from64 && ((bits(exc_class, 5, 4) == 0) &&
|
||||
(bits(exc_class, 3, 0) != 0))) {
|
||||
|
||||
if (!machInst.thumb) {
|
||||
uint32_t cond;
|
||||
ConditionCode condCode = (ConditionCode) (uint32_t) machInst.condCode;
|
||||
ConditionCode cond_code = (ConditionCode) (uint32_t) machInst.condCode;
|
||||
// If its on unconditional instruction report with a cond code of
|
||||
// 0xE, ie the unconditional code
|
||||
cond = (condCode == COND_UC) ? COND_AL : condCode;
|
||||
value |= cond << 20;
|
||||
value |= 1 << 24;
|
||||
esr.cond_iss.cv = 1;
|
||||
esr.cond_iss.cond = (cond_code == COND_UC) ? COND_AL : cond_code;
|
||||
}
|
||||
value |= bits(issVal, 19, 0);
|
||||
esr.cond_iss.iss = bits(iss_val, 19, 0);
|
||||
} else {
|
||||
value |= issVal;
|
||||
esr.iss = iss_val;
|
||||
}
|
||||
tc->setMiscReg(syndrome_reg, value);
|
||||
tc->setMiscReg(syndrome_reg, esr);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1249,18 +1248,6 @@ AbortFault<T>::annotate(ArmFault::AnnotationIDs id, uint64_t val)
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
uint32_t
|
||||
AbortFault<T>::iss() const
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = srcEncoded & 0x3F;
|
||||
val |= write << 6;
|
||||
val |= s1ptw << 7;
|
||||
return (val);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
AbortFault<T>::isMMUFault() const
|
||||
@@ -1311,6 +1298,18 @@ PrefetchAbort::ec(ThreadContext *tc) const
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PrefetchAbort::iss() const
|
||||
{
|
||||
ESR esr = 0;
|
||||
auto& iss = esr.instruction_abort_iss;
|
||||
|
||||
iss.ifsc = srcEncoded & 0x3F;
|
||||
iss.s1ptw = s1ptw;
|
||||
|
||||
return iss;
|
||||
}
|
||||
|
||||
bool
|
||||
PrefetchAbort::routeToMonitor(ThreadContext *tc) const
|
||||
{
|
||||
@@ -1406,28 +1405,29 @@ DataAbort::routeToHyp(ThreadContext *tc) const
|
||||
uint32_t
|
||||
DataAbort::iss() const
|
||||
{
|
||||
uint32_t val;
|
||||
ESR esr = 0;
|
||||
auto& iss = esr.data_abort_iss;
|
||||
|
||||
// Add on the data abort specific fields to the generic abort ISS value
|
||||
val = AbortFault<DataAbort>::iss();
|
||||
|
||||
val |= cm << 8;
|
||||
iss.dfsc = srcEncoded & 0x3F;
|
||||
iss.wnr = write;
|
||||
iss.s1ptw = s1ptw;
|
||||
iss.cm = cm;
|
||||
|
||||
// ISS is valid if not caused by a stage 1 page table walk, and when taken
|
||||
// to AArch64 only when directed to EL2
|
||||
if (!s1ptw && stage2 && (!to64 || toEL == EL2)) {
|
||||
val |= isv << 24;
|
||||
iss.isv = isv;
|
||||
if (isv) {
|
||||
val |= sas << 22;
|
||||
val |= sse << 21;
|
||||
val |= srt << 16;
|
||||
iss.sas = sas;
|
||||
iss.sse = sse;
|
||||
iss.srt = srt;
|
||||
// AArch64 only. These assignments are safe on AArch32 as well
|
||||
// because these vars are initialized to false
|
||||
val |= sf << 15;
|
||||
val |= ar << 14;
|
||||
iss.sf = sf;
|
||||
iss.ar = ar;
|
||||
}
|
||||
}
|
||||
return (val);
|
||||
return iss;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1692,14 +1692,11 @@ Watchpoint::Watchpoint(ExtMachInst _mach_inst, Addr _vaddr,
|
||||
uint32_t
|
||||
Watchpoint::iss() const
|
||||
{
|
||||
uint32_t iss = 0x0022;
|
||||
// NV
|
||||
// if (toEL == EL2)
|
||||
// iss |= 0x02000;
|
||||
if (cm)
|
||||
iss |= 0x00100;
|
||||
if (write)
|
||||
iss |= 0x00040;
|
||||
ESR esr = 0;
|
||||
auto& iss = esr.watchpoint_iss;
|
||||
iss.dfsc = 0b100010;
|
||||
iss.cm = cm;
|
||||
iss.wnr = write;
|
||||
return iss;
|
||||
}
|
||||
|
||||
@@ -1778,21 +1775,17 @@ SoftwareStepFault::ec(ThreadContext *tc) const
|
||||
uint32_t
|
||||
SoftwareStepFault::iss() const
|
||||
{
|
||||
uint32_t iss= 0x0022;
|
||||
if (stepped) {
|
||||
iss |= 0x1000000;
|
||||
}
|
||||
|
||||
if (isldx) {
|
||||
iss |= 0x40;
|
||||
}
|
||||
|
||||
ESR esr = 0;
|
||||
auto& iss = esr.software_step_iss;
|
||||
iss.ifsc = 0b100010;
|
||||
iss.isv = stepped;
|
||||
iss.ex = isldx;
|
||||
return iss;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) {
|
||||
ArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
DPRINTF(Faults, "Invoking ArmSev Fault\n");
|
||||
if (!FullSystem)
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2013, 2016-2019 ARM Limited
|
||||
* Copyright (c) 2010, 2012-2013, 2016-2019, 2022 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -476,7 +476,6 @@ class AbortFault : public ArmFaultVals<T>
|
||||
FSR getFsr(ThreadContext *tc) const override;
|
||||
uint8_t getFaultStatusCode(ThreadContext *tc) const;
|
||||
bool abortDisable(ThreadContext *tc) override;
|
||||
uint32_t iss() const override;
|
||||
bool isStage2() const override { return stage2; }
|
||||
void annotate(ArmFault::AnnotationIDs id, uint64_t val) override;
|
||||
void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) override;
|
||||
@@ -501,6 +500,7 @@ class PrefetchAbort : public AbortFault<PrefetchAbort>
|
||||
// @todo: external aborts should be routed if SCR.EA == 1
|
||||
bool routeToMonitor(ThreadContext *tc) const override;
|
||||
bool routeToHyp(ThreadContext *tc) const override;
|
||||
uint32_t iss() const override;
|
||||
uint32_t vectorCatchFlag() const override { return 0x08000808; }
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2021 Arm Limited
|
||||
* Copyright (c) 2010-2022 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -669,7 +669,59 @@ namespace ArmISA
|
||||
BitUnion32(ESR)
|
||||
Bitfield<31, 26> ec;
|
||||
Bitfield<25> il;
|
||||
Bitfield<15, 0> imm16;
|
||||
Bitfield<24, 0> iss;
|
||||
|
||||
// Generic Condition ISS
|
||||
// Used by exception syndromes holding the condition code of
|
||||
// the trapped instruction. TODO: We should really have a
|
||||
// different SubBitUnion per exception type and avoid
|
||||
// such generic sub-fields
|
||||
SubBitUnion(cond_iss, 24, 0)
|
||||
Bitfield<24> cv;
|
||||
Bitfield<23, 20> cond;
|
||||
Bitfield<19, 0> iss;
|
||||
EndSubBitUnion(cond_iss)
|
||||
|
||||
// Data Abort ISS
|
||||
SubBitUnion(data_abort_iss, 24, 0)
|
||||
Bitfield<24> isv;
|
||||
Bitfield<23, 22> sas;
|
||||
Bitfield<21> sse;
|
||||
Bitfield<20, 16> srt;
|
||||
Bitfield<15> sf;
|
||||
Bitfield<14> ar;
|
||||
Bitfield<13> vncr;
|
||||
Bitfield<10> fnv;
|
||||
Bitfield<9> ea;
|
||||
Bitfield<8> cm;
|
||||
Bitfield<7> s1ptw;
|
||||
Bitfield<6> wnr;
|
||||
Bitfield<5, 0> dfsc;
|
||||
EndSubBitUnion(data_abort_iss)
|
||||
|
||||
// Instruction Abort ISS
|
||||
SubBitUnion(instruction_abort_iss, 24, 0)
|
||||
Bitfield<12, 11> set;
|
||||
Bitfield<10> fnv;
|
||||
Bitfield<9> ea;
|
||||
Bitfield<7> s1ptw;
|
||||
Bitfield<5, 0> ifsc;
|
||||
EndSubBitUnion(instruction_abort_iss)
|
||||
|
||||
// Software Step ISS
|
||||
SubBitUnion(software_step_iss, 24, 0)
|
||||
Bitfield<24> isv;
|
||||
Bitfield<6> ex;
|
||||
Bitfield<5, 0> ifsc;
|
||||
EndSubBitUnion(software_step_iss)
|
||||
|
||||
// Watchpoint ISS
|
||||
SubBitUnion(watchpoint_iss, 24, 0)
|
||||
Bitfield<13> vncr;
|
||||
Bitfield<8> cm;
|
||||
Bitfield<6> wnr;
|
||||
Bitfield<5, 0> dfsc;
|
||||
EndSubBitUnion(watchpoint_iss)
|
||||
EndBitUnion(ESR)
|
||||
|
||||
BitUnion32(CPTR)
|
||||
|
||||
Reference in New Issue
Block a user