arm: Treat Write-Through Normal memory as Non-Cacheable

A completed write to a memory location that is Write-Through Cacheable
has to be visible to an external observer without the need of explicit
cache maintenance. This change adds support for Write-Through
Cacheable Normal memory and treats it as Non-cacheable. This incurs a
small penalty as accesses to the memory do not fill in the cache but
does not violate the properties of the memory type.

Change-Id: Iee17ef9d952a550be9ad660b1e60e9f6c4ef2c2d
Reviewed-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/2280
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
Nikos Nikoleris 2017-02-27 15:57:31 +00:00 committed by Andreas Sandberg
parent 31199bba53
commit 4b164f8382

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2012-2016 ARM Limited * Copyright (c) 2010, 2012-2017 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * The license below extends only to copyright in the software and shall
@ -1342,7 +1342,10 @@ TableWalker::memAttrsAArch64(ThreadContext *tc, TlbEntry &te,
attr_hi == 2 ? 2 : 1; attr_hi == 2 ? 2 : 1;
te.innerAttrs = attr_lo == 1 ? 0 : te.innerAttrs = attr_lo == 1 ? 0 :
attr_lo == 2 ? 6 : 5; attr_lo == 2 ? 6 : 5;
te.nonCacheable = (attr_hi == 1) || (attr_lo == 1); // Treat write-through memory as uncacheable, this is safe
// but for performance reasons not optimal.
te.nonCacheable = (attr_hi == 1) || (attr_hi == 2) ||
(attr_lo == 1) || (attr_lo == 2);
} }
} else { } else {
uint8_t attrIndx = lDescriptor.attrIndx(); uint8_t attrIndx = lDescriptor.attrIndx();
@ -1377,9 +1380,25 @@ TableWalker::memAttrsAArch64(ThreadContext *tc, TlbEntry &te,
// Cacheability // Cacheability
te.nonCacheable = false; te.nonCacheable = false;
if (te.mtype == TlbEntry::MemoryType::Device || // Device memory if (te.mtype == TlbEntry::MemoryType::Device) { // Device memory
attr_hi == 0x8 || // Normal memory, Outer Non-cacheable te.nonCacheable = true;
attr_lo == 0x8) { // Normal memory, Inner Non-cacheable }
// Treat write-through memory as uncacheable, this is safe
// but for performance reasons not optimal.
switch (attr_hi) {
case 0x1 ... 0x3: // Normal Memory, Outer Write-through transient
case 0x4: // Normal memory, Outer Non-cacheable
case 0x8 ... 0xb: // Normal Memory, Outer Write-through non-transient
te.nonCacheable = true;
}
switch (attr_lo) {
case 0x1 ... 0x3: // Normal Memory, Inner Write-through transient
case 0x9 ... 0xb: // Normal Memory, Inner Write-through non-transient
warn_if(!attr_hi, "Unpredictable behavior");
case 0x4: // Device-nGnRE memory or
// Normal memory, Inner Non-cacheable
case 0x8: // Device-nGRE memory or
// Normal memory, Inner Write-through non-transient
te.nonCacheable = true; te.nonCacheable = true;
} }