arm: Add support for memory-mapped m5ops
Add support for a memory mapped m5op interface. When enabled, the TLB intercepts accesses in the 64KiB region designated by the ArmTLB.m5ops_base parameter. An access to this range maps to a specific m5op call. The upper 8 bits of the offset into the range denote the m5op function to call and the lower 8 bits denote the subfunction. Change-Id: I55fd8ac1afef4c3cc423b973870c9fe600a843a2 Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-on: https://gem5-review.googlesource.com/2964
This commit is contained in:
@@ -76,6 +76,10 @@ class ArmSystem(System):
|
||||
have_large_asid_64 = Param.Bool(False,
|
||||
"True if ASID is 16 bits in AArch64 (ARMv8)")
|
||||
|
||||
m5ops_base = Param.Addr(0,
|
||||
"Base of the 64KiB PA range used for memory-mapped m5ops. Set to 0 "
|
||||
"to disable.")
|
||||
|
||||
class GenericArmSystem(ArmSystem):
|
||||
type = 'GenericArmSystem'
|
||||
cxx_header = "arch/arm/system.hh"
|
||||
|
||||
@@ -63,6 +63,7 @@ class ArmTLB(SimObject):
|
||||
type = 'ArmTLB'
|
||||
cxx_class = 'ArmISA::TLB'
|
||||
cxx_header = "arch/arm/tlb.hh"
|
||||
sys = Param.System(Parent.any, "system object parameter")
|
||||
size = Param.Int(64, "TLB size")
|
||||
walker = Param.ArmTableWalker(ArmTableWalker(), "HW Table walker")
|
||||
is_stage2 = Param.Bool(False, "Is this a stage 2 TLB?")
|
||||
|
||||
@@ -65,6 +65,9 @@ ArmSystem::ArmSystem(Params *p)
|
||||
_resetAddr64(p->reset_addr_64),
|
||||
_physAddrRange64(p->phys_addr_range_64),
|
||||
_haveLargeAsid64(p->have_large_asid_64),
|
||||
_m5opRange(p->m5ops_base ?
|
||||
RangeSize(p->m5ops_base, 0x10000) :
|
||||
AddrRange(1, 0)), // Create an empty range if disabled
|
||||
multiProc(p->multi_proc)
|
||||
{
|
||||
// Check if the physical address range is valid
|
||||
|
||||
@@ -116,6 +116,12 @@ class ArmSystem : public System
|
||||
*/
|
||||
const bool _haveLargeAsid64;
|
||||
|
||||
/**
|
||||
* Range for memory-mapped m5 pseudo ops. The range will be
|
||||
* invalid/empty if disabled.
|
||||
*/
|
||||
const AddrRange _m5opRange;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Get a boot loader that matches the kernel.
|
||||
@@ -216,6 +222,12 @@ class ArmSystem : public System
|
||||
return mask(physAddrRange());
|
||||
}
|
||||
|
||||
/**
|
||||
* Range used by memory-mapped m5 pseudo-ops if enabled. Returns
|
||||
* an invalid/empty range if disabled.
|
||||
*/
|
||||
const AddrRange &m5opRange() const { return _m5opRange; }
|
||||
|
||||
/** Returns true if the system of a specific thread context implements the
|
||||
* Security Extensions
|
||||
*/
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "arch/arm/system.hh"
|
||||
#include "arch/arm/table_walker.hh"
|
||||
#include "arch/arm/utility.hh"
|
||||
#include "arch/generic/mmapped_ipr.hh"
|
||||
#include "base/inifile.hh"
|
||||
#include "base/str.hh"
|
||||
#include "base/trace.hh"
|
||||
@@ -81,12 +82,17 @@ TLB::TLB(const ArmTLBParams *p)
|
||||
isHyp(false), asid(0), vmid(0), dacr(0),
|
||||
miscRegValid(false), miscRegContext(0), curTranType(NormalTran)
|
||||
{
|
||||
const ArmSystem *sys = dynamic_cast<const ArmSystem *>(p->sys);
|
||||
|
||||
tableWalker->setTlb(this);
|
||||
|
||||
// Cache system-level properties
|
||||
haveLPAE = tableWalker->haveLPAE();
|
||||
haveVirtualization = tableWalker->haveVirtualization();
|
||||
haveLargeAsid64 = tableWalker->haveLargeAsid64();
|
||||
|
||||
if (sys)
|
||||
m5opRange = sys->m5opRange();
|
||||
}
|
||||
|
||||
TLB::~TLB()
|
||||
@@ -129,6 +135,15 @@ TLB::translateFunctional(ThreadContext *tc, Addr va, Addr &pa)
|
||||
Fault
|
||||
TLB::finalizePhysical(RequestPtr req, ThreadContext *tc, Mode mode) const
|
||||
{
|
||||
const Addr paddr = req->getPaddr();
|
||||
|
||||
if (m5opRange.contains(paddr)) {
|
||||
req->setFlags(Request::MMAPPED_IPR | Request::GENERIC_IPR);
|
||||
req->setPaddr(GenericISA::iprAddressPseudoInst(
|
||||
(paddr >> 8) & 0xFF,
|
||||
paddr & 0xFF));
|
||||
}
|
||||
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
@@ -582,7 +597,7 @@ TLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
|
||||
return std::make_shared<GenericPageTableFault>(vaddr_tainted);
|
||||
req->setPaddr(paddr);
|
||||
|
||||
return NoFault;
|
||||
return finalizePhysical(req, tc, mode);
|
||||
}
|
||||
|
||||
Fault
|
||||
@@ -1108,14 +1123,18 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
|
||||
fault = testTranslation(req, mode, te->domain);
|
||||
}
|
||||
|
||||
// Generate Illegal Inst Set State fault if IL bit is set in CPSR
|
||||
if (fault == NoFault) {
|
||||
// Generate Illegal Inst Set State fault if IL bit is set in CPSR
|
||||
if (aarch64 && is_fetch && cpsr.il == 1) {
|
||||
return std::make_shared<IllegalInstSetStateFault>();
|
||||
}
|
||||
}
|
||||
|
||||
return fault;
|
||||
// Don't try to finalize a physical address unless the
|
||||
// translation has completed (i.e., there is a table entry).
|
||||
return te ? finalizePhysical(req, tc, mode) : NoFault;
|
||||
} else {
|
||||
return fault;
|
||||
}
|
||||
}
|
||||
|
||||
Fault
|
||||
|
||||
@@ -393,6 +393,8 @@ protected:
|
||||
bool haveVirtualization;
|
||||
bool haveLargeAsid64;
|
||||
|
||||
AddrRange m5opRange;
|
||||
|
||||
void updateMiscReg(ThreadContext *tc,
|
||||
ArmTranslationType tranType = NormalTran);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user