ARM: Implement and update the DFSR and IFSR registers on faults.
This commit is contained in:
parent
4491170df6
commit
527b735cfc
4 changed files with 118 additions and 24 deletions
|
@ -50,29 +50,29 @@
|
|||
namespace ArmISA
|
||||
{
|
||||
|
||||
template<> ArmFaultBase::FaultVals ArmFault<Reset>::vals =
|
||||
template<> ArmFault::FaultVals ArmFaultVals<Reset>::vals =
|
||||
{"reset", 0x00, MODE_SVC, 0, 0, true, true};
|
||||
|
||||
template<> ArmFaultBase::FaultVals ArmFault<UndefinedInstruction>::vals =
|
||||
template<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals =
|
||||
{"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ;
|
||||
|
||||
template<> ArmFaultBase::FaultVals ArmFault<SupervisorCall>::vals =
|
||||
template<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals =
|
||||
{"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false};
|
||||
|
||||
template<> ArmFaultBase::FaultVals ArmFault<PrefetchAbort>::vals =
|
||||
template<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals =
|
||||
{"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false};
|
||||
|
||||
template<> ArmFaultBase::FaultVals ArmFault<DataAbort>::vals =
|
||||
template<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals =
|
||||
{"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false};
|
||||
|
||||
template<> ArmFaultBase::FaultVals ArmFault<Interrupt>::vals =
|
||||
template<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals =
|
||||
{"IRQ", 0x18, MODE_IRQ, 4, 4, true, false};
|
||||
|
||||
template<> ArmFaultBase::FaultVals ArmFault<FastInterrupt>::vals =
|
||||
template<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals =
|
||||
{"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true};
|
||||
|
||||
Addr
|
||||
ArmFaultBase::getVector(ThreadContext *tc)
|
||||
ArmFault::getVector(ThreadContext *tc)
|
||||
{
|
||||
// ARM ARM B1-3
|
||||
|
||||
|
@ -91,7 +91,7 @@ ArmFaultBase::getVector(ThreadContext *tc)
|
|||
#if FULL_SYSTEM
|
||||
|
||||
void
|
||||
ArmFaultBase::invoke(ThreadContext *tc)
|
||||
ArmFault::invoke(ThreadContext *tc)
|
||||
{
|
||||
// ARM ARM B1.6.3
|
||||
FaultBase::invoke(tc);
|
||||
|
@ -185,6 +185,24 @@ SupervisorCall::invoke(ThreadContext *tc)
|
|||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
template<class T>
|
||||
void
|
||||
AbortFault<T>::invoke(ThreadContext *tc)
|
||||
{
|
||||
ArmFaultVals<T>::invoke(tc);
|
||||
FSR fsr = 0;
|
||||
fsr.fsLow = bits(status, 3, 0);
|
||||
fsr.fsHigh = bits(status, 4);
|
||||
fsr.domain = domain;
|
||||
fsr.wnr = (write ? 1 : 0);
|
||||
fsr.ext = 0;
|
||||
tc->setMiscReg(T::FsrIndex, fsr);
|
||||
tc->setMiscReg(T::FarIndex, faultAddr);
|
||||
}
|
||||
|
||||
template void AbortFault<PrefetchAbort>::invoke(ThreadContext *tc);
|
||||
template void AbortFault<DataAbort>::invoke(ThreadContext *tc);
|
||||
|
||||
// return via SUBS pc, lr, xxx; rfe, movs, ldm
|
||||
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#ifndef __ARM_FAULTS_HH__
|
||||
#define __ARM_FAULTS_HH__
|
||||
|
||||
#include "arch/arm/miscregs.hh"
|
||||
#include "arch/arm/types.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
@ -55,12 +56,37 @@ namespace ArmISA
|
|||
{
|
||||
typedef const Addr FaultOffset;
|
||||
|
||||
class ArmFaultBase : public FaultBase
|
||||
class ArmFault : public FaultBase
|
||||
{
|
||||
protected:
|
||||
Addr getVector(ThreadContext *tc);
|
||||
|
||||
public:
|
||||
enum StatusEncoding
|
||||
{
|
||||
// Fault Status register encodings
|
||||
// ARM ARM B3.9.4
|
||||
AlignmentFault = 0x1,
|
||||
DebugEvent = 0x2,
|
||||
AccessFlag0 = 0x3,
|
||||
InstructionCacheMaintenance = 0x4,
|
||||
Translation0 = 0x5,
|
||||
AccessFlag1 = 0x6,
|
||||
Translation1 = 0x7,
|
||||
SynchronousExternalAbort0 = 0x8,
|
||||
Domain0 = 0x9,
|
||||
Domain1 = 0xb,
|
||||
TranslationTableWalk0 = 0xc,
|
||||
Permission0 = 0xd,
|
||||
SynchronousExternalAbort1 = 0xe,
|
||||
Permission1 = 0xf,
|
||||
AsynchronousExternalAbort = 0x16,
|
||||
MemoryAccessAsynchronousParityError = 0x18,
|
||||
MemoryAccessSynchronousParityError = 0x19,
|
||||
TranslationTableWalk1 = 0x1c,
|
||||
SynchronousParityError = 0x1e
|
||||
};
|
||||
|
||||
struct FaultVals
|
||||
{
|
||||
const FaultName name;
|
||||
|
@ -86,7 +112,7 @@ class ArmFaultBase : public FaultBase
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
class ArmFault : public ArmFaultBase
|
||||
class ArmFaultVals : public ArmFault
|
||||
{
|
||||
protected:
|
||||
static FaultVals vals;
|
||||
|
@ -103,9 +129,9 @@ class ArmFault : public ArmFaultBase
|
|||
};
|
||||
|
||||
|
||||
class Reset : public ArmFault<Reset> {};
|
||||
class Reset : public ArmFaultVals<Reset> {};
|
||||
|
||||
class UndefinedInstruction : public ArmFault<UndefinedInstruction>
|
||||
class UndefinedInstruction : public ArmFaultVals<UndefinedInstruction>
|
||||
{
|
||||
#if !FULL_SYSTEM
|
||||
protected:
|
||||
|
@ -125,7 +151,7 @@ class UndefinedInstruction : public ArmFault<UndefinedInstruction>
|
|||
#endif
|
||||
};
|
||||
|
||||
class SupervisorCall : public ArmFault<SupervisorCall>
|
||||
class SupervisorCall : public ArmFaultVals<SupervisorCall>
|
||||
{
|
||||
#if !FULL_SYSTEM
|
||||
protected:
|
||||
|
@ -138,10 +164,50 @@ class SupervisorCall : public ArmFault<SupervisorCall>
|
|||
void invoke(ThreadContext *tc);
|
||||
#endif
|
||||
};
|
||||
class PrefetchAbort : public ArmFault<PrefetchAbort> {};
|
||||
class DataAbort : public ArmFault<DataAbort> {};
|
||||
class Interrupt : public ArmFault<Interrupt> {};
|
||||
class FastInterrupt : public ArmFault<FastInterrupt> {};
|
||||
|
||||
template <class T>
|
||||
class AbortFault : public ArmFaultVals<T>
|
||||
{
|
||||
protected:
|
||||
Addr faultAddr;
|
||||
bool write;
|
||||
uint8_t domain;
|
||||
uint8_t status;
|
||||
|
||||
public:
|
||||
AbortFault(Addr _faultAddr, bool _write,
|
||||
uint8_t _domain, uint8_t _status) :
|
||||
faultAddr(_faultAddr), write(_write),
|
||||
domain(_domain), status(_status)
|
||||
{}
|
||||
|
||||
void invoke(ThreadContext *tc);
|
||||
};
|
||||
|
||||
class PrefetchAbort : public AbortFault<PrefetchAbort>
|
||||
{
|
||||
public:
|
||||
static const MiscRegIndex FsrIndex = MISCREG_IFSR;
|
||||
static const MiscRegIndex FarIndex = MISCREG_IFAR;
|
||||
|
||||
PrefetchAbort(Addr _addr, uint8_t _status) :
|
||||
AbortFault<PrefetchAbort>(_addr, false, 0, _status)
|
||||
{}
|
||||
};
|
||||
|
||||
class DataAbort : public AbortFault<DataAbort>
|
||||
{
|
||||
public:
|
||||
static const MiscRegIndex FsrIndex = MISCREG_DFSR;
|
||||
static const MiscRegIndex FarIndex = MISCREG_DFAR;
|
||||
|
||||
DataAbort(Addr _addr, bool _write, uint8_t _domain, uint8_t _status) :
|
||||
AbortFault<DataAbort>(_addr, _write, _domain, _status)
|
||||
{}
|
||||
};
|
||||
|
||||
class Interrupt : public ArmFaultVals<Interrupt> {};
|
||||
class FastInterrupt : public ArmFaultVals<FastInterrupt> {};
|
||||
|
||||
|
||||
} // ArmISA namespace
|
||||
|
|
|
@ -124,6 +124,10 @@ namespace ArmISA
|
|||
MISCREG_TLBIMVA,
|
||||
MISCREG_TLBIASID,
|
||||
MISCREG_TLBIMVAA,
|
||||
MISCREG_DFSR,
|
||||
MISCREG_IFSR,
|
||||
MISCREG_DFAR,
|
||||
MISCREG_IFAR,
|
||||
MISCREG_CP15_UNIMP_START,
|
||||
MISCREG_CTR = MISCREG_CP15_UNIMP_START,
|
||||
MISCREG_TCMTR,
|
||||
|
@ -145,12 +149,8 @@ namespace ArmISA
|
|||
MISCREG_PAR,
|
||||
MISCREG_AIDR,
|
||||
MISCREG_ACTLR,
|
||||
MISCREG_DFSR,
|
||||
MISCREG_IFSR,
|
||||
MISCREG_ADFSR,
|
||||
MISCREG_AIFSR,
|
||||
MISCREG_DFAR,
|
||||
MISCREG_IFAR,
|
||||
MISCREG_DCIMVAC,
|
||||
MISCREG_DCISW,
|
||||
MISCREG_MCCSW,
|
||||
|
@ -203,12 +203,13 @@ namespace ArmISA
|
|||
"itlbiall", "itlbimva", "itlbiasid",
|
||||
"dtlbiall", "dtlbimva", "dtlbiasid",
|
||||
"tlbiall", "tlbimva", "tlbiasid", "tlbimvaa",
|
||||
"dfsr", "ifsr", "dfar", "ifar",
|
||||
"ctr", "tcmtr", "mpidr",
|
||||
"id_pfr0", "id_pfr1", "id_dfr0", "id_afr0",
|
||||
"id_mmfr0", "id_mmfr1", "id_mmfr2", "id_mmfr3",
|
||||
"id_isar0", "id_isar1", "id_isar2", "id_isar3", "id_isar4", "id_isar5",
|
||||
"par", "aidr", "actlr",
|
||||
"dfsr", "ifsr", "adfsr", "aifsr", "dfar", "ifar",
|
||||
"adfsr", "aifsr",
|
||||
"dcimvac", "dcisw", "mccsw",
|
||||
"dccmvau",
|
||||
"scr", "sder", "nsacr", "ttbcr",
|
||||
|
@ -285,6 +286,14 @@ namespace ArmISA
|
|||
Bitfield<30> d32dis;
|
||||
Bitfield<31> asedis;
|
||||
EndBitUnion(CPACR)
|
||||
|
||||
BitUnion32(FSR)
|
||||
Bitfield<3, 0> fsLow;
|
||||
Bitfield<7, 4> domain;
|
||||
Bitfield<10> fsHigh;
|
||||
Bitfield<11> wnr;
|
||||
Bitfield<12> ext;
|
||||
EndBitUnion(FSR)
|
||||
};
|
||||
|
||||
#endif // __ARCH_ARM_MISCREGS_HH__
|
||||
|
|
|
@ -299,7 +299,8 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
|
|||
|
||||
if (sctlr.a || (flags & AllowUnaligned) == 0) {
|
||||
if ((vaddr & flags & AlignmentMask) != 0) {
|
||||
return new DataAbort;
|
||||
return new DataAbort(vaddr, (mode == Write), 0,
|
||||
ArmFault::AlignmentFault);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue