1
0

New PMP encoding

This commit is contained in:
Andrew Waterman 2017-03-30 00:31:34 -07:00
parent 2f2b472098
commit fd39eadcd6
4 changed files with 18 additions and 15 deletions

2
firrtl

@ -1 +1 @@
Subproject commit 2376ff9849beafaf02b657b461c15a36d7b38fd4 Subproject commit bda2bd363fbe66de9425bba12d96f5f9816a43ce

@ -1 +1 @@
Subproject commit 89d487023c1e59ff574872e2f51ee479cda380ab Subproject commit decf42b0f357220adb6722ddba362c6884321477

View File

@ -693,7 +693,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
} }
if (reg_pmp.nonEmpty) for (((pmp, next), i) <- (reg_pmp zip (reg_pmp.tail :+ reg_pmp.last)) zipWithIndex) { if (reg_pmp.nonEmpty) for (((pmp, next), i) <- (reg_pmp zip (reg_pmp.tail :+ reg_pmp.last)) zipWithIndex) {
require(xLen % pmp.cfg.getWidth == 0) require(xLen % pmp.cfg.getWidth == 0)
when (decoded_addr(CSRs.pmpcfg0 + pmpCfgIndex(i)) && !pmp.locked) { when (decoded_addr(CSRs.pmpcfg0 + pmpCfgIndex(i)) && !pmp.cfgLocked) {
pmp.cfg := new PMPConfig().fromBits(wdata >> ((i * pmp.cfg.getWidth) % xLen)) pmp.cfg := new PMPConfig().fromBits(wdata >> ((i * pmp.cfg.getWidth) % xLen))
} }
when (decoded_addr(CSRs.pmpaddr0 + i) && !pmp.addrLocked(next)) { when (decoded_addr(CSRs.pmpaddr0 + i) && !pmp.addrLocked(next)) {
@ -741,10 +741,11 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
} }
for (bp <- reg_bp drop nBreakpoints) for (bp <- reg_bp drop nBreakpoints)
bp := new BP().fromBits(0) bp := new BP().fromBits(0)
if (reg_pmp.nonEmpty) { for (pmp <- reg_pmp) {
for (pmp <- reg_pmp) { pmp.cfg.res := 0
if (!usingUser) pmp.cfg.m := true when (reset) {
when (reset) { pmp.cfg.p := 0 } pmp.cfg.a := 0
pmp.cfg.l := 0
} }
} }

View File

@ -9,9 +9,9 @@ import tile._
import util._ import util._
class PMPConfig extends Bundle { class PMPConfig extends Bundle {
val p = UInt(width = 2) val l = Bool()
val res = UInt(width = 2)
val a = UInt(width = 2) val a = UInt(width = 2)
val m = Bool()
val x = Bool() val x = Bool()
val w = Bool() val w = Bool()
val r = Bool() val r = Bool()
@ -32,8 +32,10 @@ class PMPReg(implicit p: Parameters) extends CoreBundle()(p) {
val cfg = new PMPConfig val cfg = new PMPConfig
val addr = UInt(width = paddrBits - PMP.lgAlign) val addr = UInt(width = paddrBits - PMP.lgAlign)
def locked = cfg.p(1) def napot = cfg.a(1)
def addrLocked(next: PMPReg) = locked || next.locked && next.cfg.a(1) def torNotNAPOT = cfg.a(0)
def cfgLocked = cfg.l
def addrLocked(next: PMPReg) = cfgLocked || next.cfgLocked && next.cfg.a(1)
} }
class PMP(implicit p: Parameters) extends PMPReg { class PMP(implicit p: Parameters) extends PMPReg {
@ -99,7 +101,7 @@ class PMP(implicit p: Parameters) extends PMPReg {
// returns whether this PMP completely contains, or contains none of, a page // returns whether this PMP completely contains, or contains none of, a page
def homogeneous(x: UInt, pgLevel: UInt, prev: PMP): Bool = def homogeneous(x: UInt, pgLevel: UInt, prev: PMP): Bool =
!cfg.p(0) || Mux(cfg.a(1), rangeHomogeneous(x, pgLevel, prev), pow2Homogeneous(x, pgLevel)) Mux(napot, pow2Homogeneous(x, pgLevel), !torNotNAPOT || rangeHomogeneous(x, pgLevel, prev))
// 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 = if (lgMaxSize <= lgAlign) true.B else { def aligned(x: UInt, lgSize: UInt, lgMaxSize: Int, prev: PMP): Bool = if (lgMaxSize <= lgAlign) true.B else {
@ -108,12 +110,12 @@ class PMP(implicit p: Parameters) extends PMPReg {
val straddlesUpperBound = ((x >> lgMaxSize) ^ (comparand >> lgMaxSize)) === 0 && (comparand(lgMaxSize-1, 0) & (x(lgMaxSize-1, 0) | lsbMask)) =/= 0 val straddlesUpperBound = ((x >> lgMaxSize) ^ (comparand >> lgMaxSize)) === 0 && (comparand(lgMaxSize-1, 0) & (x(lgMaxSize-1, 0) | lsbMask)) =/= 0
val rangeAligned = !(straddlesLowerBound || straddlesUpperBound) val rangeAligned = !(straddlesLowerBound || straddlesUpperBound)
val pow2Aligned = (lsbMask & ~mask(lgMaxSize-1, 0)) === 0 val pow2Aligned = (lsbMask & ~mask(lgMaxSize-1, 0)) === 0
Mux(cfg.a(1), rangeAligned, pow2Aligned) Mux(napot, pow2Aligned, rangeAligned)
} }
// returns whether this PMP matches at least one byte of the access // returns whether this PMP matches at least one byte of the access
def hit(x: UInt, lgSize: UInt, lgMaxSize: Int, prev: PMP): Bool = def hit(x: UInt, lgSize: UInt, lgMaxSize: Int, prev: PMP): Bool =
cfg.p(0) && Mux(cfg.a(1), rangeMatch(x, lgSize, lgMaxSize, prev), pow2Match(x, lgSize, lgMaxSize)) Mux(napot, pow2Match(x, lgSize, lgMaxSize), torNotNAPOT && rangeMatch(x, lgSize, lgMaxSize, prev))
} }
class PMPHomogeneityChecker(pmps: Seq[PMP])(implicit p: Parameters) { class PMPHomogeneityChecker(pmps: Seq[PMP])(implicit p: Parameters) {
@ -144,7 +146,7 @@ class PMPChecker(lgMaxSize: Int)(implicit p: Parameters) extends CoreModule()(p)
val res = (pmp0 /: (io.pmp zip (pmp0 +: io.pmp)).reverse) { case (prev, (pmp, prevPMP)) => val res = (pmp0 /: (io.pmp zip (pmp0 +: io.pmp)).reverse) { case (prev, (pmp, prevPMP)) =>
val hit = pmp.hit(io.addr, io.size, lgMaxSize, prevPMP) val hit = pmp.hit(io.addr, io.size, lgMaxSize, prevPMP)
val ignore = default && !pmp.cfg.m val ignore = default && !pmp.cfg.l
val aligned = pmp.aligned(io.addr, io.size, lgMaxSize, prevPMP) val aligned = pmp.aligned(io.addr, io.size, lgMaxSize, prevPMP)
val cur = Wire(init = pmp) val cur = Wire(init = pmp)
cur.cfg.r := (aligned && pmp.cfg.r) || ignore cur.cfg.r := (aligned && pmp.cfg.r) || ignore