arm: Fix stage 2 memory attribute checking in AArch64

Change-Id: I14c93a5460550051a12129e792a9a9bd522a145c
This commit is contained in:
Dylan Johnson 2016-08-02 10:38:03 +01:00
parent 02fcca9b6f
commit 89511856fe
2 changed files with 76 additions and 47 deletions

View file

@ -1337,9 +1337,38 @@ 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)
{
uint8_t attr;
uint8_t attr_hi;
uint8_t attr_lo;
uint8_t sh = lDescriptor.sh();
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
@ -1361,9 +1390,9 @@ TableWalker::memAttrsAArch64(ThreadContext *tc, TlbEntry &te, uint8_t attrIndx,
}
// 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);
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;
@ -1384,6 +1413,7 @@ TableWalker::memAttrsAArch64(ThreadContext *tc, TlbEntry &te, uint8_t attrIndx,
(te.ns << 9) | // NS bit
(sh << 7);
}
}
void
TableWalker::doL1Descriptor()
@ -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 {

View file

@ -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);