From 9e05200e5140e66a8d4d3a142f4851a3bab0d54c Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 20 Mar 2017 15:05:42 -0700 Subject: [PATCH] Don't require that PMP ranges be aligned to access size e.g., if a range permits access to 0x0-0xb, allow 8-byte accesses 0x0-0x7. --- src/main/scala/rocket/PMP.scala | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/main/scala/rocket/PMP.scala b/src/main/scala/rocket/PMP.scala index 484b3fd2..b2c97537 100644 --- a/src/main/scala/rocket/PMP.scala +++ b/src/main/scala/rocket/PMP.scala @@ -56,18 +56,17 @@ class PMP(implicit p: Parameters) extends PMPReg { } } - private def boundMatch(x: UInt, lsbMask: UInt, lgMaxSize: Int) = { - if (lgMaxSize <= lgAlign) { - x < comparand - } else { - // break up the circuit; the MSB part will be CSE'd - val msbsLess = (x >> lgMaxSize) < (comparand >> lgMaxSize) - val msbsEqual = ((x >> lgMaxSize) ^ (comparand >> lgMaxSize)) === 0 - val lsbsLess = x(lgMaxSize-1, 0) < (comparand(lgMaxSize-1, 0) & lsbMask(lgMaxSize-1, 0)) - msbsLess || (msbsEqual && lsbsLess) - } + private def decomposedBoundMatch(xHi: UInt, xLo: UInt, lsbMask: UInt, lgMaxSize: Int) = { + val msbsLess = xHi < (comparand >> lgMaxSize) + val msbsEqual = (xHi ^ (comparand >> lgMaxSize)) === 0 + val lsbsLess = xLo < (comparand(lgMaxSize-1, 0) & lsbMask(lgMaxSize-1, 0)) + msbsLess || (msbsEqual && lsbsLess) } + private def boundMatch(x: UInt, lsbMask: UInt, lgMaxSize: Int) = + if (lgMaxSize <= lgAlign) x < comparand + else decomposedBoundMatch(x >> lgMaxSize, x(lgMaxSize-1, 0), lsbMask, lgMaxSize) + private def lowerBoundMatch(x: UInt, lgSize: UInt, lgMaxSize: Int) = !boundMatch(x, ((BigInt(1) << lgMaxSize) - 1).U << lgSize, lgMaxSize) @@ -99,9 +98,12 @@ class PMP(implicit p: Parameters) extends PMPReg { !cfg.p(0) || Mux(cfg.a(1), rangeHomogeneous(x, pgLevel, lgMaxSize, prev), pow2Homogeneous(x, pgLevel)) // returns whether this matching PMP fully contains the access - def aligned(x: UInt, lgSize: UInt, lgMaxSize: Int, prev: PMP): Bool = { - val alignMask = ~(((BigInt(1) << lgMaxSize) - 1).U << lgSize)(lgMaxSize-1, 0) - val rangeAligned = (prev.comparand(lgMaxSize-1, 0) & alignMask) === 0 && (comparand(lgMaxSize-1, 0) & alignMask) === 0 + def aligned(x: UInt, lgSize: UInt, lgMaxSize: Int, prev: PMP): Bool = if (lgMaxSize <= lgAlign) true.B else { + val lsbMask = ((BigInt(1) << lgMaxSize) - 1).U << lgSize + val alignMask = ~lsbMask(lgMaxSize-1, 0) + val lowerBoundOK = !prev.upperBoundMatch(x, lgMaxSize) + val upperBoundOK = decomposedBoundMatch(x >> lgMaxSize, x(lgMaxSize-1, 0) | alignMask, lsbMask, lgMaxSize) + val rangeAligned = lowerBoundOK && upperBoundOK val pow2Aligned = (alignMask & ~mask(lgMaxSize-1, 0)) === 0 Mux(cfg.a(1), rangeAligned, pow2Aligned) }