#include #include #include #include "platform.h" #include "encoding.h" extern int main(int argc, char** argv); extern void trap_entry(void); #define IRQ_M_SOFT 3 #define IRQ_M_TIMER 7 #define IRQ_M_EXT 11 #define NUM_INTERRUPTS 16 #define MTIMER_NEXT_TICK_INC 1000 void handle_m_ext_interrupt(void); void handle_m_time_interrupt(void); uint32_t handle_trap(uint32_t mcause, uint32_t mepc, uint32_t sp); void default_handler(void); void _init(void); typedef void (*my_interrupt_function_ptr_t) (void); my_interrupt_function_ptr_t localISR[NUM_INTERRUPTS] __attribute__((aligned(64))); static unsigned long mtime_lo(void) { unsigned long ret; __asm volatile("rdtime %0":"=r"(ret)); return ret; } #if __riscv_xlen==32 static uint32_t mtime_hi(void) { unsigned long ret; __asm volatile("rdtimeh %0":"=r"(ret)); return ret; } uint64_t get_timer_value(void) { while (1) { uint32_t hi = mtime_hi(); uint32_t lo = mtime_lo(); if (hi == mtime_hi()) return ((uint64_t)hi << 32) | lo; } } #elif __riscv_xlen==64 uint64_t get_timer_value() { return mtime_lo(); } #endif unsigned long get_timer_freq() { return 32768; } unsigned long get_cpu_freq() { return 100000000; } void init_pll(void){ //TODO: implement initialization } static void uart_init(size_t baud_rate) { //TODO: implement initialization } void __attribute__((weak)) handle_m_ext_interrupt(){ } void __attribute__((weak)) handle_m_time_interrupt(){ uint64_t time = get_aclint_mtime(aclint); time+=MTIMER_NEXT_TICK_INC; set_aclint_mtime(aclint, time); } void __attribute__((weak)) default_handler(void) { puts("default handler\n"); } uint32_t handle_trap(uint32_t mcause, uint32_t mepc, uint32_t sp){ if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) { handle_m_ext_interrupt(); // External Machine-Level interrupt from PLIC } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){ handle_m_time_interrupt(); } else { write(1, "trap\n", 5); _exit(1 + mcause); } return mepc; } void _init() { #ifndef NO_INIT init_pll(); uart_init(115200); printf("core freq at %lu Hz\n", get_cpu_freq()); write_csr(mtvec, &trap_entry); if (read_csr(misa) & (1 << ('F' - 'A'))) { // if F extension is present write_csr(mstatus, MSTATUS_FS); // allow FPU instructions without trapping write_csr(fcsr, 0); // initialize rounding mode, undefined at reset } int i=0; while(i