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