arch-arm: Properly implement IPASpace in the MMU (#1313)
This PR is introducing the concept of IPA space in gem5, which is necessary after the implementation of FEAT_SEL2. In fact we can now have Secure and Non-Secure intermediate physical address spaces when the PE is executing in Secure state.
This commit is contained in:
@@ -411,12 +411,13 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
TLBIALL tlbiOp(TranslationRegime::EL10, secure);
|
||||
TLBIALL tlbiOp(TranslationRegime::EL10, ss);
|
||||
if (shareable) {
|
||||
tlbiOp.broadcast(tc);
|
||||
} else {
|
||||
@@ -429,8 +430,9 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIALL tlbiOp(TranslationRegime::EL10, secure);
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIALL tlbiOp(TranslationRegime::EL10, ss);
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
@@ -440,12 +442,13 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
ITLBIALL tlbiOp(TranslationRegime::EL10, secure);
|
||||
ITLBIALL tlbiOp(TranslationRegime::EL10, ss);
|
||||
if (shareable) {
|
||||
tlbiOp.broadcast(tc);
|
||||
} else {
|
||||
@@ -459,12 +462,13 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
DTLBIALL tlbiOp(TranslationRegime::EL10, secure);
|
||||
DTLBIALL tlbiOp(TranslationRegime::EL10, ss);
|
||||
if (shareable) {
|
||||
tlbiOp.broadcast(tc);
|
||||
} else {
|
||||
@@ -478,13 +482,14 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
TLBIMVA tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7, 0),
|
||||
false);
|
||||
@@ -502,13 +507,14 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
TLBIMVA tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7, 0),
|
||||
true);
|
||||
@@ -525,9 +531,10 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIMVA tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7, 0),
|
||||
false);
|
||||
@@ -540,9 +547,10 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIMVA tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7, 0),
|
||||
true);
|
||||
@@ -556,13 +564,14 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
TLBIASID tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
bits(value, 7, 0));
|
||||
|
||||
if (shareable) {
|
||||
@@ -577,9 +586,10 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIASID tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
bits(value, 7, 0));
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
@@ -591,11 +601,12 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL10, secure,
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL10, ss,
|
||||
mbits(value, 31, 12), false);
|
||||
|
||||
if (shareable) {
|
||||
@@ -611,12 +622,13 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL10, secure,
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL10, ss,
|
||||
mbits(value, 31, 12), true);
|
||||
|
||||
if (shareable) {
|
||||
@@ -631,8 +643,9 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL10, secure,
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL10, ss,
|
||||
mbits(value, 31, 12), false);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
@@ -643,8 +656,9 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL10, secure,
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL10, ss,
|
||||
mbits(value, 31, 12), true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
@@ -655,8 +669,9 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL2, secure,
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL2, ss,
|
||||
mbits(value, 31, 12), false);
|
||||
|
||||
tlbiOp(tc);
|
||||
@@ -667,8 +682,9 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL2, secure,
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL2, ss,
|
||||
mbits(value, 31, 12), true);
|
||||
|
||||
tlbiOp(tc);
|
||||
@@ -679,8 +695,9 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL2, secure,
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL2, ss,
|
||||
mbits(value, 31, 12), false);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
@@ -691,8 +708,9 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL2, secure,
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIMVAA tlbiOp(TranslationRegime::EL2, ss,
|
||||
mbits(value, 31, 12), true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
@@ -703,9 +721,10 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIIPA tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12,
|
||||
false);
|
||||
|
||||
@@ -718,9 +737,10 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIIPA tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12,
|
||||
true);
|
||||
|
||||
@@ -733,9 +753,10 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIIPA tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12,
|
||||
false);
|
||||
|
||||
@@ -748,9 +769,10 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
TLBIIPA tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12,
|
||||
true);
|
||||
|
||||
@@ -763,12 +785,14 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
ITLBIMVA tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7, 0));
|
||||
|
||||
@@ -785,13 +809,14 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
DTLBIMVA tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7, 0));
|
||||
|
||||
@@ -808,13 +833,14 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
ITLBIASID tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
bits(value, 7, 0));
|
||||
|
||||
if (shareable) {
|
||||
@@ -830,13 +856,14 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
auto ss = release->has(ArmExtension::SECURITY) && !scr.ns ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
// Check for Force Broadcast. Ignored if HCR_EL2.TGE == 1
|
||||
bool shareable = currEL(tc) == EL1 && EL2Enabled(tc) &&
|
||||
hcr.fb && !hcr.tge;
|
||||
|
||||
DTLBIASID tlbiOp(TranslationRegime::EL10,
|
||||
secure,
|
||||
ss,
|
||||
bits(value, 7, 0));
|
||||
|
||||
if (shareable) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -292,40 +292,40 @@ class TlbiOp64 : public MiscRegRegImmOp64
|
||||
static std::unordered_map<ArmISA::MiscRegIndex, TlbiFunc> tlbiOps;
|
||||
|
||||
static void tlbiAll(ThreadContext *tc, RegVal value,
|
||||
bool secure, ArmISA::TranslationRegime regime, bool shareable,
|
||||
TlbiAttr attrs=TlbiAttr::None);
|
||||
ArmISA::SecurityState ss, ArmISA::TranslationRegime regime,
|
||||
bool shareable, TlbiAttr attrs=TlbiAttr::None);
|
||||
|
||||
static void tlbiVmall(ThreadContext *tc, RegVal value,
|
||||
bool secure, ArmISA::TranslationRegime regime, bool shareable,
|
||||
bool stage2=false, TlbiAttr attrs=TlbiAttr::None);
|
||||
ArmISA::SecurityState ss, ArmISA::TranslationRegime regime,
|
||||
bool shareable, bool stage2=false, TlbiAttr attrs=TlbiAttr::None);
|
||||
|
||||
static void tlbiVa(ThreadContext *tc, RegVal value,
|
||||
bool secure, ArmISA::TranslationRegime regime, bool shareable,
|
||||
bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
ArmISA::SecurityState ss, ArmISA::TranslationRegime regime,
|
||||
bool shareable, bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
|
||||
static void tlbiVaa(ThreadContext *tc, RegVal value,
|
||||
bool secure, ArmISA::TranslationRegime regime, bool shareable,
|
||||
bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
ArmISA::SecurityState ss, ArmISA::TranslationRegime regime,
|
||||
bool shareable, bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
|
||||
static void tlbiAsid(ThreadContext *tc, RegVal value,
|
||||
bool secure, ArmISA::TranslationRegime regime, bool shareable,
|
||||
TlbiAttr attrs=TlbiAttr::None);
|
||||
ArmISA::SecurityState ss, ArmISA::TranslationRegime regime,
|
||||
bool shareable, TlbiAttr attrs=TlbiAttr::None);
|
||||
|
||||
static void tlbiIpaS2(ThreadContext *tc, RegVal value,
|
||||
bool secure, ArmISA::TranslationRegime regime, bool shareable,
|
||||
bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
ArmISA::SecurityState ss, ArmISA::TranslationRegime regime,
|
||||
bool shareable, bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
|
||||
static void tlbiRvaa(ThreadContext *tc, RegVal value,
|
||||
bool secure, ArmISA::TranslationRegime regime, bool shareable,
|
||||
bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
ArmISA::SecurityState ss, ArmISA::TranslationRegime regime,
|
||||
bool shareable, bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
|
||||
static void tlbiRva(ThreadContext *tc, RegVal value,
|
||||
bool secure, ArmISA::TranslationRegime regime, bool shareable,
|
||||
bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
ArmISA::SecurityState ss, ArmISA::TranslationRegime regime,
|
||||
bool shareable, bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
|
||||
static void tlbiRipaS2(ThreadContext *tc, RegVal value,
|
||||
bool secure, ArmISA::TranslationRegime regime, bool shareable,
|
||||
bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
ArmISA::SecurityState ss, ArmISA::TranslationRegime regime,
|
||||
bool shareable, bool last_level, TlbiAttr attrs=TlbiAttr::None);
|
||||
|
||||
static bool fnxsAttrs(ThreadContext *tc);
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ MMU::translateFunctional(ThreadContext *tc, Addr va, Addr &pa)
|
||||
lookup_data.asn = state.asid;
|
||||
lookup_data.ignoreAsn = false;
|
||||
lookup_data.vmid = state.vmid;
|
||||
lookup_data.secure = state.isSecure;
|
||||
lookup_data.ss = state.securityState;
|
||||
lookup_data.functional = true;
|
||||
lookup_data.targetRegime = state.currRegime;
|
||||
lookup_data.mode = BaseMMU::Read;
|
||||
@@ -459,7 +459,8 @@ MMU::checkPermissions(TlbEntry *te, const RequestPtr &req, Mode mode,
|
||||
(ap == 3 && state.sctlr.uwxn && is_priv);
|
||||
if (is_fetch && (abt || xn ||
|
||||
(te->longDescFormat && te->pxn && is_priv) ||
|
||||
(state.isSecure && te->ns && state.scr.sif))) {
|
||||
(state.securityState == SecurityState::Secure &&
|
||||
te->ns && state.scr.sif))) {
|
||||
stats.permsFaults++;
|
||||
DPRINTF(TLB, "TLB Fault: Prefetch abort on permission check. AP:%d "
|
||||
"priv:%d write:%d ns:%d sif:%d sctlr.afe: %d \n",
|
||||
@@ -615,7 +616,8 @@ MMU::s2PermBits64(TlbEntry *te, const RequestPtr &req, Mode mode,
|
||||
uint8_t xn = te->xn;
|
||||
uint8_t pxn = te->pxn;
|
||||
|
||||
if (ArmSystem::haveEL(tc, EL3) && state.isSecure &&
|
||||
if (ArmSystem::haveEL(tc, EL3) &&
|
||||
state.securityState == SecurityState::Secure &&
|
||||
te->ns && state.scr.sif) {
|
||||
xn = true;
|
||||
}
|
||||
@@ -705,7 +707,8 @@ MMU::s1PermBits64(TlbEntry *te, const RequestPtr &req, Mode mode,
|
||||
// if wxn is set
|
||||
grant_exec = grant_exec && !(wxn && grant_write);
|
||||
|
||||
if (ArmSystem::haveEL(tc, EL3) && state.isSecure && te->ns) {
|
||||
if (ArmSystem::haveEL(tc, EL3) &&
|
||||
state.securityState == SecurityState::Secure && te->ns) {
|
||||
grant_exec = grant_exec && !state.scr.sif;
|
||||
}
|
||||
|
||||
@@ -811,7 +814,7 @@ MMU::translateMmuOff(ThreadContext *tc, const RequestPtr &req, Mode mode,
|
||||
req->setPaddr(vaddr);
|
||||
// When the MMU is off the security attribute corresponds to the
|
||||
// security state of the processor
|
||||
if (state.isSecure)
|
||||
if (state.securityState == SecurityState::Secure)
|
||||
req->setFlags(Request::SECURE);
|
||||
else
|
||||
req->clearFlags(Request::SECURE);
|
||||
@@ -846,8 +849,9 @@ MMU::translateMmuOff(ThreadContext *tc, const RequestPtr &req, Mode mode,
|
||||
}
|
||||
|
||||
// Set memory attributes
|
||||
bool in_secure_state = state.securityState == SecurityState::Secure;
|
||||
TlbEntry temp_te;
|
||||
temp_te.ns = !state.isSecure;
|
||||
temp_te.ns = !in_secure_state;
|
||||
bool dc = (HaveExt(tc, ArmExtension::FEAT_VHE) &&
|
||||
state.hcr.e2h == 1 && state.hcr.tge == 1) ? 0: state.hcr.dc;
|
||||
bool i_cacheability = state.sctlr.i && !state.sctlr.m;
|
||||
@@ -916,7 +920,7 @@ MMU::translateMmuOn(ThreadContext* tc, const RequestPtr &req, Mode mode,
|
||||
Addr pa = te->pAddr(vaddr);
|
||||
req->setPaddr(pa);
|
||||
|
||||
if (state.isSecure && !te->ns) {
|
||||
if (state.securityState == SecurityState::Secure && !te->ns) {
|
||||
req->setFlags(Request::SECURE);
|
||||
} else {
|
||||
req->clearFlags(Request::SECURE);
|
||||
@@ -969,7 +973,8 @@ MMU::translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
|
||||
|
||||
DPRINTF(TLBVerbose,
|
||||
"CPSR is priv:%d UserMode:%d secure:%d S1S2NsTran:%d\n",
|
||||
state.isPriv, flags & UserMode, state.isSecure,
|
||||
state.isPriv, flags & UserMode,
|
||||
state.securityState == SecurityState::Secure,
|
||||
tran_type & S1S2NsTran);
|
||||
|
||||
DPRINTF(TLB, "translateFs addr %#x, mode %d, st2 %d, scr %#x sctlr %#x "
|
||||
@@ -1214,8 +1219,9 @@ MMU::CachedState::updateMiscReg(ThreadContext *tc,
|
||||
scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
|
||||
// Dependencies: SCR/SCR_EL3, CPSR
|
||||
isSecure = ArmISA::isSecure(tc) &&
|
||||
!(tran_type & HypMode) && !(tran_type & S1S2NsTran);
|
||||
securityState = ArmISA::isSecure(tc) &&
|
||||
!(tran_type & HypMode) && !(tran_type & S1S2NsTran) ?
|
||||
SecurityState::Secure : SecurityState::NonSecure;
|
||||
|
||||
exceptionLevel = tranTypeEL(cpsr, scr, tran_type);
|
||||
currRegime = translationRegime(tc, exceptionLevel);
|
||||
@@ -1296,27 +1302,27 @@ MMU::CachedState::updateMiscReg(ThreadContext *tc,
|
||||
}
|
||||
} else { // AArch32
|
||||
sctlr = tc->readMiscReg(snsBankedIndex(MISCREG_SCTLR, tc,
|
||||
!isSecure));
|
||||
securityState == SecurityState::NonSecure));
|
||||
ttbcr = tc->readMiscReg(snsBankedIndex(MISCREG_TTBCR, tc,
|
||||
!isSecure));
|
||||
securityState == SecurityState::NonSecure));
|
||||
isPriv = cpsr.mode != MODE_USER;
|
||||
if (longDescFormatInUse(tc)) {
|
||||
uint64_t ttbr_asid = tc->readMiscReg(
|
||||
snsBankedIndex(ttbcr.a1 ? MISCREG_TTBR1 :
|
||||
MISCREG_TTBR0,
|
||||
tc, !isSecure));
|
||||
snsBankedIndex(ttbcr.a1 ? MISCREG_TTBR1 : MISCREG_TTBR0,
|
||||
tc, securityState == SecurityState::NonSecure));
|
||||
asid = bits(ttbr_asid, 55, 48);
|
||||
} else { // Short-descriptor translation table format in use
|
||||
CONTEXTIDR context_id = tc->readMiscReg(snsBankedIndex(
|
||||
MISCREG_CONTEXTIDR, tc,!isSecure));
|
||||
MISCREG_CONTEXTIDR, tc,
|
||||
securityState == SecurityState::NonSecure));
|
||||
asid = context_id.asid;
|
||||
}
|
||||
prrr = tc->readMiscReg(snsBankedIndex(MISCREG_PRRR, tc,
|
||||
!isSecure));
|
||||
securityState == SecurityState::NonSecure));
|
||||
nmrr = tc->readMiscReg(snsBankedIndex(MISCREG_NMRR, tc,
|
||||
!isSecure));
|
||||
securityState == SecurityState::NonSecure));
|
||||
dacr = tc->readMiscReg(snsBankedIndex(MISCREG_DACR, tc,
|
||||
!isSecure));
|
||||
securityState == SecurityState::NonSecure));
|
||||
|
||||
if (mmu->release()->has(ArmExtension::VIRTUALIZATION)) {
|
||||
vmid = bits(tc->readMiscReg(MISCREG_VTTBR), 55, 48);
|
||||
@@ -1379,15 +1385,15 @@ MMU::tranTypeEL(CPSR cpsr, SCR scr, ArmTranslationType type)
|
||||
Fault
|
||||
MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode,
|
||||
Translation *translation, bool timing, bool functional,
|
||||
bool is_secure, ArmTranslationType tran_type,
|
||||
SecurityState ss, PASpace ipaspace, ArmTranslationType tran_type,
|
||||
bool stage2)
|
||||
{
|
||||
return getTE(te, req, tc, mode, translation, timing, functional,
|
||||
is_secure, tran_type, stage2 ? s2State : s1State);
|
||||
ss, ipaspace, tran_type, stage2 ? s2State : s1State);
|
||||
}
|
||||
|
||||
TlbEntry*
|
||||
MMU::lookup(Addr va, uint16_t asid, vmid_t vmid, bool secure,
|
||||
MMU::lookup(Addr va, uint16_t asid, vmid_t vmid, SecurityState ss,
|
||||
bool functional, bool ignore_asn, TranslationRegime regime,
|
||||
bool stage2, BaseMMU::Mode mode)
|
||||
{
|
||||
@@ -1399,7 +1405,7 @@ MMU::lookup(Addr va, uint16_t asid, vmid_t vmid, bool secure,
|
||||
lookup_data.asn = asid;
|
||||
lookup_data.ignoreAsn = ignore_asn;
|
||||
lookup_data.vmid = vmid;
|
||||
lookup_data.secure = secure;
|
||||
lookup_data.ss = ss;
|
||||
lookup_data.functional = functional;
|
||||
lookup_data.targetRegime = regime;
|
||||
lookup_data.mode = mode;
|
||||
@@ -1410,7 +1416,7 @@ MMU::lookup(Addr va, uint16_t asid, vmid_t vmid, bool secure,
|
||||
Fault
|
||||
MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode,
|
||||
Translation *translation, bool timing, bool functional,
|
||||
bool is_secure, ArmTranslationType tran_type,
|
||||
SecurityState ss, PASpace ipaspace, ArmTranslationType tran_type,
|
||||
CachedState& state)
|
||||
{
|
||||
// In a 2-stage system, the IPA->PA translation can be started via this
|
||||
@@ -1430,7 +1436,7 @@ MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode,
|
||||
vaddr = vaddr_tainted;
|
||||
}
|
||||
|
||||
*te = lookup(vaddr, state.asid, state.vmid, is_secure, false,
|
||||
*te = lookup(vaddr, state.asid, state.vmid, ss, false,
|
||||
false, regime, state.isStage2, mode);
|
||||
|
||||
if (!isCompleteTranslation(*te)) {
|
||||
@@ -1452,15 +1458,15 @@ MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode,
|
||||
Fault fault;
|
||||
fault = getTableWalker(mode, state.isStage2)->walk(
|
||||
req, tc, state.asid, state.vmid, mode,
|
||||
translation, timing, functional, is_secure,
|
||||
tran_type, state.stage2DescReq, *te);
|
||||
translation, timing, functional, ss,
|
||||
ipaspace, tran_type, state.stage2DescReq, *te);
|
||||
|
||||
// for timing mode, return and wait for table walk,
|
||||
if (timing || fault != NoFault) {
|
||||
return fault;
|
||||
}
|
||||
|
||||
*te = lookup(vaddr, state.asid, state.vmid, is_secure,
|
||||
*te = lookup(vaddr, state.asid, state.vmid, ss,
|
||||
true, false, regime, state.isStage2, mode);
|
||||
assert(*te);
|
||||
}
|
||||
@@ -1476,12 +1482,16 @@ MMU::getResultTe(TlbEntry **te, const RequestPtr &req,
|
||||
Fault fault;
|
||||
|
||||
if (state.isStage2) {
|
||||
PASpace ipaspace = state.securityState == SecurityState::Secure ?
|
||||
PASpace::Secure : PASpace::NonSecure;
|
||||
|
||||
// We are already in the stage 2 TLB. Grab the table entry for stage
|
||||
// 2 only. We are here because stage 1 translation is disabled.
|
||||
TlbEntry *s2_te = nullptr;
|
||||
// Get the stage 2 table entry
|
||||
fault = getTE(&s2_te, req, tc, mode, translation, timing, functional,
|
||||
state.isSecure, state.curTranType, state);
|
||||
state.securityState, ipaspace,
|
||||
state.curTranType, state);
|
||||
// Check permissions of stage 2
|
||||
if (isCompleteTranslation(s2_te) && (fault == NoFault)) {
|
||||
if (state.aarch64)
|
||||
@@ -1499,7 +1509,8 @@ MMU::getResultTe(TlbEntry **te, const RequestPtr &req,
|
||||
|
||||
// Get the stage 1 table entry
|
||||
fault = getTE(&s1_te, req, tc, mode, translation, timing, functional,
|
||||
state.isSecure, state.curTranType, state);
|
||||
state.securityState, PASpace::NonSecure,
|
||||
state.curTranType, state);
|
||||
// only proceed if we have a valid table entry
|
||||
if (isCompleteTranslation(s1_te) && (fault == NoFault)) {
|
||||
// Check stage 1 permissions before checking stage 2
|
||||
@@ -1509,8 +1520,8 @@ MMU::getResultTe(TlbEntry **te, const RequestPtr &req,
|
||||
fault = checkPermissions(s1_te, req, mode, state);
|
||||
if (state.stage2Req & (fault == NoFault)) {
|
||||
Stage2LookUp *s2_lookup = new Stage2LookUp(this, *s1_te,
|
||||
req, translation, mode, timing, functional, state.isSecure,
|
||||
state.curTranType);
|
||||
req, translation, mode, timing, functional,
|
||||
state.securityState, state.curTranType);
|
||||
fault = s2_lookup->getTe(tc, mergeTe);
|
||||
if (s2_lookup->isComplete()) {
|
||||
*te = mergeTe;
|
||||
|
||||
@@ -149,7 +149,7 @@ class MMU : public BaseMMU
|
||||
sctlr = rhs.sctlr;
|
||||
scr = rhs.scr;
|
||||
isPriv = rhs.isPriv;
|
||||
isSecure = rhs.isSecure;
|
||||
securityState = rhs.securityState;
|
||||
ttbcr = rhs.ttbcr;
|
||||
asid = rhs.asid;
|
||||
vmid = rhs.vmid;
|
||||
@@ -184,7 +184,7 @@ class MMU : public BaseMMU
|
||||
SCTLR sctlr = 0;
|
||||
SCR scr = 0;
|
||||
bool isPriv = false;
|
||||
bool isSecure = false;
|
||||
SecurityState securityState = SecurityState::NonSecure;
|
||||
TTBCR ttbcr = 0;
|
||||
uint16_t asid = 0;
|
||||
vmid_t vmid = 0;
|
||||
@@ -306,7 +306,7 @@ class MMU : public BaseMMU
|
||||
}
|
||||
|
||||
if (tlbi_op.stage2Flush()) {
|
||||
flushStage2(tlbi_op.makeStage2());
|
||||
flushStage2(tlbi_op);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +397,7 @@ class MMU : public BaseMMU
|
||||
* @param vpn virtual address
|
||||
* @param asn context id/address space id to use
|
||||
* @param vmid The virtual machine ID used for stage 2 translation
|
||||
* @param secure if the lookup is secure
|
||||
* @param ss security state of the PE
|
||||
* @param functional if the lookup should modify state
|
||||
* @param ignore_asn if on lookup asn should be ignored
|
||||
* @param target_regime selecting the translation regime
|
||||
@@ -405,19 +405,21 @@ class MMU : public BaseMMU
|
||||
* @return pointer to TLB entry if it exists
|
||||
*/
|
||||
TlbEntry *lookup(Addr vpn, uint16_t asn, vmid_t vmid,
|
||||
bool secure, bool functional,
|
||||
SecurityState ss, bool functional,
|
||||
bool ignore_asn, TranslationRegime target_regime,
|
||||
bool stage2, BaseMMU::Mode mode);
|
||||
|
||||
Fault getTE(TlbEntry **te, const RequestPtr &req,
|
||||
ThreadContext *tc, Mode mode,
|
||||
Translation *translation, bool timing, bool functional,
|
||||
bool is_secure, ArmTranslationType tran_type,
|
||||
SecurityState ss, PASpace ipaspace,
|
||||
ArmTranslationType tran_type,
|
||||
bool stage2);
|
||||
Fault getTE(TlbEntry **te, const RequestPtr &req,
|
||||
ThreadContext *tc, Mode mode,
|
||||
Translation *translation, bool timing, bool functional,
|
||||
bool is_secure, ArmTranslationType tran_type,
|
||||
SecurityState ss, PASpace ipaspace,
|
||||
ArmTranslationType tran_type,
|
||||
CachedState &state);
|
||||
|
||||
Fault getResultTe(TlbEntry **te, const RequestPtr &req,
|
||||
|
||||
@@ -199,7 +199,7 @@ struct TlbEntry : public Serializable
|
||||
// The virtual machine ID used for stage 2 translation
|
||||
vmid_t vmid = 0;
|
||||
// if the lookup is secure
|
||||
bool secure = false;
|
||||
SecurityState ss = SecurityState::NonSecure;
|
||||
// if the lookup should modify state
|
||||
bool functional = false;
|
||||
// selecting the translation regime
|
||||
@@ -239,8 +239,10 @@ struct TlbEntry : public Serializable
|
||||
|
||||
// True if the entry targets the non-secure physical address space
|
||||
bool ns;
|
||||
// True if the entry was brought in from a non-secure page table
|
||||
bool nstid;
|
||||
// Security state of the translation regime
|
||||
SecurityState ss;
|
||||
// IPA Space (stage2 entries only)
|
||||
PASpace ipaSpace;
|
||||
// Translation regime on insert, AARCH64 EL0&1, AARCH32 -> el=1
|
||||
TranslationRegime regime;
|
||||
// This is used to distinguish between instruction and data entries
|
||||
@@ -271,7 +273,9 @@ struct TlbEntry : public Serializable
|
||||
innerAttrs(0), outerAttrs(0), ap(read_only ? 0x3 : 0), hap(0x3),
|
||||
domain(DomainType::Client), mtype(MemoryType::StronglyOrdered),
|
||||
longDescFormat(false), global(false), valid(true),
|
||||
ns(true), nstid(true), regime(TranslationRegime::EL10),
|
||||
ns(true), ss(SecurityState::NonSecure),
|
||||
ipaSpace(PASpace::NonSecure),
|
||||
regime(TranslationRegime::EL10),
|
||||
type(TypeTLB::unified), partial(false),
|
||||
nonCacheable(uncacheable),
|
||||
shareable(false), outerShareable(false), xn(0), pxn(0),
|
||||
@@ -290,7 +294,9 @@ struct TlbEntry : public Serializable
|
||||
innerAttrs(0), outerAttrs(0), ap(0), hap(0x3),
|
||||
domain(DomainType::Client), mtype(MemoryType::StronglyOrdered),
|
||||
longDescFormat(false), global(false), valid(false),
|
||||
ns(true), nstid(true), regime(TranslationRegime::EL10),
|
||||
ns(true), ss(SecurityState::NonSecure),
|
||||
ipaSpace(PASpace::NonSecure),
|
||||
regime(TranslationRegime::EL10),
|
||||
type(TypeTLB::unified), partial(false), nonCacheable(false),
|
||||
shareable(false), outerShareable(false), xn(0), pxn(0),
|
||||
xs(true)
|
||||
@@ -330,8 +336,7 @@ struct TlbEntry : public Serializable
|
||||
match(const Lookup &lookup) const
|
||||
{
|
||||
bool match = false;
|
||||
if (valid && matchAddress(lookup) &&
|
||||
(lookup.secure == !nstid))
|
||||
if (valid && matchAddress(lookup) && lookup.ss == ss)
|
||||
{
|
||||
match = checkRegime(lookup.targetRegime);
|
||||
|
||||
@@ -410,8 +415,8 @@ struct TlbEntry : public Serializable
|
||||
print() const
|
||||
{
|
||||
return csprintf("%#x, asn %d vmn %d ppn %#x size: %#x ap:%d "
|
||||
"ns:%d nstid:%d g:%d xs: %d regime:%s", vpn << N, asid, vmid,
|
||||
pfn << N, size, ap, ns, nstid, global,
|
||||
"ns:%d ss:%s g:%d xs: %d regime:%s", vpn << N, asid, vmid,
|
||||
pfn << N, size, ap, ns, ss, global,
|
||||
xs, regimeToStr(regime));
|
||||
}
|
||||
|
||||
@@ -428,7 +433,7 @@ struct TlbEntry : public Serializable
|
||||
SERIALIZE_SCALAR(global);
|
||||
SERIALIZE_SCALAR(valid);
|
||||
SERIALIZE_SCALAR(ns);
|
||||
SERIALIZE_SCALAR(nstid);
|
||||
SERIALIZE_ENUM(ss);
|
||||
SERIALIZE_ENUM(type);
|
||||
SERIALIZE_SCALAR(nonCacheable);
|
||||
SERIALIZE_ENUM(lookupLevel);
|
||||
@@ -458,7 +463,7 @@ struct TlbEntry : public Serializable
|
||||
UNSERIALIZE_SCALAR(global);
|
||||
UNSERIALIZE_SCALAR(valid);
|
||||
UNSERIALIZE_SCALAR(ns);
|
||||
UNSERIALIZE_SCALAR(nstid);
|
||||
UNSERIALIZE_ENUM(ss);
|
||||
UNSERIALIZE_ENUM(type);
|
||||
UNSERIALIZE_SCALAR(nonCacheable);
|
||||
UNSERIALIZE_ENUM(lookupLevel);
|
||||
|
||||
@@ -655,6 +655,10 @@ namespace ArmISA
|
||||
Bitfield<19> vs; // Only defined for VTCR_EL2
|
||||
Bitfield<21> ha; // Only defined for VTCR_EL2
|
||||
Bitfield<22> hd; // Only defined for VTCR_EL2
|
||||
Bitfield<29> nsw; // Only defined for VTCR_EL2
|
||||
Bitfield<29> sw; // Only defined for VSTCR_EL2
|
||||
Bitfield<30> nsa; // Only defined for VTCR_EL2
|
||||
Bitfield<30> sa; // Only defined for VSTCR_EL2
|
||||
EndBitUnion(VTCR_t)
|
||||
|
||||
BitUnion32(PRRR)
|
||||
|
||||
@@ -57,7 +57,7 @@ Fault
|
||||
Stage2LookUp::getTe(ThreadContext *tc, TlbEntry *destTe)
|
||||
{
|
||||
fault = mmu->getTE(&stage2Te, req, tc, mode, this, timing,
|
||||
functional, secure, tranType, true);
|
||||
functional, ss, ipaSpace, tranType, true);
|
||||
|
||||
// Call finish if we're done already
|
||||
if ((fault != NoFault) || (stage2Te != NULL)) {
|
||||
@@ -193,7 +193,7 @@ Stage2LookUp::finish(const Fault &_fault, const RequestPtr &req,
|
||||
if ((fault == NoFault) && (stage2Te == NULL)) {
|
||||
// OLD_LOOK: stage2Tlb
|
||||
fault = mmu->getTE(&stage2Te, req, tc, mode, this,
|
||||
timing, functional, secure, tranType, true);
|
||||
timing, functional, ss, ipaSpace, tranType, true);
|
||||
}
|
||||
|
||||
// Now we have the stage 2 table entry we need to merge it with the stage
|
||||
|
||||
@@ -72,16 +72,19 @@ class Stage2LookUp : public BaseMMU::Translation
|
||||
Fault fault;
|
||||
bool complete;
|
||||
bool selfDelete;
|
||||
bool secure;
|
||||
SecurityState ss;
|
||||
PASpace ipaSpace;
|
||||
|
||||
public:
|
||||
Stage2LookUp(MMU *_mmu, TlbEntry s1_te, const RequestPtr &_req,
|
||||
MMU::Translation *_transState, BaseMMU::Mode _mode, bool _timing,
|
||||
bool _functional, bool _secure, MMU::ArmTranslationType _tranType) :
|
||||
mmu(_mmu), stage1Te(s1_te), s1Req(_req),
|
||||
bool _functional, SecurityState _ss,
|
||||
MMU::ArmTranslationType _tranType)
|
||||
: mmu(_mmu), stage1Te(s1_te), s1Req(_req),
|
||||
transState(_transState), mode(_mode), timing(_timing),
|
||||
functional(_functional), tranType(_tranType), stage2Te(nullptr),
|
||||
fault(NoFault), complete(false), selfDelete(false), secure(_secure)
|
||||
fault(NoFault), complete(false), selfDelete(false), ss(_ss),
|
||||
ipaSpace(s1_te.ns ? PASpace::NonSecure : PASpace::Secure)
|
||||
{
|
||||
req = std::make_shared<Request>();
|
||||
req->setVirt(s1_te.pAddr(s1Req->getVaddr()), s1Req->getSize(),
|
||||
|
||||
@@ -131,7 +131,7 @@ TableWalker::WalkerState::WalkerState() :
|
||||
vaddr(0), vaddr_tainted(0),
|
||||
sctlr(0), scr(0), cpsr(0), tcr(0),
|
||||
htcr(0), hcr(0), vtcr(0),
|
||||
isWrite(false), isFetch(false), isSecure(false),
|
||||
isWrite(false), isFetch(false), ss(SecurityState::NonSecure),
|
||||
isUncacheable(false), longDescData(std::nullopt),
|
||||
hpd(false), sh(0), irgn(0), orgn(0), stage2Req(false),
|
||||
stage2Tran(nullptr), timing(false), functional(false),
|
||||
@@ -295,7 +295,8 @@ Fault
|
||||
TableWalker::walk(const RequestPtr &_req, ThreadContext *_tc, uint16_t _asid,
|
||||
vmid_t _vmid, MMU::Mode _mode,
|
||||
MMU::Translation *_trans, bool _timing, bool _functional,
|
||||
bool secure, MMU::ArmTranslationType tranType,
|
||||
SecurityState ss, PASpace ipaspace,
|
||||
MMU::ArmTranslationType tranType,
|
||||
bool _stage2Req, const TlbEntry *walk_entry)
|
||||
{
|
||||
assert(!(_functional && _timing));
|
||||
@@ -344,6 +345,7 @@ TableWalker::walk(const RequestPtr &_req, ThreadContext *_tc, uint16_t _asid,
|
||||
if (isStage2) {
|
||||
currState->regime = TranslationRegime::EL10;
|
||||
currState->aarch64 = ELIs64(_tc, EL2);
|
||||
currState->ipaSpace = ipaspace;
|
||||
} else {
|
||||
currState->regime =
|
||||
translationRegime(_tc, currState->el);
|
||||
@@ -364,8 +366,8 @@ TableWalker::walk(const RequestPtr &_req, ThreadContext *_tc, uint16_t _asid,
|
||||
currState->functional = _functional;
|
||||
currState->mode = _mode;
|
||||
currState->tranType = tranType;
|
||||
currState->isSecure = secure;
|
||||
currState->secureLookup = secure;
|
||||
currState->ss = ss;
|
||||
currState->secureLookup = currState->ss == SecurityState::Secure;
|
||||
currState->physAddrRange = _physAddrRange;
|
||||
|
||||
/** @todo These should be cached or grabbed from cached copies in
|
||||
@@ -382,7 +384,8 @@ TableWalker::walk(const RequestPtr &_req, ThreadContext *_tc, uint16_t _asid,
|
||||
currState->hcr = currState->tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
if (isStage2) {
|
||||
currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL1);
|
||||
if (currState->secureLookup) {
|
||||
if (currState->ss == SecurityState::Secure &&
|
||||
currState->ipaSpace == PASpace::Secure) {
|
||||
currState->vtcr =
|
||||
currState->tc->readMiscReg(MISCREG_VSTCR_EL2);
|
||||
} else {
|
||||
@@ -411,9 +414,11 @@ TableWalker::walk(const RequestPtr &_req, ThreadContext *_tc, uint16_t _asid,
|
||||
}
|
||||
} else {
|
||||
currState->sctlr = currState->tc->readMiscReg(snsBankedIndex(
|
||||
MISCREG_SCTLR, currState->tc, !currState->isSecure));
|
||||
MISCREG_SCTLR, currState->tc,
|
||||
currState->ss == SecurityState::NonSecure));
|
||||
currState->ttbcr = currState->tc->readMiscReg(snsBankedIndex(
|
||||
MISCREG_TTBCR, currState->tc, !currState->isSecure));
|
||||
MISCREG_TTBCR, currState->tc,
|
||||
currState->ss == SecurityState::NonSecure));
|
||||
currState->htcr = currState->tc->readMiscReg(MISCREG_HTCR);
|
||||
currState->hcr = currState->tc->readMiscReg(MISCREG_HCR);
|
||||
currState->vtcr = currState->tc->readMiscReg(MISCREG_VTCR);
|
||||
@@ -504,7 +509,7 @@ TableWalker::processWalkWrapper()
|
||||
// Check if a previous walk filled this request already
|
||||
// @TODO Should this always be the TLB or should we look in the stage2 TLB?
|
||||
TlbEntry* te = mmu->lookup(currState->vaddr, currState->asid,
|
||||
currState->vmid, currState->isSecure, true, false,
|
||||
currState->vmid, currState->ss, true, false,
|
||||
currState->regime, isStage2, currState->mode);
|
||||
|
||||
// Check if we still need to have a walk for this request. If the requesting
|
||||
@@ -585,7 +590,7 @@ TableWalker::processWalkWrapper()
|
||||
if (pendingQueue.size()) {
|
||||
currState = pendingQueue.front();
|
||||
te = mmu->lookup(currState->vaddr, currState->asid,
|
||||
currState->vmid, currState->isSecure, true,
|
||||
currState->vmid, currState->ss, true,
|
||||
false, currState->regime, isStage2, currState->mode);
|
||||
} else {
|
||||
// Terminate the loop, nothing more to do
|
||||
@@ -607,7 +612,8 @@ TableWalker::processWalk()
|
||||
// For short descriptors, translation configs are held in
|
||||
// TTBR1.
|
||||
RegVal ttbr1 = currState->tc->readMiscReg(snsBankedIndex(
|
||||
MISCREG_TTBR1, currState->tc, !currState->isSecure));
|
||||
MISCREG_TTBR1, currState->tc,
|
||||
currState->ss == SecurityState::NonSecure));
|
||||
|
||||
const auto irgn0_mask = 0x1;
|
||||
const auto irgn1_mask = 0x40;
|
||||
@@ -644,7 +650,8 @@ TableWalker::processWalk()
|
||||
ArmFault::VmsaTran);
|
||||
}
|
||||
ttbr = currState->tc->readMiscReg(snsBankedIndex(
|
||||
MISCREG_TTBR0, currState->tc, !currState->isSecure));
|
||||
MISCREG_TTBR0, currState->tc,
|
||||
currState->ss == SecurityState::NonSecure));
|
||||
} else {
|
||||
DPRINTF(TLB, " - Selecting TTBR1\n");
|
||||
// Check if table walk is allowed when Security Extensions are enabled
|
||||
@@ -670,7 +677,7 @@ TableWalker::processWalk()
|
||||
Addr l1desc_addr = mbits(ttbr, 31, 14 - currState->ttbcr.n) |
|
||||
(bits(currState->vaddr, 31 - currState->ttbcr.n, 20) << 2);
|
||||
DPRINTF(TLB, " - Descriptor at address %#x (%s)\n", l1desc_addr,
|
||||
currState->isSecure ? "s" : "ns");
|
||||
currState->ss == SecurityState::Secure ? "s" : "ns");
|
||||
|
||||
Request::Flags flag = Request::PT_WALK;
|
||||
if (uncacheableWalk()) {
|
||||
@@ -762,7 +769,8 @@ TableWalker::processWalkLPAE()
|
||||
ArmFault::LpaeTran);
|
||||
}
|
||||
ttbr = currState->tc->readMiscReg(snsBankedIndex(
|
||||
MISCREG_TTBR0, currState->tc, !currState->isSecure));
|
||||
MISCREG_TTBR0, currState->tc,
|
||||
currState->ss == SecurityState::NonSecure));
|
||||
tsz = currState->ttbcr.t0sz;
|
||||
currState->isUncacheable = currState->ttbcr.irgn0 == 0;
|
||||
if (ttbr0_max < (1ULL << 30)) // Upper limit < 1 GiB
|
||||
@@ -787,7 +795,8 @@ TableWalker::processWalkLPAE()
|
||||
ArmFault::LpaeTran);
|
||||
}
|
||||
ttbr = currState->tc->readMiscReg(snsBankedIndex(
|
||||
MISCREG_TTBR1, currState->tc, !currState->isSecure));
|
||||
MISCREG_TTBR1, currState->tc,
|
||||
currState->ss == SecurityState::NonSecure));
|
||||
tsz = currState->ttbcr.t1sz;
|
||||
currState->isUncacheable = currState->ttbcr.irgn1 == 0;
|
||||
// Lower limit >= 3 GiB
|
||||
@@ -818,14 +827,16 @@ TableWalker::processWalkLPAE()
|
||||
desc_addr = mbits(ttbr, 39, n) |
|
||||
(bits(currState->vaddr, n + 26, 30) << 3);
|
||||
DPRINTF(TLB, " - Descriptor at address %#x (%s) (long-desc.)\n",
|
||||
desc_addr, currState->isSecure ? "s" : "ns");
|
||||
desc_addr, currState->ss == SecurityState::Secure ?
|
||||
"s" : "ns");
|
||||
} else {
|
||||
// Skip first-level lookup
|
||||
n = (tsz >= 2 ? 14 - tsz : 12);
|
||||
desc_addr = mbits(ttbr, 39, n) |
|
||||
(bits(currState->vaddr, n + 17, 21) << 3);
|
||||
DPRINTF(TLB, " - Descriptor at address %#x (%s) (long-desc.)\n",
|
||||
desc_addr, currState->isSecure ? "s" : "ns");
|
||||
desc_addr, currState->ss == SecurityState::Secure ?
|
||||
"s" : "ns");
|
||||
}
|
||||
|
||||
if (uncacheableWalk()) {
|
||||
@@ -835,6 +846,7 @@ TableWalker::processWalkLPAE()
|
||||
currState->longDesc.lookupLevel = start_lookup_level;
|
||||
currState->longDesc.aarch64 = false;
|
||||
currState->longDesc.grainSize = Grain4KB;
|
||||
currState->longDesc.isStage2 = isStage2;
|
||||
|
||||
fetchDescriptor(
|
||||
desc_addr, currState->longDesc,
|
||||
@@ -896,12 +908,19 @@ TableWalker::processWalkAArch64()
|
||||
switch (currState->regime) {
|
||||
case TranslationRegime::EL10:
|
||||
if (isStage2) {
|
||||
if (currState->secureLookup) {
|
||||
if (currState->ss == SecurityState::Secure &&
|
||||
currState->ipaSpace == PASpace::Secure) {
|
||||
// Secure EL1&0 Secure IPA
|
||||
DPRINTF(TLB, " - Selecting VSTTBR_EL2 (AArch64 stage 2)\n");
|
||||
ttbr = currState->tc->readMiscReg(MISCREG_VSTTBR_EL2);
|
||||
currState->secureLookup = !currState->vtcr.sw;
|
||||
} else {
|
||||
// Secure EL1&0 NonSecure IPA or NonSecure EL1&0
|
||||
DPRINTF(TLB, " - Selecting VTTBR_EL2 (AArch64 stage 2)\n");
|
||||
ttbr = currState->tc->readMiscReg(MISCREG_VTTBR_EL2);
|
||||
currState->secureLookup = currState->ss == SecurityState::Secure ?
|
||||
!currState->vtcr.nsw : // Secure EL1&0 NonSecure IPA
|
||||
false; // NonSecure EL1&0
|
||||
}
|
||||
tsz = 64 - currState->vtcr.t0sz64;
|
||||
tg = GrainMap_tg0[currState->vtcr.tg0];
|
||||
@@ -1087,6 +1106,7 @@ TableWalker::processWalkAArch64()
|
||||
currState->longDesc.aarch64 = true;
|
||||
currState->longDesc.grainSize = tg;
|
||||
currState->longDesc.physAddrRange = _physAddrRange;
|
||||
currState->longDesc.isStage2 = isStage2;
|
||||
|
||||
fetchDescriptor(desc_addr, currState->longDesc,
|
||||
sizeof(uint64_t), flag, start_lookup_level,
|
||||
@@ -1227,9 +1247,9 @@ TableWalker::memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
|
||||
} else {
|
||||
assert(tc);
|
||||
PRRR prrr = tc->readMiscReg(snsBankedIndex(MISCREG_PRRR,
|
||||
currState->tc, !currState->isSecure));
|
||||
currState->tc, currState->ss == SecurityState::NonSecure));
|
||||
NMRR nmrr = tc->readMiscReg(snsBankedIndex(MISCREG_NMRR,
|
||||
currState->tc, !currState->isSecure));
|
||||
currState->tc, currState->ss == SecurityState::NonSecure));
|
||||
DPRINTF(TLBVerbose, "memAttrs PRRR:%08x NMRR:%08x\n", prrr, nmrr);
|
||||
uint8_t curr_tr = 0, curr_ir = 0, curr_or = 0;
|
||||
switch(bits(texcb, 2,0)) {
|
||||
@@ -1391,7 +1411,7 @@ TableWalker::memAttrsLPAE(ThreadContext *tc, TlbEntry &te,
|
||||
// value of SCTLR.TRE
|
||||
MiscRegIndex reg = attrIndx & 0x4 ? MISCREG_MAIR1 : MISCREG_MAIR0;
|
||||
int reg_as_int = snsBankedIndex(reg, currState->tc,
|
||||
!currState->isSecure);
|
||||
currState->ss == SecurityState::NonSecure);
|
||||
uint32_t mair = currState->tc->readMiscReg(reg_as_int);
|
||||
attr = (mair >> (8 * (attrIndx % 4))) & 0xff;
|
||||
uint8_t attr_7_4 = bits(attr, 7, 4);
|
||||
@@ -1674,7 +1694,8 @@ TableWalker::doL1Descriptor()
|
||||
l2desc_addr = currState->l1Desc.l2Addr() |
|
||||
(bits(currState->vaddr, 19, 12) << 2);
|
||||
DPRINTF(TLB, "L1 descriptor points to page table at: %#x (%s)\n",
|
||||
l2desc_addr, currState->isSecure ? "s" : "ns");
|
||||
l2desc_addr, currState->ss == SecurityState::Secure ?
|
||||
"s" : "ns");
|
||||
|
||||
Request::Flags flag = Request::PT_WALK;
|
||||
|
||||
@@ -1798,8 +1819,10 @@ TableWalker::doLongDescriptor()
|
||||
case LongDescriptor::Table:
|
||||
{
|
||||
// Set hierarchical permission flags
|
||||
currState->secureLookup = currState->secureLookup &&
|
||||
currState->longDesc.secureTable();
|
||||
if (!isStage2) {
|
||||
currState->secureLookup = currState->secureLookup &&
|
||||
currState->longDesc.secureTable();
|
||||
}
|
||||
currState->longDescData->rwTable =
|
||||
currState->longDescData->rwTable &&
|
||||
(currState->longDesc.rwTable() || currState->hpd);
|
||||
@@ -2234,7 +2257,8 @@ TableWalker::insertPartialTableEntry(LongDescriptor &descriptor)
|
||||
te.domain = descriptor.domain();
|
||||
te.lookupLevel = descriptor.lookupLevel;
|
||||
te.ns = !descriptor.secure(have_security, currState);
|
||||
te.nstid = !currState->isSecure;
|
||||
te.ss = currState->ss;
|
||||
te.ipaSpace = currState->ipaSpace; // Used by stage2 entries only
|
||||
te.type = TypeTLB::unified;
|
||||
|
||||
te.regime = currState->regime;
|
||||
@@ -2280,7 +2304,8 @@ TableWalker::insertTableEntry(DescriptorBase &descriptor, bool long_descriptor)
|
||||
te.domain = descriptor.domain();
|
||||
te.lookupLevel = descriptor.lookupLevel;
|
||||
te.ns = !descriptor.secure(have_security, currState);
|
||||
te.nstid = !currState->isSecure;
|
||||
te.ss = currState->ss;
|
||||
te.ipaSpace = currState->ipaSpace; // Used by stage2 entries only
|
||||
te.xn = descriptor.xn();
|
||||
te.type = currState->mode == BaseMMU::Execute ?
|
||||
TypeTLB::instruction : TypeTLB::data;
|
||||
@@ -2379,7 +2404,8 @@ TableWalker::testWalk(const RequestPtr &walk_req, TlbEntry::DomainType domain,
|
||||
if (!test) {
|
||||
return NoFault;
|
||||
} else {
|
||||
return test->walkCheck(walk_req, currState->vaddr, currState->isSecure,
|
||||
return test->walkCheck(walk_req, currState->vaddr,
|
||||
currState->ss == SecurityState::Secure,
|
||||
currState->el != EL0,
|
||||
currState->mode, domain, lookup_level);
|
||||
}
|
||||
|
||||
@@ -436,7 +436,7 @@ class TableWalker : public ClockedObject
|
||||
|
||||
LongDescriptor()
|
||||
: data(0), _dirty(false), aarch64(false), grainSize(Grain4KB),
|
||||
physAddrRange(0)
|
||||
physAddrRange(0), isStage2(false)
|
||||
{}
|
||||
|
||||
/** The raw bits of the entry */
|
||||
@@ -454,6 +454,8 @@ class TableWalker : public ClockedObject
|
||||
|
||||
uint8_t physAddrRange;
|
||||
|
||||
bool isStage2;
|
||||
|
||||
uint8_t*
|
||||
getRawPtr() override
|
||||
{
|
||||
@@ -491,8 +493,13 @@ class TableWalker : public ClockedObject
|
||||
secure(bool have_security, WalkerState *currState) const override
|
||||
{
|
||||
if (type() == Block || type() == Page) {
|
||||
return have_security &&
|
||||
(currState->secureLookup && !bits(data, 5));
|
||||
if (isStage2) {
|
||||
return have_security && currState->secureLookup &&
|
||||
!currState->vtcr.nsa;
|
||||
} else {
|
||||
return have_security &&
|
||||
(currState->secureLookup && !bits(data, 5));
|
||||
}
|
||||
} else {
|
||||
return have_security && currState->secureLookup;
|
||||
}
|
||||
@@ -662,8 +669,9 @@ class TableWalker : public ClockedObject
|
||||
global(WalkerState *currState) const override
|
||||
{
|
||||
assert(currState && (type() == Block || type() == Page));
|
||||
if (!currState->aarch64 && (currState->isSecure &&
|
||||
!currState->secureLookup)) {
|
||||
const bool secure_state = currState->ss == SecurityState::Secure;
|
||||
if (!currState->aarch64 && secure_state &&
|
||||
!currState->secureLookup) {
|
||||
return false; // ARM ARM issue C B3.6.3
|
||||
} else if (currState->aarch64) {
|
||||
if (!MMU::hasUnprivRegime(currState->regime)) {
|
||||
@@ -671,7 +679,7 @@ class TableWalker : public ClockedObject
|
||||
// in AArch64 for regimes without an unpriviledged
|
||||
// component
|
||||
return true;
|
||||
} else if (currState->isSecure && !currState->secureLookup) {
|
||||
} else if (secure_state && !currState->secureLookup) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -896,13 +904,18 @@ class TableWalker : public ClockedObject
|
||||
/** If the access is a fetch (for execution, and no-exec) must be checked?*/
|
||||
bool isFetch;
|
||||
|
||||
/** If the access comes from the secure state. */
|
||||
bool isSecure;
|
||||
/** Security State of the access */
|
||||
SecurityState ss;
|
||||
/** Whether lookups should be treated as using the secure state.
|
||||
* This is usually the same as isSecure, but can be set to false by the
|
||||
* long descriptor table attributes. */
|
||||
bool secureLookup = false;
|
||||
|
||||
/** IPA space (Secure vs NonSecure); stage2 only.
|
||||
* This depends on whether the stage1 translation targeted
|
||||
* a secure or non-secure IPA space */
|
||||
PASpace ipaSpace;
|
||||
|
||||
/** True if table walks are uncacheable (for table descriptors) */
|
||||
bool isUncacheable;
|
||||
|
||||
@@ -1139,7 +1152,8 @@ class TableWalker : public ClockedObject
|
||||
Fault walk(const RequestPtr &req, ThreadContext *tc,
|
||||
uint16_t asid, vmid_t _vmid,
|
||||
BaseMMU::Mode mode, BaseMMU::Translation *_trans,
|
||||
bool timing, bool functional, bool secure,
|
||||
bool timing, bool functional, SecurityState ss,
|
||||
PASpace ipaspace,
|
||||
MMU::ArmTranslationType tran_type, bool stage2,
|
||||
const TlbEntry *walk_entry);
|
||||
|
||||
|
||||
@@ -160,15 +160,16 @@ TLB::lookup(const Lookup &lookup_data)
|
||||
|
||||
TlbEntry *retval = match(lookup_data);
|
||||
|
||||
DPRINTF(TLBVerbose, "Lookup %#x, asn %#x -> %s vmn 0x%x secure %d "
|
||||
"ppn %#x size: %#x pa: %#x ap:%d ns:%d nstid:%d g:%d asid: %d "
|
||||
DPRINTF(TLBVerbose, "Lookup %#x, asn %#x -> %s vmn 0x%x ss %s "
|
||||
"ppn %#x size: %#x pa: %#x ap:%d ns:%d ss:%s g:%d asid: %d "
|
||||
"xs: %d regime: %s\n",
|
||||
lookup_data.va, lookup_data.asn, retval ? "hit" : "miss",
|
||||
lookup_data.vmid, lookup_data.secure,
|
||||
lookup_data.vmid, lookup_data.ss,
|
||||
retval ? retval->pfn : 0, retval ? retval->size : 0,
|
||||
retval ? retval->pAddr(lookup_data.va) : 0,
|
||||
retval ? retval->ap : 0,
|
||||
retval ? retval->ns : 0, retval ? retval->nstid : 0,
|
||||
retval ? retval->ns : 0,
|
||||
retval ? retval->ss : SecurityState::NonSecure,
|
||||
retval ? retval->global : 0, retval ? retval->asid : 0,
|
||||
retval ? retval->xs : 0,
|
||||
retval ? regimeToStr(retval->regime) : "None");
|
||||
@@ -243,19 +244,19 @@ TLB::insert(TlbEntry &entry)
|
||||
{
|
||||
DPRINTF(TLB, "Inserting entry into TLB with pfn:%#x size:%#x vpn: %#x"
|
||||
" asid:%d vmid:%d N:%d global:%d valid:%d nc:%d xn:%d"
|
||||
" ap:%#x domain:%#x ns:%d nstid:%d, xs:%d regime: %s\n", entry.pfn,
|
||||
" ap:%#x domain:%#x ns:%d ss:%s xs:%d regime: %s\n", entry.pfn,
|
||||
entry.size, entry.vpn, entry.asid, entry.vmid, entry.N,
|
||||
entry.global, entry.valid, entry.nonCacheable, entry.xn,
|
||||
entry.ap, static_cast<uint8_t>(entry.domain), entry.ns,
|
||||
entry.nstid, entry.xs, regimeToStr(entry.regime));
|
||||
entry.ss, entry.xs, regimeToStr(entry.regime));
|
||||
|
||||
if (table[size - 1].valid)
|
||||
DPRINTF(TLB, " - Replacing Valid entry %#x, asn %d vmn %d ppn %#x "
|
||||
"size: %#x ap:%d ns:%d nstid:%d g:%d xs:%d regime: %s\n",
|
||||
"size: %#x ap:%d ns:%d ss:%s g:%d xs:%d regime: %s\n",
|
||||
table[size-1].vpn << table[size-1].N, table[size-1].asid,
|
||||
table[size-1].vmid, table[size-1].pfn << table[size-1].N,
|
||||
table[size-1].size, table[size-1].ap, table[size-1].ns,
|
||||
table[size-1].nstid, table[size-1].global,
|
||||
table[size-1].ss, table[size-1].global,
|
||||
table[size-1].xs, regimeToStr(table[size-1].regime));
|
||||
|
||||
// inserting to MRU position and evicting the LRU one
|
||||
|
||||
@@ -69,7 +69,7 @@ TLBIALL::operator()(ThreadContext* tc)
|
||||
bool
|
||||
TLBIALL::matchEntry(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
return te->valid && secureLookup == !te->nstid &&
|
||||
return te->valid && ss == te->ss &&
|
||||
(te->vmid == vmid || el2Enabled) &&
|
||||
te->checkRegime(targetRegime);
|
||||
}
|
||||
@@ -115,7 +115,7 @@ TLBIALLEL::operator()(ThreadContext* tc)
|
||||
bool
|
||||
TLBIALLEL::matchEntry(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
return te->valid && secureLookup == !te->nstid &&
|
||||
return te->valid && ss == te->ss &&
|
||||
te->checkRegime(targetRegime);
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ TLBIVMALL::operator()(ThreadContext* tc)
|
||||
bool
|
||||
TLBIVMALL::matchEntry(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
return te->valid && secureLookup == !te->nstid &&
|
||||
return te->valid && ss == te->ss &&
|
||||
te->checkRegime(targetRegime) &&
|
||||
(te->vmid == vmid || !el2Enabled || !useVMID(targetRegime));
|
||||
}
|
||||
@@ -157,7 +157,7 @@ bool
|
||||
TLBIASID::matchEntry(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
return te->valid && te->asid == asid &&
|
||||
secureLookup == !te->nstid &&
|
||||
ss == te->ss &&
|
||||
te->checkRegime(targetRegime) &&
|
||||
(te->vmid == vmid || !el2Enabled || !useVMID(targetRegime));
|
||||
}
|
||||
@@ -202,7 +202,7 @@ TLBIALLN::operator()(ThreadContext* tc)
|
||||
bool
|
||||
TLBIALLN::matchEntry(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
return te->valid && te->nstid &&
|
||||
return te->valid && te->ss == SecurityState::NonSecure &&
|
||||
te->checkRegime(targetRegime);
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ TLBIMVAA::lookupGen(vmid_t vmid) const
|
||||
lookup_data.va = sext<56>(addr);
|
||||
lookup_data.ignoreAsn = true;
|
||||
lookup_data.vmid = vmid;
|
||||
lookup_data.secure = secureLookup;
|
||||
lookup_data.ss = ss;
|
||||
lookup_data.functional = true;
|
||||
lookup_data.targetRegime = targetRegime;
|
||||
lookup_data.mode = BaseMMU::Read;
|
||||
@@ -247,7 +247,7 @@ TLBIMVA::lookupGen(vmid_t vmid) const
|
||||
lookup_data.asn = asid;
|
||||
lookup_data.ignoreAsn = false;
|
||||
lookup_data.vmid = vmid;
|
||||
lookup_data.secure = secureLookup;
|
||||
lookup_data.ss = ss;
|
||||
lookup_data.functional = true;
|
||||
lookup_data.targetRegime = targetRegime;
|
||||
lookup_data.mode = BaseMMU::Read;
|
||||
@@ -301,14 +301,37 @@ DTLBIMVA::matchEntry(TlbEntry* te, vmid_t vmid) const
|
||||
void
|
||||
TLBIIPA::operator()(ThreadContext* tc)
|
||||
{
|
||||
getMMUPtr(tc)->flushStage2(makeStage2());
|
||||
getMMUPtr(tc)->flushStage2(*this);
|
||||
|
||||
CheckerCPU *checker = tc->getCheckerCpuPtr();
|
||||
if (checker) {
|
||||
getMMUPtr(checker)->flushStage2(makeStage2());
|
||||
getMMUPtr(checker)->flushStage2(*this);
|
||||
}
|
||||
}
|
||||
|
||||
TlbEntry::Lookup
|
||||
TLBIIPA::lookupGen(vmid_t vmid) const
|
||||
{
|
||||
TlbEntry::Lookup lookup_data;
|
||||
lookup_data.va = szext<56>(addr);
|
||||
lookup_data.ignoreAsn = true;
|
||||
lookup_data.vmid = vmid;
|
||||
lookup_data.ss = ss;
|
||||
lookup_data.functional = true;
|
||||
lookup_data.targetRegime = targetRegime;
|
||||
lookup_data.mode = BaseMMU::Read;
|
||||
return lookup_data;
|
||||
}
|
||||
|
||||
bool
|
||||
TLBIIPA::matchEntry(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
TlbEntry::Lookup lookup_data = lookupGen(vmid);
|
||||
|
||||
return te->match(lookup_data) && (!lastLevel || !te->partial) &&
|
||||
ipaSpace == te->ipaSpace;
|
||||
}
|
||||
|
||||
bool
|
||||
TLBIRMVA::matchEntry(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
@@ -341,5 +364,22 @@ TLBIRMVAA::matchEntry(TlbEntry* te, vmid_t vmid) const
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TLBIRIPA::matchEntry(TlbEntry* te, vmid_t vmid) const
|
||||
{
|
||||
TlbEntry::Lookup lookup_data = lookupGen(vmid);
|
||||
lookup_data.size = rangeSize();
|
||||
|
||||
auto addr_match = te->match(lookup_data) && (!lastLevel || !te->partial);
|
||||
if (addr_match) {
|
||||
return ipaSpace == te->ipaSpace &&
|
||||
tgMap[rangeData.tg] == te->tg &&
|
||||
(resTLBIttl(rangeData.tg, rangeData.ttl) ||
|
||||
rangeData.ttl == te->lookupLevel);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ArmISA
|
||||
} // namespace gem5
|
||||
|
||||
@@ -63,8 +63,8 @@ class TLBIOp
|
||||
ExcludeXS
|
||||
};
|
||||
|
||||
TLBIOp(TranslationRegime _target_regime, bool _secure, Attr _attr)
|
||||
: secureLookup(_secure), targetRegime(_target_regime), attr(_attr)
|
||||
TLBIOp(TranslationRegime _target_regime, SecurityState _ss, Attr _attr)
|
||||
: ss(_ss), targetRegime(_target_regime), attr(_attr)
|
||||
{}
|
||||
|
||||
virtual ~TLBIOp() {}
|
||||
@@ -108,7 +108,7 @@ class TLBIOp
|
||||
return false;
|
||||
}
|
||||
|
||||
bool secureLookup;
|
||||
SecurityState ss;
|
||||
TranslationRegime targetRegime;
|
||||
Attr attr;
|
||||
};
|
||||
@@ -117,9 +117,9 @@ class TLBIOp
|
||||
class TLBIALL : public TLBIOp
|
||||
{
|
||||
public:
|
||||
TLBIALL(TranslationRegime _target_regime, bool _secure,
|
||||
TLBIALL(TranslationRegime _target_regime, SecurityState _ss,
|
||||
Attr _attr=Attr::None)
|
||||
: TLBIOp(_target_regime, _secure, _attr), el2Enabled(false),
|
||||
: TLBIOp(_target_regime, _ss, _attr), el2Enabled(false),
|
||||
currentEL(EL0)
|
||||
{}
|
||||
|
||||
@@ -135,12 +135,6 @@ class TLBIALL : public TLBIOp
|
||||
return currentEL == EL2;
|
||||
}
|
||||
|
||||
TLBIALL
|
||||
makeStage2() const
|
||||
{
|
||||
return TLBIALL(targetRegime, secureLookup, attr);
|
||||
}
|
||||
|
||||
bool el2Enabled;
|
||||
ExceptionLevel currentEL;
|
||||
};
|
||||
@@ -149,8 +143,8 @@ class TLBIALL : public TLBIOp
|
||||
class ITLBIALL : public TLBIALL
|
||||
{
|
||||
public:
|
||||
ITLBIALL(TranslationRegime _target_regime, bool _secure)
|
||||
: TLBIALL(_target_regime, _secure)
|
||||
ITLBIALL(TranslationRegime _target_regime, SecurityState _ss)
|
||||
: TLBIALL(_target_regime, _ss)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -162,8 +156,8 @@ class ITLBIALL : public TLBIALL
|
||||
class DTLBIALL : public TLBIALL
|
||||
{
|
||||
public:
|
||||
DTLBIALL(TranslationRegime _target_regime, bool _secure)
|
||||
: TLBIALL(_target_regime, _secure)
|
||||
DTLBIALL(TranslationRegime _target_regime, SecurityState _ss)
|
||||
: TLBIALL(_target_regime, _ss)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -175,8 +169,8 @@ class DTLBIALL : public TLBIALL
|
||||
class TLBIALLEL : public TLBIOp
|
||||
{
|
||||
public:
|
||||
TLBIALLEL(TranslationRegime _target_regime, bool _secure, Attr _attr)
|
||||
: TLBIOp(_target_regime, _secure, _attr)
|
||||
TLBIALLEL(TranslationRegime _target_regime, SecurityState _ss, Attr _attr)
|
||||
: TLBIOp(_target_regime, _ss, _attr)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -190,22 +184,15 @@ class TLBIALLEL : public TLBIOp
|
||||
return targetRegime == TranslationRegime::EL10 ||
|
||||
targetRegime == TranslationRegime::EL20;
|
||||
}
|
||||
|
||||
TLBIALLEL
|
||||
makeStage2() const
|
||||
{
|
||||
return TLBIALLEL(targetRegime, secureLookup, attr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Implementaton of AArch64 TLBI VMALLE1(IS)/VMALLS112E1(IS) instructions */
|
||||
class TLBIVMALL : public TLBIOp
|
||||
{
|
||||
public:
|
||||
TLBIVMALL(TranslationRegime _target_regime, bool _secure,
|
||||
bool _stage2, Attr _attr)
|
||||
: TLBIOp(_target_regime, _secure, _attr), el2Enabled(false),
|
||||
TLBIVMALL(TranslationRegime _target_regime,
|
||||
SecurityState _ss, bool _stage2, Attr _attr)
|
||||
: TLBIOp(_target_regime, _ss, _attr), el2Enabled(false),
|
||||
stage2(_stage2)
|
||||
{}
|
||||
|
||||
@@ -219,12 +206,6 @@ class TLBIVMALL : public TLBIOp
|
||||
return stage2;
|
||||
}
|
||||
|
||||
TLBIVMALL
|
||||
makeStage2() const
|
||||
{
|
||||
return TLBIVMALL(targetRegime, secureLookup, false, attr);
|
||||
}
|
||||
|
||||
bool el2Enabled;
|
||||
bool stage2;
|
||||
};
|
||||
@@ -233,9 +214,9 @@ class TLBIVMALL : public TLBIOp
|
||||
class TLBIASID : public TLBIOp
|
||||
{
|
||||
public:
|
||||
TLBIASID(TranslationRegime _target_regime, bool _secure,
|
||||
TLBIASID(TranslationRegime _target_regime, SecurityState _ss,
|
||||
uint16_t _asid, Attr _attr=Attr::None)
|
||||
: TLBIOp(_target_regime, _secure, _attr), asid(_asid),
|
||||
: TLBIOp(_target_regime, _ss, _attr), asid(_asid),
|
||||
el2Enabled(false)
|
||||
{}
|
||||
|
||||
@@ -251,8 +232,9 @@ class TLBIASID : public TLBIOp
|
||||
class ITLBIASID : public TLBIASID
|
||||
{
|
||||
public:
|
||||
ITLBIASID(TranslationRegime _target_regime, bool _secure, uint16_t _asid)
|
||||
: TLBIASID(_target_regime, _secure, _asid)
|
||||
ITLBIASID(TranslationRegime _target_regime,
|
||||
SecurityState _ss, uint16_t _asid)
|
||||
: TLBIASID(_target_regime, _ss, _asid)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -264,8 +246,9 @@ class ITLBIASID : public TLBIASID
|
||||
class DTLBIASID : public TLBIASID
|
||||
{
|
||||
public:
|
||||
DTLBIASID(TranslationRegime _target_regime, bool _secure, uint16_t _asid)
|
||||
: TLBIASID(_target_regime, _secure, _asid)
|
||||
DTLBIASID(TranslationRegime _target_regime,
|
||||
SecurityState _ss, uint16_t _asid)
|
||||
: TLBIASID(_target_regime, _ss, _asid)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -278,7 +261,7 @@ class TLBIALLN : public TLBIOp
|
||||
{
|
||||
public:
|
||||
TLBIALLN(TranslationRegime _target_regime)
|
||||
: TLBIOp(_target_regime, false, Attr::None)
|
||||
: TLBIOp(_target_regime, SecurityState::NonSecure, Attr::None)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -290,12 +273,6 @@ class TLBIALLN : public TLBIOp
|
||||
{
|
||||
return targetRegime != TranslationRegime::EL2;
|
||||
}
|
||||
|
||||
TLBIALLN
|
||||
makeStage2() const
|
||||
{
|
||||
return TLBIALLN(targetRegime);
|
||||
}
|
||||
};
|
||||
|
||||
/** TLB Invalidate by VA, All ASID */
|
||||
@@ -304,9 +281,9 @@ class TLBIMVAA : public TLBIOp
|
||||
protected:
|
||||
TlbEntry::Lookup lookupGen(vmid_t vmid) const;
|
||||
public:
|
||||
TLBIMVAA(TranslationRegime _target_regime, bool _secure,
|
||||
TLBIMVAA(TranslationRegime _target_regime, SecurityState _ss,
|
||||
Addr _addr, bool last_level, Attr _attr=Attr::None)
|
||||
: TLBIOp(_target_regime, _secure, _attr), addr(_addr),
|
||||
: TLBIOp(_target_regime, _ss, _attr), addr(_addr),
|
||||
lastLevel(last_level)
|
||||
{}
|
||||
|
||||
@@ -325,10 +302,10 @@ class TLBIMVA : public TLBIOp
|
||||
TlbEntry::Lookup lookupGen(vmid_t vmid) const;
|
||||
|
||||
public:
|
||||
TLBIMVA(TranslationRegime _target_regime, bool _secure,
|
||||
TLBIMVA(TranslationRegime _target_regime, SecurityState _ss,
|
||||
Addr _addr, uint16_t _asid, bool last_level,
|
||||
Attr _attr=Attr::None)
|
||||
: TLBIOp(_target_regime, _secure, _attr), addr(_addr), asid(_asid),
|
||||
: TLBIOp(_target_regime, _ss, _attr), addr(_addr), asid(_asid),
|
||||
lastLevel(last_level)
|
||||
{}
|
||||
|
||||
@@ -345,9 +322,9 @@ class TLBIMVA : public TLBIOp
|
||||
class ITLBIMVA : public TLBIMVA
|
||||
{
|
||||
public:
|
||||
ITLBIMVA(TranslationRegime _target_regime, bool _secure,
|
||||
ITLBIMVA(TranslationRegime _target_regime, SecurityState _ss,
|
||||
Addr _addr, uint16_t _asid)
|
||||
: TLBIMVA(_target_regime, _secure, _addr, _asid, false)
|
||||
: TLBIMVA(_target_regime, _ss, _addr, _asid, false)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -359,9 +336,9 @@ class ITLBIMVA : public TLBIMVA
|
||||
class DTLBIMVA : public TLBIMVA
|
||||
{
|
||||
public:
|
||||
DTLBIMVA(TranslationRegime _target_regime, bool _secure,
|
||||
DTLBIMVA(TranslationRegime _target_regime, SecurityState _ss,
|
||||
Addr _addr, uint16_t _asid)
|
||||
: TLBIMVA(_target_regime, _secure, _addr, _asid, false)
|
||||
: TLBIMVA(_target_regime, _ss, _addr, _asid, false)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -427,20 +404,45 @@ class TLBIRange
|
||||
/** TLB Invalidate by Intermediate Physical Address */
|
||||
class TLBIIPA : public TLBIOp
|
||||
{
|
||||
protected:
|
||||
TlbEntry::Lookup lookupGen(vmid_t vmid) const;
|
||||
public:
|
||||
TLBIIPA(TranslationRegime _target_regime, bool _secure, Addr _addr,
|
||||
TLBIIPA(TranslationRegime _target_regime, SecurityState _ss, Addr _addr,
|
||||
bool last_level, Attr _attr=Attr::None)
|
||||
: TLBIOp(_target_regime, _secure, _attr),
|
||||
addr(_addr), lastLevel(last_level)
|
||||
: TLBIOp(_target_regime, _ss, _attr),
|
||||
addr(_addr),
|
||||
lastLevel(last_level),
|
||||
ipaSpace(PASpace::NonSecure)
|
||||
{}
|
||||
|
||||
TLBIIPA(ThreadContext *tc, TranslationRegime _target_regime,
|
||||
SecurityState _ss, RegVal val,
|
||||
bool last_level, Attr _attr=Attr::None)
|
||||
: TLBIOp(_target_regime, _ss, _attr),
|
||||
addr(0),
|
||||
lastLevel(last_level),
|
||||
ipaSpace(PASpace::NonSecure)
|
||||
{
|
||||
const int top_bit = ArmSystem::physAddrRange(tc) == 52 ?
|
||||
39 : 35;
|
||||
addr = static_cast<Addr>(bits(val, top_bit, 0)) << 12;
|
||||
|
||||
switch (ss) {
|
||||
case SecurityState::NonSecure:
|
||||
ipaSpace = PASpace::NonSecure;
|
||||
break;
|
||||
case SecurityState::Secure:
|
||||
ipaSpace = bits(val, 63) ?
|
||||
PASpace::NonSecure : PASpace::Secure;
|
||||
break;
|
||||
default:
|
||||
panic("Invalid SecurityState\n");
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
|
||||
bool
|
||||
matchEntry(TlbEntry *entry, vmid_t curr_vmid) const override
|
||||
{
|
||||
panic("This shouldn't be called\n");
|
||||
}
|
||||
bool matchEntry(TlbEntry *entry, vmid_t curr_vmid) const override;
|
||||
|
||||
bool
|
||||
stage1Flush() const override
|
||||
@@ -448,26 +450,19 @@ class TLBIIPA : public TLBIOp
|
||||
return false;
|
||||
}
|
||||
|
||||
/** TLBIIPA is basically a TLBIMVAA for stage2 TLBs */
|
||||
virtual TLBIMVAA
|
||||
makeStage2() const
|
||||
{
|
||||
return TLBIMVAA(targetRegime, secureLookup, addr, lastLevel, attr);
|
||||
}
|
||||
|
||||
Addr addr;
|
||||
bool lastLevel;
|
||||
PASpace ipaSpace;
|
||||
};
|
||||
|
||||
/** TLB Range Invalidate by VA */
|
||||
class TLBIRMVA : public TLBIRange, public TLBIMVA
|
||||
{
|
||||
public:
|
||||
TLBIRMVA(TranslationRegime _target_regime, bool _secure,
|
||||
TLBIRMVA(TranslationRegime _target_regime, SecurityState _ss,
|
||||
RegVal val, uint16_t _asid, bool last_level, Attr _attr)
|
||||
: TLBIRange(val),
|
||||
TLBIMVA(_target_regime, _secure, startAddress(),
|
||||
_asid, last_level, _attr)
|
||||
TLBIMVA(_target_regime, _ss, startAddress(), _asid, last_level, _attr)
|
||||
{}
|
||||
|
||||
bool matchEntry(TlbEntry *entry, vmid_t curr_vmid) const override;
|
||||
@@ -477,10 +472,10 @@ class TLBIRMVA : public TLBIRange, public TLBIMVA
|
||||
class TLBIRMVAA : public TLBIRange, public TLBIMVAA
|
||||
{
|
||||
public:
|
||||
TLBIRMVAA(TranslationRegime _target_regime, bool _secure,
|
||||
TLBIRMVAA(TranslationRegime _target_regime, SecurityState _ss,
|
||||
RegVal val, bool last_level, Attr _attr)
|
||||
: TLBIRange(val),
|
||||
TLBIMVAA(_target_regime, _secure, startAddress(), last_level, _attr)
|
||||
TLBIMVAA(_target_regime, _ss, startAddress(), last_level, _attr)
|
||||
{}
|
||||
|
||||
bool matchEntry(TlbEntry *entry, vmid_t curr_vmid) const override;
|
||||
@@ -490,18 +485,15 @@ class TLBIRMVAA : public TLBIRange, public TLBIMVAA
|
||||
class TLBIRIPA : public TLBIRange, public TLBIIPA
|
||||
{
|
||||
public:
|
||||
TLBIRIPA(TranslationRegime _target_regime, bool _secure,
|
||||
TLBIRIPA(ThreadContext *tc, TranslationRegime _target_regime, SecurityState _ss,
|
||||
RegVal val, bool last_level, Attr _attr)
|
||||
: TLBIRange(val),
|
||||
TLBIIPA(_target_regime, _secure, startAddress(), last_level, _attr)
|
||||
{}
|
||||
|
||||
virtual TLBIMVAA
|
||||
makeStage2() const
|
||||
TLBIIPA(tc, _target_regime, _ss, val, last_level, _attr)
|
||||
{
|
||||
return TLBIRMVAA(targetRegime, secureLookup, rangeData,
|
||||
lastLevel, attr);
|
||||
addr = startAddress();
|
||||
}
|
||||
|
||||
bool matchEntry(TlbEntry *entry, vmid_t curr_vmid) const override;
|
||||
};
|
||||
|
||||
} // namespace ArmISA
|
||||
|
||||
@@ -268,6 +268,20 @@ namespace ArmISA
|
||||
RND_NEAREST
|
||||
};
|
||||
|
||||
/** Security State */
|
||||
enum class SecurityState
|
||||
{
|
||||
NonSecure,
|
||||
Secure
|
||||
};
|
||||
|
||||
/** Physical Address Space */
|
||||
enum class PASpace
|
||||
{
|
||||
NonSecure,
|
||||
Secure
|
||||
};
|
||||
|
||||
enum ExceptionLevel
|
||||
{
|
||||
EL0 = 0,
|
||||
@@ -487,6 +501,22 @@ namespace ArmISA
|
||||
}
|
||||
}
|
||||
|
||||
static inline std::ostream&
|
||||
operator<<(std::ostream& os, SecurityState ss)
|
||||
{
|
||||
switch (ss) {
|
||||
case SecurityState::NonSecure:
|
||||
os << "NonSecure";
|
||||
break;
|
||||
case SecurityState::Secure:
|
||||
os << "Secure";
|
||||
break;
|
||||
default:
|
||||
panic("Invalid SecurityState\n");
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
constexpr unsigned MaxSveVecLenInBits = 2048;
|
||||
static_assert(MaxSveVecLenInBits >= 128 &&
|
||||
MaxSveVecLenInBits <= 2048 &&
|
||||
|
||||
@@ -89,13 +89,14 @@ isSecureBelowEL3(ThreadContext *tc)
|
||||
static_cast<SCR>(tc->readMiscRegNoEffect(MISCREG_SCR_EL3)).ns == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
isSecureAtEL(ThreadContext *tc, ExceptionLevel el)
|
||||
SecurityState
|
||||
securityStateAtEL(ThreadContext *tc, ExceptionLevel el)
|
||||
{
|
||||
if (ArmSystem::haveEL(tc, EL3) && el == EL3)
|
||||
return true;
|
||||
return SecurityState::Secure;
|
||||
else
|
||||
return isSecureBelowEL3(tc);
|
||||
return isSecureBelowEL3(tc) ? SecurityState::Secure :
|
||||
SecurityState::NonSecure;
|
||||
}
|
||||
|
||||
ExceptionLevel
|
||||
|
||||
@@ -217,7 +217,7 @@ int computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr,
|
||||
|
||||
bool isSecureBelowEL3(ThreadContext *tc);
|
||||
|
||||
bool isSecureAtEL(ThreadContext *tc, ExceptionLevel el);
|
||||
SecurityState securityStateAtEL(ThreadContext *tc, ExceptionLevel el);
|
||||
|
||||
bool longDescFormatInUse(ThreadContext *tc);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user