1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util.BitPat.bitPatToUInt 5import chisel3.util._ 6import freechips.rocketchip.rocket.CSRs 7import utility.SignExt 8import xiangshan.backend.fu.NewCSR.CSRBundles._ 9import xiangshan.backend.fu.NewCSR.CSRDefines.{ 10 CSRRWField => RW, 11 CSRROField => RO, 12 CSRWLRLField => WLRL, 13 CSRWARLField => WARL, 14 VirtMode, 15 _ 16} 17import xiangshan.backend.fu.NewCSR.CSREvents.{SretEventSinkBundle, TrapEntryVSEventSinkBundle} 18import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._ 19import xiangshan.backend.fu.NewCSR.CSRBundleImplicitCast._ 20import xiangshan.backend.fu.NewCSR.ChiselRecordForField._ 21 22import scala.collection.immutable.SeqMap 23 24trait VirtualSupervisorLevel { self: NewCSR with SupervisorLevel with HypervisorLevel => 25 26 val vsstatus = Module( 27 new CSRModule("VSstatus", new SstatusBundle) 28 with SretEventSinkBundle 29 with TrapEntryVSEventSinkBundle 30 with HasRobCommitBundle 31 { 32 when (fsDirty) { 33 assert(reg.FS =/= ContextStatus.Off, "The vsstatus.FS should not be Off when set dirty, please check decode") 34 reg.FS := ContextStatus.Dirty 35 } 36 37 when (vsDirty) { 38 assert(reg.VS =/= ContextStatus.Off, "The vsstatus.VS should not be Off when set dirty, please check decode") 39 reg.VS := ContextStatus.Dirty 40 } 41 } 42 ) 43 .setAddr(CSRs.vsstatus) 44 45 val vsie = Module(new CSRModule("VSie", new VSieBundle) 46 with HypervisorBundle 47 with HasIpIeBundle 48 { 49 val toMie = IO(new VSieToMie) 50 val toSie = IO(new VSieToSie) 51 52 val mieIsAlias = hideleg & mideleg 53 val sieIsAlias = hideleg & ~mideleg & mvien 54 val usingReg = ~hideleg & hvien 55 56 val originAliasIE = (mieIsAlias & mie) | (sieIsAlias & sie) 57 val shiftedIE = Cat(originAliasIE(63, InterruptNO.COI), 0.U(1.W), originAliasIE(InterruptNO.SGEI, InterruptNO.SSI)) 58 val shiftedUsingReg = Cat(usingReg(63, InterruptNO.COI), 0.U(1.W), usingReg(InterruptNO.SGEI, InterruptNO.SSI)) 59 60 regOut := 61 shiftedIE | 62 (shiftedUsingReg & reg) 63 64 bundle.getVS.map(_.lsb).foreach { vsNum => 65 // vsie.SSIE(1) map mie.VSSIE(1) 66 val sNum = vsNum - 1 67 val wtMie = toMie.getByNum(vsNum) 68 val wtSie = toSie.getByNum(vsNum) 69 val r = reg(sNum) 70 71 wtMie.specifyField( 72 _.valid := mieIsAlias(vsNum) && wtMie.bits.isRW.B && wen, 73 _.bits := mieIsAlias(vsNum) && wtMie.bits.isRW.B && wen &< wdata(sNum), 74 ) 75 76 wtSie.specifyField( 77 _.valid := sieIsAlias(vsNum) && wtSie.bits.isRW.B && wen, 78 _.bits := sieIsAlias(vsNum) && wtSie.bits.isRW.B && wen &< wdata(sNum), 79 ) 80 81 when (wen && usingReg(vsNum) && r.isRW.B) { 82 r := wdata(sNum) 83 }.otherwise { 84 r := r 85 } 86 } 87 88 bundle.getNonVS.map(_.lsb).foreach { num => 89 val wtMie = toMie.getByNum(num) 90 val wtSie = toSie.getByNum(num) 91 92 val r = reg(num) 93 94 wtMie.specifyField( 95 _.valid := mieIsAlias(num) && wtMie.bits.isRW.B && wen, 96 _.bits := mieIsAlias(num) && wtMie.bits.isRW.B && wen &< wdata(num), 97 ) 98 99 wtSie.specifyField( 100 _.valid := sieIsAlias(num) && wtSie.bits.isRW.B && wen, 101 _.bits := sieIsAlias(num) && wtSie.bits.isRW.B && wen &< wdata(num), 102 ) 103 104 when(wen && usingReg(num) && r.isRW.B) { 105 r := wdata(num) 106 }.otherwise { 107 r := r 108 } 109 } 110 111 regOut.getFields.foreach { field => 112 if (field.isHardWired) { 113 field := field.getHardWireValue 114 } 115 } 116 }).setAddr(CSRs.vsie) 117 118 val vstvec = Module(new CSRModule("VStvec", new XtvecBundle)) 119 .setAddr(CSRs.vstvec) 120 121 val vsscratch = Module(new CSRModule("VSscratch")) 122 .setAddr(CSRs.vsscratch) 123 124 val vsepc = Module( 125 new CSRModule("VSepc", new Epc) 126 with TrapEntryVSEventSinkBundle 127 { 128 rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN) 129 } 130 ) 131 .setAddr(CSRs.vsepc) 132 133 val vscause = Module( 134 new CSRModule("VScause", new CauseBundle) 135 with TrapEntryVSEventSinkBundle 136 ) 137 .setAddr(CSRs.vscause) 138 139 // Todo: shrink the width of vstval to the maximum width Virtual Address 140 val vstval = Module( 141 new CSRModule("VStval") 142 with TrapEntryVSEventSinkBundle 143 ) 144 .setAddr(CSRs.vstval) 145 146 val vsip = Module(new CSRModule("VSip", new VSipBundle) 147 with HypervisorBundle 148 with HasIpIeBundle 149 { 150 val toMip = IO(new VSipToMip).connectZeroNonRW 151 val toMvip = IO(new VSipToMvip).connectZeroNonRW 152 val toHvip = IO(new VSipToHvip).connectZeroNonRW 153 154 val originIP = mideleg & hideleg & mip | (~mideleg & hideleg & mvien & mvip) | (~hideleg & hvien & hvip) 155 val shiftedIP = Cat(originIP(63, InterruptNO.COI), 0.U(1.W), originIP(InterruptNO.SGEI, InterruptNO.SSI)) 156 157 regOut := shiftedIP 158 regOut.getM.foreach(_ := 0.U) 159 regOut.getVS.foreach(_ := 0.U) 160 regOut.SGEIP := 0.U 161 162 toHvip.VSSIP.valid := wen && hideleg.VSSI 163 toHvip.VSSIP.bits := wdata.SSIP 164 165 wdata.getLocal lazyZip 166 (toMip.getLocal lazyZip toMvip.getLocal lazyZip toHvip.getLocal) lazyZip 167 (mideleg.getLocal lazyZip hideleg.getLocal lazyZip mvien.getLocal) foreach { 168 case (wLCIP, (toMipLCIP, toMvipLCIP, toHvipLCIP), (midelegBit, hidelegBit, mvienBit)) => 169 toMipLCIP .valid := wen && midelegBit && hidelegBit 170 toMvipLCIP.valid := wen && !midelegBit && hidelegBit && mvienBit 171 toHvipLCIP.valid := wen && !hidelegBit && mvienBit 172 toMipLCIP .bits := wLCIP 173 toMvipLCIP.bits := wLCIP 174 toHvipLCIP.bits := wLCIP 175 } 176 177 regOut.getFields.foreach { field => 178 if (field.isHardWired) { 179 field := field.getHardWireValue 180 } 181 } 182 }).setAddr(CSRs.vsip) 183 184 val vstimecmp = Module(new CSRModule("VStimecmp", new CSRBundle { 185 val vstimecmp = RW(63, 0).withReset(bitPatToUInt(BitPat.Y(64))) 186 })) 187 .setAddr(CSRs.vstimecmp) 188 189 val vsatp = Module(new CSRModule("VSatp", new SatpBundle) with VirtualSupervisorBundle { 190 // Ref: 13.2.18. Virtual Supervisor Address Translation and Protection Register (vsatp) 191 // When V=0, a write to vsatp with an unsupported MODE value is either ignored as it is for satp, or the 192 // fields of vsatp are treated as WARL in the normal way. 193 // However, when V=1, a write to satp with an unsupported MODE value is ignored and no write to vsatp is effected. 194 // if satp is written with an unsupported MODE, the entire write has no effect; no fields in satp are modified. 195 // 196 // We treat all circumstances as if V=1. That is if vsatp is written with an unsupported MODE, 197 // the entire write has no effect; no fields in satp are modified. 198 when(wen && wdata.MODE.isLegal) { 199 reg := wdata 200 }.elsewhen(wen && !v && !wdata.MODE.isLegal) { 201 reg.PPN := wdata.PPN 202 reg.ASID := wdata.ASID 203 }.otherwise { 204 reg := reg 205 } 206 }).setAddr(CSRs.vsatp) 207 208 val virtualSupervisorCSRMods = Seq( 209 vsstatus, 210 vsie, 211 vstvec, 212 vsscratch, 213 vsepc, 214 vscause, 215 vstval, 216 vsip, 217 vstimecmp, 218 vsatp, 219 ) 220 221 virtualSupervisorCSRMods.foreach(mod => 222 require(mod.addr > 0, s"The address of ${mod.modName} has not been set, you can use setAddr(CSRAddr) to set it.")) 223 224 val virtualSupervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 225 virtualSupervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))) 226 ) 227 228 val virtualSupervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 229 virtualSupervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)) 230 ) 231 232 import freechips.rocketchip.rocket.CSRs 233 234 val sMapVS = SeqMap( 235 CSRs.sstatus -> CSRs.vsstatus, 236 CSRs.sie -> CSRs.vsie, 237 CSRs.stvec -> CSRs.vstvec, 238 CSRs.sscratch -> CSRs.vsscratch, 239 CSRs.sepc -> CSRs.vsepc, 240 CSRs.scause -> CSRs.vscause, 241 CSRs.stval -> CSRs.vstval, 242 CSRs.sip -> CSRs.vsip, 243 CSRs.stimecmp -> CSRs.vstimecmp, 244 CSRs.siselect -> CSRs.vsiselect, 245 CSRs.sireg -> CSRs.vsireg, 246 CSRs.stopei -> CSRs.vstopei, 247 CSRs.satp -> CSRs.vsatp, 248 CSRs.stopi -> CSRs.vstopi, 249 ) 250 251 val vsMapS: SeqMap[Int, Int] = SeqMap.from(sMapVS.map(x => (x._2 -> x._1))) 252} 253 254class VSipBundle extends InterruptPendingBundle { 255 // All pending bits in vsip are aliases of mip/mvip/hvip or read-only 0 256 this.getM.foreach(_.setHardWired(0.U)) 257 this.getVS.foreach(_.setHardWired(0.U)) 258 this.SGEIP.setHardWired(0.U) 259} 260 261class VSieBundle extends InterruptEnableBundle { 262 this.getLocal.foreach(_.setRW()) 263 this.getM .foreach(_.setHardWired(0.U)) 264 this.getVS.foreach(_.setHardWired(0.U)) 265 this.SGEIE.setHardWired(0.U) 266} 267 268class VSipToMvip extends IpValidBundle { 269 this.getLocal.foreach(_.bits.setRW()) 270} 271 272class VSipToHvip extends IpValidBundle { 273 this.VSSIP.bits.setRW() 274 this.getLocal.foreach(_.bits.setRW()) 275} 276 277class VSieToMie extends IeValidBundle { 278 this.getVS.foreach(_.bits.setRW()) 279 this.getLocal.foreach(_.bits.setRW()) 280} 281 282class VSieToSie extends IeValidBundle { 283 this.getVS.foreach(_.bits.setRW()) 284 this.getLocal.foreach(_.bits.setRW()) 285} 286 287class VSipToHip extends Bundle { 288 val SSIP = ValidIO(RW(0)) 289 val STIP = ValidIO(RW(0)) 290 val SEIP = ValidIO(RW(0)) 291} 292 293trait VirtualSupervisorBundle { self: CSRModule[_] => 294 val v = IO(Input(Bool())) 295} 296