#pragma once #include "kernel/lib.h" __attribute__((noreturn)) static inline void hart_halt() { while (true) { __asm__ volatile("wfi"); } } static inline void w_mideleg(uint32_t v) { __asm__ volatile("csrw mideleg, %0" :: "r"(v)); } static inline void w_medeleg(uint32_t v) { __asm__ volatile("csrw medeleg, %0" :: "r"(v)); } #define SSTATUS_SIE (1U << 1) #define SSTATUS_SPIE (1U << 5) #define SSTATUS_SPP_S (1U << 8) static inline void w_sstatus(uint32_t v) { __asm__ volatile("csrw sstatus, %0" :: "r"(v)); } static inline uint32_t r_sstatus() { uint32_t v; __asm__ volatile("csrr sstatus, %0" : "=r"(v)); return v; } static inline void s_sstatus(uint32_t v) { __asm__ volatile("csrs sstatus, %0" :: "r"(v)); } static inline uint32_t rc_sstatus(uint32_t v) { uint32_t v2; __asm__ volatile("csrrc %0, sstatus, %0" : "=r"(v2) : "r"(v)); return v2; } #define SIE_SSIE (1U << 1) #define SIE_STIE (1U << 5) #define SIE_SEIE (1U << 9) static inline void w_sie(uint32_t v) { __asm__ volatile("csrw sie, %0" :: "r"(v)); } static inline void w_sepc(void* addr) { __asm__ volatile("csrw sepc, %0" :: "r"((uint32_t)addr)); } static inline void w_stvec(void* addr) { __asm__ volatile("csrw stvec, %0" :: "r"((uint32_t)addr)); } #define PMPCFG_R 0x01 #define PMPCFG_RW 0x03 #define PMPCFG_X 0x04 #define PMPCFG_OFF 0x00 #define PMPCFG_TOR 0x08 #define PMPCFG_NA4 0x10 #define PMPCFG_NAPOT 0x18 #define PMPCFG_LOCKED 0x80 static inline void w_pmpcfg0(uint32_t v) { __asm__ volatile("csrw pmpcfg0, %0" :: "r"(v)); } #define PMPADDR_SHIFT 2 static inline void w_pmpaddr0(uint32_t addr) { __asm__ volatile("csrw pmpaddr0, %0" :: "r"(addr)); } static inline void sfence_vma() { __asm__ volatile("sfence.vma zero, zero"); } #define SATP_MODE_BARE 0 #define SATP_MODE_SV32 0x8000'0000 static inline void w_satp(uint32_t v) { __asm__ volatile("csrw satp, %0" :: "r"(v)); }