1
0

Merge remote-tracking branch 'origin/master' into debug_v013_pr

This commit is contained in:
Megan Wachs
2017-03-30 08:01:11 -07:00
16 changed files with 130 additions and 60 deletions

View File

@ -140,6 +140,8 @@ object CSR
val firstHPM = 3
val nCtr = 32
val nHPM = nCtr - firstHPM
val maxPMPs = 16
}
class PerfCounterIO(implicit p: Parameters) extends CoreBundle
@ -418,10 +420,14 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
val pmpCfgPerCSR = xLen / new PMPConfig().getWidth
def pmpCfgIndex(i: Int) = (xLen / 32) * (i / pmpCfgPerCSR)
for (i <- 0 until reg_pmp.size by pmpCfgPerCSR)
read_mapping += (CSRs.pmpcfg0 + pmpCfgIndex(i)) -> reg_pmp.map(_.cfg).slice(i, i + pmpCfgPerCSR).asUInt
for ((pmp, i) <- reg_pmp zipWithIndex)
read_mapping += (CSRs.pmpaddr0 + i) -> pmp.addr
if (reg_pmp.nonEmpty) {
require(reg_pmp.size <= CSR.maxPMPs)
val read_pmp = reg_pmp.padTo(CSR.maxPMPs, 0.U.asTypeOf(new PMP))
for (i <- 0 until read_pmp.size by pmpCfgPerCSR)
read_mapping += (CSRs.pmpcfg0 + pmpCfgIndex(i)) -> read_pmp.map(_.cfg).slice(i, i + pmpCfgPerCSR).asUInt
for ((pmp, i) <- read_pmp zipWithIndex)
read_mapping += (CSRs.pmpaddr0 + i) -> pmp.addr
}
for (i <- 0 until nCustomMrwCsrs) {
val addr = 0xff0 + i
@ -687,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) {
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))
}
when (decoded_addr(CSRs.pmpaddr0 + i) && !pmp.addrLocked(next)) {
@ -735,10 +741,11 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
}
for (bp <- reg_bp drop nBreakpoints)
bp := new BP().fromBits(0)
if (reg_pmp.nonEmpty) {
for (pmp <- reg_pmp) {
if (!usingUser) pmp.cfg.m := true
when (reset) { pmp.cfg.p := 0 }
for (pmp <- reg_pmp) {
pmp.cfg.res := 0
when (reset) {
pmp.cfg.a := 0
pmp.cfg.l := 0
}
}

View File

@ -180,6 +180,12 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
io.cpu.s2_nack := s2_valid && !s2_valid_hit && !(s2_valid_uncached && tl_out.a.ready && !uncachedInFlight.asUInt.andR)
when (io.cpu.s2_nack || (s2_valid_hit && s2_update_meta)) { s1_nack := true }
val s3_valid = Reg(next = s2_valid, init=Bool(false))
val s3_uncached = Reg(next = s2_uncached, init=Bool(false))
when (s2_valid_cached_miss) {
assert( !(s3_valid && s3_uncached) )
}
// exceptions
val s1_storegen = new StoreGen(s1_req.typ, s1_req.addr, UInt(0), wordBytes)
val no_xcpt = Bool(usingDataScratchpad) && s1_req.phys /* slave port */ && s1_hit_state.isValid()

View File

@ -9,9 +9,9 @@ import tile._
import util._
class PMPConfig extends Bundle {
val p = UInt(width = 2)
val l = Bool()
val res = UInt(width = 2)
val a = UInt(width = 2)
val m = Bool()
val x = Bool()
val w = Bool()
val r = Bool()
@ -32,8 +32,10 @@ class PMPReg(implicit p: Parameters) extends CoreBundle()(p) {
val cfg = new PMPConfig
val addr = UInt(width = paddrBits - PMP.lgAlign)
def locked = cfg.p(1)
def addrLocked(next: PMPReg) = locked || next.locked && next.cfg.a(1)
def napot = 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 {
@ -99,7 +101,7 @@ class PMP(implicit p: Parameters) extends PMPReg {
// returns whether this PMP completely contains, or contains none of, a page
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
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 rangeAligned = !(straddlesLowerBound || straddlesUpperBound)
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
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) {
@ -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 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 cur = Wire(init = pmp)
cur.cfg.r := (aligned && pmp.cfg.r) || ignore

View File

@ -79,6 +79,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(
val s1_kill = Reg(next = Bool(false))
val resp_valid = Reg(next = Vec.fill(io.requestor.size)(Bool(false)))
val ae = Reg(next = io.mem.xcpt.ae.ld)
val resp_ae = Reg(Bool())
val r_req = Reg(new PTWReq)
val r_req_dest = Reg(Bits())
@ -99,7 +100,6 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(
}
val traverse = pte.table() && !invalid_paddr && count < pgLevels-1
val pte_addr = Cat(r_pte.ppn, vpn_idx) << log2Ceil(xLen/8)
val resp_ae = Reg(next = ae || invalid_paddr)
when (arb.io.out.fire()) {
r_req := arb.io.out.bits

View File

@ -61,6 +61,7 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
val level = UInt(width = log2Ceil(pgLevels))
val u = Bool()
val g = Bool()
val ae = Bool()
val sw = Bool()
val sx = Bool()
val sr = Bool()
@ -140,9 +141,13 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
newEntry.c := cacheable
newEntry.u := pte.u
newEntry.g := pte.g
newEntry.sr := pte.sr()
newEntry.sw := pte.sw()
newEntry.sx := pte.sx()
// if an access exception occurs during PTW, pretend the page has full
// permissions so that a page fault will not occur, but clear the
// phyiscal memory permissions, so that an access exception will occur.
newEntry.ae := io.ptw.resp.bits.ae
newEntry.sr := pte.sr() || io.ptw.resp.bits.ae
newEntry.sw := pte.sw() || io.ptw.resp.bits.ae
newEntry.sx := pte.sx() || io.ptw.resp.bits.ae
newEntry.pr := prot_r && !io.ptw.resp.bits.ae
newEntry.pw := prot_w && !io.ptw.resp.bits.ae
newEntry.px := prot_x && !io.ptw.resp.bits.ae
@ -154,7 +159,7 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
val plru = new PseudoLRU(normalEntries)
val repl_waddr = Mux(!valid(normalEntries-1, 0).andR, PriorityEncoder(~valid(normalEntries-1, 0)), plru.replace)
val priv_ok = Mux(priv_s, ~Mux(io.ptw.status.sum, UInt(0), entries.map(_.u).asUInt), entries.map(_.u).asUInt)
val priv_ok = entries.map(_.ae).asUInt | Mux(priv_s, ~Mux(io.ptw.status.sum, UInt(0), entries.map(_.u).asUInt), entries.map(_.u).asUInt)
val r_array = Cat(true.B, priv_ok & (entries.map(_.sr).asUInt | Mux(io.ptw.status.mxr, entries.map(_.sx).asUInt, UInt(0))))
val w_array = Cat(true.B, priv_ok & entries.map(_.sw).asUInt)
val x_array = Cat(true.B, priv_ok & entries.map(_.sx).asUInt)

View File

@ -29,9 +29,10 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
nDCachePorts += 1 // core TODO dcachePorts += () => module.core.io.dmem ??
val device = new Device {
def ofInt(x: Int) = Seq(ResourceInt(BigInt(x)))
def ofStr(x: String) = Seq(ResourceString(x))
private def ofInt(x: Int) = Seq(ResourceInt(BigInt(x)))
private def ofStr(x: String) = Seq(ResourceString(x))
val cpuDevice = new Device {
def describe(resources: ResourceBindings): Description = {
val block = p(CacheBlockBytes)
val m = if (rocketParams.core.mulDiv.nonEmpty) "m" else ""
@ -85,24 +86,28 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
"compatible" -> ofStr("riscv"),
"status" -> ofStr("okay"),
"clock-frequency" -> Seq(ResourceInt(rocketParams.core.bootFreqHz)),
"riscv,isa" -> ofStr(isa),
"interrupt-controller" -> Nil,
"#interrupt-cells" -> ofInt(1))
"riscv,isa" -> ofStr(isa))
++ dcache ++ icache ++ nextlevel ++ mmu ++ itlb ++ dtlb)
}
}
val intcDevice = new Device {
def describe(resources: ResourceBindings): Description = {
Description(s"cpus/cpu@${hartid}/interrupt-controller", Map(
"compatible" -> ofStr("riscv,cpu-intc"),
"interrupt-controller" -> Nil,
"#interrupt-cells" -> ofInt(1)))
}
}
ResourceBinding {
Resource(device, "reg").bind(ResourceInt(BigInt(hartid)))
// debug, msip, mtip, meip, seip offsets in CSRs
val intMap = Seq(65535, 3, 7, 11, 9)
Resource(cpuDevice, "reg").bind(ResourceInt(BigInt(hartid)))
Resource(intcDevice, "reg").bind(ResourceInt(BigInt(hartid)))
intNode.edgesIn.flatMap(_.source.sources).map { case s =>
for (i <- s.range.start until s.range.end) {
intMap.lift(i).foreach { j =>
csrIntMap.lift(i).foreach { j =>
s.resources.foreach { r =>
r.bind(device, ResourceInt(j))
r.bind(intcDevice, ResourceInt(j))
}
}
}
@ -122,7 +127,8 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
require(outer.p(PAddrBits) >= outer.masterNode.edgesIn(0).bundle.addressBits)
val core = Module(p(BuildCore)(outer.p))
core.io.hartid := io.hartid
decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector
core.io.hartid := io.hartid // Pass through the hartid
outer.frontend.module.io.cpu <> core.io.imem
outer.frontend.module.io.resetVector := io.resetVector
dcachePorts += core.io.dmem // TODO outer.dcachePorts += () => module.core.io.dmem ??
@ -136,12 +142,6 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
core.io.rocc.interrupt := lr.module.io.core.interrupt
}
// Decode the interrupt vector
core.io.interrupts.debug := io.interrupts(0)(0)
core.io.interrupts.msip := io.interrupts(0)(1)
core.io.interrupts.mtip := io.interrupts(0)(2)
core.io.interrupts.meip := io.interrupts(0)(3)
core.io.interrupts.seip.foreach { _ := io.interrupts(0)(4) }
// TODO eliminate this redundancy
val h = dcachePorts.size