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