From db0a02b78e594febe6e4767caa872261c1e4be4b Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 27 Feb 2017 14:27:19 -0800 Subject: [PATCH] WIP on priv-1.10 --- src/main/scala/coreplex/Configs.scala | 2 +- src/main/scala/groundtest/DummyPTW.scala | 2 +- src/main/scala/rocket/CSR.scala | 121 ++++++++++++++--------- src/main/scala/rocket/IDecode.scala | 2 +- src/main/scala/rocket/Instructions.scala | 10 +- src/main/scala/rocket/PTW.scala | 63 +++--------- src/main/scala/rocket/TLB.scala | 10 +- src/main/scala/tile/Core.scala | 2 +- 8 files changed, 101 insertions(+), 111 deletions(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index e67f4117..ece3aaa8 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -17,7 +17,7 @@ import util._ class BaseCoreplexConfig extends Config ((site, here, up) => { case PAddrBits => 32 case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */ - case ASIdBits => 7 + case ASIdBits => 0 case XLen => 64 // Applies to all cores case BuildCore => (p: Parameters) => new Rocket()(p) case RocketCrossing => Synchronous diff --git a/src/main/scala/groundtest/DummyPTW.scala b/src/main/scala/groundtest/DummyPTW.scala index 99a8f79e..f770e42d 100644 --- a/src/main/scala/groundtest/DummyPTW.scala +++ b/src/main/scala/groundtest/DummyPTW.scala @@ -45,11 +45,11 @@ class DummyPTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { io.requestors.zipWithIndex.foreach { case (requestor, i) => requestor.resp.valid := s2_valid && s2_chosen === UInt(i) requestor.resp.bits := s2_resp - requestor.status.vm := UInt("b01000") requestor.status.prv := UInt(PRV.S) requestor.status.debug := Bool(false) requestor.status.mprv := Bool(true) requestor.status.mpp := UInt(0) + requestor.ptbr.mode := requestor.ptbr.pgLevelsToMode(pgLevels).U requestor.ptbr.asid := UInt(0) requestor.ptbr.ppn := UInt(0) requestor.invalidate := Bool(false) diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index d21561fe..4d640caa 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -18,11 +18,13 @@ class MStatus extends Bundle { val prv = UInt(width = PRV.SZ) // not truly part of mstatus, but convenient val sd = Bool() - val zero3 = UInt(width = 31) + val zero2 = UInt(width = 27) + val sxl = UInt(width = 2) + val uxl = UInt(width = 2) val sd_rv32 = Bool() - val zero2 = UInt(width = 2) - val vm = UInt(width = 5) - val zero1 = UInt(width = 4) + val zero1 = UInt(width = 9) + val tw = Bool() + val tvm = Bool() val mxr = Bool() val pum = Bool() val mprv = Bool() @@ -78,8 +80,18 @@ class MIP extends Bundle { } class PTBR(implicit p: Parameters) extends CoreBundle()(p) { - require(maxPAddrBits - pgIdxBits + asIdBits <= xLen) - val asid = UInt(width = asIdBits) + def pgLevelsToMode(i: Int) = (xLen, i) match { + case (32, 2) => 1 + case (64, x) if x >= 3 && x <= 6 => x + 5 + } + val (modeBits, maxASIdBits) = xLen match { + case 32 => (1, 9) + case 64 => (4, 16) + } + require(modeBits + maxASIdBits + maxPAddrBits - pgIdxBits == xLen) + + val mode = UInt(width = modeBits) + val asid = UInt(width = maxASIdBits) val ppn = UInt(width = maxPAddrBits - pgIdxBits) } @@ -112,12 +124,12 @@ object CSR } val firstCtr = CSRs.cycle + val firstHPC = CSRs.hpmcounter3 + val firstHPE = CSRs.mhpmevent3 + val firstMHPC = CSRs.mhpmcounter3 val firstHPM = 3 - val firstHPC = CSRs.cycle + firstHPM - val firstHPE = CSRs.mucounteren + firstHPM - val firstMHPC = CSRs.mcycle + firstHPM - val nHPM = 29 - val nCtr = firstHPM + nHPM + val nCtr = 32 + val nHPM = nCtr - firstHPM } class CSRFileIO(implicit p: Parameters) extends CoreBundle @@ -200,6 +212,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) val exception = io.exception || io.csr_xcpt val reg_debug = Reg(init=Bool(false)) + val effective_prv = Cat(reg_debug, reg_mstatus.prv) val reg_dpc = Reg(UInt(width = vaddrBitsExtended)) val reg_dscratch = Reg(UInt(width = xLen)) @@ -225,8 +238,8 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) case Some(addr) => Reg(init=UInt(addr, mtvecWidth)) case None => Reg(UInt(width = mtvecWidth)) } - val reg_mucounteren = Reg(UInt(width = 32)) - val reg_mscounteren = Reg(UInt(width = 32)) + val reg_mcounteren = Reg(UInt(width = 32)) + val reg_scounteren = Reg(UInt(width = 32)) val delegable_counters = (BigInt(1) << (nPerfCounters + CSR.firstHPM)) - 1 val reg_sepc = Reg(UInt(width = vaddrBitsExtended)) @@ -250,12 +263,12 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) val read_mip = mip.asUInt & supported_interrupts val pending_interrupts = read_mip & reg_mie - val m_interrupts = Mux(!reg_debug && (reg_mstatus.prv < PRV.M || (reg_mstatus.prv === PRV.M && reg_mstatus.mie)), pending_interrupts & ~reg_mideleg, UInt(0)) - val s_interrupts = Mux(!reg_debug && (reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie)), pending_interrupts & reg_mideleg, UInt(0)) + val m_interrupts = Mux(reg_mstatus.prv <= PRV.S || (reg_mstatus.prv === PRV.M && reg_mstatus.mie), pending_interrupts & ~reg_mideleg, UInt(0)) + val s_interrupts = Mux(m_interrupts === 0 && (reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie)), pending_interrupts & reg_mideleg, UInt(0)) val all_interrupts = m_interrupts | s_interrupts val interruptMSB = BigInt(1) << (xLen-1) val interruptCause = UInt(interruptMSB) + PriorityEncoder(all_interrupts) - io.interrupt := all_interrupts.orR && !io.singleStep || reg_singleStepped + io.interrupt := all_interrupts.orR && !reg_debug && !io.singleStep || reg_singleStepped io.interrupt_cause := interruptCause io.bp := reg_bp take nBreakpoints @@ -332,7 +345,6 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) val read_sie = reg_mie & reg_mideleg val read_sip = read_mip & reg_mideleg val read_sstatus = Wire(init=io.status) - read_sstatus.vm := 0 read_sstatus.mprv := 0 read_sstatus.mpp := 0 read_sstatus.hpp := 0 @@ -350,11 +362,11 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) read_mapping += CSRs.sptbr -> reg_sptbr.asUInt read_mapping += CSRs.sepc -> reg_sepc.sextTo(xLen) read_mapping += CSRs.stvec -> reg_stvec.sextTo(xLen) - read_mapping += CSRs.mscounteren -> reg_mscounteren + read_mapping += CSRs.scounteren -> reg_scounteren } if (usingUser) { - read_mapping += CSRs.mucounteren -> reg_mucounteren + read_mapping += CSRs.mcounteren -> reg_mcounteren read_mapping += CSRs.cycle -> reg_cycle read_mapping += CSRs.instret -> reg_instret } @@ -379,9 +391,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) val addr_valid = decoded_addr.values.reduce(_||_) val fp_csr = if (usingFPU) decoded_addr.filterKeys(fp_csrs contains _ ).values reduce(_||_) else Bool(false) val hpm_csr = if (usingUser) io.rw.addr >= CSR.firstCtr && io.rw.addr < CSR.firstCtr + CSR.nCtr else Bool(false) - val hpm_en = reg_debug || reg_mstatus.prv === PRV.M || - (reg_mstatus.prv === PRV.S && reg_mscounteren(io.rw.addr(log2Ceil(CSR.nCtr)-1, 0))) || - (reg_mstatus.prv === PRV.U && reg_mucounteren(io.rw.addr(log2Ceil(CSR.nCtr)-1, 0))) + val hpm_en = effective_prv > PRV.S || (reg_mcounteren & Mux((!usingVM).B || reg_mstatus.prv === PRV.S, delegable_counters.U, reg_scounteren))(io.rw.addr(log2Ceil(CSR.nCtr)-1, 0)) val csr_addr_priv = io.rw.addr(9,8) val debug_csr_mask = 0x090 // only debug CSRs have address bits 7 and 4 set @@ -392,25 +402,37 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) val read_only = io.rw.addr(11,10).andR val wen = cpu_wen && priv_sufficient && !read_only - val wdata = (Mux(io.rw.cmd.isOneOf(CSR.S, CSR.C), io.rw.rdata, UInt(0)) | - Mux(io.rw.cmd =/= CSR.C, io.rw.wdata, UInt(0))) & + val wdata = (Mux(io.rw.cmd.isOneOf(CSR.S, CSR.C), io.rw.rdata, UInt(0)) | io.rw.wdata) & ~Mux(io.rw.cmd === CSR.C, io.rw.wdata, UInt(0)) val do_system_insn = priv_sufficient && system_insn val opcode = UInt(1) << io.rw.addr(2,0) - val insn_call = do_system_insn && opcode(0) + val insn_rs2 = io.rw.addr(5) + val insn_call = do_system_insn && !insn_rs2 && opcode(0) val insn_break = do_system_insn && opcode(1) val insn_ret = do_system_insn && opcode(2) - val insn_sfence_vm = do_system_insn && opcode(4) - val insn_wfi = do_system_insn && opcode(5) + val allow_wfi = effective_prv > PRV.S || !reg_mstatus.tw + val want_wfi = do_system_insn && opcode(5) + val insn_wfi = want_wfi && allow_wfi + val allow_sfence_vma = effective_prv > PRV.S || !reg_mstatus.tvm + val want_sfence_vma = do_system_insn && insn_rs2 + val insn_sfence_vma = want_sfence_vma && allow_sfence_vma + val allow_fcsr = io.status.fs.orR && reg_misa('f'-'a') io.csr_xcpt := (cpu_wen && read_only) || - (cpu_ren && (!priv_sufficient || !addr_valid || (hpm_csr && !hpm_en) || (fp_csr && !(io.status.fs.orR && reg_misa('f'-'a'))))) || + (cpu_ren && + (!priv_sufficient || + !addr_valid || + (if (usingVM) decoded_addr(CSRs.sptbr) && !allow_sfence_vma else false.B) || + (hpm_csr && !hpm_en) || + (fp_csr && !allow_fcsr))) || (system_insn && !priv_sufficient) || - insn_call || insn_break + insn_call || insn_break || + want_wfi && !allow_wfi || + want_sfence_vma && !allow_sfence_vma when (insn_wfi) { reg_wfi := true } - when (pending_interrupts.orR) { reg_wfi := false } + when (pending_interrupts.orR || exception) { reg_wfi := false } val cause = Mux(!io.csr_xcpt, io.cause, @@ -421,12 +443,12 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) val causeIsDebugTrigger = !cause(xLen-1) && cause_lsbs === CSR.debugTriggerCause val causeIsDebugBreak = !cause(xLen-1) && insn_break && Cat(reg_dcsr.ebreakm, reg_dcsr.ebreakh, reg_dcsr.ebreaks, reg_dcsr.ebreaku)(reg_mstatus.prv) val trapToDebug = Bool(usingDebug) && (reg_singleStepped || causeIsDebugInt || causeIsDebugTrigger || causeIsDebugBreak || reg_debug) - val delegate = Bool(usingVM) && reg_mstatus.prv < PRV.M && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs)) + val delegate = Bool(usingVM) && reg_mstatus.prv <= PRV.S && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs)) val debugTVec = Mux(reg_debug, UInt(0x808), UInt(0x800)) val tvec = Mux(trapToDebug, debugTVec, Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec)) val epc = Mux(csr_debug, reg_dpc, Mux(Bool(usingVM) && !csr_addr_priv(1), reg_sepc, reg_mepc)) - io.fatc := insn_sfence_vm - io.evec := Mux(exception, tvec, epc) + io.fatc := insn_sfence_vma + io.evec := Mux(insn_ret, epc, tvec) io.ptbr := reg_sptbr io.eret := insn_ret io.singleStep := reg_dcsr.step && !reg_debug @@ -434,6 +456,8 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) io.status.sd := io.status.fs.andR || io.status.xs.andR io.status.debug := reg_debug io.status.isa := reg_misa + io.status.uxl := (if (usingUser) log2Ceil(xLen) - 4 else 0) + io.status.sxl := (if (usingVM) log2Ceil(xLen) - 4 else 0) if (xLen == 32) io.status.sd_rv32 := io.status.sd @@ -508,21 +532,17 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) if (usingUser) { reg_mstatus.mprv := new_mstatus.mprv reg_mstatus.mpp := trimPrivilege(new_mstatus.mpp) + reg_mstatus.mxr := new_mstatus.mxr if (usingVM) { - reg_mstatus.mxr := new_mstatus.mxr reg_mstatus.pum := new_mstatus.pum reg_mstatus.spp := new_mstatus.spp reg_mstatus.spie := new_mstatus.spie reg_mstatus.sie := new_mstatus.sie + reg_mstatus.tw := new_mstatus.tw + reg_mstatus.tvm := new_mstatus.tvm } } - if (usingVM) { - require(if (xLen == 32) pgLevels == 2 else pgLevels > 2 && pgLevels < 6) - val vm_on = 6 + pgLevels // TODO Sv48 support should imply Sv39 support - when (new_mstatus.vm === 0) { reg_mstatus.vm := 0 } - when (new_mstatus.vm === vm_on) { reg_mstatus.vm := vm_on } - } if (usingVM || usingFPU) reg_mstatus.fs := Fill(2, new_mstatus.fs.orR) if (usingRoCC) reg_mstatus.xs := Fill(2, new_mstatus.xs.orR) } @@ -554,7 +574,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) writeCounter(CSRs.mcycle, reg_cycle, wdata) writeCounter(CSRs.minstret, reg_instret, wdata) - if (usingFPU) { + if (usingFPU) when (allow_fcsr) { when (decoded_addr(CSRs.fflags)) { reg_fflags := wdata } when (decoded_addr(CSRs.frm)) { reg_frm := wdata } when (decoded_addr(CSRs.fcsr)) { reg_fflags := wdata; reg_frm := wdata >> reg_fflags.getWidth } @@ -586,19 +606,28 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) val new_sip = new MIP().fromBits(wdata) reg_mip.ssip := new_sip.ssip } + when (decoded_addr(CSRs.sptbr) && allow_sfence_vma) { + val new_sptbr = new PTBR().fromBits(wdata) + val valid_mode = new_sptbr.pgLevelsToMode(pgLevels) + when (new_sptbr.mode === 0) { reg_sptbr.mode := 0 } + when (new_sptbr.mode === valid_mode) { reg_sptbr.mode := valid_mode } + when (new_sptbr.mode === 0 || new_sptbr.mode === valid_mode) { + reg_sptbr.ppn := new_sptbr.ppn(ppnBits-1,0) + if (asIdBits > 0) reg_sptbr.asid := new_sptbr.asid(asIdBits-1,0) + } + } when (decoded_addr(CSRs.sie)) { reg_mie := (reg_mie & ~reg_mideleg) | (wdata & reg_mideleg) } when (decoded_addr(CSRs.sscratch)) { reg_sscratch := wdata } - when (decoded_addr(CSRs.sptbr)) { reg_sptbr.ppn := wdata(ppnBits-1,0) } when (decoded_addr(CSRs.sepc)) { reg_sepc := formEPC(wdata) } when (decoded_addr(CSRs.stvec)) { reg_stvec := wdata >> 2 << 2 } when (decoded_addr(CSRs.scause)) { reg_scause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ } when (decoded_addr(CSRs.sbadaddr)) { reg_sbadaddr := wdata(vaddrBitsExtended-1,0) } when (decoded_addr(CSRs.mideleg)) { reg_mideleg := wdata & delegable_interrupts } when (decoded_addr(CSRs.medeleg)) { reg_medeleg := wdata & delegable_exceptions } - when (decoded_addr(CSRs.mscounteren)) { reg_mscounteren := wdata & UInt(delegable_counters) } + when (decoded_addr(CSRs.scounteren)) { reg_scounteren := wdata & UInt(delegable_counters) } } if (usingUser) { - when (decoded_addr(CSRs.mucounteren)) { reg_mucounteren := wdata & UInt(delegable_counters) } + when (decoded_addr(CSRs.mcounteren)) { reg_mcounteren := wdata & UInt(delegable_counters) } } if (nBreakpoints > 0) { when (decoded_addr(CSRs.tselect)) { reg_tselect := wdata } @@ -623,11 +652,11 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) if (!usingVM) { reg_mideleg := 0 reg_medeleg := 0 - reg_mscounteren := 0 + reg_scounteren := 0 } if (!usingUser) { - reg_mucounteren := 0 + reg_mcounteren := 0 } reg_sptbr.asid := 0 diff --git a/src/main/scala/rocket/IDecode.scala b/src/main/scala/rocket/IDecode.scala index 5e420a38..89ee819a 100644 --- a/src/main/scala/rocket/IDecode.scala +++ b/src/main/scala/rocket/IDecode.scala @@ -129,7 +129,7 @@ class IDecode(implicit val p: Parameters) extends DecodeConstants class SDecode(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - SFENCE_VM-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N,N), + SFENCE_VMA->List(Y,N,N,N,N,N,Y,Y,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N,N), SRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,N,N,N,CSR.I,N,N,N,N)) } diff --git a/src/main/scala/rocket/Instructions.scala b/src/main/scala/rocket/Instructions.scala index 228724f3..aef4c910 100644 --- a/src/main/scala/rocket/Instructions.scala +++ b/src/main/scala/rocket/Instructions.scala @@ -100,7 +100,7 @@ object Instructions { def HRET = BitPat("b00100000001000000000000001110011") def MRET = BitPat("b00110000001000000000000001110011") def DRET = BitPat("b01111011001000000000000001110011") - def SFENCE_VM = BitPat("b000100000100?????000000001110011") + def SFENCE_VMA = BitPat("b0001001??????????000000001110011") def WFI = BitPat("b00010000010100000000000001110011") def CSRRW = BitPat("b?????????????????001?????1110011") def CSRRS = BitPat("b?????????????????010?????1110011") @@ -283,6 +283,7 @@ object CSRs { val sstatus = 0x100 val sie = 0x104 val stvec = 0x105 + val scounteren = 0x106 val sscratch = 0x140 val sepc = 0x141 val scause = 0x142 @@ -295,6 +296,7 @@ object CSRs { val mideleg = 0x303 val mie = 0x304 val mtvec = 0x305 + val mcounteren = 0x306 val mscratch = 0x340 val mepc = 0x341 val mcause = 0x342 @@ -338,8 +340,6 @@ object CSRs { val mhpmcounter29 = 0xb1d val mhpmcounter30 = 0xb1e val mhpmcounter31 = 0xb1f - val mucounteren = 0x320 - val mscounteren = 0x321 val mhpmevent3 = 0x323 val mhpmevent4 = 0x324 val mhpmevent5 = 0x325 @@ -476,6 +476,7 @@ object CSRs { res += sstatus res += sie res += stvec + res += scounteren res += sscratch res += sepc res += scause @@ -488,6 +489,7 @@ object CSRs { res += mideleg res += mie res += mtvec + res += mcounteren res += mscratch res += mepc res += mcause @@ -531,8 +533,6 @@ object CSRs { res += mhpmcounter29 res += mhpmcounter30 res += mhpmcounter31 - res += mucounteren - res += mscounteren res += mhpmevent3 res += mhpmevent4 res += mhpmevent5 diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index eeb4050e..e9f86d0a 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -40,8 +40,7 @@ class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p) { } class PTE(implicit p: Parameters) extends CoreBundle()(p) { - val reserved_for_hardware = Bits(width = 16) - val ppn = UInt(width = 38) + val ppn = UInt(width = 54) val reserved_for_software = Bits(width = 2) val d = Bool() val a = Bool() @@ -53,19 +52,13 @@ class PTE(implicit p: Parameters) extends CoreBundle()(p) { val v = Bool() def table(dummy: Int = 0) = v && !r && !w && !x - def leaf(dummy: Int = 0) = v && (r || (x && !w)) + def leaf(dummy: Int = 0) = v && (r || (x && !w)) && a def ur(dummy: Int = 0) = sr() && u def uw(dummy: Int = 0) = sw() && u def ux(dummy: Int = 0) = sx() && u def sr(dummy: Int = 0) = leaf() && r - def sw(dummy: Int = 0) = leaf() && w + def sw(dummy: Int = 0) = leaf() && w && d def sx(dummy: Int = 0) = leaf() && x - - def access_ok(req: PTWReq) = { - val perm_ok = Mux(req.fetch, x, Mux(req.store, w, r || (x && req.mxr))) - val priv_ok = Mux(u, !req.pum, req.prv(0)) - leaf() && priv_ok && perm_ok - } } class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { @@ -77,10 +70,11 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { require(usingAtomics, "PTW requires atomic memory operations") - val s_ready :: s_req :: s_wait1 :: s_wait2 :: s_set_dirty :: s_wait1_dirty :: s_wait2_dirty :: s_done :: Nil = Enum(UInt(), 8) + val s_ready :: s_req :: s_wait1 :: s_wait2 :: Nil = Enum(UInt(), 4) val state = Reg(init=s_ready) val count = Reg(UInt(width = log2Up(pgLevels))) val s1_kill = Reg(next = Bool(false)) + val resp_valid = Reg(next = Bool(false)) val r_req = Reg(new PTWReq) val r_req_dest = Reg(Bits()) @@ -128,23 +122,18 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { (hit && count < pgLevels-1, Mux1H(hits, data)) } - - val pte_wdata = Wire(init=new PTE().fromBits(0)) - pte_wdata.a := true - pte_wdata.d := r_req.store - io.mem.req.valid := state.isOneOf(s_req, s_set_dirty) + io.mem.req.valid := state === s_req io.mem.req.bits.phys := Bool(true) - io.mem.req.bits.cmd := Mux(state === s_set_dirty, M_XA_OR, M_XRD) + io.mem.req.bits.cmd := M_XRD io.mem.req.bits.typ := log2Ceil(xLen/8) io.mem.req.bits.addr := pte_addr - io.mem.s1_data := pte_wdata.asUInt io.mem.s1_kill := s1_kill io.mem.invalidate_lr := Bool(false) val resp_ppns = (0 until pgLevels-1).map(i => Cat(pte_addr >> (pgIdxBits + pgLevelBits*(pgLevels-i-1)), r_req.addr(pgLevelBits*(pgLevels-i-1)-1,0))) :+ (pte_addr >> pgIdxBits) for (i <- 0 until io.requestor.size) { - io.requestor(i).resp.valid := state === s_done && (r_req_dest === i) + io.requestor(i).resp.valid := resp_valid && (r_req_dest === i) io.requestor(i).resp.bits.pte := r_pte io.requestor(i).resp.bits.pte.ppn := resp_ppns(count) io.requestor(i).ptbr := io.dpath.ptbr @@ -174,7 +163,8 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { state := s_wait2 when (io.mem.xcpt.pf.ld) { r_pte.v := false - state := s_done + state := s_ready + resp_valid := true } } is (s_wait2) { @@ -182,41 +172,16 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { state := s_req } when (io.mem.resp.valid) { - state := s_done - when (pte.access_ok(r_req) && (!pte.a || (r_req.store && !pte.d))) { - state := s_set_dirty - }.otherwise { - r_pte := pte - } + r_pte := pte when (pte.table() && count < pgLevels-1) { state := s_req count := count + 1 + }.otherwise { + state := s_ready + resp_valid := true } } } - is (s_set_dirty) { - when (io.mem.req.ready) { - state := s_wait1_dirty - } - } - is (s_wait1_dirty) { - state := s_wait2_dirty - when (io.mem.xcpt.pf.st) { - r_pte.v := false - state := s_done - } - } - is (s_wait2_dirty) { - when (io.mem.s2_nack) { - state := s_set_dirty - } - when (io.mem.resp.valid) { - state := s_req - } - } - is (s_done) { - state := s_ready - } } } diff --git a/src/main/scala/rocket/TLB.scala b/src/main/scala/rocket/TLB.scala index b4b78fce..0bc39053 100644 --- a/src/main/scala/rocket/TLB.scala +++ b/src/main/scala/rocket/TLB.scala @@ -86,7 +86,7 @@ class TLB(entries: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreMod } val lookup_tag = Cat(io.ptw.ptbr.asid, io.req.bits.vpn(vpnBits-1,0)) - val vm_enabled = Bool(usingVM) && io.ptw.status.vm(3) && priv_uses_vm && !io.req.bits.passthrough + val vm_enabled = Bool(usingVM) && io.ptw.ptbr.mode(io.ptw.ptbr.mode.getWidth-1) && priv_uses_vm && !io.req.bits.passthrough val hitsVec = (0 until entries).map(i => valid(i) && vm_enabled && tags(i) === lookup_tag) :+ !vm_enabled val hits = hitsVec.asUInt @@ -98,7 +98,6 @@ class TLB(entries: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreMod val sr_array = Reg(UInt(width = entries)) // read permission val xr_array = Reg(UInt(width = entries)) // read permission to executable page val cash_array = Reg(UInt(width = entries)) // cacheable - val dirty_array = Reg(UInt(width = entries)) // PTE dirty bit when (do_refill) { val pte = io.ptw.resp.bits.pte ppns(r_refill_waddr) := pte.ppn @@ -112,7 +111,6 @@ class TLB(entries: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreMod sr_array := Mux(pte.sr() && prot_r, sr_array | mask, sr_array & ~mask) xr_array := Mux(pte.sx() && prot_r, xr_array | mask, xr_array & ~mask) cash_array := Mux(cacheable, cash_array | mask, cash_array & ~mask) - dirty_array := Mux(pte.d, dirty_array | mask, dirty_array & ~mask) } val plru = new PseudoLRU(entries) @@ -121,15 +119,13 @@ class TLB(entries: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreMod val priv_ok = Mux(priv_s, ~Mux(io.ptw.status.pum, u_array, UInt(0)), u_array) val w_array = Cat(prot_w, priv_ok & sw_array) val x_array = Cat(prot_x, priv_ok & sx_array) - val r_array = Cat(prot_r, priv_ok & (sr_array | Mux(io.ptw.status.mxr, xr_array, UInt(0)))) + val r_array = Cat(prot_r | (prot_x & io.ptw.status.mxr), priv_ok & (sr_array | Mux(io.ptw.status.mxr, xr_array, UInt(0)))) val c_array = Cat(cacheable, cash_array) val bad_va = if (vpnBits == vpnBitsExtended) Bool(false) else io.req.bits.vpn(vpnBits) =/= io.req.bits.vpn(vpnBits-1) - // it's only a store hit if the dirty bit is set - val tlb_hits = hits(entries-1, 0) & (dirty_array | ~Mux(io.req.bits.store, w_array, UInt(0))) - val tlb_hit = tlb_hits.orR + val tlb_hit = hits(entries-1, 0).orR val tlb_miss = vm_enabled && !bad_va && !tlb_hit when (io.req.valid && !tlb_miss) { diff --git a/src/main/scala/tile/Core.scala b/src/main/scala/tile/Core.scala index 8e45da3b..66068474 100644 --- a/src/main/scala/tile/Core.scala +++ b/src/main/scala/tile/Core.scala @@ -60,7 +60,7 @@ trait HasCoreParameters extends HasTileParameters { val vpnBitsExtended = vpnBits + (vaddrBits < xLen).toInt val vaddrBitsExtended = vpnBitsExtended + pgIdxBits val coreMaxAddrBits = paddrBits max vaddrBitsExtended - val maxPAddrBits = xLen match { case 32 => 34; case 64 => 50 } + val maxPAddrBits = xLen match { case 32 => 34; case 64 => 56 } require(paddrBits <= maxPAddrBits) // Print out log of committed instructions and their writeback values.