#include "kernel/lib.h" #include "kernel/riscv.h" #include "kernel/kalloc.h" #include "kernel/vm.h" #include "kernel/cpu.h" #include "kernel/aplic.h" Cpu cpus[MAX_CPU]; extern uint32_t _bss_start; extern uint32_t _bss_end; extern uint32_t _ram_end; #define UART_MSI 1 extern uint32_t strap; void ktrap(uint32_t cause) { if ((cause & 0x8000'0000) == 0) { switch (cause) { case 0: panic("kstrap: Instruction address misaligned"); case 1: panic("kstrap: Instruction access fault"); case 2: panic("kstrap: Illegal instruction"); case 3: panic("kstrap: Breakpoint"); case 4: panic("kstrap: Load address misaligned"); case 5: panic("kstrap: Load access fault"); case 6: panic("kstrap: Store/AMO address misaligned"); case 7: panic("kstrap: Store/AMO access fault"); case 8: panic("kstrap: Environment call from U-mode"); case 9: panic("kstrap: Environment call from S-mode"); case 12: panic("kstrap: Instruction page fault"); case 13: panic("kstrap: Load page fault"); case 14: panic("kstrap: Reserved"); case 15: panic("kstrap: Store/AMO page fault"); case 18: panic("kstrap: Software check"); case 19: panic("kstrap: Hardware error"); default: panic("kstrap: Unknown"); } } else { cause = cause & 0x7fff'ffff; if (cause == 9) { uint32_t msi = aplic_claim_msi_s(); switch (msi) { case UART_MSI: { volatile char* UART_BASE = (volatile char*)0x1000'0000; *UART_BASE = *UART_BASE; break; } default: panic("Unknown MSI"); } } else { panic("Interrupt"); } } } void uart_init() { volatile char* UART_BASE = (volatile char*)0x1000'0000; // Set LCR[1:0] to 0b11 for 8-bit words *(UART_BASE + 3) = 0b0000'0011; // Set FCR[0] to 1 to enable FIFO *(UART_BASE + 2) = 0b0000'0001; // Set IER[0] to 1 to enable interrupts on receive *(UART_BASE + 1) = 0b0000'0001; } void kstart() { uart_init(); kalloc_init(); kvm_init(); panic("kstart: end\n"); } void kinit() { // @Todo Initialize CPUs Cpu null_cpu = {0}; cpus[0] = null_cpu; // Clear the BSS section for (uint32_t* ptr = &_bss_start; ptr < &_bss_end; ++ptr) { *ptr = 0U; } w_mideleg(0xFFFF); w_medeleg(0xFFFF); w_sstatus(SSTATUS_SPIE | SSTATUS_SPP_S); w_sie(SIE_SEIE); w_sepc(&kstart); w_stvec(&strap); aplic_init(); aplic_enable_intr_s(10, UART_MSI); w_pmpcfg0(PMPCFG_RW | PMPCFG_X | PMPCFG_TOR); w_pmpaddr0(((uint32_t)&_ram_end) >> PMPADDR_SHIFT); __asm__ volatile("sret"); }