From 6d6fc38787b43790137bc20e383a387759f75dac Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 8 Aug 2017 16:43:59 -0700 Subject: [PATCH 1/3] BusBlocker: lock bit should affect the prior PMP address, not next --- src/main/scala/devices/tilelink/BusBlocker.scala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/scala/devices/tilelink/BusBlocker.scala b/src/main/scala/devices/tilelink/BusBlocker.scala index ae853c6b..996f9636 100644 --- a/src/main/scala/devices/tilelink/BusBlocker.scala +++ b/src/main/scala/devices/tilelink/BusBlocker.scala @@ -37,16 +37,17 @@ class DevicePMP(params: DevicePMPParams) extends GenericParameterizedBundle(para val addr_hi = UInt(width = params.addressBits-12) def address = Cat(addr_hi, UInt(0, width=12)) + def blockPriorAddress = l(0) && a(0) - def fields(locked: Bool): Seq[RegField] = { - def field(bits: Int, reg: UInt) = + def fields(blockAddress: Bool): Seq[RegField] = { + def field(bits: Int, reg: UInt, lock: Bool = l(0)) = RegField(bits, RegReadFn(reg), RegWriteFn((wen, data) => { - when (wen && !locked) { reg := data } + when (wen && !lock) { reg := data } Bool(true) })) Seq( RegField(10), - field(params.addressBits-12, addr_hi), + field(params.addressBits-12, addr_hi, l(0) || blockAddress), RegField(56 - (params.addressBits-2)), field(1, r), field(1, w), @@ -88,8 +89,8 @@ class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBus // We need to be able to represent +1 larger than the largest populated address val addressBits = log2Ceil(nodeOut.edgesOut(0).manager.maxAddress+1+1) val pmps = RegInit(Vec.fill(params.pmpRegisters) { DevicePMP(addressBits) }) - val locks = (pmps.map(_.l) zip (UInt(0) +: pmps.map(_.l))) map { case (x, n) => x | n } - controlNode.regmap(0 -> (pmps zip locks).map { case (p, l) => p.fields(l(0)) }.toList.flatten) + val blocks = pmps.tail.map(_.blockPriorAddress) :+ Bool(false) + controlNode.regmap(0 -> (pmps zip blocks).map { case (p, b) => p.fields(b) }.toList.flatten) val in = io.in(0) val edge = nodeIn.edgesIn(0) From 010ba9447437ca1c8e6f79778e42fdec4eedf378 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 8 Aug 2017 16:44:51 -0700 Subject: [PATCH 2/3] BusBlocker: rename a variable --- src/main/scala/devices/tilelink/BusBlocker.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/devices/tilelink/BusBlocker.scala b/src/main/scala/devices/tilelink/BusBlocker.scala index 996f9636..88158624 100644 --- a/src/main/scala/devices/tilelink/BusBlocker.scala +++ b/src/main/scala/devices/tilelink/BusBlocker.scala @@ -98,8 +98,8 @@ class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBus // Determine if a request is allowed val needW = in.a.bits.opcode =/= TLMessages.Get val needR = in.a.bits.opcode =/= TLMessages.PutFullData && in.a.bits.opcode =/= TLMessages.PutPartialData - val lte = Bool(false) +: pmps.map(in.a.bits.address < _.address) - val sel = (pmps.map(_.a) zip (lte.init zip lte.tail)) map { case (a, (l, r)) => a(0) && !l && r } + val lt = Bool(false) +: pmps.map(in.a.bits.address < _.address) + val sel = (pmps.map(_.a) zip (lt.init zip lt.tail)) map { case (a, (l, r)) => a(0) && !l && r } val ok = pmps.map(p => (p.r(0) || !needR) && (p.w(0) || !needW)) val allow = PriorityMux(sel :+ Bool(true), ok :+ Bool(false)) // no match => deny From a9b1410f016d3dbc01cf5ef8bcfae43a464a57fa Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 8 Aug 2017 17:10:01 -0700 Subject: [PATCH 3/3] BusBlocker: parameterize page granularity --- .../scala/devices/tilelink/BusBlocker.scala | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/scala/devices/tilelink/BusBlocker.scala b/src/main/scala/devices/tilelink/BusBlocker.scala index 88158624..dbf4314a 100644 --- a/src/main/scala/devices/tilelink/BusBlocker.scala +++ b/src/main/scala/devices/tilelink/BusBlocker.scala @@ -16,6 +16,7 @@ case class BusBlockerParams( pmpRegisters: Int) { val page = 4096 + val pageBits = log2Ceil(page) val size = (((pmpRegisters * 8) + page - 1) / page) * page require (pmpRegisters > 0) @@ -25,18 +26,18 @@ case class BusBlockerParams( require (deviceBeatBytes > 0 && isPow2(deviceBeatBytes)) } -case class DevicePMPParams(addressBits: Int) +case class DevicePMPParams(addressBits: Int, pageBits: Int) class DevicePMP(params: DevicePMPParams) extends GenericParameterizedBundle(params) { - require (params.addressBits > 12) + require (params.addressBits > params.pageBits) val l = UInt(width = 1) // locked val a = UInt(width = 1) // LSB of A (0=disabled, 1=TOR) val r = UInt(width = 1) val w = UInt(width = 1) - val addr_hi = UInt(width = params.addressBits-12) - def address = Cat(addr_hi, UInt(0, width=12)) + val addr_hi = UInt(width = params.addressBits-params.pageBits) + def address = Cat(addr_hi, UInt(0, width=params.pageBits)) def blockPriorAddress = l(0) && a(0) def fields(blockAddress: Bool): Seq[RegField] = { @@ -47,7 +48,7 @@ class DevicePMP(params: DevicePMPParams) extends GenericParameterizedBundle(para })) Seq( RegField(10), - field(params.addressBits-12, addr_hi, l(0) || blockAddress), + field(params.addressBits-params.pageBits, addr_hi, l(0) || blockAddress), RegField(56 - (params.addressBits-2)), field(1, r), field(1, w), @@ -60,8 +61,8 @@ class DevicePMP(params: DevicePMPParams) extends GenericParameterizedBundle(para object DevicePMP { - def apply(addressBits: Int) = { - val out = Wire(new DevicePMP(DevicePMPParams(addressBits))) + def apply(addressBits: Int, pageBits: Int) = { + val out = Wire(new DevicePMP(DevicePMPParams(addressBits, pageBits))) out.l := UInt(0) out.a := UInt(0) out.r := UInt(0) @@ -88,7 +89,7 @@ class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBus // We need to be able to represent +1 larger than the largest populated address val addressBits = log2Ceil(nodeOut.edgesOut(0).manager.maxAddress+1+1) - val pmps = RegInit(Vec.fill(params.pmpRegisters) { DevicePMP(addressBits) }) + val pmps = RegInit(Vec.fill(params.pmpRegisters) { DevicePMP(addressBits, params.pageBits) }) val blocks = pmps.tail.map(_.blockPriorAddress) :+ Bool(false) controlNode.regmap(0 -> (pmps zip blocks).map { case (p, b) => p.fields(b) }.toList.flatten)