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 }).setAddr(0x204) 98 99 val vstvec = Module(new CSRModule("VStvec", new XtvecBundle)) 100 .setAddr(0x205) 101 102 val vsscratch = Module(new CSRModule("VSscratch")) 103 .setAddr(0x240) 104 105 val vsepc = Module( 106 new CSRModule("VSepc", new Epc) 107 with TrapEntryVSEventSinkBundle 108 { 109 rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN) 110 } 111 ) 112 .setAddr(0x241) 113 114 val vscause = Module( 115 new CSRModule("VScause", new CauseBundle) 116 with TrapEntryVSEventSinkBundle 117 ) 118 .setAddr(0x242) 119 120 // Todo: shrink the width of vstval to the maximum width Virtual Address 121 val vstval = Module( 122 new CSRModule("VStval") 123 with TrapEntryVSEventSinkBundle 124 ) 125 .setAddr(0x243) 126 127 val vsip = Module(new CSRModule("VSip", new VSipBundle) 128 with HypervisorBundle 129 with HasIpIeBundle 130 { 131 val toMip = IO(new VSipToMip).connectZeroNonRW 132 val toMvip = IO(new VSipToMvip).connectZeroNonRW 133 val toHvip = IO(new VSipToHvip).connectZeroNonRW 134 135 val originIP = mideleg & hideleg & mip | (~mideleg & hideleg & mvien & mvip) | (~hideleg & hvien & hvip) 136 val shiftedIP = Cat(originIP(63, InterruptNO.COI), 0.U(1.W), originIP(InterruptNO.SGEI, InterruptNO.SSI)) 137 138 regOut := shiftedIP 139 regOut.getM.foreach(_ := 0.U) 140 regOut.getVS.foreach(_ := 0.U) 141 regOut.SGEIP := 0.U 142 143 toHvip.VSSIP.valid := wen && hideleg.VSSI 144 toHvip.VSSIP.bits := wdata.SSIP 145 146 wdata.getLocal lazyZip 147 (toMip.getLocal lazyZip toMvip.getLocal lazyZip toHvip.getLocal) lazyZip 148 (mideleg.getLocal lazyZip hideleg.getLocal lazyZip mvien.getLocal) foreach { 149 case (wLCIP, (toMipLCIP, toMvipLCIP, toHvipLCIP), (midelegBit, hidelegBit, mvienBit)) => 150 toMipLCIP .valid := wen && midelegBit && hidelegBit 151 toMvipLCIP.valid := wen && !midelegBit && hidelegBit && mvienBit 152 toHvipLCIP.valid := wen && !hidelegBit && mvienBit 153 toMipLCIP .bits := wLCIP 154 toMvipLCIP.bits := wLCIP 155 toHvipLCIP.bits := wLCIP 156 } 157 }).setAddr(0x244) 158 159 val vstimecmp = Module(new CSRModule("VStimecmp", new CSRBundle { 160 val vstimecmp = RW(63, 0).withReset(bitPatToUInt(BitPat.Y(64))) 161 })) 162 .setAddr(0x24D) 163 164 val vsatp = Module(new CSRModule("VSatp", new SatpBundle) with VirtualSupervisorBundle { 165 // Ref: 13.2.18. Virtual Supervisor Address Translation and Protection Register (vsatp) 166 // When V=0, a write to vsatp with an unsupported MODE value is either ignored as it is for satp, or the 167 // fields of vsatp are treated as WARL in the normal way. 168 // However, when V=1, a write to satp with an unsupported MODE value is ignored and no write to vsatp is effected. 169 // if satp is written with an unsupported MODE, the entire write has no effect; no fields in satp are modified. 170 // 171 // We treat all circumstances as if V=1. That is if vsatp is written with an unsupported MODE, 172 // the entire write has no effect; no fields in satp are modified. 173 when(wen && wdata.MODE.isLegal) { 174 reg := wdata 175 }.elsewhen(wen && !v && !wdata.MODE.isLegal) { 176 reg.PPN := wdata.PPN 177 reg.ASID := wdata.ASID 178 }.otherwise { 179 reg := reg 180 } 181 }).setAddr(0x280) 182 183 val virtualSupervisorCSRMods = Seq( 184 vsstatus, 185 vsie, 186 vstvec, 187 vsscratch, 188 vsepc, 189 vscause, 190 vstval, 191 vsip, 192 vstimecmp, 193 vsatp, 194 ) 195 196 virtualSupervisorCSRMods.foreach(mod => 197 require(mod.addr > 0, s"The address of ${mod.modName} has not been set, you can use setAddr(CSRAddr) to set it.")) 198 199 val virtualSupervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 200 virtualSupervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))) 201 ) 202 203 val virtualSupervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 204 virtualSupervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)) 205 ) 206 207 import freechips.rocketchip.rocket.CSRs 208 209 val sMapVS = SeqMap( 210 CSRs.sstatus -> CSRs.vsstatus, 211 CSRs.sie -> CSRs.vsie, 212 CSRs.stvec -> CSRs.vstvec, 213 CSRs.sscratch -> CSRs.vsscratch, 214 CSRs.sepc -> CSRs.vsepc, 215 CSRs.scause -> CSRs.vscause, 216 CSRs.stval -> CSRs.vstval, 217 CSRs.sip -> CSRs.vsip, 218 CSRs.stimecmp -> CSRs.vstimecmp, 219 CSRs.siselect -> CSRs.vsiselect, 220 CSRs.sireg -> CSRs.vsireg, 221 CSRs.stopei -> CSRs.vstopei, 222 CSRs.satp -> CSRs.vsatp, 223 CSRs.stopi -> CSRs.vstopi, 224 ) 225 226 val vsMapS: SeqMap[Int, Int] = SeqMap.from(sMapVS.map(x => (x._2 -> x._1))) 227} 228 229class VSipBundle extends InterruptPendingBundle { 230 // All pending bits in vsip are aliases of mip/mvip/hvip or read-only 0 231} 232 233class VSieBundle extends InterruptEnableBundle { 234 this.getLocal.foreach(_.setRW()) 235} 236 237class VSipToMvip extends IpValidBundle { 238 this.getLocal.foreach(_.bits.setRW()) 239} 240 241class VSipToHvip extends IpValidBundle { 242 this.VSSIP.bits.setRW() 243 this.getLocal.foreach(_.bits.setRW()) 244} 245 246class VSieToMie extends IeValidBundle { 247 this.getVS.foreach(_.bits.setRW()) 248 this.getLocal.foreach(_.bits.setRW()) 249} 250 251class VSieToSie extends IeValidBundle { 252 this.getVS.foreach(_.bits.setRW()) 253 this.getLocal.foreach(_.bits.setRW()) 254} 255 256class VSipToHip extends Bundle { 257 val SSIP = ValidIO(RW(0)) 258 val STIP = ValidIO(RW(0)) 259 val SEIP = ValidIO(RW(0)) 260} 261 262trait VirtualSupervisorBundle { self: CSRModule[_] => 263 val v = IO(Input(Bool())) 264} 265