summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDylan Johnson <Dylan.Johnson@ARM.com>2016-08-02 10:38:03 +0100
committerDylan Johnson <Dylan.Johnson@ARM.com>2016-08-02 10:38:03 +0100
commit89511856fe15077d4f568e3226aff66d1f3b39eb (patch)
treef7bcdbf67b863f85cb150e9ec2dede8e64d0b379 /src
parent02fcca9b6ff8a6f8db06cbd3f897956bc218a544 (diff)
downloadgem5-89511856fe15077d4f568e3226aff66d1f3b39eb.tar.xz
arm: Fix stage 2 memory attribute checking in AArch64
Change-Id: I14c93a5460550051a12129e792a9a9bd522a145c
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/table_walker.cc113
-rw-r--r--src/arch/arm/table_walker.hh4
2 files changed, 73 insertions, 44 deletions
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 1c1f70599..1f06d009a 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -1337,52 +1337,82 @@ TableWalker::memAttrsLPAE(ThreadContext *tc, TlbEntry &te,
}
void
-TableWalker::memAttrsAArch64(ThreadContext *tc, TlbEntry &te, uint8_t attrIndx,
- uint8_t sh)
+TableWalker::memAttrsAArch64(ThreadContext *tc, TlbEntry &te,
+ LongDescriptor &lDescriptor)
{
- DPRINTF(TLBVerbose, "memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx, sh);
+ uint8_t attr;
+ uint8_t attr_hi;
+ uint8_t attr_lo;
+ uint8_t sh = lDescriptor.sh();
- // Select MAIR
- uint64_t mair;
- switch (currState->el) {
- case EL0:
- case EL1:
- mair = tc->readMiscReg(MISCREG_MAIR_EL1);
- break;
- case EL2:
- mair = tc->readMiscReg(MISCREG_MAIR_EL2);
- break;
- case EL3:
- mair = tc->readMiscReg(MISCREG_MAIR_EL3);
- break;
- default:
- panic("Invalid exception level");
- break;
- }
+ if (isStage2) {
+ attr = lDescriptor.memAttr();
+ uint8_t attr_hi = (attr >> 2) & 0x3;
+ uint8_t attr_lo = attr & 0x3;
+
+ DPRINTF(TLBVerbose, "memAttrsAArch64 MemAttr:%#x sh:%#x\n", attr, sh);
+
+ if (attr_hi == 0) {
+ te.mtype = attr_lo == 0 ? TlbEntry::MemoryType::StronglyOrdered
+ : TlbEntry::MemoryType::Device;
+ te.outerAttrs = 0;
+ te.innerAttrs = attr_lo == 0 ? 1 : 3;
+ te.nonCacheable = true;
+ } else {
+ te.mtype = TlbEntry::MemoryType::Normal;
+ te.outerAttrs = attr_hi == 1 ? 0 :
+ attr_hi == 2 ? 2 : 1;
+ te.innerAttrs = attr_lo == 1 ? 0 :
+ attr_lo == 2 ? 6 : 5;
+ te.nonCacheable = (attr_hi == 1) || (attr_lo == 1);
+ }
+ } else {
+ uint8_t attrIndx = lDescriptor.attrIndx();
+
+ DPRINTF(TLBVerbose, "memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx, sh);
+
+ // Select MAIR
+ uint64_t mair;
+ switch (currState->el) {
+ case EL0:
+ case EL1:
+ mair = tc->readMiscReg(MISCREG_MAIR_EL1);
+ break;
+ case EL2:
+ mair = tc->readMiscReg(MISCREG_MAIR_EL2);
+ break;
+ case EL3:
+ mair = tc->readMiscReg(MISCREG_MAIR_EL3);
+ break;
+ default:
+ panic("Invalid exception level");
+ break;
+ }
- // Select attributes
- uint8_t attr = bits(mair, 8 * attrIndx + 7, 8 * attrIndx);
- uint8_t attr_lo = bits(attr, 3, 0);
- uint8_t attr_hi = bits(attr, 7, 4);
+ // Select attributes
+ attr = bits(mair, 8 * attrIndx + 7, 8 * attrIndx);
+ attr_lo = bits(attr, 3, 0);
+ attr_hi = bits(attr, 7, 4);
- // Memory type
- te.mtype = attr_hi == 0 ? TlbEntry::MemoryType::Device : TlbEntry::MemoryType::Normal;
+ // Memory type
+ te.mtype = attr_hi == 0 ? TlbEntry::MemoryType::Device : TlbEntry::MemoryType::Normal;
- // Cacheability
- te.nonCacheable = false;
- if (te.mtype == TlbEntry::MemoryType::Device || // Device memory
- attr_hi == 0x8 || // Normal memory, Outer Non-cacheable
- attr_lo == 0x8) { // Normal memory, Inner Non-cacheable
- te.nonCacheable = true;
- }
+ // Cacheability
+ te.nonCacheable = false;
+ if (te.mtype == TlbEntry::MemoryType::Device || // Device memory
+ attr_hi == 0x8 || // Normal memory, Outer Non-cacheable
+ attr_lo == 0x8) { // Normal memory, Inner Non-cacheable
+ te.nonCacheable = true;
+ }
- te.shareable = sh == 2;
- te.outerShareable = (sh & 0x2) ? true : false;
- // Attributes formatted according to the 64-bit PAR
- te.attributes = ((uint64_t) attr << 56) |
- (1 << 11) | // LPAE bit
- (te.ns << 9) | // NS bit
- (sh << 7);
+ te.shareable = sh == 2;
+ te.outerShareable = (sh & 0x2) ? true : false;
+ // Attributes formatted according to the 64-bit PAR
+ te.attributes = ((uint64_t) attr << 56) |
+ (1 << 11) | // LPAE bit
+ (te.ns << 9) | // NS bit
+ (sh << 7);
+ }
}
void
@@ -2038,8 +2068,7 @@ TableWalker::insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
(currState->userTable && (descriptor.ap() & 0x1));
}
if (currState->aarch64)
- memAttrsAArch64(currState->tc, te, currState->longDesc.attrIndx(),
- currState->longDesc.sh());
+ memAttrsAArch64(currState->tc, te, lDescriptor);
else
memAttrsLPAE(currState->tc, te, lDescriptor);
} else {
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index e3c7d33d7..fc628f714 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -911,8 +911,8 @@ class TableWalker : public MemObject
uint8_t texcb, bool s);
void memAttrsLPAE(ThreadContext *tc, TlbEntry &te,
LongDescriptor &lDescriptor);
- void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, uint8_t attrIndx,
- uint8_t sh);
+ void memAttrsAArch64(ThreadContext *tc, TlbEntry &te,
+ LongDescriptor &lDescriptor);
static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);