1/*************************************************************************************** 2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences 3* Copyright (c) 2020-2021 Peng Cheng Laboratory 4* 5* XiangShan is licensed under Mulan PSL v2. 6* You can use this software according to the terms and conditions of the Mulan PSL v2. 7* You may obtain a copy of Mulan PSL v2 at: 8* http://license.coscl.org.cn/MulanPSL2 9* 10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13* 14* See the Mulan PSL v2 for more details. 15***************************************************************************************/ 16 17package xiangshan.backend.fu.util 18 19import chisel3._ 20import chisel3.util._ 21 22trait HasCSRConst { 23 24 // User Trap Setup 25 val Ustatus = 0x000 26 val Uie = 0x004 27 val Utvec = 0x005 28 29 // User Trap Handling 30 val Uscratch = 0x040 31 val Uepc = 0x041 32 val Ucause = 0x042 33 val Utval = 0x043 34 val Uip = 0x044 35 36 // User Floating-Point CSRs (not implemented) 37 val Fflags = 0x001 38 val Frm = 0x002 39 val Fcsr = 0x003 40 41 // Vector Extension CSRs 42 val Vstart = 0x008 43 val Vxsat = 0x009 44 val Vxrm = 0x00A 45 val Vcsr = 0x00F 46 val Vl = 0xC20 47 val Vtype = 0xC21 48 val Vlenb = 0xC22 49 50 // User Counter/Timers 51 val Cycle = 0xC00 52 val Time = 0xC01 53 val Instret = 0xC02 54 val Hpmcounter3 = 0xC03 55 val Hpmcounter4 = 0xC04 56 val Hpmcounter5 = 0xC05 57 val Hpmcounter6 = 0xC06 58 val Hpmcounter7 = 0xC07 59 val Hpmcounter8 = 0xC08 60 val Hpmcounter9 = 0xC09 61 val Hpmcounter10 = 0xC0A 62 val Hpmcounter11 = 0xC0B 63 val Hpmcounter12 = 0xC0C 64 val Hpmcounter13 = 0xC0D 65 val Hpmcounter14 = 0xC0E 66 val Hpmcounter15 = 0xC0F 67 val Hpmcounter16 = 0xC10 68 val Hpmcounter17 = 0xC11 69 val Hpmcounter18 = 0xC12 70 val Hpmcounter19 = 0xC13 71 val Hpmcounter20 = 0xC14 72 val Hpmcounter21 = 0xC15 73 val Hpmcounter22 = 0xC16 74 val Hpmcounter23 = 0xC17 75 val Hpmcounter24 = 0xC18 76 val Hpmcounter25 = 0xC19 77 val Hpmcounter26 = 0xC1A 78 val Hpmcounter27 = 0xC1B 79 val Hpmcounter28 = 0xC1C 80 val Hpmcounter29 = 0xC1D 81 val Hpmcounter30 = 0xC1E 82 val Hpmcounter31 = 0xC1F 83 84 // Supervisor Trap Setup 85 val Sstatus = 0x100 86 val Sedeleg = 0x102 87 val Sideleg = 0x103 88 val Sie = 0x104 89 val Stvec = 0x105 90 val Scounteren = 0x106 91 92 // Supervisor Configuration 93 val Senvcfg = 0x10A 94 95 // Supervisor Trap Handling 96 val Sscratch = 0x140 97 val Sepc = 0x141 98 val Scause = 0x142 99 val Stval = 0x143 100 val Sip = 0x144 101 102 // Supervisor Protection and Translation 103 val Satp = 0x180 104 105 // Supervisor Custom Read/Write 106 val Sbpctl = 0x5C0 107 val Spfctl = 0x5C1 108 val Slvpredctl = 0x5C2 109 val Smblockctl = 0x5C3 110 val Srnctl = 0x5C4 111 /** 0x5C5-0x5E5 for cache instruction register*/ 112 val Scachebase = 0x5C5 113 114 // Supervisor Custom Read/Write 115 val Sfetchctl = 0x9e0 116 117 // Hypervisor Trap Setup 118 val Hstatus = 0x600 119 val Hedeleg = 0x602 120 val Hideleg = 0x603 121 val Hie = 0x604 122 val Hcounteren = 0x606 123 val Hgeie = 0x607 124 125 // Hypervisor Trap Handling 126 val Htval = 0x643 127 val Hip = 0x644 128 val Hvip = 0x645 129 val Htinst = 0x64A 130 val Hgeip = 0xE12 131 132 // Hypervisor Configuration 133 val Henvcfg = 0x60A 134 135 // Hypervisor Protection and Translation 136 val Hgatp = 0x680 137 138 //Hypervisor Counter/Timer Virtualization Registers 139 val Htimedelta = 0x605 140 141 // Virtual Supervisor Registers 142 val Vsstatus = 0x200 143 val Vsie = 0x204 144 val Vstvec = 0x205 145 val Vsscratch = 0x240 146 val Vsepc = 0x241 147 val Vscause = 0x242 148 val Vstval = 0x243 149 val Vsip = 0x244 150 val Vsatp = 0x280 151 152 // Machine Information Registers 153 val Mvendorid = 0xF11 154 val Marchid = 0xF12 155 val Mimpid = 0xF13 156 val Mhartid = 0xF14 157 val Mconfigptr = 0xF15 158 159 // Machine Trap Setup 160 val Mstatus = 0x300 161 val Misa = 0x301 162 val Medeleg = 0x302 163 val Mideleg = 0x303 164 val Mie = 0x304 165 val Mtvec = 0x305 166 val Mcounteren = 0x306 167 168 // Machine Trap Handling 169 val Mscratch = 0x340 170 val Mepc = 0x341 171 val Mcause = 0x342 172 val Mtval = 0x343 173 val Mip = 0x344 174 val Mtinst = 0x34A 175 val Mtval2 = 0x34B 176 177 // Machine Configuration 178 val Menvcfg = 0x30A 179 180 // Machine Memory Protection 181 // TBD 182 val PmpcfgBase = 0x3A0 183 val PmpaddrBase = 0x3B0 184 // Machine level PMA 185 val PmacfgBase = 0x7C0 186 val PmaaddrBase = 0x7C8 // 64 entry at most 187 188 // Machine Counter/Timers 189 // Currently, we uses perfcnt csr set instead of standard Machine Counter/Timers 190 // 0xB80 - 0x89F are also used as perfcnt csr 191 val Mcycle = 0xb00 192 val Minstret = 0xb02 193 194 val Mhpmcounter3 = 0xB03 195 val Mhpmcounter4 = 0xB04 196 val Mhpmcounter5 = 0xB05 197 val Mhpmcounter6 = 0xB06 198 val Mhpmcounter7 = 0xB07 199 val Mhpmcounter8 = 0xB08 200 val Mhpmcounter9 = 0xB09 201 val Mhpmcounter10 = 0xB0A 202 val Mhpmcounter11 = 0xB0B 203 val Mhpmcounter12 = 0xB0C 204 val Mhpmcounter13 = 0xB0D 205 val Mhpmcounter14 = 0xB0E 206 val Mhpmcounter15 = 0xB0F 207 val Mhpmcounter16 = 0xB10 208 val Mhpmcounter17 = 0xB11 209 val Mhpmcounter18 = 0xB12 210 val Mhpmcounter19 = 0xB13 211 val Mhpmcounter20 = 0xB14 212 val Mhpmcounter21 = 0xB15 213 val Mhpmcounter22 = 0xB16 214 val Mhpmcounter23 = 0xB17 215 val Mhpmcounter24 = 0xB18 216 val Mhpmcounter25 = 0xB19 217 val Mhpmcounter26 = 0xB1A 218 val Mhpmcounter27 = 0xB1B 219 val Mhpmcounter28 = 0xB1C 220 val Mhpmcounter29 = 0xB1D 221 val Mhpmcounter30 = 0xB1E 222 val Mhpmcounter31 = 0xB1F 223 224 val Mcountinhibit = 0x320 225 val Mhpmevent3 = 0x323 226 val Mhpmevent4 = 0x324 227 val Mhpmevent5 = 0x325 228 val Mhpmevent6 = 0x326 229 val Mhpmevent7 = 0x327 230 val Mhpmevent8 = 0x328 231 val Mhpmevent9 = 0x329 232 val Mhpmevent10 = 0x32A 233 val Mhpmevent11 = 0x32B 234 val Mhpmevent12 = 0x32C 235 val Mhpmevent13 = 0x32D 236 val Mhpmevent14 = 0x32E 237 val Mhpmevent15 = 0x32F 238 val Mhpmevent16 = 0x330 239 val Mhpmevent17 = 0x331 240 val Mhpmevent18 = 0x332 241 val Mhpmevent19 = 0x333 242 val Mhpmevent20 = 0x334 243 val Mhpmevent21 = 0x335 244 val Mhpmevent22 = 0x336 245 val Mhpmevent23 = 0x337 246 val Mhpmevent24 = 0x338 247 val Mhpmevent25 = 0x339 248 val Mhpmevent26 = 0x33A 249 val Mhpmevent27 = 0x33B 250 val Mhpmevent28 = 0x33C 251 val Mhpmevent29 = 0x33D 252 val Mhpmevent30 = 0x33E 253 val Mhpmevent31 = 0x33F 254 255 // Debug/Trace Registers (shared with Debug Mode) (not implemented) 256 257 // Trigger Registers 258 val Tselect = 0x7A0 259 val Tdata1 = 0x7A1 260 val Tdata2 = 0x7A2 261 val Tinfo = 0x7A4 262 val Tcontrol = 0x7A5 263 264 // Debug Mode Registers 265 val Dcsr = 0x7B0 266 val Dpc = 0x7B1 267 val Dscratch0 = 0x7B2 268 val Dscratch1 = 0x7B3 269 270 def privEcall = 0x000.U 271 def privEbreak = 0x001.U 272 def privMret = 0x302.U 273 def privSret = 0x102.U 274 def privUret = 0x002.U 275 def privDret = 0x7b2.U 276 277 def ModeM = 0x3.U 278 def ModeH = 0x2.U 279 def ModeS = 0x1.U 280 def ModeU = 0x0.U 281 282 def IRQ_USIP = 0 283 def IRQ_SSIP = 1 284 def IRQ_VSSIP = 2 285 def IRQ_MSIP = 3 286 287 def IRQ_UTIP = 4 288 def IRQ_STIP = 5 289 def IRQ_VSTIP = 6 290 def IRQ_MTIP = 7 291 292 def IRQ_UEIP = 8 293 def IRQ_SEIP = 9 294 def IRQ_VSEIP = 10 295 def IRQ_MEIP = 11 296 297 def IRQ_SGEIP = 12 298 def IRQ_DEBUG = 17 299 300 val Hgatp_Mode_len = 4 301 val Hgatp_Vmid_len = 16 302 val Hgatp_Addr_len = 44 303 304 val Satp_Mode_len = 4 305 val Satp_Asid_len = 16 306 val Satp_Addr_len = 44 307 def satp_part_wmask(max_length: Int, length: Int) : UInt = { 308 require(length > 0 && length <= max_length) 309 ((1L << length) - 1).U(max_length.W) 310 } 311 312 val IntPriority = Seq( 313 IRQ_DEBUG, 314 IRQ_MEIP, IRQ_MSIP, IRQ_MTIP, 315 IRQ_SEIP, IRQ_SSIP, IRQ_STIP, 316 IRQ_UEIP, IRQ_USIP, IRQ_UTIP, 317 IRQ_VSEIP, IRQ_VSSIP, IRQ_VSTIP, IRQ_SGEIP 318 ) 319 320 def csrAccessPermissionCheck(addr: UInt, wen: Bool, mode: UInt, virt: Bool, hasH: Bool): UInt = { 321 val readOnly = addr(11, 10) === "b11".U 322 val lowestAccessPrivilegeLevel = addr(9,8) 323 val priv = Mux(mode === ModeS, ModeH, mode) 324 val ret = Wire(Bool()) //0.U: normal, 1.U: illegal_instruction, 2.U: virtual instruction 325 when (lowestAccessPrivilegeLevel === ModeH && !hasH){ 326 ret := 1.U 327 }.elsewhen (readOnly && wen) { 328 ret := 1.U 329 }.elsewhen (priv < lowestAccessPrivilegeLevel) { 330 when(virt && lowestAccessPrivilegeLevel <= ModeH){ 331 ret := 2.U 332 }.otherwise{ 333 ret := 1.U 334 } 335 }.otherwise{ 336 ret := 0.U 337 } 338 ret 339 } 340 341 def perfcntPermissionCheck(addr: UInt, mode: UInt, mmask: UInt, smask: UInt): Bool = { 342 val index = UIntToOH(addr & 31.U) 343 Mux(mode === ModeM, true.B, Mux(mode === ModeS, (index & mmask) =/= 0.U, (index & mmask & smask) =/= 0.U)) 344 } 345 346 def dcsrPermissionCheck(addr: UInt, mModeCanWrite: UInt, debug: Bool): Bool = { 347 // debug mode write only regs 348 val isDebugReg = addr(11, 4) === "h7b".U 349 Mux(!mModeCanWrite && isDebugReg, debug, true.B) 350 } 351 352 def triggerPermissionCheck(addr: UInt, mModeCanWrite: UInt, debug: Bool): Bool = { 353 val isTriggerReg = addr(11, 4) === "h7a".U 354 Mux(!mModeCanWrite && isTriggerReg, debug, true.B) 355 } 356} 357object CSRConst extends HasCSRConst 358