1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright 2022 NXP 4 */ 5 6 #ifndef RISCV_H 7 #define RISCV_H 8 9 #include <compiler.h> 10 #include <encoding.h> 11 #include <stdint.h> 12 #include <sys/cdefs.h> 13 #include <util.h> 14 15 #define RISCV_XLEN_BITS (__riscv_xlen) 16 #define RISCV_XLEN_BYTES (__riscv_xlen / 8) 17 18 #define REGOFF(x) ((x) * RISCV_XLEN_BYTES) 19 20 #if __riscv_xlen == 32 21 #define STR sw 22 #define LDR lw 23 #else 24 #define STR sd 25 #define LDR ld 26 #endif 27 28 #if defined(CFG_RISCV_M_MODE) 29 #define CSR_MODE_OFFSET PRV_M 30 #define XRET mret 31 #elif defined(CFG_RISCV_S_MODE) 32 #define CSR_MODE_OFFSET PRV_S 33 #define XRET sret 34 #endif 35 36 #define CSR_MODE_BITS SHIFT_U64(CSR_MODE_OFFSET, 8) 37 38 #define CSR_XSTATUS (CSR_MODE_BITS | 0x000) 39 #define CSR_XIE (CSR_MODE_BITS | 0x004) 40 #define CSR_XTVEC (CSR_MODE_BITS | 0x005) 41 #define CSR_XSCRATCH (CSR_MODE_BITS | 0x040) 42 #define CSR_XEPC (CSR_MODE_BITS | 0x041) 43 #define CSR_XCAUSE (CSR_MODE_BITS | 0x042) 44 #define CSR_XTVAL (CSR_MODE_BITS | 0x043) 45 #define CSR_XIP (CSR_MODE_BITS | 0x044) 46 47 #ifndef __ASSEMBLER__ 48 49 static inline __noprof void mb(void) 50 { 51 asm volatile ("fence" : : : "memory"); 52 } 53 54 static inline __noprof unsigned long read_tp(void) 55 { 56 unsigned long tp; 57 58 asm volatile("mv %0, tp" : "=&r"(tp)); 59 return tp; 60 } 61 62 static inline __noprof void wfi(void) 63 { 64 asm volatile ("wfi"); 65 } 66 67 static inline __noprof void flush_tlb(void) 68 { 69 asm volatile("sfence.vma zero, zero"); 70 } 71 72 static inline __noprof void flush_tlb_entry(unsigned long va) 73 { 74 asm volatile ("sfence.vma %0" : : "r" (va) : "memory"); 75 } 76 77 /* supervisor address translation and protection */ 78 static inline __noprof unsigned long read_satp(void) 79 { 80 unsigned long satp; 81 82 asm volatile("csrr %0, satp" : "=r" (satp)); 83 84 return satp; 85 } 86 87 static inline __noprof void write_satp(unsigned long satp) 88 { 89 asm volatile("csrw satp, %0" : : "r" (satp)); 90 } 91 92 /* machine trap-vector base-address register */ 93 static inline __noprof unsigned long read_mtvec(void) 94 { 95 unsigned long mtvec; 96 97 asm volatile("csrr %0, mtvec" : "=r" (mtvec)); 98 99 return mtvec; 100 } 101 102 static inline __noprof void write_mtvec(unsigned long mtvec) 103 { 104 asm volatile("csrw mtvec, %0" : : "r" (mtvec)); 105 } 106 107 /* supervisor trap-vector base-address register */ 108 static inline __noprof unsigned long read_stvec(void) 109 { 110 unsigned long stvec; 111 112 asm volatile("csrr %0, stvec" : "=r" (stvec)); 113 114 return stvec; 115 } 116 117 static inline __noprof void write_stvec(unsigned long stvec) 118 { 119 asm volatile("csrw stvec, %0" : : "r" (stvec)); 120 } 121 122 /* machine status register */ 123 static inline __noprof unsigned long read_mstatus(void) 124 { 125 unsigned long mstatus; 126 127 asm volatile("csrr %0, mstatus" : "=r" (mstatus)); 128 129 return mstatus; 130 } 131 132 static inline __noprof void write_mstatus(unsigned long mstatus) 133 { 134 asm volatile("csrw mstatus, %0" : : "r" (mstatus)); 135 } 136 137 /* supervisor status register */ 138 static inline __noprof unsigned long read_sstatus(void) 139 { 140 unsigned long sstatus; 141 142 asm volatile("csrr %0, sstatus" : "=r" (sstatus)); 143 144 return sstatus; 145 } 146 147 static inline __noprof void write_sstatus(unsigned long sstatus) 148 { 149 asm volatile("csrw sstatus, %0" : : "r" (sstatus)); 150 } 151 152 static inline __noprof void set_sstatus(unsigned long sstatus) 153 { 154 unsigned long x; 155 156 asm volatile ("csrrs %0, sstatus, %1" : "=r"(x) : "rK"(sstatus)); 157 } 158 159 /* machine exception delegation */ 160 static inline __noprof unsigned long read_medeleg(void) 161 { 162 unsigned long medeleg; 163 164 asm volatile("csrr %0, medeleg" : "=r" (medeleg)); 165 166 return medeleg; 167 } 168 169 static inline __noprof void write_medeleg(unsigned long medeleg) 170 { 171 asm volatile("csrw medeleg, %0" : : "r" (medeleg)); 172 } 173 174 /* machine interrupt delegation */ 175 static inline __noprof unsigned long read_mideleg(void) 176 { 177 unsigned long mideleg; 178 179 asm volatile("csrr %0, mideleg" : "=r" (mideleg)); 180 181 return mideleg; 182 } 183 184 static inline __noprof void write_mideleg(unsigned long mideleg) 185 { 186 asm volatile("csrw mideleg, %0" : : "r" (mideleg)); 187 } 188 189 /* machine interrupt-enable register */ 190 static inline __noprof unsigned long read_mie(void) 191 { 192 unsigned long mie; 193 194 asm volatile("csrr %0, mie" : "=r" (mie)); 195 196 return mie; 197 } 198 199 static inline __noprof void write_mie(unsigned long mie) 200 { 201 asm volatile("csrw mie, %0" : : "r" (mie)); 202 } 203 204 /* supervisor interrupt-enable register */ 205 static inline __noprof unsigned long read_sie(void) 206 { 207 unsigned long sie; 208 209 asm volatile("csrr %0, sie" : "=r" (sie)); 210 211 return sie; 212 } 213 214 static inline __noprof void write_sie(unsigned long sie) 215 { 216 asm volatile("csrw sie, %0" : : "r" (sie)); 217 } 218 219 /* machine exception program counter */ 220 static inline __noprof unsigned long read_mepc(void) 221 { 222 unsigned long mepc; 223 224 asm volatile("csrr %0, mepc" : "=r" (mepc)); 225 226 return mepc; 227 } 228 229 static inline __noprof void write_mepc(unsigned long mepc) 230 { 231 asm volatile("csrw mepc, %0" : : "r" (mepc)); 232 } 233 234 /* supervisor exception program counter */ 235 static inline __noprof unsigned long read_sepc(void) 236 { 237 unsigned long sepc; 238 239 asm volatile("csrr %0, sepc" : "=r" (sepc)); 240 241 return sepc; 242 } 243 244 static inline __noprof void write_sepc(unsigned long sepc) 245 { 246 asm volatile("csrw sepc, %0" : : "r" (sepc)); 247 } 248 249 /* machine scratch register */ 250 static inline __noprof unsigned long read_mscratch(void) 251 { 252 unsigned long mscratch; 253 254 asm volatile("csrr %0, mscratch" : "=r" (mscratch)); 255 256 return mscratch; 257 } 258 259 static inline __noprof void write_mscratch(unsigned long mscratch) 260 { 261 asm volatile("csrw mscratch, %0" : : "r" (mscratch)); 262 } 263 264 /* supervisor scratch register */ 265 static inline __noprof unsigned long read_sscratch(void) 266 { 267 unsigned long sscratch; 268 269 asm volatile("csrr %0, sscratch" : "=r" (sscratch)); 270 271 return sscratch; 272 } 273 274 static inline __noprof void write_sscratch(unsigned long sscratch) 275 { 276 asm volatile("csrw sscratch, %0" : : "r" (sscratch)); 277 } 278 279 /* trap-return instructions */ 280 static inline __noprof void mret(void) 281 { 282 asm volatile("mret"); 283 } 284 285 static inline __noprof void sret(void) 286 { 287 asm volatile("sret"); 288 } 289 290 static inline __noprof void uret(void) 291 { 292 asm volatile("uret"); 293 } 294 295 #endif /*__ASSEMBLER__*/ 296 297 #endif /*RISCV_H*/ 298