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