WIP on priv spec v1.9
This commit is contained in:
		| @@ -46,10 +46,4 @@ trait ScalarOpConstants { | |||||||
|   val DW_32 = N |   val DW_32 = N | ||||||
|   val DW_64 = Y |   val DW_64 = Y | ||||||
|   val DW_XPR = Y |   val DW_XPR = Y | ||||||
|  |  | ||||||
|   val SZ_PRV = 2 |  | ||||||
|   val PRV_U = 0 |  | ||||||
|   val PRV_S = 1 |  | ||||||
|   val PRV_H = 2 |  | ||||||
|   val PRV_M = 3 |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -10,40 +10,37 @@ import uncore._ | |||||||
| import scala.math._ | import scala.math._ | ||||||
|  |  | ||||||
| class MStatus extends Bundle { | class MStatus extends Bundle { | ||||||
|  |   val prv = UInt(width = PRV.SZ) // not truly part of mstatus, but convenient | ||||||
|   val sd = Bool() |   val sd = Bool() | ||||||
|   val zero2 = UInt(width = 31) |   val zero3 = UInt(width = 31) | ||||||
|   val sd_rv32 = UInt(width = 1) |   val sd_rv32 = Bool() | ||||||
|   val zero1 = UInt(width = 9) |   val zero2 = UInt(width = 2) | ||||||
|   val vm = UInt(width = 5) |   val vm = UInt(width = 5) | ||||||
|  |   val zero1 = UInt(width = 5) | ||||||
|  |   val pum = Bool() | ||||||
|   val mprv = Bool() |   val mprv = Bool() | ||||||
|   val xs = UInt(width = 2) |   val xs = UInt(width = 2) | ||||||
|   val fs = UInt(width = 2) |   val fs = UInt(width = 2) | ||||||
|   val prv3 = UInt(width = 2) |   val mpp = UInt(width = 2) | ||||||
|   val ie3 = Bool() |   val hpp = UInt(width = 2) | ||||||
|   val prv2 = UInt(width = 2) |   val spp = UInt(width = 1) | ||||||
|   val ie2 = Bool() |   val mpie = Bool() | ||||||
|   val prv1 = UInt(width = 2) |   val hpie = Bool() | ||||||
|   val ie1 = Bool() |   val spie = Bool() | ||||||
|   val prv = UInt(width = 2) |   val upie = Bool() | ||||||
|   val ie = Bool() |   val mie = Bool() | ||||||
| } |   val hie = Bool() | ||||||
|  |   val sie = Bool() | ||||||
| class SStatus extends Bundle { |   val uie = Bool() | ||||||
|   val sd = Bool() |  | ||||||
|   val zero4 = UInt(width = 31) |  | ||||||
|   val sd_rv32 = UInt(width = 1) |  | ||||||
|   val zero3 = UInt(width = 14) |  | ||||||
|   val mprv = Bool() |  | ||||||
|   val xs = UInt(width = 2) |  | ||||||
|   val fs = UInt(width = 2) |  | ||||||
|   val zero2 = UInt(width = 7) |  | ||||||
|   val ps = Bool() |  | ||||||
|   val pie = Bool() |  | ||||||
|   val zero1 = UInt(width = 2) |  | ||||||
|   val ie = Bool() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| class MIP extends Bundle { | class MIP extends Bundle { | ||||||
|  |   val host = Bool() | ||||||
|  |   val rocc = Bool() | ||||||
|  |   val mdip = Bool() | ||||||
|  |   val hdip = Bool() | ||||||
|  |   val sdip = Bool() | ||||||
|  |   val udip = Bool() | ||||||
|   val mtip = Bool() |   val mtip = Bool() | ||||||
|   val htip = Bool() |   val htip = Bool() | ||||||
|   val stip = Bool() |   val stip = Bool() | ||||||
| @@ -54,6 +51,15 @@ class MIP extends Bundle { | |||||||
|   val usip = Bool() |   val usip = Bool() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | object PRV | ||||||
|  | { | ||||||
|  |   val SZ = 2 | ||||||
|  |   val U = 0 | ||||||
|  |   val S = 1 | ||||||
|  |   val H = 2 | ||||||
|  |   val M = 3 | ||||||
|  | } | ||||||
|  |  | ||||||
| object CSR | object CSR | ||||||
| { | { | ||||||
|   // commands |   // commands | ||||||
| @@ -82,6 +88,7 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle { | |||||||
|   val csr_xcpt = Bool(OUTPUT) |   val csr_xcpt = Bool(OUTPUT) | ||||||
|   val eret = Bool(OUTPUT) |   val eret = Bool(OUTPUT) | ||||||
|  |  | ||||||
|  |   val prv = UInt(OUTPUT, PRV.SZ) | ||||||
|   val status = new MStatus().asOutput |   val status = new MStatus().asOutput | ||||||
|   val ptbr = UInt(OUTPUT, paddrBits) |   val ptbr = UInt(OUTPUT, paddrBits) | ||||||
|   val evec = UInt(OUTPUT, vaddrBitsExtended) |   val evec = UInt(OUTPUT, vaddrBitsExtended) | ||||||
| @@ -104,13 +111,44 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
| { | { | ||||||
|   val io = new CSRFileIO |   val io = new CSRFileIO | ||||||
|  |  | ||||||
|   val reg_mstatus = Reg(new MStatus) |   val reset_mstatus = Wire(init=new MStatus().fromBits(0)) | ||||||
|   val reg_mie = Reg(init=new MIP().fromBits(0)) |   reset_mstatus.mpp := PRV.M | ||||||
|  |   reset_mstatus.prv := PRV.M | ||||||
|  |   val reg_mstatus = Reg(init=reset_mstatus) | ||||||
|  |  | ||||||
|  |   val (supported_interrupts, delegable_interrupts) = { | ||||||
|  |     val sup = Wire(init=new MIP().fromBits(0)) | ||||||
|  |     sup.ssip := Bool(p(UseVM)) | ||||||
|  |     sup.msip := true | ||||||
|  |     sup.stip := Bool(p(UseVM)) | ||||||
|  |     sup.mtip := true | ||||||
|  |     sup.rocc := usingRoCC | ||||||
|  |     sup.host := true | ||||||
|  |  | ||||||
|  |     val del = Wire(init=sup) | ||||||
|  |     del.msip := false | ||||||
|  |     del.mtip := false | ||||||
|  |     del.mdip := false | ||||||
|  |  | ||||||
|  |     (sup.toBits, del.toBits) | ||||||
|  |   } | ||||||
|  |   val delegable_exceptions = UInt(Seq( | ||||||
|  |     Causes.misaligned_fetch, | ||||||
|  |     Causes.fault_fetch, | ||||||
|  |     Causes.breakpoint, | ||||||
|  |     Causes.fault_load, | ||||||
|  |     Causes.fault_store, | ||||||
|  |     Causes.user_ecall).map(1 << _).sum) | ||||||
|  |  | ||||||
|  |   val reg_mie = Reg(init=UInt(0, xLen)) | ||||||
|  |   val reg_mideleg = Reg(init=UInt(0, xLen)) | ||||||
|  |   val reg_medeleg = Reg(init=UInt(0, xLen)) | ||||||
|   val reg_mip = Reg(init=new MIP().fromBits(0)) |   val reg_mip = Reg(init=new MIP().fromBits(0)) | ||||||
|   val reg_mepc = Reg(UInt(width = vaddrBitsExtended)) |   val reg_mepc = Reg(UInt(width = vaddrBitsExtended)) | ||||||
|   val reg_mcause = Reg(Bits(width = xLen)) |   val reg_mcause = Reg(Bits(width = xLen)) | ||||||
|   val reg_mbadaddr = Reg(UInt(width = vaddrBitsExtended)) |   val reg_mbadaddr = Reg(UInt(width = vaddrBitsExtended)) | ||||||
|   val reg_mscratch = Reg(Bits(width = xLen)) |   val reg_mscratch = Reg(Bits(width = xLen)) | ||||||
|  |   val reg_mtvec = Reg(init=UInt(p(MtvecInit), paddrBits min xLen)) | ||||||
|  |  | ||||||
|   val reg_sepc = Reg(UInt(width = vaddrBitsExtended)) |   val reg_sepc = Reg(UInt(width = vaddrBitsExtended)) | ||||||
|   val reg_scause = Reg(Bits(width = xLen)) |   val reg_scause = Reg(Bits(width = xLen)) | ||||||
| @@ -118,7 +156,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
|   val reg_sscratch = Reg(Bits(width = xLen)) |   val reg_sscratch = Reg(Bits(width = xLen)) | ||||||
|   val reg_stvec = Reg(UInt(width = vaddrBits)) |   val reg_stvec = Reg(UInt(width = vaddrBits)) | ||||||
|   val reg_mtimecmp = Reg(Bits(width = xLen)) |   val reg_mtimecmp = Reg(Bits(width = xLen)) | ||||||
|   val reg_sptbr = Reg(UInt(width = paddrBits)) |   val reg_sptbr = Reg(UInt(width = ppnBits)) | ||||||
|   val reg_wfi = Reg(init=Bool(false)) |   val reg_wfi = Reg(init=Bool(false)) | ||||||
|  |  | ||||||
|   val reg_tohost = Reg(init=Bits(0, xLen)) |   val reg_tohost = Reg(init=Bits(0, xLen)) | ||||||
| @@ -126,31 +164,22 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
|   val reg_stats = Reg(init=Bool(false)) |   val reg_stats = Reg(init=Bool(false)) | ||||||
|   val reg_time = Reg(UInt(width = xLen)) |   val reg_time = Reg(UInt(width = xLen)) | ||||||
|   val reg_instret = WideCounter(xLen, io.retire) |   val reg_instret = WideCounter(xLen, io.retire) | ||||||
|   val reg_cycle = if (enableCommitLog) { reg_instret } else { WideCounter(xLen) } |   val reg_cycle: UInt = if (enableCommitLog) { reg_instret } else { WideCounter(xLen) } | ||||||
|   val reg_uarch_counters = io.uarch_counters.map(WideCounter(xLen, _)) |   val reg_uarch_counters = io.uarch_counters.map(WideCounter(xLen, _)) | ||||||
|   val reg_fflags = Reg(UInt(width = 5)) |   val reg_fflags = Reg(UInt(width = 5)) | ||||||
|   val reg_frm = Reg(UInt(width = 3)) |   val reg_frm = Reg(UInt(width = 3)) | ||||||
|  |  | ||||||
|   val irq_rocc = Bool(usingRoCC) && io.rocc.interrupt |   val mip = Wire(init=reg_mip) | ||||||
|  |   mip.host := (reg_fromhost =/= 0) | ||||||
|  |   mip.rocc := io.rocc.interrupt | ||||||
|  |   val read_mip = mip.toBits & supported_interrupts | ||||||
|  |  | ||||||
|   io.interrupt_cause := 0 |   val pending_interrupts = read_mip & reg_mie | ||||||
|   io.interrupt := io.interrupt_cause(xLen-1) |   val m_interrupts = Mux(reg_mstatus.prv < PRV.M || (reg_mstatus.prv === PRV.M && reg_mstatus.mie), pending_interrupts & ~reg_mideleg, UInt(0)) | ||||||
|   val some_interrupt_pending = Wire(init=Bool(false)) |   val s_interrupts = Mux(reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie), pending_interrupts & reg_mideleg, UInt(0)) | ||||||
|   def checkInterrupt(max_priv: UInt, cond: Bool, num: Int) = { |   val all_interrupts = m_interrupts | s_interrupts | ||||||
|     when (cond && (reg_mstatus.prv < max_priv || reg_mstatus.prv === max_priv && reg_mstatus.ie)) { |   io.interrupt := all_interrupts.orR | ||||||
|       io.interrupt_cause := UInt((BigInt(1) << (xLen-1)) + num) |   io.interrupt_cause := (io.interrupt << (xLen-1)) + PriorityEncoder(all_interrupts) | ||||||
|     } |  | ||||||
|     when (cond && reg_mstatus.prv <= max_priv) { |  | ||||||
|       some_interrupt_pending := true |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   checkInterrupt(PRV_S, reg_mie.ssip && reg_mip.ssip, 0) |  | ||||||
|   checkInterrupt(PRV_M, reg_mie.msip && reg_mip.msip, 0) |  | ||||||
|   checkInterrupt(PRV_S, reg_mie.stip && reg_mip.stip, 1) |  | ||||||
|   checkInterrupt(PRV_M, reg_mie.mtip && reg_mip.mtip, 1) |  | ||||||
|   checkInterrupt(PRV_M, reg_fromhost =/= 0, 2) |  | ||||||
|   checkInterrupt(PRV_M, irq_rocc, 3) |  | ||||||
|  |  | ||||||
|   val system_insn = io.rw.cmd === CSR.I |   val system_insn = io.rw.cmd === CSR.I | ||||||
|   val cpu_ren = io.rw.cmd =/= CSR.N && !system_insn |   val cpu_ren = io.rw.cmd =/= CSR.N && !system_insn | ||||||
| @@ -175,38 +204,34 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
|  |  | ||||||
|   io.host.debug_stats_csr := reg_stats // direct export up the hierarchy |   io.host.debug_stats_csr := reg_stats // direct export up the hierarchy | ||||||
|  |  | ||||||
|   val read_time = if (usingPerfCounters) reg_time else (reg_cycle: UInt) |  | ||||||
|   val read_mstatus = io.status.toBits |  | ||||||
|   val isa_string = "IMA" + |   val isa_string = "IMA" + | ||||||
|     (if (usingVM) "S" else "") + |     (if (usingVM) "S" else "") + | ||||||
|     (if (usingFPU) "FD" else "") + |     (if (usingFPU) "FDG" else "") + | ||||||
|     (if (usingRoCC) "X" else "") |     (if (usingRoCC) "X" else "") | ||||||
|   val cpuid = ((if (xLen == 32) BigInt(0) else BigInt(2)) << (xLen-2)) | |   val isa = ((if (xLen == 32) BigInt(0) else BigInt(2)) << (xLen-2)) | | ||||||
|     isa_string.map(x => 1 << (x - 'A')).reduce(_|_) |     isa_string.map(x => 1 << (x - 'A')).reduce(_|_) | ||||||
|   val impid = 1 |   val read_mstatus = io.status.toBits()(xLen-1,0) | ||||||
|   val reg_mtvec = Reg(init = UInt(mtvecInit, xLen)) |  | ||||||
|  |  | ||||||
|   val read_mapping = collection.mutable.LinkedHashMap[Int,Bits]( |   val read_mapping = collection.mutable.LinkedHashMap[Int,Bits]( | ||||||
|     CSRs.fflags -> (if (usingFPU) reg_fflags else UInt(0)), |     CSRs.mimpid -> UInt(0), | ||||||
|     CSRs.frm -> (if (usingFPU) reg_frm else UInt(0)), |     CSRs.marchid -> UInt(0), | ||||||
|     CSRs.fcsr -> (if (usingFPU) Cat(reg_frm, reg_fflags) else UInt(0)), |     CSRs.mvendorid -> UInt(0), | ||||||
|     CSRs.cycle -> reg_cycle, |     CSRs.mtime -> reg_time, | ||||||
|     CSRs.cyclew -> reg_cycle, |     CSRs.mcycle -> reg_cycle, | ||||||
|     CSRs.time -> read_time, |     CSRs.minstret -> reg_instret, | ||||||
|     CSRs.timew -> read_time, |     CSRs.mucounteren -> UInt(0), | ||||||
|     CSRs.stime -> read_time, |     CSRs.mutime_delta -> UInt(0), | ||||||
|     CSRs.stimew -> read_time, |     CSRs.mucycle_delta -> UInt(0), | ||||||
|     CSRs.mtime -> read_time, |     CSRs.muinstret_delta -> UInt(0), | ||||||
|     CSRs.mcpuid -> UInt(cpuid), |     CSRs.misa -> UInt(isa), | ||||||
|     CSRs.mimpid -> UInt(impid), |  | ||||||
|     CSRs.mstatus -> read_mstatus, |     CSRs.mstatus -> read_mstatus, | ||||||
|     CSRs.mtdeleg -> UInt(0), |  | ||||||
|     CSRs.mreset -> UInt(0), |  | ||||||
|     CSRs.mtvec -> reg_mtvec, |     CSRs.mtvec -> reg_mtvec, | ||||||
|     CSRs.miobase -> UInt(p(junctions.MMIOBase)), |     CSRs.mcfgaddr -> UInt(p(junctions.MMIOBase)), | ||||||
|     CSRs.mipi -> UInt(0), |     CSRs.mipi -> reg_mip.msip, | ||||||
|     CSRs.mip -> reg_mip.toBits, |     CSRs.mip -> read_mip, | ||||||
|     CSRs.mie -> reg_mie.toBits, |     CSRs.mie -> reg_mie, | ||||||
|  |     CSRs.mideleg -> reg_mideleg, | ||||||
|  |     CSRs.medeleg -> reg_medeleg, | ||||||
|     CSRs.mscratch -> reg_mscratch, |     CSRs.mscratch -> reg_mscratch, | ||||||
|     CSRs.mepc -> reg_mepc.sextTo(xLen), |     CSRs.mepc -> reg_mepc.sextTo(xLen), | ||||||
|     CSRs.mbadaddr -> reg_mbadaddr.sextTo(xLen), |     CSRs.mbadaddr -> reg_mbadaddr.sextTo(xLen), | ||||||
| @@ -217,30 +242,26 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
|     CSRs.mtohost -> reg_tohost, |     CSRs.mtohost -> reg_tohost, | ||||||
|     CSRs.mfromhost -> reg_fromhost) |     CSRs.mfromhost -> reg_fromhost) | ||||||
|  |  | ||||||
|   if (usingPerfCounters) { |   if (usingFPU) { | ||||||
|     read_mapping += CSRs.instret -> reg_instret |     read_mapping += CSRs.fflags -> reg_fflags | ||||||
|     read_mapping += CSRs.instretw -> reg_instret |     read_mapping += CSRs.frm -> reg_frm | ||||||
|  |     read_mapping += CSRs.fcsr -> Cat(reg_frm, reg_fflags) | ||||||
|     for (i <- 0 until reg_uarch_counters.size) |  | ||||||
|       read_mapping += (CSRs.uarch0 + i) -> reg_uarch_counters(i) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (usingVM) { |   if (usingVM) { | ||||||
|     val read_sstatus = Wire(init=new SStatus().fromBits(read_mstatus)) |     val read_sie = reg_mie & reg_mideleg | ||||||
|     read_sstatus.zero1 := 0 |     val read_sip = read_mip & reg_mideleg | ||||||
|     read_sstatus.zero2 := 0 |     val read_sstatus = Wire(init=io.status) | ||||||
|     read_sstatus.zero3 := 0 |     read_sstatus.vm := 0 | ||||||
|     read_sstatus.zero4 := 0 |     read_sstatus.mprv := 0 | ||||||
|  |     read_sstatus.mpp := 0 | ||||||
|  |     read_sstatus.hpp := 0 | ||||||
|  |     read_sstatus.mpie := 0 | ||||||
|  |     read_sstatus.hpie := 0 | ||||||
|  |     read_sstatus.mie := 0 | ||||||
|  |     read_sstatus.hie := 0 | ||||||
|  |  | ||||||
|     val read_sip = Wire(init=new MIP().fromBits(0)) |     read_mapping += CSRs.sstatus -> (read_sstatus.toBits())(xLen-1,0) | ||||||
|     read_sip.ssip := reg_mip.ssip |  | ||||||
|     read_sip.stip := reg_mip.stip |  | ||||||
|  |  | ||||||
|     val read_sie = Wire(init=new MIP().fromBits(0)) |  | ||||||
|     read_sie.ssip := reg_mie.ssip |  | ||||||
|     read_sie.stip := reg_mie.stip |  | ||||||
|  |  | ||||||
|     read_mapping += CSRs.sstatus -> read_sstatus.toBits |  | ||||||
|     read_mapping += CSRs.sip -> read_sip.toBits |     read_mapping += CSRs.sip -> read_sip.toBits | ||||||
|     read_mapping += CSRs.sie -> read_sie.toBits |     read_mapping += CSRs.sie -> read_sie.toBits | ||||||
|     read_mapping += CSRs.sscratch -> reg_sscratch |     read_mapping += CSRs.sscratch -> reg_sscratch | ||||||
| @@ -250,10 +271,15 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
|     read_mapping += CSRs.sasid -> UInt(0) |     read_mapping += CSRs.sasid -> UInt(0) | ||||||
|     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 -> UInt(0) | ||||||
|  |     read_mapping += CSRs.mstime_delta -> UInt(0) | ||||||
|  |     read_mapping += CSRs.mscycle_delta -> UInt(0) | ||||||
|  |     read_mapping += CSRs.msinstret_delta -> UInt(0) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   for (i <- 0 until nCustomMrwCsrs) { |   for (i <- 0 until nCustomMrwCsrs) { | ||||||
|     val addr = CSRs.mrwbase + i |     val addr = 0xff0 + i | ||||||
|  |     require(addr < (1 << CSR.ADDRSZ)) | ||||||
|     require(!read_mapping.contains(addr), "custom MRW CSR address " + i + " is already in use") |     require(!read_mapping.contains(addr), "custom MRW CSR address " + i + " is already in use") | ||||||
|     read_mapping += addr -> io.custom_mrw_csrs(i) |     read_mapping += addr -> io.custom_mrw_csrs(i) | ||||||
|   } |   } | ||||||
| @@ -278,14 +304,13 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
|               Mux(io.rw.cmd === CSR.S, io.rw.rdata | io.rw.wdata, |               Mux(io.rw.cmd === CSR.S, io.rw.rdata | io.rw.wdata, | ||||||
|               host_csr_bits.data))) |               host_csr_bits.data))) | ||||||
|  |  | ||||||
|   val opcode = io.rw.addr |   val do_system_insn = priv_sufficient && system_insn | ||||||
|   val insn_call = !opcode(8) && !opcode(0) && system_insn |   val opcode = UInt(1) << io.rw.addr(2,0) | ||||||
|   val insn_break = !opcode(8) && opcode(0) && system_insn |   val insn_call = do_system_insn && opcode(0) | ||||||
|   val insn_ret = opcode(8) && !opcode(1) && !opcode(0) && system_insn && priv_sufficient |   val insn_break = do_system_insn && opcode(1) | ||||||
|   val insn_sfence_vm = opcode(8) && !opcode(1) && opcode(0) && system_insn && priv_sufficient |   val insn_ret = do_system_insn && opcode(2) | ||||||
|   val maybe_insn_redirect_trap = opcode(2) && system_insn |   val insn_sfence_vm = do_system_insn && opcode(4) | ||||||
|   val insn_redirect_trap = maybe_insn_redirect_trap && priv_sufficient |   val insn_wfi = do_system_insn && opcode(5) | ||||||
|   val insn_wfi = opcode(8) && opcode(1) && !opcode(0) && system_insn && priv_sufficient |  | ||||||
|  |  | ||||||
|   val csr_xcpt = (cpu_wen && read_only) || |   val csr_xcpt = (cpu_wen && read_only) || | ||||||
|     (cpu_ren && (!priv_sufficient || !addr_valid || fp_csr && !io.status.fs.orR)) || |     (cpu_ren && (!priv_sufficient || !addr_valid || fp_csr && !io.status.fs.orR)) || | ||||||
| @@ -293,67 +318,77 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
|     insn_call || insn_break |     insn_call || insn_break | ||||||
|  |  | ||||||
|   when (insn_wfi) { reg_wfi := true } |   when (insn_wfi) { reg_wfi := true } | ||||||
|   when (some_interrupt_pending) { reg_wfi := false } |   when (read_mip.orR) { reg_wfi := false } | ||||||
|  |  | ||||||
|  |   val cause = | ||||||
|  |     Mux(!csr_xcpt, io.cause, | ||||||
|  |     Mux(insn_call, reg_mstatus.prv + Causes.user_ecall, | ||||||
|  |     Mux[UInt](insn_break, Causes.breakpoint, Causes.illegal_instruction))) | ||||||
|  |   val cause_lsbs = cause(log2Up(xLen)-1,0) | ||||||
|  |   val can_delegate = Bool(p(UseVM)) && reg_mstatus.prv < PRV.M | ||||||
|  |   val delegate = can_delegate && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs)) | ||||||
|  |   val tvec = Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec) | ||||||
|  |   val epc = Mux(can_delegate, reg_sepc, reg_mepc) | ||||||
|   io.fatc := insn_sfence_vm |   io.fatc := insn_sfence_vm | ||||||
|   io.evec := Mux(io.exception || csr_xcpt, (reg_mstatus.prv << 6) + reg_mtvec, |   io.evec := Mux(io.exception || csr_xcpt, tvec, epc) | ||||||
|              Mux(maybe_insn_redirect_trap, reg_stvec.sextTo(vaddrBitsExtended), |  | ||||||
|              Mux(reg_mstatus.prv(1) || Bool(!p(UseVM)), reg_mepc, reg_sepc))) |  | ||||||
|   io.ptbr := reg_sptbr |   io.ptbr := reg_sptbr | ||||||
|   io.csr_xcpt := csr_xcpt |   io.csr_xcpt := csr_xcpt | ||||||
|   io.eret := insn_ret || insn_redirect_trap |   io.eret := insn_ret | ||||||
|   io.status := reg_mstatus |   io.status := reg_mstatus | ||||||
|   io.status.fs := Fill(2, reg_mstatus.fs.orR) // either off or dirty (no clean/initial support yet) |  | ||||||
|   io.status.xs := Fill(2, reg_mstatus.xs.orR) // either off or dirty (no clean/initial support yet) |  | ||||||
|   io.status.sd := io.status.fs.andR || io.status.xs.andR |   io.status.sd := io.status.fs.andR || io.status.xs.andR | ||||||
|   if (xLen == 32) |   if (xLen == 32) | ||||||
|     io.status.sd_rv32 := io.status.sd |     io.status.sd_rv32 := io.status.sd | ||||||
|  |  | ||||||
|   when (io.exception || csr_xcpt) { |   when (io.exception || csr_xcpt) { | ||||||
|     reg_mstatus.ie := false |     val ldst_badaddr = { | ||||||
|     reg_mstatus.prv := PRV_M |  | ||||||
|     reg_mstatus.mprv := false |  | ||||||
|     reg_mstatus.prv1 := reg_mstatus.prv |  | ||||||
|     reg_mstatus.ie1 := reg_mstatus.ie |  | ||||||
|     reg_mstatus.prv2 := reg_mstatus.prv1 |  | ||||||
|     reg_mstatus.ie2 := reg_mstatus.ie1 |  | ||||||
|  |  | ||||||
|     reg_mepc := ~(~io.pc | (coreInstBytes-1)) |  | ||||||
|     reg_mcause := io.cause |  | ||||||
|     when (csr_xcpt) { |  | ||||||
|       reg_mcause := Causes.illegal_instruction |  | ||||||
|       when (insn_break) { reg_mcause := Causes.breakpoint } |  | ||||||
|       when (insn_call) { reg_mcause := reg_mstatus.prv + Causes.user_ecall } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     reg_mbadaddr := io.pc |  | ||||||
|     when (io.cause === Causes.fault_load || io.cause === Causes.misaligned_load || |  | ||||||
|           io.cause === Causes.fault_store || io.cause === Causes.misaligned_store) { |  | ||||||
|       val (upper, lower) = Split(io.rw.wdata, vaddrBits) |       val (upper, lower) = Split(io.rw.wdata, vaddrBits) | ||||||
|       val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR) |       val sign = Mux(lower.toSInt < SInt(0), upper.andR, upper.orR) | ||||||
|       reg_mbadaddr := Cat(sign, lower) |       Cat(sign, lower) | ||||||
|  |     } | ||||||
|  |     val ldst = | ||||||
|  |       cause === Causes.fault_load || cause === Causes.misaligned_load || | ||||||
|  |       cause === Causes.fault_store || cause === Causes.misaligned_store | ||||||
|  |     val badaddr = Mux(ldst, ldst_badaddr, io.pc) | ||||||
|  |     val epc = ~(~io.pc | (coreInstBytes-1)) | ||||||
|  |     val pie = read_mstatus(reg_mstatus.prv) | ||||||
|  |  | ||||||
|  |     when (delegate) { | ||||||
|  |       reg_sepc := epc | ||||||
|  |       reg_scause := cause | ||||||
|  |       reg_sbadaddr := badaddr | ||||||
|  |       reg_mstatus.spie := pie | ||||||
|  |       reg_mstatus.spp := reg_mstatus.prv | ||||||
|  |       reg_mstatus.sie := false | ||||||
|  |       reg_mstatus.prv := PRV.S | ||||||
|  |     }.otherwise { | ||||||
|  |       reg_mepc := epc | ||||||
|  |       reg_mcause := cause | ||||||
|  |       reg_mbadaddr := badaddr | ||||||
|  |       reg_mstatus.mpie := pie | ||||||
|  |       reg_mstatus.mpp := reg_mstatus.prv | ||||||
|  |       reg_mstatus.mie := false | ||||||
|  |       reg_mstatus.prv := PRV.M | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   when (insn_ret) { |   when (insn_ret) { | ||||||
|     reg_mstatus.ie := reg_mstatus.ie1 |     when (can_delegate) { | ||||||
|     reg_mstatus.prv := reg_mstatus.prv1 |       when (reg_mstatus.spp.toBool) { reg_mstatus.sie := reg_mstatus.spie } | ||||||
|     reg_mstatus.prv1 := reg_mstatus.prv2 |       reg_mstatus.spie := false | ||||||
|     reg_mstatus.ie1 := reg_mstatus.ie2 |       reg_mstatus.spp := PRV.U | ||||||
|     reg_mstatus.prv2 := PRV_U |       reg_mstatus.prv := reg_mstatus.spp | ||||||
|     reg_mstatus.ie2 := true |     }.otherwise { | ||||||
|  |       when (reg_mstatus.mpp(1)) { reg_mstatus.mie := reg_mstatus.mpie } | ||||||
|  |       when (reg_mstatus.mpp(0)) { reg_mstatus.sie := reg_mstatus.mpie } | ||||||
|  |       reg_mstatus.mpie := false | ||||||
|  |       reg_mstatus.mpp := PRV.U | ||||||
|  |       reg_mstatus.prv := reg_mstatus.mpp | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   when (insn_redirect_trap) { |   assert(PopCount(insn_ret :: io.exception :: csr_xcpt :: Nil) <= 1, "these conditions must be mutually exclusive") | ||||||
|     reg_mstatus.prv := PRV_S |  | ||||||
|     reg_sbadaddr := reg_mbadaddr |  | ||||||
|     reg_scause := reg_mcause |  | ||||||
|     reg_sepc := reg_mepc |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   assert(PopCount(insn_ret :: insn_redirect_trap :: io.exception :: csr_xcpt :: Nil) <= 1, "these conditions must be mutually exclusive") |   when (reg_time >= reg_mtimecmp) { | ||||||
|  |  | ||||||
|   when (read_time >= reg_mtimecmp) { |  | ||||||
|     reg_mip.mtip := true |     reg_mip.mtip := true | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -372,17 +407,18 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
|   when (wen) { |   when (wen) { | ||||||
|     when (decoded_addr(CSRs.mstatus)) { |     when (decoded_addr(CSRs.mstatus)) { | ||||||
|       val new_mstatus = new MStatus().fromBits(wdata) |       val new_mstatus = new MStatus().fromBits(wdata) | ||||||
|       reg_mstatus.ie := new_mstatus.ie |       reg_mstatus.mie := new_mstatus.mie | ||||||
|       reg_mstatus.ie1 := new_mstatus.ie1 |       reg_mstatus.mpie := new_mstatus.mpie | ||||||
|  |  | ||||||
|       val supportedModes = Vec((PRV_M :: PRV_U :: (if (usingVM) List(PRV_S) else Nil)).map(UInt(_))) |       val supportedModes = Vec((PRV.M :: PRV.U :: (if (usingVM) List(PRV.S) else Nil)).map(UInt(_))) | ||||||
|       if (supportedModes.size > 1) { |       if (supportedModes.size > 1) { | ||||||
|         reg_mstatus.mprv := new_mstatus.mprv |         reg_mstatus.mprv := new_mstatus.mprv | ||||||
|         when (supportedModes contains new_mstatus.prv) { reg_mstatus.prv := new_mstatus.prv } |         when (supportedModes contains new_mstatus.mpp) { reg_mstatus.mpp := new_mstatus.mpp } | ||||||
|         when (supportedModes contains new_mstatus.prv1) { reg_mstatus.prv1 := new_mstatus.prv1 } |  | ||||||
|         if (supportedModes.size > 2) { |         if (supportedModes.size > 2) { | ||||||
|           when (supportedModes contains new_mstatus.prv2) { reg_mstatus.prv2 := new_mstatus.prv2 } |           reg_mstatus.pum := new_mstatus.pum | ||||||
|           reg_mstatus.ie2 := new_mstatus.ie2 |           reg_mstatus.spp := new_mstatus.spp | ||||||
|  |           reg_mstatus.spie := new_mstatus.spie | ||||||
|  |           reg_mstatus.sie := new_mstatus.sie | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -391,8 +427,8 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
|         when (new_mstatus.vm === 0) { reg_mstatus.vm := 0 } |         when (new_mstatus.vm === 0) { reg_mstatus.vm := 0 } | ||||||
|         when (new_mstatus.vm === vm_on) { reg_mstatus.vm := vm_on } |         when (new_mstatus.vm === vm_on) { reg_mstatus.vm := vm_on } | ||||||
|       } |       } | ||||||
|       if (usingVM || usingFPU) reg_mstatus.fs := new_mstatus.fs |       if (usingVM || usingFPU) reg_mstatus.fs := Fill(2, new_mstatus.fs.orR) | ||||||
|       if (usingRoCC) reg_mstatus.xs := new_mstatus.xs |       if (usingRoCC) reg_mstatus.xs := Fill(2, new_mstatus.xs.orR) | ||||||
|     } |     } | ||||||
|     when (decoded_addr(CSRs.mip)) { |     when (decoded_addr(CSRs.mip)) { | ||||||
|       val new_mip = new MIP().fromBits(wdata) |       val new_mip = new MIP().fromBits(wdata) | ||||||
| @@ -405,76 +441,48 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p) | |||||||
|     when (decoded_addr(CSRs.mipi)) { |     when (decoded_addr(CSRs.mipi)) { | ||||||
|       reg_mip.msip := wdata(0) |       reg_mip.msip := wdata(0) | ||||||
|     } |     } | ||||||
|     when (decoded_addr(CSRs.mie)) { |     when (decoded_addr(CSRs.mie))      { reg_mie := wdata & supported_interrupts } | ||||||
|       val new_mie = new MIP().fromBits(wdata) |  | ||||||
|       if (usingVM) { |  | ||||||
|         reg_mie.ssip := new_mie.ssip |  | ||||||
|         reg_mie.stip := new_mie.stip |  | ||||||
|       } |  | ||||||
|       reg_mie.msip := new_mie.msip |  | ||||||
|       reg_mie.mtip := new_mie.mtip |  | ||||||
|     } |  | ||||||
|     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 } | ||||||
|     when (decoded_addr(CSRs.mepc))     { reg_mepc := ~(~wdata | (coreInstBytes-1)) } |     when (decoded_addr(CSRs.mepc))     { reg_mepc := ~(~wdata | (coreInstBytes-1)) } | ||||||
|     when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata } |     when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata } | ||||||
|  |     if (p(MtvecWritable)) | ||||||
|  |       when (decoded_addr(CSRs.mtvec))  { reg_mtvec := wdata >> 2 << 2 } | ||||||
|     when (decoded_addr(CSRs.mcause))   { reg_mcause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ } |     when (decoded_addr(CSRs.mcause))   { reg_mcause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ } | ||||||
|     when (decoded_addr(CSRs.mbadaddr)) { reg_mbadaddr := wdata(vaddrBitsExtended-1,0) } |     when (decoded_addr(CSRs.mbadaddr)) { reg_mbadaddr := wdata(vaddrBitsExtended-1,0) } | ||||||
|     if (usingPerfCounters) |  | ||||||
|       when (decoded_addr(CSRs.instretw)) { reg_instret := wdata } |  | ||||||
|     when (decoded_addr(CSRs.mtimecmp)) { reg_mtimecmp := wdata; reg_mip.mtip := false } |     when (decoded_addr(CSRs.mtimecmp)) { reg_mtimecmp := wdata; reg_mip.mtip := false } | ||||||
|     when (decoded_addr(CSRs.mtime))    { reg_time := wdata } |     when (decoded_addr(CSRs.mtime))    { reg_time := wdata } | ||||||
|     when (decoded_addr(CSRs.mfromhost)){ when (reg_fromhost === UInt(0) || !host_csr_req_fire) { reg_fromhost := wdata } } |     when (decoded_addr(CSRs.mfromhost)){ when (reg_fromhost === UInt(0) || !host_csr_req_fire) { reg_fromhost := wdata } } | ||||||
|     when (decoded_addr(CSRs.mtohost))  { when (reg_tohost === UInt(0) || host_csr_req_fire) { reg_tohost := wdata } } |     when (decoded_addr(CSRs.mtohost))  { when (reg_tohost === UInt(0) || host_csr_req_fire) { reg_tohost := wdata } } | ||||||
|     when (decoded_addr(CSRs.stats))    { reg_stats := wdata(0) } |     when (decoded_addr(CSRs.stats))    { reg_stats := wdata(0) } | ||||||
|     when (decoded_addr(CSRs.mtvec))    { reg_mtvec := wdata & ~UInt("b11") } |  | ||||||
|     if (usingVM) { |     if (usingVM) { | ||||||
|       when (decoded_addr(CSRs.sstatus)) { |       when (decoded_addr(CSRs.sstatus)) { | ||||||
|         val new_sstatus = new SStatus().fromBits(wdata) |         val new_sstatus = new MStatus().fromBits(wdata) | ||||||
|         reg_mstatus.ie := new_sstatus.ie |         reg_mstatus.sie := new_sstatus.sie | ||||||
|         reg_mstatus.ie1 := new_sstatus.pie |         reg_mstatus.spie := new_sstatus.spie | ||||||
|         reg_mstatus.prv1 := Mux[UInt](new_sstatus.ps, PRV_S, PRV_U) |         reg_mstatus.spp := new_sstatus.spp | ||||||
|         reg_mstatus.mprv := new_sstatus.mprv |         reg_mstatus.pum := new_sstatus.pum | ||||||
|         reg_mstatus.fs := new_sstatus.fs // even without an FPU |         reg_mstatus.fs := Fill(2, new_sstatus.fs.orR) // even without an FPU | ||||||
|         if (usingRoCC) reg_mstatus.xs := new_sstatus.xs |         if (usingRoCC) reg_mstatus.xs := Fill(2, new_sstatus.xs.orR) | ||||||
|       } |       } | ||||||
|       when (decoded_addr(CSRs.sip)) { |       when (decoded_addr(CSRs.sip)) { | ||||||
|         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.sie)) { |       when (decoded_addr(CSRs.sie))      { reg_mie := (reg_mie & ~reg_mideleg) | (wdata & reg_mideleg) } | ||||||
|         val new_sie = new MIP().fromBits(wdata) |  | ||||||
|         reg_mie.ssip := new_sie.ssip |  | ||||||
|         reg_mie.stip := new_sie.stip |  | ||||||
|       } |  | ||||||
|       when (decoded_addr(CSRs.sscratch)) { reg_sscratch := wdata } |       when (decoded_addr(CSRs.sscratch)) { reg_sscratch := wdata } | ||||||
|       when (decoded_addr(CSRs.sptbr))    { reg_sptbr := Cat(wdata(paddrBits-1, pgIdxBits), Bits(0, pgIdxBits)) } |       when (decoded_addr(CSRs.sptbr))    { reg_sptbr := wdata } | ||||||
|       when (decoded_addr(CSRs.sepc))     { reg_sepc := ~(~wdata | (coreInstBytes-1)) } |       when (decoded_addr(CSRs.sepc))     { reg_sepc := wdata >> log2Up(coreInstBytes) << log2Up(coreInstBytes) } | ||||||
|       when (decoded_addr(CSRs.stvec))    { reg_stvec := ~(~wdata | (coreInstBytes-1)) } |       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 } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   io.rocc.csr.waddr := addr |   io.rocc.csr.waddr := addr | ||||||
|   io.rocc.csr.wdata := wdata |   io.rocc.csr.wdata := wdata | ||||||
|   io.rocc.csr.wen := wen |   io.rocc.csr.wen := wen | ||||||
|  |  | ||||||
|   when(this.reset) { |  | ||||||
|     reg_mstatus.zero1 := 0 |  | ||||||
|     reg_mstatus.zero2 := 0 |  | ||||||
|     reg_mstatus.ie := false |  | ||||||
|     reg_mstatus.prv := PRV_M |  | ||||||
|     reg_mstatus.ie1 := false |  | ||||||
|     reg_mstatus.prv1 := PRV_M /* hard-wired to M when missing user mode */ |  | ||||||
|     reg_mstatus.ie2 := false  /* hard-wired to 0 when missing supervisor mode */ |  | ||||||
|     reg_mstatus.prv2 := PRV_U /* hard-wired to 0 when missing supervisor mode */ |  | ||||||
|     reg_mstatus.ie3 := false  /* hard-wired to 0 when missing hypervisor mode */ |  | ||||||
|     reg_mstatus.prv3 := PRV_U /* hard-wired to 0 when missing hypervisor mode */ |  | ||||||
|     reg_mstatus.mprv := false |  | ||||||
|     reg_mstatus.vm := 0 |  | ||||||
|     reg_mstatus.fs := 0 |  | ||||||
|     reg_mstatus.xs := 0 |  | ||||||
|     reg_mstatus.sd_rv32 := false |  | ||||||
|     reg_mstatus.sd := false |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ class Frontend(implicit p: Parameters) extends CoreModule()(p) with HasL1CachePa | |||||||
|   val s1_pc = ~(~s1_pc_ | (coreInstBytes-1)) // discard PC LSBS (this propagates down the pipeline) |   val s1_pc = ~(~s1_pc_ | (coreInstBytes-1)) // discard PC LSBS (this propagates down the pipeline) | ||||||
|   val s1_same_block = Reg(Bool()) |   val s1_same_block = Reg(Bool()) | ||||||
|   val s2_valid = Reg(init=Bool(true)) |   val s2_valid = Reg(init=Bool(true)) | ||||||
|   val s2_pc = Reg(init=UInt(startAddr)) |   val s2_pc = Reg(init=UInt(p(ResetVector))) | ||||||
|   val s2_btb_resp_valid = Reg(init=Bool(false)) |   val s2_btb_resp_valid = Reg(init=Bool(false)) | ||||||
|   val s2_btb_resp_bits = Reg(btb.io.resp.bits) |   val s2_btb_resp_bits = Reg(btb.io.resp.bits) | ||||||
|   val s2_xcpt_if = Reg(init=Bool(false)) |   val s2_xcpt_if = Reg(init=Bool(false)) | ||||||
|   | |||||||
| @@ -174,7 +174,6 @@ object XDecode extends DecodeConstants | |||||||
|     SCALL->     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), |     SCALL->     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), | ||||||
|     SBREAK->    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), |     SBREAK->    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), | ||||||
|     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), |     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), | ||||||
|     MRTS->      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), |  | ||||||
|     WFI->       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), |     WFI->       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), | ||||||
|     CSRRW->     List(Y,    N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,      MT_X, N,N,N,N,N,Y,CSR.W,N,N,N), |     CSRRW->     List(Y,    N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,      MT_X, N,N,N,N,N,Y,CSR.W,N,N,N), | ||||||
|     CSRRS->     List(Y,    N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,      MT_X, N,N,N,N,N,Y,CSR.S,N,N,N), |     CSRRS->     List(Y,    N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,      MT_X, N,N,N,N,N,Y,CSR.S,N,N,N), | ||||||
|   | |||||||
| @@ -94,12 +94,9 @@ object Instructions { | |||||||
|   def SC_D               = BitPat("b00011????????????011?????0101111") |   def SC_D               = BitPat("b00011????????????011?????0101111") | ||||||
|   def SCALL              = BitPat("b00000000000000000000000001110011") |   def SCALL              = BitPat("b00000000000000000000000001110011") | ||||||
|   def SBREAK             = BitPat("b00000000000100000000000001110011") |   def SBREAK             = BitPat("b00000000000100000000000001110011") | ||||||
|   def SRET               = BitPat("b00010000000000000000000001110011") |   def SRET               = BitPat("b00010000001000000000000001110011") | ||||||
|   def SFENCE_VM          = BitPat("b000100000001?????000000001110011") |   def SFENCE_VM          = BitPat("b000100000100?????000000001110011") | ||||||
|   def WFI                = BitPat("b00010000001000000000000001110011") |   def WFI                = BitPat("b00010000010100000000000001110011") | ||||||
|   def MRTH               = BitPat("b00110000011000000000000001110011") |  | ||||||
|   def MRTS               = BitPat("b00110000010100000000000001110011") |  | ||||||
|   def HRTS               = BitPat("b00100000010100000000000001110011") |  | ||||||
|   def CSRRW              = BitPat("b?????????????????001?????1110011") |   def CSRRW              = BitPat("b?????????????????001?????1110011") | ||||||
|   def CSRRS              = BitPat("b?????????????????010?????1110011") |   def CSRRS              = BitPat("b?????????????????010?????1110011") | ||||||
|   def CSRRC              = BitPat("b?????????????????011?????1110011") |   def CSRRC              = BitPat("b?????????????????011?????1110011") | ||||||
| @@ -268,50 +265,63 @@ object CSRs { | |||||||
|   val uarch14 = 0xcce |   val uarch14 = 0xcce | ||||||
|   val uarch15 = 0xccf |   val uarch15 = 0xccf | ||||||
|   val sstatus = 0x100 |   val sstatus = 0x100 | ||||||
|   val stvec = 0x101 |  | ||||||
|   val sie = 0x104 |   val sie = 0x104 | ||||||
|  |   val stvec = 0x105 | ||||||
|   val sscratch = 0x140 |   val sscratch = 0x140 | ||||||
|   val sepc = 0x141 |   val sepc = 0x141 | ||||||
|  |   val scause = 0x142 | ||||||
|  |   val sbadaddr = 0x143 | ||||||
|   val sip = 0x144 |   val sip = 0x144 | ||||||
|   val sptbr = 0x180 |   val sptbr = 0x180 | ||||||
|   val sasid = 0x181 |   val sasid = 0x181 | ||||||
|   val cyclew = 0x900 |   val scycle = 0xd00 | ||||||
|   val timew = 0x901 |  | ||||||
|   val instretw = 0x902 |  | ||||||
|   val stime = 0xd01 |   val stime = 0xd01 | ||||||
|   val scause = 0xd42 |   val sinstret = 0xd02 | ||||||
|   val sbadaddr = 0xd43 |  | ||||||
|   val stimew = 0xa01 |  | ||||||
|   val mstatus = 0x300 |   val mstatus = 0x300 | ||||||
|   val mtvec = 0x301 |   val medeleg = 0x302 | ||||||
|   val mtdeleg = 0x302 |   val mideleg = 0x303 | ||||||
|   val mie = 0x304 |   val mie = 0x304 | ||||||
|  |   val mtvec = 0x305 | ||||||
|   val mtimecmp = 0x321 |   val mtimecmp = 0x321 | ||||||
|   val mscratch = 0x340 |   val mscratch = 0x340 | ||||||
|   val mepc = 0x341 |   val mepc = 0x341 | ||||||
|   val mcause = 0x342 |   val mcause = 0x342 | ||||||
|   val mbadaddr = 0x343 |   val mbadaddr = 0x343 | ||||||
|   val mip = 0x344 |   val mip = 0x344 | ||||||
|   val mtime = 0x701 |   val mipi = 0x345 | ||||||
|   val mcpuid = 0xf00 |   val mucounteren = 0x310 | ||||||
|   val mimpid = 0xf01 |   val mscounteren = 0x311 | ||||||
|   val mhartid = 0xf10 |   val mucycle_delta = 0x700 | ||||||
|   val mtohost = 0x780 |   val mutime_delta = 0x701 | ||||||
|   val mfromhost = 0x781 |   val muinstret_delta = 0x702 | ||||||
|   val mreset = 0x782 |   val mscycle_delta = 0x704 | ||||||
|   val mipi = 0x783 |   val mstime_delta = 0x705 | ||||||
|   val miobase = 0x784 |   val msinstret_delta = 0x706 | ||||||
|  |   val mcycle = 0xf00 | ||||||
|  |   val mtime = 0xf01 | ||||||
|  |   val minstret = 0xf02 | ||||||
|  |   val misa = 0xf10 | ||||||
|  |   val mvendorid = 0xf11 | ||||||
|  |   val marchid = 0xf12 | ||||||
|  |   val mimpid = 0xf13 | ||||||
|  |   val mcfgaddr = 0xf14 | ||||||
|  |   val mhartid = 0xf15 | ||||||
|  |   val mtohost = 0x7c0 | ||||||
|  |   val mfromhost = 0x7c1 | ||||||
|  |   val mreset = 0x7c2 | ||||||
|   val cycleh = 0xc80 |   val cycleh = 0xc80 | ||||||
|   val timeh = 0xc81 |   val timeh = 0xc81 | ||||||
|   val instreth = 0xc82 |   val instreth = 0xc82 | ||||||
|   val cyclehw = 0x980 |  | ||||||
|   val timehw = 0x981 |  | ||||||
|   val instrethw = 0x982 |  | ||||||
|   val stimeh = 0xd81 |  | ||||||
|   val stimehw = 0xa81 |  | ||||||
|   val mtimecmph = 0x361 |   val mtimecmph = 0x361 | ||||||
|   val mtimeh = 0x741 |   val mucycle_deltah = 0x780 | ||||||
|   val mrwbase = 0x790 |   val mutime_deltah = 0x781 | ||||||
|  |   val muinstret_deltah = 0x782 | ||||||
|  |   val mscycle_deltah = 0x784 | ||||||
|  |   val mstime_deltah = 0x785 | ||||||
|  |   val msinstret_deltah = 0x786 | ||||||
|  |   val mcycleh = 0xf80 | ||||||
|  |   val mtimeh = 0xf81 | ||||||
|  |   val minstreth = 0xf82 | ||||||
|   val all = { |   val all = { | ||||||
|     val res = collection.mutable.ArrayBuffer[Int]() |     val res = collection.mutable.ArrayBuffer[Int]() | ||||||
|     res += fflags |     res += fflags | ||||||
| @@ -338,39 +348,50 @@ object CSRs { | |||||||
|     res += uarch14 |     res += uarch14 | ||||||
|     res += uarch15 |     res += uarch15 | ||||||
|     res += sstatus |     res += sstatus | ||||||
|     res += stvec |  | ||||||
|     res += sie |     res += sie | ||||||
|  |     res += stvec | ||||||
|     res += sscratch |     res += sscratch | ||||||
|     res += sepc |     res += sepc | ||||||
|  |     res += scause | ||||||
|  |     res += sbadaddr | ||||||
|     res += sip |     res += sip | ||||||
|     res += sptbr |     res += sptbr | ||||||
|     res += sasid |     res += sasid | ||||||
|     res += cyclew |     res += scycle | ||||||
|     res += timew |  | ||||||
|     res += instretw |  | ||||||
|     res += stime |     res += stime | ||||||
|     res += scause |     res += sinstret | ||||||
|     res += sbadaddr |  | ||||||
|     res += stimew |  | ||||||
|     res += mstatus |     res += mstatus | ||||||
|     res += mtvec |     res += medeleg | ||||||
|     res += mtdeleg |     res += mideleg | ||||||
|     res += mie |     res += mie | ||||||
|  |     res += mtvec | ||||||
|     res += mtimecmp |     res += mtimecmp | ||||||
|     res += mscratch |     res += mscratch | ||||||
|     res += mepc |     res += mepc | ||||||
|     res += mcause |     res += mcause | ||||||
|     res += mbadaddr |     res += mbadaddr | ||||||
|     res += mip |     res += mip | ||||||
|  |     res += mipi | ||||||
|  |     res += mucounteren | ||||||
|  |     res += mscounteren | ||||||
|  |     res += mucycle_delta | ||||||
|  |     res += mutime_delta | ||||||
|  |     res += muinstret_delta | ||||||
|  |     res += mscycle_delta | ||||||
|  |     res += mstime_delta | ||||||
|  |     res += msinstret_delta | ||||||
|  |     res += mcycle | ||||||
|     res += mtime |     res += mtime | ||||||
|     res += mcpuid |     res += minstret | ||||||
|  |     res += misa | ||||||
|  |     res += mvendorid | ||||||
|  |     res += marchid | ||||||
|     res += mimpid |     res += mimpid | ||||||
|  |     res += mcfgaddr | ||||||
|     res += mhartid |     res += mhartid | ||||||
|     res += mtohost |     res += mtohost | ||||||
|     res += mfromhost |     res += mfromhost | ||||||
|     res += mreset |     res += mreset | ||||||
|     res += mipi |  | ||||||
|     res += miobase |  | ||||||
|     res.toArray |     res.toArray | ||||||
|   } |   } | ||||||
|   val all32 = { |   val all32 = { | ||||||
| @@ -378,13 +399,16 @@ object CSRs { | |||||||
|     res += cycleh |     res += cycleh | ||||||
|     res += timeh |     res += timeh | ||||||
|     res += instreth |     res += instreth | ||||||
|     res += cyclehw |  | ||||||
|     res += timehw |  | ||||||
|     res += instrethw |  | ||||||
|     res += stimeh |  | ||||||
|     res += stimehw |  | ||||||
|     res += mtimecmph |     res += mtimecmph | ||||||
|  |     res += mucycle_deltah | ||||||
|  |     res += mutime_deltah | ||||||
|  |     res += muinstret_deltah | ||||||
|  |     res += mscycle_deltah | ||||||
|  |     res += mstime_deltah | ||||||
|  |     res += msinstret_deltah | ||||||
|  |     res += mcycleh | ||||||
|     res += mtimeh |     res += mtimeh | ||||||
|  |     res += minstreth | ||||||
|     res.toArray |     res.toArray | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ class PTWReq(implicit p: Parameters) extends CoreBundle()(p) { | |||||||
| } | } | ||||||
|  |  | ||||||
| class PTWResp(implicit p: Parameters) extends CoreBundle()(p) { | class PTWResp(implicit p: Parameters) extends CoreBundle()(p) { | ||||||
|   val error = Bool() |  | ||||||
|   val pte = new PTE |   val pte = new PTE | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -27,7 +26,7 @@ class TLBPTWIO(implicit p: Parameters) extends CoreBundle()(p) { | |||||||
| } | } | ||||||
|  |  | ||||||
| class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p) { | class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p) { | ||||||
|   val ptbr = UInt(INPUT, paddrBits) |   val ptbr = UInt(INPUT, ppnBits) | ||||||
|   val invalidate = Bool(INPUT) |   val invalidate = Bool(INPUT) | ||||||
|   val status = new MStatus().asInput |   val status = new MStatus().asInput | ||||||
| } | } | ||||||
| @@ -59,7 +58,7 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { | |||||||
|     val dpath = new DatapathPTWIO |     val dpath = new DatapathPTWIO | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   val s_ready :: s_req :: s_wait :: s_set_dirty :: s_wait_dirty :: s_done :: s_error :: Nil = Enum(UInt(), 7) |   val s_ready :: s_req :: s_wait :: s_set_dirty :: s_wait_dirty :: s_done :: Nil = Enum(UInt(), 6) | ||||||
|   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))) | ||||||
|  |  | ||||||
| @@ -79,7 +78,7 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { | |||||||
|   when (arb.io.out.fire()) { |   when (arb.io.out.fire()) { | ||||||
|     r_req := arb.io.out.bits |     r_req := arb.io.out.bits | ||||||
|     r_req_dest := arb.io.chosen |     r_req_dest := arb.io.chosen | ||||||
|     r_pte.ppn := io.dpath.ptbr(paddrBits-1,pgIdxBits) |     r_pte.ppn := io.dpath.ptbr | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   val (pte_cache_hit, pte_cache_data) = { |   val (pte_cache_hit, pte_cache_data) = { | ||||||
| @@ -122,16 +121,12 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { | |||||||
|   io.mem.req.bits.kill := Bool(false) |   io.mem.req.bits.kill := Bool(false) | ||||||
|   io.mem.req.bits.data := pte_wdata.toBits |   io.mem.req.bits.data := pte_wdata.toBits | ||||||
|    |    | ||||||
|   val resp_err = state === s_error |  | ||||||
|   val resp_val = state === s_done || resp_err |  | ||||||
|  |  | ||||||
|   val r_resp_ppn = io.mem.req.bits.addr >> pgIdxBits |   val r_resp_ppn = io.mem.req.bits.addr >> pgIdxBits | ||||||
|   val resp_ppn = Vec((0 until pgLevels-1).map(i => Cat(r_resp_ppn >> pgLevelBits*(pgLevels-i-1), r_req.addr(pgLevelBits*(pgLevels-i-1)-1,0))) :+ r_resp_ppn)(count) |   val resp_ppn = Vec((0 until pgLevels-1).map(i => Cat(r_resp_ppn >> pgLevelBits*(pgLevels-i-1), r_req.addr(pgLevelBits*(pgLevels-i-1)-1,0))) :+ r_resp_ppn)(count) | ||||||
|  |   val resp_val = state === s_done | ||||||
|  |  | ||||||
|   for (i <- 0 until io.requestor.size) { |   for (i <- 0 until io.requestor.size) { | ||||||
|     val me = r_req_dest === UInt(i) |     io.requestor(i).resp.valid := resp_val && (r_req_dest === i) | ||||||
|     io.requestor(i).resp.valid := resp_val && me |  | ||||||
|     io.requestor(i).resp.bits.error := resp_err |  | ||||||
|     io.requestor(i).resp.bits.pte := r_pte |     io.requestor(i).resp.bits.pte := r_pte | ||||||
|     io.requestor(i).resp.bits.pte.ppn := resp_ppn |     io.requestor(i).resp.bits.pte.ppn := resp_ppn | ||||||
|     io.requestor(i).invalidate := io.dpath.invalidate |     io.requestor(i).invalidate := io.dpath.invalidate | ||||||
| @@ -161,14 +156,14 @@ 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_error |         state := s_done | ||||||
|  |         when (pte.leaf() && set_dirty_bit) { | ||||||
|  |           state := s_set_dirty | ||||||
|  |         } | ||||||
|         when (pte.table() && count < pgLevels-1) { |         when (pte.table() && count < pgLevels-1) { | ||||||
|           state := s_req |           state := s_req | ||||||
|           count := count + 1 |           count := count + 1 | ||||||
|         } |         } | ||||||
|         when (pte.leaf()) { |  | ||||||
|           state := Mux(set_dirty_bit, s_set_dirty, s_done) |  | ||||||
|         } |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     is (s_set_dirty) { |     is (s_set_dirty) { | ||||||
| @@ -187,8 +182,5 @@ class PTW(n: Int)(implicit p: Parameters) extends CoreModule()(p) { | |||||||
|     is (s_done) { |     is (s_done) { | ||||||
|       state := s_ready |       state := s_ready | ||||||
|     } |     } | ||||||
|     is (s_error) { |  | ||||||
|       state := s_ready |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -47,7 +47,7 @@ class RoCCInterface(implicit p: Parameters) extends CoreBundle()(p) { | |||||||
|   val resp = Decoupled(new RoCCResponse) |   val resp = Decoupled(new RoCCResponse) | ||||||
|   val mem = new HellaCacheIO()(p.alterPartial({ case CacheName => "L1D" })) |   val mem = new HellaCacheIO()(p.alterPartial({ case CacheName => "L1D" })) | ||||||
|   val busy = Bool(OUTPUT) |   val busy = Bool(OUTPUT) | ||||||
|   val s = Bool(INPUT) |   val status = new MStatus().asInput | ||||||
|   val interrupt = Bool(OUTPUT) |   val interrupt = Bool(OUTPUT) | ||||||
|    |    | ||||||
|   // These should be handled differently, eventually |   // These should be handled differently, eventually | ||||||
| @@ -142,8 +142,7 @@ class TranslatorExample(implicit p: Parameters) extends RoCC()(p) { | |||||||
|   val req_rd = Reg(io.resp.bits.rd) |   val req_rd = Reg(io.resp.bits.rd) | ||||||
|   val req_offset = req_addr(pgIdxBits - 1, 0) |   val req_offset = req_addr(pgIdxBits - 1, 0) | ||||||
|   val req_vpn = req_addr(coreMaxAddrBits - 1, pgIdxBits) |   val req_vpn = req_addr(coreMaxAddrBits - 1, pgIdxBits) | ||||||
|   val ppn = Reg(UInt(width = ppnBits)) |   val pte = Reg(new PTE) | ||||||
|   val error = Reg(Bool()) |  | ||||||
|  |  | ||||||
|   val s_idle :: s_ptw_req :: s_ptw_resp :: s_resp :: Nil = Enum(Bits(), 4) |   val s_idle :: s_ptw_req :: s_ptw_resp :: s_resp :: Nil = Enum(Bits(), 4) | ||||||
|   val state = Reg(init = s_idle) |   val state = Reg(init = s_idle) | ||||||
| @@ -161,8 +160,7 @@ class TranslatorExample(implicit p: Parameters) extends RoCC()(p) { | |||||||
|   when (ptw.req.fire()) { state := s_ptw_resp } |   when (ptw.req.fire()) { state := s_ptw_resp } | ||||||
|  |  | ||||||
|   when (state === s_ptw_resp && ptw.resp.valid) { |   when (state === s_ptw_resp && ptw.resp.valid) { | ||||||
|     error := ptw.resp.bits.error |     pte := ptw.resp.bits.pte | ||||||
|     ppn := ptw.resp.bits.pte.ppn |  | ||||||
|     state := s_resp |     state := s_resp | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -175,7 +173,7 @@ class TranslatorExample(implicit p: Parameters) extends RoCC()(p) { | |||||||
|  |  | ||||||
|   io.resp.valid := (state === s_resp) |   io.resp.valid := (state === s_resp) | ||||||
|   io.resp.bits.rd := req_rd |   io.resp.bits.rd := req_rd | ||||||
|   io.resp.bits.data := Mux(error, SInt(-1).toUInt, Cat(ppn, req_offset)) |   io.resp.bits.data := Mux(pte.leaf(), Cat(pte.ppn, req_offset), ~UInt(0, xLen)) | ||||||
|  |  | ||||||
|   io.busy := (state =/= s_idle) |   io.busy := (state =/= s_idle) | ||||||
|   io.interrupt := Bool(false) |   io.interrupt := Bool(false) | ||||||
|   | |||||||
| @@ -22,7 +22,9 @@ case object CoreInstBits extends Field[Int] | |||||||
| case object CoreDataBits extends Field[Int] | case object CoreDataBits extends Field[Int] | ||||||
| case object CoreDCacheReqTagBits extends Field[Int] | case object CoreDCacheReqTagBits extends Field[Int] | ||||||
| case object NCustomMRWCSRs extends Field[Int] | case object NCustomMRWCSRs extends Field[Int] | ||||||
|  | case object MtvecWritable extends Field[Boolean] | ||||||
| case object MtvecInit extends Field[BigInt] | case object MtvecInit extends Field[BigInt] | ||||||
|  | case object ResetVector extends Field[BigInt] | ||||||
|  |  | ||||||
| trait HasCoreParameters extends HasAddrMapParameters { | trait HasCoreParameters extends HasAddrMapParameters { | ||||||
|   implicit val p: Parameters |   implicit val p: Parameters | ||||||
| @@ -51,8 +53,6 @@ trait HasCoreParameters extends HasAddrMapParameters { | |||||||
|     else p(BuildRoCC).flatMap(_.csrs) |     else p(BuildRoCC).flatMap(_.csrs) | ||||||
|   val nRoccCsrs = p(RoccNCSRs) |   val nRoccCsrs = p(RoccNCSRs) | ||||||
|   val nCores = p(HtifKey).nCores |   val nCores = p(HtifKey).nCores | ||||||
|   val mtvecInit = p(MtvecInit) |  | ||||||
|   val startAddr = mtvecInit + 0x100 |  | ||||||
|  |  | ||||||
|   // Print out log of committed instructions and their writeback values. |   // Print out log of committed instructions and their writeback values. | ||||||
|   // Requires post-processing due to out-of-order writebacks. |   // Requires post-processing due to out-of-order writebacks. | ||||||
| @@ -539,7 +539,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) { | |||||||
|  |  | ||||||
|   io.rocc.cmd.valid := wb_rocc_val |   io.rocc.cmd.valid := wb_rocc_val | ||||||
|   io.rocc.exception := wb_xcpt && csr.io.status.xs.orR |   io.rocc.exception := wb_xcpt && csr.io.status.xs.orR | ||||||
|   io.rocc.s := csr.io.status.prv.orR // should we just pass all of mstatus? |   io.rocc.status := csr.io.status | ||||||
|   io.rocc.cmd.bits.inst := new RoCCInstruction().fromBits(wb_reg_inst) |   io.rocc.cmd.bits.inst := new RoCCInstruction().fromBits(wb_reg_inst) | ||||||
|   io.rocc.cmd.bits.rs1 := wb_reg_wdata |   io.rocc.cmd.bits.rs1 := wb_reg_wdata | ||||||
|   io.rocc.cmd.bits.rs2 := wb_reg_rs2 |   io.rocc.cmd.bits.rs2 := wb_reg_rs2 | ||||||
|   | |||||||
| @@ -84,7 +84,7 @@ class RocketTile(resetSignal: Bool = null)(implicit p: Parameters) extends Tile( | |||||||
|       })) |       })) | ||||||
|       val dcIF = Module(new SimpleHellaCacheIF()(dcacheParams)) |       val dcIF = Module(new SimpleHellaCacheIF()(dcacheParams)) | ||||||
|       rocc.io.cmd <> cmdRouter.io.out(i) |       rocc.io.cmd <> cmdRouter.io.out(i) | ||||||
|       rocc.io.s := core.io.rocc.s |       rocc.io.status := core.io.rocc.status | ||||||
|       rocc.io.exception := core.io.rocc.exception |       rocc.io.exception := core.io.rocc.exception | ||||||
|       rocc.io.host_id := io.host.id |       rocc.io.host_id := io.host.id | ||||||
|       dcIF.io.requestor <> rocc.io.mem |       dcIF.io.requestor <> rocc.io.mem | ||||||
|   | |||||||
| @@ -100,7 +100,6 @@ class TLB(implicit p: Parameters) extends TLBModule()(p) { | |||||||
|   val tag_hit_addr = OHToUInt(tag_cam.io.hits) |   val tag_hit_addr = OHToUInt(tag_cam.io.hits) | ||||||
|    |    | ||||||
|   // permission bit arrays |   // permission bit arrays | ||||||
|   val valid_array = Reg(Vec(entries, Bool())) // PTE is valid (not equivalent to CAM tag valid bit!) |  | ||||||
|   val ur_array = Reg(Vec(entries, Bool())) // user read permission |   val ur_array = Reg(Vec(entries, Bool())) // user read permission | ||||||
|   val uw_array = Reg(Vec(entries, Bool())) // user write permission |   val uw_array = Reg(Vec(entries, Bool())) // user write permission | ||||||
|   val ux_array = Reg(Vec(entries, Bool())) // user execute permission |   val ux_array = Reg(Vec(entries, Bool())) // user execute permission | ||||||
| @@ -111,13 +110,12 @@ class TLB(implicit p: Parameters) extends TLBModule()(p) { | |||||||
|   when (io.ptw.resp.valid) { |   when (io.ptw.resp.valid) { | ||||||
|     val pte = io.ptw.resp.bits.pte |     val pte = io.ptw.resp.bits.pte | ||||||
|     tag_ram(r_refill_waddr) := pte.ppn |     tag_ram(r_refill_waddr) := pte.ppn | ||||||
|     valid_array(r_refill_waddr) := !io.ptw.resp.bits.error |     ur_array(r_refill_waddr) := pte.ur() | ||||||
|     ur_array(r_refill_waddr) := pte.ur() && !io.ptw.resp.bits.error |     uw_array(r_refill_waddr) := pte.uw() | ||||||
|     uw_array(r_refill_waddr) := pte.uw() && !io.ptw.resp.bits.error |     ux_array(r_refill_waddr) := pte.ux() | ||||||
|     ux_array(r_refill_waddr) := pte.ux() && !io.ptw.resp.bits.error |     sr_array(r_refill_waddr) := pte.sr() | ||||||
|     sr_array(r_refill_waddr) := pte.sr() && !io.ptw.resp.bits.error |     sw_array(r_refill_waddr) := pte.sw() | ||||||
|     sw_array(r_refill_waddr) := pte.sw() && !io.ptw.resp.bits.error |     sx_array(r_refill_waddr) := pte.sx() | ||||||
|     sx_array(r_refill_waddr) := pte.sx() && !io.ptw.resp.bits.error |  | ||||||
|     dirty_array(r_refill_waddr) := pte.d |     dirty_array(r_refill_waddr) := pte.d | ||||||
|   } |   } | ||||||
|   |   | ||||||
| @@ -127,13 +125,16 @@ class TLB(implicit p: Parameters) extends TLBModule()(p) { | |||||||
|   val plru = new PseudoLRU(entries) |   val plru = new PseudoLRU(entries) | ||||||
|   val repl_waddr = Mux(has_invalid_entry, invalid_entry, plru.replace) |   val repl_waddr = Mux(has_invalid_entry, invalid_entry, plru.replace) | ||||||
|  |  | ||||||
|   val priv = Mux(io.ptw.status.mprv && !io.req.bits.instruction, io.ptw.status.prv1, io.ptw.status.prv) |   val do_mprv = io.ptw.status.prv === PRV.M && io.ptw.status.mprv && !io.req.bits.instruction | ||||||
|   val priv_s = priv === PRV_S |   val priv = Mux(do_mprv, io.ptw.status.mpp, io.ptw.status.prv) | ||||||
|   val priv_uses_vm = priv <= PRV_S |   val priv_s = priv === PRV.S | ||||||
|  |   val priv_uses_vm = priv <= PRV.S | ||||||
|   val req_xwr = Cat(!r_req.store, r_req.store, !(r_req.instruction || r_req.store)) |   val req_xwr = Cat(!r_req.store, r_req.store, !(r_req.instruction || r_req.store)) | ||||||
|  |  | ||||||
|   val r_array = Mux(priv_s, sr_array.toBits, ur_array.toBits) |   val ur_bits = ur_array.toBits | ||||||
|   val w_array = Mux(priv_s, sw_array.toBits, uw_array.toBits) |   val pum_ok = ~Mux(io.ptw.status.pum, ur_bits, UInt(0)) | ||||||
|  |   val r_array = Mux(priv_s, sr_array.toBits & pum_ok, ur_bits) | ||||||
|  |   val w_array = Mux(priv_s, sw_array.toBits & pum_ok, uw_array.toBits) | ||||||
|   val x_array = Mux(priv_s, sx_array.toBits, ux_array.toBits) |   val x_array = Mux(priv_s, sx_array.toBits, ux_array.toBits) | ||||||
|  |  | ||||||
|   val vm_enabled = io.ptw.status.vm(3) && priv_uses_vm && !io.req.bits.passthrough |   val vm_enabled = io.ptw.status.vm(3) && priv_uses_vm && !io.req.bits.passthrough | ||||||
| @@ -160,10 +161,10 @@ class TLB(implicit p: Parameters) extends TLBModule()(p) { | |||||||
|   io.resp.ppn := Mux(vm_enabled, Mux1H(tag_cam.io.hits, tag_ram), io.req.bits.vpn(ppnBits-1,0)) |   io.resp.ppn := Mux(vm_enabled, Mux1H(tag_cam.io.hits, tag_ram), io.req.bits.vpn(ppnBits-1,0)) | ||||||
|   io.resp.hit_idx := tag_cam.io.hits |   io.resp.hit_idx := tag_cam.io.hits | ||||||
|  |  | ||||||
|   // clear invalid entries on access, or all entries on a TLB flush |   // clear entries on a TLB flush. | ||||||
|   tag_cam.io.clear := io.ptw.invalidate || io.req.fire() |   // TODO: selective flushing.  careful with superpage mappings (flush it all) | ||||||
|   tag_cam.io.clear_mask := ~valid_array.toBits | (tag_cam.io.hits & ~tag_hits) |   tag_cam.io.clear := io.ptw.invalidate | ||||||
|   when (io.ptw.invalidate) { tag_cam.io.clear_mask := ~UInt(0, entries) } |   tag_cam.io.clear_mask := ~UInt(0, entries) | ||||||
|    |    | ||||||
|   io.ptw.req.valid := state === s_request |   io.ptw.req.valid := state === s_request | ||||||
|   io.ptw.req.bits.addr := r_refill_tag |   io.ptw.req.bits.addr := r_refill_tag | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user