From 4b164f8382e78e26dc796559ee58ee31abca5d4c Mon Sep 17 00:00:00 2001 From: Nikos Nikoleris Date: Mon, 27 Feb 2017 15:57:31 +0000 Subject: [PATCH] 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 Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/2280 Maintainer: Andreas Sandberg Reviewed-by: Jason Lowe-Power --- src/arch/arm/table_walker.cc | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index 82462ab33..8783d0a00 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012-2016 ARM Limited + * Copyright (c) 2010, 2012-2017 ARM Limited * All rights reserved * * 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; te.innerAttrs = attr_lo == 1 ? 0 : 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 { uint8_t attrIndx = lDescriptor.attrIndx(); @@ -1377,9 +1380,25 @@ TableWalker::memAttrsAArch64(ThreadContext *tc, TlbEntry &te, // 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 + if (te.mtype == TlbEntry::MemoryType::Device) { // Device memory + te.nonCacheable = true; + } + // 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; }