#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 */ /** Page Table Entry Type */ typedef u64 pte_t; /** Page Table Type */ typedef u64 *pagetable_t; // 512 PTEs // CSR numeric addresses #define CSR_MSTATUS 0x300 #define CSR_MISA 0x301 #define CSR_MIE 0x304 #define CSR_MTVEC 0x305 #define CSR_MCOUNTEREN 0x306 #define CSR_MSCRATCH 0x340 #define CSR_MEPC 0x341 #define CSR_MCAUSE 0x342 #define CSR_MTVAL 0x343 #define CSR_MIP 0x344 #define CSR_MHARTID 0xF14 static inline u64 read_csr(u32 csr) { u64 value; asm volatile("csrr %0, %1" : "=r"(value) : "i"(csr)); return value; } static inline void write_csr(u32 csr, u64 value) { asm volatile("csrw %0, %1" ::"i"(csr), "r"(value)); } static inline u64 read_mstatus(void) { return read_csr(CSR_MSTATUS); } static inline void write_mstatus(u64 val) { write_csr(CSR_MSTATUS, val); } static inline u64 read_mcause(void) { return read_csr(CSR_MCAUSE); } static inline u64 read_mtval(void) { return read_csr(CSR_MTVAL); } static inline u64 read_mepc(void) { return read_csr(CSR_MEPC); } static inline void write_mepc(u64 val) { write_csr(CSR_MEPC, val); } static inline void write_mtvec(u64 val) { write_csr(CSR_MTVEC, val); } static inline u64 read_mtvec(void) { return read_csr(CSR_MTVEC); } /** Returns the current hart id */ static inline u64 read_mhartid(void) { return read_csr(CSR_MHARTID); } // static inline u64 r_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; } #endif