#ifndef RISCV_KERNEL_H #define RISCV_KERNEL_H #include // Supervisor Status Register, sstatus /** Supervisor Previous Privilege */ #define SSTATUS_SPP (1L << 8) // Previous mode, 1=Supervisor, 0=User /** Supervisor Previous Interrupt Enable */ #define SSTATUS_SPIE (1L << 5) /** User Previous Interrupt Enable */ #define SSTATUS_UPIE (1L << 4) /** Supervisor Interrupt Enable */ #define SSTATUS_SIE (1L << 1) /** User Interrupt Enable */ #define SSTATUS_UIE (1L << 0) /** Page Table Entry Type */ typedef u64 pte_t; /** Page Table Type */ typedef u64 *pagetable_t; // 512 PTEs /** Returns the current hart id */ static inline u64 r_mhartid() { u64 x; asm volatile("csrr %0, mhartid" : "=r"(x)); return x; } /** Read thread pointer */ static inline u64 r_tp() { u64 x; asm volatile("mv %0, tp" : "=r"(x)); return x; } /** * Read the value of the sstatus register. * (Supervisor Status Register) */ static inline u64 r_sstatus() { u64 x; asm volatile("csrr %0, sstatus" : "=r"(x)); return x; } /** * Write a value to the sstatus register. * (Supervisor Status Register) */ static inline void w_sstatus(u64 x) { asm volatile("csrw sstatus, %0" : : "r"(x)); } /** Enable device interrupts */ static inline void intr_on() { w_sstatus(r_sstatus() | SSTATUS_SIE); } /** Disable device interrupts */ static inline void intr_off() { w_sstatus(r_sstatus() & ~SSTATUS_SIE); } /** Are device interrupts enabled? */ static inline int intr_get() { u64 x = r_sstatus(); return (x & SSTATUS_SIE) != 0; } #endif