diff --git a/src/main/scala/rocket/PMA.scala b/src/main/scala/rocket/PMA.scala new file mode 100644 index 00000000000..ec1228a8d29 --- /dev/null +++ b/src/main/scala/rocket/PMA.scala @@ -0,0 +1,50 @@ +// See LICENSE.SiFive for license details. +// See LICENSE.Berkeley for license details. + +package freechips.rocketchip.rocket + +import chisel3._ +import chisel3.util._ + +import org.chipsalliance.cde.config.{Field, Parameters} +import freechips.rocketchip.subsystem.CacheBlockBytes +import freechips.rocketchip.diplomacy.RegionType +import freechips.rocketchip.tile.{CoreModule, CoreBundle} +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ +import freechips.rocketchip.util.property +import freechips.rocketchip.devices.debug.DebugModuleKey +import chisel3.experimental.SourceInfo + +class PMAChecker(edge: TLEdgeOut)(implicit p: Parameters) extends CoreModule()(p) { + val io = IO(new Bundle { + val paddr = Input(UInt()) + + val resp = Output(new Bundle { + val cacheable = Bool() + val r = Bool() + val w = Bool() + val pp = Bool() + val al = Bool() + val aa = Bool() + val x = Bool() + val eff = Bool() + }) + }) + + // PMA + // check exist a slave can consume this address. + val legal_address = edge.manager.findSafe(io.paddr).reduce(_||_) + // check utility to help check SoC property. + def fastCheck(member: TLManagerParameters => Boolean) = + legal_address && edge.manager.fastProperty(io.paddr, member, (b:Boolean) => b.B) + + io.resp.cacheable := fastCheck(_.supportsAcquireB) + io.resp.r := fastCheck(_.supportsGet) + io.resp.w := fastCheck(_.supportsPutFull) + io.resp.pp := fastCheck(_.supportsPutPartial) + io.resp.al := fastCheck(_.supportsLogical) + io.resp.aa := fastCheck(_.supportsArithmetic) + io.resp.x := fastCheck(_.executable) + io.resp.eff := fastCheck(Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains _.regionType) +} diff --git a/src/main/scala/rocket/TLB.scala b/src/main/scala/rocket/TLB.scala index f0f0b1a4a7b..56bcd04067f 100644 --- a/src/main/scala/rocket/TLB.scala +++ b/src/main/scala/rocket/TLB.scala @@ -407,24 +407,20 @@ class TLB(instruction: Boolean, lgMaxSize: Int, cfg: TLBConfig)(implicit edge: T pmp.io.size := io.req.bits.size pmp.io.pmp := (io.ptw.pmp: Seq[PMP]) pmp.io.prv := mpu_priv - // PMA - // check exist a slave can consume this address. - val legal_address = edge.manager.findSafe(mpu_physaddr).reduce(_||_) - // check utility to help check SoC property. - def fastCheck(member: TLManagerParameters => Boolean) = - legal_address && edge.manager.fastProperty(mpu_physaddr, member, (b:Boolean) => b.B) + + val pma = Module(new PMAChecker(edge)(p)) + pma.io.paddr := mpu_physaddr // todo: using DataScratchpad doesn't support cacheable. - val cacheable = fastCheck(_.supportsAcquireB) && (instruction || !usingDataScratchpad).B + val cacheable = pma.io.resp.cacheable && (instruction || !usingDataScratchpad).B val homogeneous = TLBPageLookup(edge.manager.managers, xLen, p(CacheBlockBytes), BigInt(1) << pgIdxBits)(mpu_physaddr).homogeneous - // In M mode, if access DM address(debug module program buffer) val deny_access_to_debug = mpu_priv <= PRV.M.U && p(DebugModuleKey).map(dmp => dmp.address.contains(mpu_physaddr)).getOrElse(false.B) - val prot_r = fastCheck(_.supportsGet) && !deny_access_to_debug && pmp.io.r - val prot_w = fastCheck(_.supportsPutFull) && !deny_access_to_debug && pmp.io.w - val prot_pp = fastCheck(_.supportsPutPartial) - val prot_al = fastCheck(_.supportsLogical) - val prot_aa = fastCheck(_.supportsArithmetic) - val prot_x = fastCheck(_.executable) && !deny_access_to_debug && pmp.io.x - val prot_eff = fastCheck(Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains _.regionType) + val prot_r = pma.io.resp.r && !deny_access_to_debug && pmp.io.r + val prot_w = pma.io.resp.w && !deny_access_to_debug && pmp.io.w + val prot_pp = pma.io.resp.pp + val prot_al = pma.io.resp.al + val prot_aa = pma.io.resp.aa + val prot_x = pma.io.resp.x && !deny_access_to_debug && pmp.io.x + val prot_eff = pma.io.resp.eff // hit check val sector_hits = sectored_entries(memIdx).map(_.sectorHit(vpn, priv_v))