From e90b72ec3082588b296956730bd2930cf8d5d671 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Fri, 10 Jul 2026 11:31:46 +0800 Subject: refactor: promote new architecture to repository root Archive the deprecated implementation under lume-legacy, make the new kernel the default root-level build, and update repository entry points without changing kernel behavior. --- lume-legacy/src/kernel/trap/handler.cc | 217 +++++++++++++++++++++++++++++++ lume-legacy/src/kernel/trap/trampoline.S | 101 ++++++++++++++ lume-legacy/src/kernel/trap/trap.S | 90 +++++++++++++ 3 files changed, 408 insertions(+) create mode 100644 lume-legacy/src/kernel/trap/handler.cc create mode 100644 lume-legacy/src/kernel/trap/trampoline.S create mode 100644 lume-legacy/src/kernel/trap/trap.S (limited to 'lume-legacy/src/kernel/trap') diff --git a/lume-legacy/src/kernel/trap/handler.cc b/lume-legacy/src/kernel/trap/handler.cc new file mode 100644 index 0000000..b7bd5f0 --- /dev/null +++ b/lume-legacy/src/kernel/trap/handler.cc @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2026 Richard QIn + */ +#include "kernel/trap.h" +#include "kernel/riscv.h" +#include "kernel/proc.h" +#include "drivers/uart.h" +#include "kernel/syscall.h" +#include "kernel/mm.h" +#include "kernel/timer.h" +#include "drivers/plic.h" +#include "drivers/virtio.h" +#include "kernel/fdt.h" +#include "lib/string.h" + + +extern "C" void kernelvec(); + +// Handle Function + +void panic(const char *s) +{ + Drivers::uart_puts("\n\n!!! KERNEL PANIC !!!\n"); + Drivers::uart_puts(s); + Drivers::uart_puts("\nSystem Halted.\n"); + while (1) + ; +} + +// Trap Implementation + +namespace Trap +{ + void init() + { + Drivers::uart_puts("[Trap] Global init done.\n"); + } + + // Each CPU core needs to call this function when starting to set its own stvec + void inithart() + { + w_stvec((uint64)kernelvec); + + // Ensure that the S-Mode interrupt enable bit (SIE) is cleared during initialization + // Interrupt enabling will be done by the scheduler when the first process runs + w_sstatus(r_sstatus() & ~SSTATUS_SIE); + + // Enable the external interrupt, clock interrupt, and software interrupt bits in S-Mode (in SIE register) + uint64 sie = r_sie(); + sie |= SIE_SEIE | SIE_STIE | SIE_SSIE; + w_sie(sie); + + Drivers::uart_puts("[Trap] Hart initialized (stvec set).\n"); + } + + // Device Interrupt Check + int devintr() + { + uint64 scause = r_scause(); + + bool is_interrupt = (scause & 0x8000000000000000L) != 0; + uint64 code = scause & 0xff; + + if (is_interrupt && code == 9) + { + // Supervisor External Interrupt (IRQ 9) + int irq = PLIC::claim(); + + if (irq == (int)g_devices.uart.irq) + { + Drivers::uart_intr(); + } + else + { + // Check if it's a VirtIO IRQ + bool handled = false; + for (int i = 0; i < g_devices.virtio_count; i++) + { + if (irq == (int)g_devices.virtio[i].irq) + { + VirtIO::intr(); + handled = true; + break; + } + } + } + + if (irq > 0) + { + PLIC::complete(irq); + } + + return 1; + } + else if (is_interrupt && code == 5) + { + // Supervisor Timer Interrupt (IRQ 5) + // Timer::set_next_trigger(); + Timer::tick(); + // w_sip(r_sip() & ~2); + return 2; + } + + return 0; + } +} + +// Exception Handling Entry + +extern "C" void kerneltrap(struct Trapframe *tf) +{ + uint64 sepc = r_sepc(); + uint64 sstatus = r_sstatus(); + uint64 scause = r_scause(); + + if ((sstatus & SSTATUS_SPP) == 0) + panic("kerneltrap: not from supervisor mode"); + + if (intr_get() != 0) + panic("kerneltrap: interrupts enabled"); + + if (Trap::devintr() == 0) + { + Drivers::uart_puts("\n--- KERNEL EXCEPTION ---\n"); + Drivers::uart_puts("scause: "); + Drivers::print_hex(scause); + Drivers::uart_puts("\n"); + Drivers::uart_puts("sepc: "); + Drivers::print_hex(sepc); + Drivers::uart_puts("\n"); + Drivers::uart_puts("stval: "); + Drivers::print_hex(r_stval()); + Drivers::uart_puts("\n"); + panic("kerneltrap exception"); + } + + w_sepc(sepc); + w_sstatus(sstatus); +} + +extern "C" void usertrap() +{ + // Drivers::uart_puts("[Debug] Entered usertrap!\n"); + int which_dev = 0; + + if ((r_sstatus() & SSTATUS_SPP) != 0) + panic("usertrap: not from user mode"); + + w_stvec((uint64)kernelvec); + + struct Proc *p = myproc(); + if (!p) + panic("usertrap: no process"); + + p->tf->epc = r_sepc(); + + uint64 scause = r_scause(); + uint64 stval = r_stval(); + + if (scause == 8) // Syscall + { + if (p->state == ZOMBIE) + ProcManager::exit(-1); + p->tf->epc += 4; + intr_on(); + syscall(); + intr_off(); + } + else if (scause == 15) // Store Page Fault + { + if (VM::handle_cow_fault(p->pagetable, PGROUNDDOWN(stval)) != 0) + { + uint64 pa = VM::walkaddr(p->pagetable, stval); + + if (pa == 0) + { + Drivers::uart_puts("usertrap: Segmentation Fault (unmapped) at "); + } + else + { + Drivers::uart_puts("usertrap: Protection Fault (or OOM) at "); + } + + Drivers::print_hex(stval); + Drivers::uart_puts("\n"); + p->state = ZOMBIE; + ProcManager::exit(-1); + } + } + else if ((which_dev = Trap::devintr()) != 0) + { + if (which_dev == 2) + { + ProcManager::yield(); + } + } + else + { + Drivers::uart_puts("\nusertrap(): unexpected scause "); + Drivers::print_hex(scause); + Drivers::uart_puts(" pid="); + Drivers::uart_put_int(p->pid); + Drivers::uart_puts(" sepc="); + Drivers::print_hex(p->tf->epc); + Drivers::uart_puts(" stval="); + Drivers::print_hex(stval); + Drivers::uart_puts("\n"); + p->state = ZOMBIE; + ProcManager::exit(-1); + } + + if (p->state == ZOMBIE) + ProcManager::exit(-1); + + usertrapret(); +} \ No newline at end of file diff --git a/lume-legacy/src/kernel/trap/trampoline.S b/lume-legacy/src/kernel/trap/trampoline.S new file mode 100644 index 0000000..57d6f25 --- /dev/null +++ b/lume-legacy/src/kernel/trap/trampoline.S @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026 Richard Qin + +.section .text +.globl trampoline +.globl uservec +.globl userret + +.align 12 +trampoline: +.align 4 +uservec: + + csrrw a0, sscratch, a0 + + sd ra, 40(a0) + sd sp, 48(a0) + sd gp, 56(a0) + sd tp, 64(a0) + sd t0, 72(a0) + sd t1, 80(a0) + sd t2, 88(a0) + sd s0, 96(a0) + sd s1, 104(a0) + sd a1, 120(a0) + sd a2, 128(a0) + sd a3, 136(a0) + sd a4, 144(a0) + sd a5, 152(a0) + sd a6, 160(a0) + sd a7, 168(a0) + sd s2, 176(a0) + sd s3, 184(a0) + sd s4, 192(a0) + sd s5, 200(a0) + sd s6, 208(a0) + sd s7, 216(a0) + sd s8, 224(a0) + sd s9, 232(a0) + sd s10, 240(a0) + sd s11, 248(a0) + sd t3, 256(a0) + sd t4, 264(a0) + sd t5, 272(a0) + sd t6, 280(a0) + + csrr t0, sscratch + sd t0, 112(a0) + + ld sp, 8(a0) + ld tp, 32(a0) + ld t0, 16(a0) + ld t1, 0(a0) + + csrw satp, t1 + sfence.vma zero, zero + + jr t0 + +.align 4 +userret: + + csrw satp, a1 + sfence.vma zero, zero + + csrw sscratch, a0 + + ld ra, 40(a0) + ld sp, 48(a0) + ld gp, 56(a0) + ld tp, 64(a0) + ld t0, 72(a0) + ld t1, 80(a0) + ld t2, 88(a0) + ld s0, 96(a0) + ld s1, 104(a0) + ld a1, 120(a0) + ld a2, 128(a0) + ld a3, 136(a0) + ld a4, 144(a0) + ld a5, 152(a0) + ld a6, 160(a0) + ld a7, 168(a0) + ld s2, 176(a0) + ld s3, 184(a0) + ld s4, 192(a0) + ld s5, 200(a0) + ld s6, 208(a0) + ld s7, 216(a0) + ld s8, 224(a0) + ld s9, 232(a0) + ld s10, 240(a0) + ld s11, 248(a0) + ld t3, 256(a0) + ld t4, 264(a0) + ld t5, 272(a0) + ld t6, 280(a0) + + ld a0, 112(a0) + + sret \ No newline at end of file diff --git a/lume-legacy/src/kernel/trap/trap.S b/lume-legacy/src/kernel/trap/trap.S new file mode 100644 index 0000000..8bce53d --- /dev/null +++ b/lume-legacy/src/kernel/trap/trap.S @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2026 Richard Qin + +.section .text +.global kernelvec +.global uservec +.global userret +.align 12 + +kernelvec: + addi sp, sp, -288 + + sd ra, 40(sp) + sd sp, 48(sp) + sd gp, 56(sp) + sd tp, 64(sp) + sd t0, 72(sp) + sd t1, 80(sp) + sd t2, 88(sp) + sd s0, 96(sp) + sd s1, 104(sp) + sd a0, 112(sp) + sd a1, 120(sp) + sd a2, 128(sp) + sd a3, 136(sp) + sd a4, 144(sp) + sd a5, 152(sp) + sd a6, 160(sp) + sd a7, 168(sp) + sd s2, 176(sp) + sd s3, 184(sp) + sd s4, 192(sp) + sd s5, 200(sp) + sd s6, 208(sp) + sd s7, 216(sp) + sd s8, 224(sp) + sd s9, 232(sp) + sd s10, 240(sp) + sd s11, 248(sp) + sd t3, 256(sp) + sd t4, 264(sp) + sd t5, 272(sp) + sd t6, 280(sp) + + csrr t0, sepc + csrr t1, sstatus + sd t0, 24(sp) # Trapframe.epc + sd t1, 32(sp) # Trapframe.kernel_hartid + + mv a0, sp + call kerneltrap + + ld t0, 24(sp) + ld t1, 32(sp) + csrw sepc, t0 + csrw sstatus, t1 + + ld ra, 40(sp) + ld gp, 56(sp) + ld tp, 64(sp) + ld t0, 72(sp) + ld t1, 80(sp) + ld t2, 88(sp) + ld s0, 96(sp) + ld s1, 104(sp) + ld a0, 112(sp) + ld a1, 120(sp) + ld a2, 128(sp) + ld a3, 136(sp) + ld a4, 144(sp) + ld a5, 152(sp) + ld a6, 160(sp) + ld a7, 168(sp) + ld s2, 176(sp) + ld s3, 184(sp) + ld s4, 192(sp) + ld s5, 200(sp) + ld s6, 208(sp) + ld s7, 216(sp) + ld s8, 224(sp) + ld s9, 232(sp) + ld s10, 240(sp) + ld s11, 248(sp) + ld t3, 256(sp) + ld t4, 264(sp) + ld t5, 272(sp) + ld t6, 280(sp) + + addi sp, sp, 288 + sret \ No newline at end of file -- cgit v1.2.3