1
0

WIP on priv-1.10

This commit is contained in:
Andrew Waterman 2017-02-27 14:27:19 -08:00
parent 43dea38ee9
commit db0a02b78e
8 changed files with 101 additions and 111 deletions

View File

@ -17,7 +17,7 @@ import util._
class BaseCoreplexConfig extends Config ((site, here, up) => { class BaseCoreplexConfig extends Config ((site, here, up) => {
case PAddrBits => 32 case PAddrBits => 32
case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */ 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 XLen => 64 // Applies to all cores
case BuildCore => (p: Parameters) => new Rocket()(p) case BuildCore => (p: Parameters) => new Rocket()(p)
case RocketCrossing => Synchronous case RocketCrossing => Synchronous

View File

@ -45,11 +45,11 @@ class DummyPTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
io.requestors.zipWithIndex.foreach { case (requestor, i) => io.requestors.zipWithIndex.foreach { case (requestor, i) =>
requestor.resp.valid := s2_valid && s2_chosen === UInt(i) requestor.resp.valid := s2_valid && s2_chosen === UInt(i)
requestor.resp.bits := s2_resp requestor.resp.bits := s2_resp
requestor.status.vm := UInt("b01000")
requestor.status.prv := UInt(PRV.S) requestor.status.prv := UInt(PRV.S)
requestor.status.debug := Bool(false) requestor.status.debug := Bool(false)
requestor.status.mprv := Bool(true) requestor.status.mprv := Bool(true)
requestor.status.mpp := UInt(0) requestor.status.mpp := UInt(0)
requestor.ptbr.mode := requestor.ptbr.pgLevelsToMode(pgLevels).U
requestor.ptbr.asid := UInt(0) requestor.ptbr.asid := UInt(0)
requestor.ptbr.ppn := UInt(0) requestor.ptbr.ppn := UInt(0)
requestor.invalidate := Bool(false) requestor.invalidate := Bool(false)

View File

@ -18,11 +18,13 @@ class MStatus extends Bundle {
val prv = UInt(width = PRV.SZ) // not truly part of mstatus, but convenient val prv = UInt(width = PRV.SZ) // not truly part of mstatus, but convenient
val sd = Bool() 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 sd_rv32 = Bool()
val zero2 = UInt(width = 2) val zero1 = UInt(width = 9)
val vm = UInt(width = 5) val tw = Bool()
val zero1 = UInt(width = 4) val tvm = Bool()
val mxr = Bool() val mxr = Bool()
val pum = Bool() val pum = Bool()
val mprv = Bool() val mprv = Bool()
@ -78,8 +80,18 @@ class MIP extends Bundle {
} }
class PTBR(implicit p: Parameters) extends CoreBundle()(p) { class PTBR(implicit p: Parameters) extends CoreBundle()(p) {
require(maxPAddrBits - pgIdxBits + asIdBits <= xLen) def pgLevelsToMode(i: Int) = (xLen, i) match {
val asid = UInt(width = asIdBits) 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) val ppn = UInt(width = maxPAddrBits - pgIdxBits)
} }
@ -112,12 +124,12 @@ object CSR
} }
val firstCtr = CSRs.cycle val firstCtr = CSRs.cycle
val firstHPC = CSRs.hpmcounter3
val firstHPE = CSRs.mhpmevent3
val firstMHPC = CSRs.mhpmcounter3
val firstHPM = 3 val firstHPM = 3
val firstHPC = CSRs.cycle + firstHPM val nCtr = 32
val firstHPE = CSRs.mucounteren + firstHPM val nHPM = nCtr - firstHPM
val firstMHPC = CSRs.mcycle + firstHPM
val nHPM = 29
val nCtr = firstHPM + nHPM
} }
class CSRFileIO(implicit p: Parameters) extends CoreBundle 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 exception = io.exception || io.csr_xcpt
val reg_debug = Reg(init=Bool(false)) 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_dpc = Reg(UInt(width = vaddrBitsExtended))
val reg_dscratch = Reg(UInt(width = xLen)) 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 Some(addr) => Reg(init=UInt(addr, mtvecWidth))
case None => Reg(UInt(width = mtvecWidth)) case None => Reg(UInt(width = mtvecWidth))
} }
val reg_mucounteren = Reg(UInt(width = 32)) val reg_mcounteren = Reg(UInt(width = 32))
val reg_mscounteren = Reg(UInt(width = 32)) val reg_scounteren = Reg(UInt(width = 32))
val delegable_counters = (BigInt(1) << (nPerfCounters + CSR.firstHPM)) - 1 val delegable_counters = (BigInt(1) << (nPerfCounters + CSR.firstHPM)) - 1
val reg_sepc = Reg(UInt(width = vaddrBitsExtended)) 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 read_mip = mip.asUInt & supported_interrupts
val pending_interrupts = read_mip & reg_mie 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 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(!reg_debug && (reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie)), 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 all_interrupts = m_interrupts | s_interrupts
val interruptMSB = BigInt(1) << (xLen-1) val interruptMSB = BigInt(1) << (xLen-1)
val interruptCause = UInt(interruptMSB) + PriorityEncoder(all_interrupts) 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.interrupt_cause := interruptCause
io.bp := reg_bp take nBreakpoints 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_sie = reg_mie & reg_mideleg
val read_sip = read_mip & reg_mideleg val read_sip = read_mip & reg_mideleg
val read_sstatus = Wire(init=io.status) val read_sstatus = Wire(init=io.status)
read_sstatus.vm := 0
read_sstatus.mprv := 0 read_sstatus.mprv := 0
read_sstatus.mpp := 0 read_sstatus.mpp := 0
read_sstatus.hpp := 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.sptbr -> reg_sptbr.asUInt
read_mapping += CSRs.sepc -> reg_sepc.sextTo(xLen) read_mapping += CSRs.sepc -> reg_sepc.sextTo(xLen)
read_mapping += CSRs.stvec -> reg_stvec.sextTo(xLen) read_mapping += CSRs.stvec -> reg_stvec.sextTo(xLen)
read_mapping += CSRs.mscounteren -> reg_mscounteren read_mapping += CSRs.scounteren -> reg_scounteren
} }
if (usingUser) { if (usingUser) {
read_mapping += CSRs.mucounteren -> reg_mucounteren read_mapping += CSRs.mcounteren -> reg_mcounteren
read_mapping += CSRs.cycle -> reg_cycle read_mapping += CSRs.cycle -> reg_cycle
read_mapping += CSRs.instret -> reg_instret 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 addr_valid = decoded_addr.values.reduce(_||_)
val fp_csr = if (usingFPU) decoded_addr.filterKeys(fp_csrs contains _ ).values reduce(_||_) else Bool(false) 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_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 || 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))
(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 csr_addr_priv = io.rw.addr(9,8) val csr_addr_priv = io.rw.addr(9,8)
val debug_csr_mask = 0x090 // only debug CSRs have address bits 7 and 4 set 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 read_only = io.rw.addr(11,10).andR
val wen = cpu_wen && priv_sufficient && !read_only val wen = cpu_wen && priv_sufficient && !read_only
val wdata = (Mux(io.rw.cmd.isOneOf(CSR.S, CSR.C), io.rw.rdata, 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))) &
~Mux(io.rw.cmd === CSR.C, io.rw.wdata, UInt(0)) ~Mux(io.rw.cmd === CSR.C, io.rw.wdata, UInt(0))
val do_system_insn = priv_sufficient && system_insn val do_system_insn = priv_sufficient && system_insn
val opcode = UInt(1) << io.rw.addr(2,0) 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_break = do_system_insn && opcode(1)
val insn_ret = do_system_insn && opcode(2) val insn_ret = do_system_insn && opcode(2)
val insn_sfence_vm = do_system_insn && opcode(4) val allow_wfi = effective_prv > PRV.S || !reg_mstatus.tw
val insn_wfi = do_system_insn && opcode(5) 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) || 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) || (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 (insn_wfi) { reg_wfi := true }
when (pending_interrupts.orR) { reg_wfi := false } when (pending_interrupts.orR || exception) { reg_wfi := false }
val cause = val cause =
Mux(!io.csr_xcpt, io.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 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 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 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 debugTVec = Mux(reg_debug, UInt(0x808), UInt(0x800))
val tvec = Mux(trapToDebug, debugTVec, Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec)) 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)) val epc = Mux(csr_debug, reg_dpc, Mux(Bool(usingVM) && !csr_addr_priv(1), reg_sepc, reg_mepc))
io.fatc := insn_sfence_vm io.fatc := insn_sfence_vma
io.evec := Mux(exception, tvec, epc) io.evec := Mux(insn_ret, epc, tvec)
io.ptbr := reg_sptbr io.ptbr := reg_sptbr
io.eret := insn_ret io.eret := insn_ret
io.singleStep := reg_dcsr.step && !reg_debug 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.sd := io.status.fs.andR || io.status.xs.andR
io.status.debug := reg_debug io.status.debug := reg_debug
io.status.isa := reg_misa 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) if (xLen == 32)
io.status.sd_rv32 := io.status.sd io.status.sd_rv32 := io.status.sd
@ -508,21 +532,17 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
if (usingUser) { if (usingUser) {
reg_mstatus.mprv := new_mstatus.mprv reg_mstatus.mprv := new_mstatus.mprv
reg_mstatus.mpp := trimPrivilege(new_mstatus.mpp) reg_mstatus.mpp := trimPrivilege(new_mstatus.mpp)
reg_mstatus.mxr := new_mstatus.mxr
if (usingVM) { if (usingVM) {
reg_mstatus.mxr := new_mstatus.mxr
reg_mstatus.pum := new_mstatus.pum reg_mstatus.pum := new_mstatus.pum
reg_mstatus.spp := new_mstatus.spp reg_mstatus.spp := new_mstatus.spp
reg_mstatus.spie := new_mstatus.spie reg_mstatus.spie := new_mstatus.spie
reg_mstatus.sie := new_mstatus.sie 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 (usingVM || usingFPU) reg_mstatus.fs := Fill(2, new_mstatus.fs.orR)
if (usingRoCC) reg_mstatus.xs := Fill(2, new_mstatus.xs.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.mcycle, reg_cycle, wdata)
writeCounter(CSRs.minstret, reg_instret, 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.fflags)) { reg_fflags := wdata }
when (decoded_addr(CSRs.frm)) { reg_frm := wdata } when (decoded_addr(CSRs.frm)) { reg_frm := wdata }
when (decoded_addr(CSRs.fcsr)) { reg_fflags := wdata; reg_frm := wdata >> reg_fflags.getWidth } 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) val new_sip = new MIP().fromBits(wdata)
reg_mip.ssip := new_sip.ssip 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.sie)) { reg_mie := (reg_mie & ~reg_mideleg) | (wdata & reg_mideleg) }
when (decoded_addr(CSRs.sscratch)) { reg_sscratch := wdata } 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.sepc)) { reg_sepc := formEPC(wdata) }
when (decoded_addr(CSRs.stvec)) { reg_stvec := wdata >> 2 << 2 } 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.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.sbadaddr)) { reg_sbadaddr := wdata(vaddrBitsExtended-1,0) }
when (decoded_addr(CSRs.mideleg)) { reg_mideleg := wdata & delegable_interrupts } when (decoded_addr(CSRs.mideleg)) { reg_mideleg := wdata & delegable_interrupts }
when (decoded_addr(CSRs.medeleg)) { reg_medeleg := wdata & delegable_exceptions } 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) { 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) { if (nBreakpoints > 0) {
when (decoded_addr(CSRs.tselect)) { reg_tselect := wdata } when (decoded_addr(CSRs.tselect)) { reg_tselect := wdata }
@ -623,11 +652,11 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
if (!usingVM) { if (!usingVM) {
reg_mideleg := 0 reg_mideleg := 0
reg_medeleg := 0 reg_medeleg := 0
reg_mscounteren := 0 reg_scounteren := 0
} }
if (!usingUser) { if (!usingUser) {
reg_mucounteren := 0 reg_mcounteren := 0
} }
reg_sptbr.asid := 0 reg_sptbr.asid := 0

View File

@ -129,7 +129,7 @@ class IDecode(implicit val p: Parameters) extends DecodeConstants
class SDecode(implicit val p: Parameters) extends DecodeConstants class SDecode(implicit val p: Parameters) extends DecodeConstants
{ {
val table: Array[(BitPat, List[BitPat])] = Array( 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)) 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))
} }

View File

@ -100,7 +100,7 @@ object Instructions {
def HRET = BitPat("b00100000001000000000000001110011") def HRET = BitPat("b00100000001000000000000001110011")
def MRET = BitPat("b00110000001000000000000001110011") def MRET = BitPat("b00110000001000000000000001110011")
def DRET = BitPat("b01111011001000000000000001110011") def DRET = BitPat("b01111011001000000000000001110011")
def SFENCE_VM = BitPat("b000100000100?????000000001110011") def SFENCE_VMA = BitPat("b0001001??????????000000001110011")
def WFI = BitPat("b00010000010100000000000001110011") def WFI = BitPat("b00010000010100000000000001110011")
def CSRRW = BitPat("b?????????????????001?????1110011") def CSRRW = BitPat("b?????????????????001?????1110011")
def CSRRS = BitPat("b?????????????????010?????1110011") def CSRRS = BitPat("b?????????????????010?????1110011")
@ -283,6 +283,7 @@ object CSRs {
val sstatus = 0x100 val sstatus = 0x100
val sie = 0x104 val sie = 0x104
val stvec = 0x105 val stvec = 0x105
val scounteren = 0x106
val sscratch = 0x140 val sscratch = 0x140
val sepc = 0x141 val sepc = 0x141
val scause = 0x142 val scause = 0x142
@ -295,6 +296,7 @@ object CSRs {
val mideleg = 0x303 val mideleg = 0x303
val mie = 0x304 val mie = 0x304
val mtvec = 0x305 val mtvec = 0x305
val mcounteren = 0x306
val mscratch = 0x340 val mscratch = 0x340
val mepc = 0x341 val mepc = 0x341
val mcause = 0x342 val mcause = 0x342
@ -338,8 +340,6 @@ object CSRs {
val mhpmcounter29 = 0xb1d val mhpmcounter29 = 0xb1d
val mhpmcounter30 = 0xb1e val mhpmcounter30 = 0xb1e
val mhpmcounter31 = 0xb1f val mhpmcounter31 = 0xb1f
val mucounteren = 0x320
val mscounteren = 0x321
val mhpmevent3 = 0x323 val mhpmevent3 = 0x323
val mhpmevent4 = 0x324 val mhpmevent4 = 0x324
val mhpmevent5 = 0x325 val mhpmevent5 = 0x325
@ -476,6 +476,7 @@ object CSRs {
res += sstatus res += sstatus
res += sie res += sie
res += stvec res += stvec
res += scounteren
res += sscratch res += sscratch
res += sepc res += sepc
res += scause res += scause
@ -488,6 +489,7 @@ object CSRs {
res += mideleg res += mideleg
res += mie res += mie
res += mtvec res += mtvec
res += mcounteren
res += mscratch res += mscratch
res += mepc res += mepc
res += mcause res += mcause
@ -531,8 +533,6 @@ object CSRs {
res += mhpmcounter29 res += mhpmcounter29
res += mhpmcounter30 res += mhpmcounter30
res += mhpmcounter31 res += mhpmcounter31
res += mucounteren
res += mscounteren
res += mhpmevent3 res += mhpmevent3
res += mhpmevent4 res += mhpmevent4
res += mhpmevent5 res += mhpmevent5

View File

@ -40,8 +40,7 @@ class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p) {
} }
class PTE(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 = 54)
val ppn = UInt(width = 38)
val reserved_for_software = Bits(width = 2) val reserved_for_software = Bits(width = 2)
val d = Bool() val d = Bool()
val a = Bool() val a = Bool()
@ -53,19 +52,13 @@ class PTE(implicit p: Parameters) extends CoreBundle()(p) {
val v = Bool() val v = Bool()
def table(dummy: Int = 0) = v && !r && !w && !x 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 ur(dummy: Int = 0) = sr() && u
def uw(dummy: Int = 0) = sw() && u def uw(dummy: Int = 0) = sw() && u
def ux(dummy: Int = 0) = sx() && u def ux(dummy: Int = 0) = sx() && u
def sr(dummy: Int = 0) = leaf() && r 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 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) { 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") 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 state = Reg(init=s_ready)
val count = Reg(UInt(width = log2Up(pgLevels))) val count = Reg(UInt(width = log2Up(pgLevels)))
val s1_kill = Reg(next = Bool(false)) val s1_kill = Reg(next = Bool(false))
val resp_valid = Reg(next = Bool(false))
val r_req = Reg(new PTWReq) val r_req = Reg(new PTWReq)
val r_req_dest = Reg(Bits()) 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)) (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.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.typ := log2Ceil(xLen/8)
io.mem.req.bits.addr := pte_addr io.mem.req.bits.addr := pte_addr
io.mem.s1_data := pte_wdata.asUInt
io.mem.s1_kill := s1_kill io.mem.s1_kill := s1_kill
io.mem.invalidate_lr := Bool(false) 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) 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) { 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 := r_pte
io.requestor(i).resp.bits.pte.ppn := resp_ppns(count) io.requestor(i).resp.bits.pte.ppn := resp_ppns(count)
io.requestor(i).ptbr := io.dpath.ptbr io.requestor(i).ptbr := io.dpath.ptbr
@ -174,7 +163,8 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
state := s_wait2 state := s_wait2
when (io.mem.xcpt.pf.ld) { when (io.mem.xcpt.pf.ld) {
r_pte.v := false r_pte.v := false
state := s_done state := s_ready
resp_valid := true
} }
} }
is (s_wait2) { is (s_wait2) {
@ -182,41 +172,16 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) {
state := s_req state := s_req
} }
when (io.mem.resp.valid) { when (io.mem.resp.valid) {
state := s_done r_pte := pte
when (pte.access_ok(r_req) && (!pte.a || (r_req.store && !pte.d))) {
state := s_set_dirty
}.otherwise {
r_pte := pte
}
when (pte.table() && count < pgLevels-1) { when (pte.table() && count < pgLevels-1) {
state := s_req state := s_req
count := count + 1 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
}
} }
} }

View File

@ -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 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 hitsVec = (0 until entries).map(i => valid(i) && vm_enabled && tags(i) === lookup_tag) :+ !vm_enabled
val hits = hitsVec.asUInt 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 sr_array = Reg(UInt(width = entries)) // read permission
val xr_array = Reg(UInt(width = entries)) // read permission to executable page val xr_array = Reg(UInt(width = entries)) // read permission to executable page
val cash_array = Reg(UInt(width = entries)) // cacheable val cash_array = Reg(UInt(width = entries)) // cacheable
val dirty_array = Reg(UInt(width = entries)) // PTE dirty bit
when (do_refill) { when (do_refill) {
val pte = io.ptw.resp.bits.pte val pte = io.ptw.resp.bits.pte
ppns(r_refill_waddr) := pte.ppn 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) 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) xr_array := Mux(pte.sx() && prot_r, xr_array | mask, xr_array & ~mask)
cash_array := Mux(cacheable, cash_array | mask, cash_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) 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 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 w_array = Cat(prot_w, priv_ok & sw_array)
val x_array = Cat(prot_x, priv_ok & sx_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 c_array = Cat(cacheable, cash_array)
val bad_va = val bad_va =
if (vpnBits == vpnBitsExtended) Bool(false) if (vpnBits == vpnBitsExtended) Bool(false)
else io.req.bits.vpn(vpnBits) =/= io.req.bits.vpn(vpnBits-1) 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_hit = hits(entries-1, 0).orR
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_miss = vm_enabled && !bad_va && !tlb_hit val tlb_miss = vm_enabled && !bad_va && !tlb_hit
when (io.req.valid && !tlb_miss) { when (io.req.valid && !tlb_miss) {

View File

@ -60,7 +60,7 @@ trait HasCoreParameters extends HasTileParameters {
val vpnBitsExtended = vpnBits + (vaddrBits < xLen).toInt val vpnBitsExtended = vpnBits + (vaddrBits < xLen).toInt
val vaddrBitsExtended = vpnBitsExtended + pgIdxBits val vaddrBitsExtended = vpnBitsExtended + pgIdxBits
val coreMaxAddrBits = paddrBits max vaddrBitsExtended 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) require(paddrBits <= maxPAddrBits)
// Print out log of committed instructions and their writeback values. // Print out log of committed instructions and their writeback values.