#ifndef RISCV_KERNEL_H #define RISCV_KERNEL_H #include /** Page Size */ #define PGSIZE 4096 // bytes per page // /** Page Shift, bits of offset within a page */ #define PGSHIFT 12 #define PGROUNDUP(sz) (((sz) + PGSIZE - 1) & ~(PGSIZE - 1)) #define PGROUNDDOWN(a) (((a)) & ~(PGSIZE - 1)) // Supervisor Status Register, sstatus #define SSTATUS_SPP (1L << 8) /** Supervisor Previous Privilege 1=S, 0=U */ #define SSTATUS_SPIE (1L << 5) /** Supervisor Previous Interrupt Enable */ #define SSTATUS_UPIE (1L << 4) /** User Previous Interrupt Enable */ #define SSTATUS_SIE (1L << 1) /** Supervisor Interrupt Enable */ #define SSTATUS_UIE (1L << 0) /** User Interrupt Enable */ // Machine Status Register, mstatus #define MSTATUS_MPP_MASK (3L << 11) /** M-mode Previous Privilege */ #define MSTATUS_MPP_M (3L << 11) /** M-mode Previous Privilege Machine-mode */ #define MSTATUS_MPP_S (1L << 11) /** M-mode Previous Privilege Supervisor-mode */ #define MSTATUS_MPP_U (0L << 11) /** M-mode Previous Privilege User-mode */ #define MSTATUS_MIE (1L << 3) /** M-mode Interrupt Enable */ /** 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 read_mhartid() { u64 x; asm volatile("csrr %0, mhartid" : "=r"(x)); return x; } /** Read thread pointer */ static inline u64 read_tp() { u64 x; asm volatile("mv %0, tp" : "=r"(x)); return x; } /** Write thread pointer */ static inline void write_tp(u64 x) { asm volatile("mv tp, %0" : : "r"(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; } /** Read Machine Exception Delegation */ static inline u64 r_medeleg() { u64 x; asm volatile("csrr %0, medeleg" : "=r"(x)); return x; } /** Write Machine Exception Delegation */ static inline void w_medeleg(u64 x) { asm volatile("csrw medeleg, %0" : : "r"(x)); } /** Read Machine Interrupt Delegation */ static inline u64 r_mideleg() { u64 x; asm volatile("csrr %0, mideleg" : "=r"(x)); return x; } /** Write Machine Interrupt Delegation */ static inline void w_mideleg(u64 x) { asm volatile("csrw mideleg, %0" : : "r"(x)); } static inline u64 r_mstatus() { u64 x; asm volatile("csrr %0, mstatus" : "=r"(x)); return x; } static inline void w_mstatus(u64 x) { asm volatile("csrw mstatus, %0" : : "r"(x)); } /** Supervisor External Interrup Enable */ #define SIE_SEIE (1L << 9) /** Supervisor Timer Interrupt Enable */ #define SIE_STIE (1L << 5) /** Supervisor Software Interrupt Enable */ #define SIE_SSIE (1L << 1) /** Read the value of the sie register. (Supervisor Interrupt Enable) */ static inline u64 r_sie() { u64 x; asm volatile("csrr %0, sie" : "=r"(x)); return x; } /** Write the valie to the sie rgister. (Supervisor Interrupt Enable) */ static inline void w_sie(u64 x) { asm volatile("csrw sie, %0" : : "r"(x)); } /** Machine External Interrupt Enable */ #define MIE_MEIE (1L << 11) /** Machine Timer Interrupt Enable */ #define MIE_MTIE (1L << 7) /** Machine Software Interrupt Enable */ #define MIE_MSIE (1L << 3) /** Read the value of the mie register. (Machine Interrupt Enable) */ static inline u64 r_mie() { u64 x; asm volatile("csrr %0, mie" : "=r"(x)); return x; } /** Write the value to the mie register. (Machine Interrupt Enable) */ static inline void w_mie(u64 x) { asm volatile("csrw mie, %0" : : "r"(x)); } #endif // RISCV_KERNEL_H