root/kernel/riscv.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. r_mhartid
  2. r_mstatus
  3. w_mstatus
  4. w_mepc
  5. r_sstatus
  6. w_sstatus
  7. r_sip
  8. w_sip
  9. r_sie
  10. w_sie
  11. r_mie
  12. w_mie
  13. w_sepc
  14. r_sepc
  15. r_medeleg
  16. w_medeleg
  17. r_mideleg
  18. w_mideleg
  19. w_stvec
  20. r_stvec
  21. r_stimecmp
  22. w_stimecmp
  23. r_menvcfg
  24. w_menvcfg
  25. w_pmpcfg0
  26. w_pmpaddr0
  27. w_satp
  28. r_satp
  29. r_scause
  30. r_stval
  31. w_mcounteren
  32. r_mcounteren
  33. r_time
  34. intr_on
  35. intr_off
  36. intr_get
  37. r_sp
  38. r_tp
  39. w_tp
  40. r_ra
  41. sfence_vma

   1 #ifndef __ASSEMBLER__
   2 
   3 // which hart (core) is this?
   4 static inline uint64
   5 r_mhartid()
   6 {
   7   uint64 x;
   8   asm volatile("csrr %0, mhartid" : "=r" (x) );
   9   return x;
  10 }
  11 
  12 // Machine Status Register, mstatus
  13 
  14 #define MSTATUS_MPP_MASK (3L << 11) // previous mode.
  15 #define MSTATUS_MPP_M (3L << 11)
  16 #define MSTATUS_MPP_S (1L << 11)
  17 #define MSTATUS_MPP_U (0L << 11)
  18 
  19 static inline uint64
  20 r_mstatus()
  21 {
  22   uint64 x;
  23   asm volatile("csrr %0, mstatus" : "=r" (x) );
  24   return x;
  25 }
  26 
  27 static inline void 
  28 w_mstatus(uint64 x)
  29 {
  30   asm volatile("csrw mstatus, %0" : : "r" (x));
  31 }
  32 
  33 // machine exception program counter, holds the
  34 // instruction address to which a return from
  35 // exception will go.
  36 static inline void 
  37 w_mepc(uint64 x)
  38 {
  39   asm volatile("csrw mepc, %0" : : "r" (x));
  40 }
  41 
  42 // Supervisor Status Register, sstatus
  43 
  44 #define SSTATUS_SPP (1L << 8)  // Previous mode, 1=Supervisor, 0=User
  45 #define SSTATUS_SPIE (1L << 5) // Supervisor Previous Interrupt Enable
  46 #define SSTATUS_UPIE (1L << 4) // User Previous Interrupt Enable
  47 #define SSTATUS_SIE (1L << 1)  // Supervisor Interrupt Enable
  48 #define SSTATUS_UIE (1L << 0)  // User Interrupt Enable
  49 
  50 static inline uint64
  51 r_sstatus()
  52 {
  53   uint64 x;
  54   asm volatile("csrr %0, sstatus" : "=r" (x) );
  55   return x;
  56 }
  57 
  58 static inline void 
  59 w_sstatus(uint64 x)
  60 {
  61   asm volatile("csrw sstatus, %0" : : "r" (x));
  62 }
  63 
  64 // Supervisor Interrupt Pending
  65 static inline uint64
  66 r_sip()
  67 {
  68   uint64 x;
  69   asm volatile("csrr %0, sip" : "=r" (x) );
  70   return x;
  71 }
  72 
  73 static inline void 
  74 w_sip(uint64 x)
  75 {
  76   asm volatile("csrw sip, %0" : : "r" (x));
  77 }
  78 
  79 // Supervisor Interrupt Enable
  80 #define SIE_SEIE (1L << 9) // external
  81 #define SIE_STIE (1L << 5) // timer
  82 static inline uint64
  83 r_sie()
  84 {
  85   uint64 x;
  86   asm volatile("csrr %0, sie" : "=r" (x) );
  87   return x;
  88 }
  89 
  90 static inline void 
  91 w_sie(uint64 x)
  92 {
  93   asm volatile("csrw sie, %0" : : "r" (x));
  94 }
  95 
  96 // Machine-mode Interrupt Enable
  97 #define MIE_STIE (1L << 5)  // supervisor timer
  98 static inline uint64
  99 r_mie()
 100 {
 101   uint64 x;
 102   asm volatile("csrr %0, mie" : "=r" (x) );
 103   return x;
 104 }
 105 
 106 static inline void 
 107 w_mie(uint64 x)
 108 {
 109   asm volatile("csrw mie, %0" : : "r" (x));
 110 }
 111 
 112 // supervisor exception program counter, holds the
 113 // instruction address to which a return from
 114 // exception will go.
 115 static inline void 
 116 w_sepc(uint64 x)
 117 {
 118   asm volatile("csrw sepc, %0" : : "r" (x));
 119 }
 120 
 121 static inline uint64
 122 r_sepc()
 123 {
 124   uint64 x;
 125   asm volatile("csrr %0, sepc" : "=r" (x) );
 126   return x;
 127 }
 128 
 129 // Machine Exception Delegation
 130 static inline uint64
 131 r_medeleg()
 132 {
 133   uint64 x;
 134   asm volatile("csrr %0, medeleg" : "=r" (x) );
 135   return x;
 136 }
 137 
 138 static inline void 
 139 w_medeleg(uint64 x)
 140 {
 141   asm volatile("csrw medeleg, %0" : : "r" (x));
 142 }
 143 
 144 // Machine Interrupt Delegation
 145 static inline uint64
 146 r_mideleg()
 147 {
 148   uint64 x;
 149   asm volatile("csrr %0, mideleg" : "=r" (x) );
 150   return x;
 151 }
 152 
 153 static inline void 
 154 w_mideleg(uint64 x)
 155 {
 156   asm volatile("csrw mideleg, %0" : : "r" (x));
 157 }
 158 
 159 // Supervisor Trap-Vector Base Address
 160 // low two bits are mode.
 161 static inline void 
 162 w_stvec(uint64 x)
 163 {
 164   asm volatile("csrw stvec, %0" : : "r" (x));
 165 }
 166 
 167 static inline uint64
 168 r_stvec()
 169 {
 170   uint64 x;
 171   asm volatile("csrr %0, stvec" : "=r" (x) );
 172   return x;
 173 }
 174 
 175 // Supervisor Timer Comparison Register
 176 static inline uint64
 177 r_stimecmp()
 178 {
 179   uint64 x;
 180   // asm volatile("csrr %0, stimecmp" : "=r" (x) );
 181   asm volatile("csrr %0, 0x14d" : "=r" (x) );
 182   return x;
 183 }
 184 
 185 static inline void 
 186 w_stimecmp(uint64 x)
 187 {
 188   // asm volatile("csrw stimecmp, %0" : : "r" (x));
 189   asm volatile("csrw 0x14d, %0" : : "r" (x));
 190 }
 191 
 192 // Machine Environment Configuration Register
 193 static inline uint64
 194 r_menvcfg()
 195 {
 196   uint64 x;
 197   // asm volatile("csrr %0, menvcfg" : "=r" (x) );
 198   asm volatile("csrr %0, 0x30a" : "=r" (x) );
 199   return x;
 200 }
 201 
 202 static inline void 
 203 w_menvcfg(uint64 x)
 204 {
 205   // asm volatile("csrw menvcfg, %0" : : "r" (x));
 206   asm volatile("csrw 0x30a, %0" : : "r" (x));
 207 }
 208 
 209 // Physical Memory Protection
 210 static inline void
 211 w_pmpcfg0(uint64 x)
 212 {
 213   asm volatile("csrw pmpcfg0, %0" : : "r" (x));
 214 }
 215 
 216 static inline void
 217 w_pmpaddr0(uint64 x)
 218 {
 219   asm volatile("csrw pmpaddr0, %0" : : "r" (x));
 220 }
 221 
 222 // use riscv's sv39 page table scheme.
 223 #define SATP_SV39 (8L << 60)
 224 
 225 #define MAKE_SATP(pagetable) (SATP_SV39 | (((uint64)pagetable) >> 12))
 226 
 227 // supervisor address translation and protection;
 228 // holds the address of the page table.
 229 static inline void 
 230 w_satp(uint64 x)
 231 {
 232   asm volatile("csrw satp, %0" : : "r" (x));
 233 }
 234 
 235 static inline uint64
 236 r_satp()
 237 {
 238   uint64 x;
 239   asm volatile("csrr %0, satp" : "=r" (x) );
 240   return x;
 241 }
 242 
 243 // Supervisor Trap Cause
 244 static inline uint64
 245 r_scause()
 246 {
 247   uint64 x;
 248   asm volatile("csrr %0, scause" : "=r" (x) );
 249   return x;
 250 }
 251 
 252 // Supervisor Trap Value
 253 static inline uint64
 254 r_stval()
 255 {
 256   uint64 x;
 257   asm volatile("csrr %0, stval" : "=r" (x) );
 258   return x;
 259 }
 260 
 261 // Machine-mode Counter-Enable
 262 static inline void 
 263 w_mcounteren(uint64 x)
 264 {
 265   asm volatile("csrw mcounteren, %0" : : "r" (x));
 266 }
 267 
 268 static inline uint64
 269 r_mcounteren()
 270 {
 271   uint64 x;
 272   asm volatile("csrr %0, mcounteren" : "=r" (x) );
 273   return x;
 274 }
 275 
 276 // machine-mode cycle counter
 277 static inline uint64
 278 r_time()
 279 {
 280   uint64 x;
 281   asm volatile("csrr %0, time" : "=r" (x) );
 282   return x;
 283 }
 284 
 285 // enable device interrupts
 286 static inline void
 287 intr_on()
 288 {
 289   w_sstatus(r_sstatus() | SSTATUS_SIE);
 290 }
 291 
 292 // disable device interrupts
 293 static inline void
 294 intr_off()
 295 {
 296   w_sstatus(r_sstatus() & ~SSTATUS_SIE);
 297 }
 298 
 299 // are device interrupts enabled?
 300 static inline int
 301 intr_get()
 302 {
 303   uint64 x = r_sstatus();
 304   return (x & SSTATUS_SIE) != 0;
 305 }
 306 
 307 static inline uint64
 308 r_sp()
 309 {
 310   uint64 x;
 311   asm volatile("mv %0, sp" : "=r" (x) );
 312   return x;
 313 }
 314 
 315 // read and write tp, the thread pointer, which xv6 uses to hold
 316 // this core's hartid (core number), the index into cpus[].
 317 static inline uint64
 318 r_tp()
 319 {
 320   uint64 x;
 321   asm volatile("mv %0, tp" : "=r" (x) );
 322   return x;
 323 }
 324 
 325 static inline void 
 326 w_tp(uint64 x)
 327 {
 328   asm volatile("mv tp, %0" : : "r" (x));
 329 }
 330 
 331 static inline uint64
 332 r_ra()
 333 {
 334   uint64 x;
 335   asm volatile("mv %0, ra" : "=r" (x) );
 336   return x;
 337 }
 338 
 339 // flush the TLB.
 340 static inline void
 341 sfence_vma()
 342 {
 343   // the zero, zero means flush all TLB entries.
 344   asm volatile("sfence.vma zero, zero");
 345 }
 346 
 347 typedef uint64 pte_t;
 348 typedef uint64 *pagetable_t; // 512 PTEs
 349 
 350 #endif // __ASSEMBLER__
 351 
 352 #define PGSIZE 4096 // bytes per page
 353 #define PGSHIFT 12  // bits of offset within a page
 354 
 355 #define PGROUNDUP(sz)  (((sz)+PGSIZE-1) & ~(PGSIZE-1))
 356 #define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1))
 357 
 358 #define PTE_V (1L << 0) // valid
 359 #define PTE_R (1L << 1)
 360 #define PTE_W (1L << 2)
 361 #define PTE_X (1L << 3)
 362 #define PTE_U (1L << 4) // user can access
 363 
 364 // shift a physical address to the right place for a PTE.
 365 #define PA2PTE(pa) ((((uint64)pa) >> 12) << 10)
 366 
 367 #define PTE2PA(pte) (((pte) >> 10) << 12)
 368 
 369 #define PTE_FLAGS(pte) ((pte) & 0x3FF)
 370 
 371 // extract the three 9-bit page table indices from a virtual address.
 372 #define PXMASK          0x1FF // 9 bits
 373 #define PXSHIFT(level)  (PGSHIFT+(9*(level)))
 374 #define PX(level, va) ((((uint64) (va)) >> PXSHIFT(level)) & PXMASK)
 375 
 376 // one beyond the highest possible virtual address.
 377 // MAXVA is actually one bit less than the max allowed by
 378 // Sv39, to avoid having to sign-extend virtual addresses
 379 // that have the high bit set.
 380 #define MAXVA (1L << (9 + 9 + 9 + 12 - 1))

/* [<][>][^][v][top][bottom][index][help] */