#include #include #include #include "encoding.h" #include "platform.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 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_mtimecmp(aclint, time); } void __attribute__((weak)) default_handler(void) { puts("default handler\n"); } void __attribute__((weak)) interrupt_handler(unsigned) { puts("interrupt handler\n"); } uint32_t handle_trap(uint32_t mcause, uint32_t mepc, uint32_t sp) { if((mcause & MCAUSE_INT)) { if((mcause & MCAUSE_CAUSE) == IRQ_M_EXT) { handle_m_ext_interrupt(); } else if(((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)) { handle_m_time_interrupt(); } else { interrupt_handler(mcause & ~MCAUSE_INT); } } else { write(1, "trap\n", 5); _exit(1 + mcause); } return mepc; } void __attribute__((weak)) _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 < NUM_INTERRUPTS) { localISR[i++] = default_handler; } #endif } void _fini(void) {}