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