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