1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util.BitPat.bitPatToUInt 5import chisel3.util.{BitPat, Cat, Fill, Mux1H, MuxCase, ValidIO} 6import utility.{SignExt, ZeroExt} 7import freechips.rocketchip.rocket.CSRs 8import xiangshan.backend.fu.NewCSR.CSRBundles._ 9import xiangshan.backend.fu.NewCSR.CSRDefines._ 10import xiangshan.backend.fu.NewCSR.CSRFunc._ 11import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, CSRWARLField => WARL, CSRWLRLField => WLRL, _} 12import xiangshan.backend.fu.NewCSR.CSRConfig._ 13import xiangshan.backend.fu.NewCSR.CSREvents.TrapEntryHSEventSinkBundle 14import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._ 15import xiangshan.backend.fu.NewCSR.CSRBundleImplicitCast._ 16import xiangshan.backend.fu.NewCSR.ChiselRecordForField._ 17 18import scala.collection.immutable.SeqMap 19 20trait SupervisorLevel { self: NewCSR with MachineLevel => 21 val sie = Module(new CSRModule("Sie", new SieBundle) 22 with HasIpIeBundle 23 { 24 val toMie = IO(new SieToMie) 25 val fromVSie = IO(Flipped(new VSieToSie)) 26 27 // Sie is alias of mie when mideleg=1. 28 // Otherwise, sie has seperate writable registers 29 // There are no regs in CSR sie. 30 val mieIsAlias = mideleg 31 val usingReg = ~mideleg & mvien 32 regOut := (mieIsAlias & mie) | (usingReg & reg) 33 34 bundle.getFields.map(_.lsb).foreach { num => 35 val wtMie = toMie.getByNum(num) 36 val vsieWt = fromVSie.getByNum(num) 37 38 wtMie.specifyField( 39 _.valid := wen && mieIsAlias(num) && wtMie.bits.isRW.B, 40 _.bits := wen && mieIsAlias(num) && wtMie.bits.isRW.B &< wdata(num), 41 ) 42 43 when ( 44 wen && usingReg(num) && reg(num).isRW.B || 45 vsieWt.valid && usingReg(num) && vsieWt.bits.isRW.B 46 ) { 47 reg(num) := Mux1H(Seq( 48 wen -> wdata(num), 49 vsieWt.valid -> vsieWt.bits, 50 )) 51 }.otherwise { 52 reg(num) := reg(num) 53 } 54 } 55 56 regOut.getFields.foreach { field => 57 if (field.isHardWired) { 58 field := field.getHardWireValue 59 } 60 } 61 }) 62 .setAddr(CSRs.sie) 63 64 val stvec = Module(new CSRModule("Stvec", new XtvecBundle)) 65 .setAddr(CSRs.stvec) 66 67 val scounteren = Module(new CSRModule("Scounteren", new Counteren)) 68 .setAddr(CSRs.scounteren) 69 70 val senvcfg = Module(new CSRModule("Senvcfg", new SEnvCfg)) 71 .setAddr(CSRs.senvcfg) 72 73 val sscratch = Module(new CSRModule("Sscratch")) 74 .setAddr(CSRs.sscratch) 75 76 val sepc = Module(new CSRModule("Sepc", new Epc) with TrapEntryHSEventSinkBundle { 77 rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN) 78 }) 79 .setAddr(CSRs.sepc) 80 81 val scause = Module(new CSRModule("Scause", new CauseBundle) with TrapEntryHSEventSinkBundle) 82 .setAddr(CSRs.scause) 83 84 val stval = Module(new CSRModule("Stval", new XtvalBundle) with TrapEntryHSEventSinkBundle) 85 .setAddr(CSRs.stval) 86 87 val sip = Module(new CSRModule("Sip", new SipBundle) 88 with HasIpIeBundle 89 { 90 val toMip = IO(new SipToMip) 91 val toMvip = IO(new SipToMvip) 92 93 // Ref: 7.1.3. Supervisor Interrupt Registers (sip and sie) 94 // The sip and sie registers are subsets of the mip and mie registers. Reading any 95 // implemented field, or writing any writable field, of sip/sie effects a read or write of the 96 // homonymous field of mip/mie. 97 98 // Ref: 3.1.9. Machine Interrupt Registers (mip and mie) 99 // Restricted views of the mip and mie registers appear as the sip and sie registers for supervisor level. If 100 // an interrupt is delegated to S-mode by setting a bit in the mideleg register, it becomes visible in the 101 // sip register and is maskable using the sie register. Otherwise, the corresponding bits in sip and sie 102 // are **read-only zero**. 103 val mipIsAlias = mideleg 104 val mvipIsAlias = ~mideleg & mvien 105 106 dontTouch(mvipIsAlias) 107 108 regOut := mipIsAlias & mip | (mvipIsAlias & mvip) 109 110 bundle.getFields.map(_.lsb).foreach { num => 111 val wtMip = toMip.getByNum(num) 112 val wtMvip = toMvip.getByNum(num) 113 114 wtMip.specifyField( 115 _.valid := wen && mipIsAlias(num) && wtMip.bits.isRW.B, 116 _.bits := wen && mipIsAlias(num) && wtMip.bits.isRW.B &< wdata(num), 117 ) 118 119 wtMvip.specifyField( 120 _.valid := wen && mvipIsAlias(num) && wtMvip.bits.isRW.B, 121 _.bits := wen && mvipIsAlias(num) && wtMvip.bits.isRW.B &< wdata(num), 122 ) 123 } 124 125 regOut.getFields.foreach { field => 126 if (field.isHardWired) { 127 field := field.getHardWireValue 128 } 129 } 130 }) 131 .setAddr(CSRs.sip) 132 133 val stimecmp = Module(new CSRModule("Stimecmp", new CSRBundle { 134 val stimecmp = RW(63, 0).withReset(bitPatToUInt(BitPat.Y(64))) 135 })) 136 .setAddr(CSRs.stimecmp) 137 138 val satp = Module(new CSRModule("Satp", new SatpBundle) { 139 val ppnMask = ZeroExt(Fill(PPNLength, 1.U(1.W)).take(PAddrBits - PageOffsetWidth), PPNLength) 140 // If satp is written with an unsupported MODE, 141 // the entire write has no effect; no fields in satp are modified. 142 when (wen && wdata.MODE.isLegal) { 143 reg.MODE := wdata.MODE 144 reg.ASID := wdata.ASID 145 reg.PPN := wdata.PPN & ppnMask 146 }.otherwise { 147 reg := reg 148 } 149 }) 150 .setAddr(CSRs.satp) 151 152 // scountovf: This register enables supervisor-level overflow interrupt handler software to quickly and easily 153 // determine which counter(s) have overflowed (without needing to make an execution environment call 154 // or series of calls ultimately up to M-mode). 155 val scountovf = Module(new CSRModule("Scountovf", new CSRBundle { 156 override val len: Int = 32 157 val OFVEC = RO(31, 3).withReset(0.U) 158 }) with HasMhpmeventOfBundle { 159 reg.OFVEC := ofVec 160 regOut.OFVEC := Mux1H(Seq( 161 privState.isModeM -> reg.OFVEC.asUInt, 162 privState.isModeHS -> (mcounteren.HPM.asUInt & reg.OFVEC.asUInt), 163 privState.isModeVS -> (mcounteren.HPM.asUInt & hcounteren.HPM.asUInt & reg.OFVEC.asUInt), 164 ) 165 ) 166 }).setAddr(CSRs.scountovf) 167 168 val sstateen0 = Module(new CSRModule("Sstateen", new SstateenBundle0) with HasStateen0Bundle { 169 // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), the same bit 170 // appears as read-only zero in the matching hstateen and sstateen CSRs. For every bit in an hstateen 171 // CSR that is zero (whether read-only zero or set to zero), the same bit appears as read-only zero in 172 // sstateen when accessed in VS-mode. 173 regOut := Mux(privState.isVirtual, fromHstateen0.asUInt, fromMstateen0.asUInt) & reg.asUInt 174 }).setAddr(CSRs.sstateen0) 175 176 val supervisorLevelCSRMods: Seq[CSRModule[_]] = Seq( 177 sie, 178 stvec, 179 scounteren, 180 senvcfg, 181 sscratch, 182 sepc, 183 scause, 184 stval, 185 sip, 186 stimecmp, 187 satp, 188 scountovf, 189 sstateen0, 190 ) 191 192 val supervisorLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap( 193 CSRs.sstatus -> (mstatus.wAliasSstatus, mstatus.sstatusRdata), 194 ) ++ SeqMap.from( 195 supervisorLevelCSRMods.map(csr => (csr.addr -> (csr.w, csr.rdata))).iterator 196 ) 197 198 val supervisorLevelCSROutMap: SeqMap[Int, UInt] = SeqMap( 199 CSRs.sstatus -> mstatus.sstatus.asUInt, 200 ) ++ SeqMap.from( 201 supervisorLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 202 ) 203} 204 205class SstatusBundle extends CSRBundle { 206 val SIE = CSRWARLField (1, wNoFilter) 207 val SPIE = CSRWARLField (5, wNoFilter) 208 val UBE = CSRROField (6).withReset(0.U) 209 val SPP = CSRWARLField (8, wNoFilter).withReset(0.U) 210 val VS = ContextStatus (10, 9).withReset(ContextStatus.Off) 211 val FS = ContextStatus (14, 13).withReset(ContextStatus.Off) 212 val XS = ContextStatusRO(16, 15).withReset(0.U) 213 val SUM = CSRWARLField (18, wNoFilter).withReset(0.U) 214 val MXR = CSRWARLField (19, wNoFilter).withReset(0.U) 215 val UXL = XLENField (33, 32).withReset(XLENField.XLEN64) 216 val SD = CSRROField (63, (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty) 217} 218 219class SieBundle extends InterruptEnableBundle { 220 this.getHS.foreach(_.setRW().withReset(0.U)) 221 this.STIE.setRO().withReset(0.U) 222 this.getLocal.foreach(_.setRW().withReset(0.U)) 223 this.getM .foreach(_.setHardWired(0.U)) 224 this.getVS.foreach(_.setHardWired(0.U)) 225 this.SGEIE.setHardWired(0.U) 226} 227 228class SipBundle extends InterruptPendingBundle { 229 // All pending bits in sip are aliases of mip or read-only 0 230 this.getM .foreach(_.setHardWired(0.U)) 231 this.getVS.foreach(_.setHardWired(0.U)) 232 this.SGEIP.setHardWired(0.U) 233} 234 235class SatpBundle extends CSRBundle { 236 val MODE = SatpMode(63, 60, null).withReset(SatpMode.Bare) 237 // WARL in privileged spec. 238 // RW, since we support max width of ASID 239 val ASID = RW(44 - 1 + ASIDLEN, 44).withReset(0.U) 240 // Do WARL in SatpModule/VSatpModule 241 val PPN = RW(43, 0).withReset(0.U) 242} 243 244class SEnvCfg extends EnvCfg 245 246class SipToMip extends IpValidBundle { 247 this.SSIP.bits.setRW() 248 this.LCOFIP.bits.setRW() 249} 250 251class SipToMvip extends IpValidBundle { 252 this.SSIP.bits.setRW() 253 this.getLocal.foreach(_.bits.setRW()) 254} 255 256class SieToMie extends IeValidBundle { 257 this.getHS.foreach(_.bits.setRW()) 258 this.getLocal.foreach(_.bits.setRW()) 259} 260 261trait HasMhpmeventOfBundle { self: CSRModule[_] => 262 val ofVec = IO(Input(UInt(perfCntNum.W))) 263 val privState = IO(Input(new PrivState)) 264 val mcounteren = IO(Input(new Counteren)) 265 val hcounteren = IO(Input(new Counteren)) 266}