1
0

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.
This commit is contained in:
Andrew Waterman 2017-03-20 15:05:42 -07:00
parent 29e67279ba
commit 9e05200e51

View File

@ -56,18 +56,17 @@ class PMP(implicit p: Parameters) extends PMPReg {
} }
} }
private def boundMatch(x: UInt, lsbMask: UInt, lgMaxSize: Int) = { private def decomposedBoundMatch(xHi: UInt, xLo: UInt, lsbMask: UInt, lgMaxSize: Int) = {
if (lgMaxSize <= lgAlign) { val msbsLess = xHi < (comparand >> lgMaxSize)
x < comparand val msbsEqual = (xHi ^ (comparand >> lgMaxSize)) === 0
} else { val lsbsLess = xLo < (comparand(lgMaxSize-1, 0) & lsbMask(lgMaxSize-1, 0))
// break up the circuit; the MSB part will be CSE'd msbsLess || (msbsEqual && lsbsLess)
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 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) = private def lowerBoundMatch(x: UInt, lgSize: UInt, lgMaxSize: Int) =
!boundMatch(x, ((BigInt(1) << lgMaxSize) - 1).U << lgSize, lgMaxSize) !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)) !cfg.p(0) || Mux(cfg.a(1), rangeHomogeneous(x, pgLevel, lgMaxSize, prev), pow2Homogeneous(x, pgLevel))
// returns whether this matching PMP fully contains the access // returns whether this matching PMP fully contains the access
def aligned(x: UInt, lgSize: UInt, lgMaxSize: Int, prev: PMP): Bool = { def aligned(x: UInt, lgSize: UInt, lgMaxSize: Int, prev: PMP): Bool = if (lgMaxSize <= lgAlign) true.B else {
val alignMask = ~(((BigInt(1) << lgMaxSize) - 1).U << lgSize)(lgMaxSize-1, 0) val lsbMask = ((BigInt(1) << lgMaxSize) - 1).U << lgSize
val rangeAligned = (prev.comparand(lgMaxSize-1, 0) & alignMask) === 0 && (comparand(lgMaxSize-1, 0) & alignMask) === 0 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 val pow2Aligned = (alignMask & ~mask(lgMaxSize-1, 0)) === 0
Mux(cfg.a(1), rangeAligned, pow2Aligned) Mux(cfg.a(1), rangeAligned, pow2Aligned)
} }