summaryrefslogtreecommitdiff
path: root/arch/riscv/kernel
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-10-16 02:39:56 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-10-16 02:39:56 +0800
commit8cace3f05003c6cb4d38c36890055f03151c2ad4 (patch)
treeaa739deaac0266f17c4e91b333957501cb1ea2e9 /arch/riscv/kernel
parent3ad39e9878310e5317ee73c9b353c1e2c1c5c4ee (diff)
downloadlume-8cace3f05003c6cb4d38c36890055f03151c2ad4.tar.gz
lume-8cace3f05003c6cb4d38c36890055f03151c2ad4.tar.xz
Remove old code
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
Diffstat (limited to 'arch/riscv/kernel')
-rw-r--r--arch/riscv/kernel/asm-offsets.c29
-rw-r--r--arch/riscv/kernel/head.S317
-rw-r--r--arch/riscv/kernel/lumeos.lds.S120
-rw-r--r--arch/riscv/kernel/signal.cc163
4 files changed, 0 insertions, 629 deletions
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
deleted file mode 100644
index edecab7..0000000
--- a/arch/riscv/kernel/asm-offsets.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-// Copyright (C) 2026 Richard Qin
-//
-// arch/riscv/kernel/asm-offsets.c — emit struct field offsets and
-// scalar constants for consumption by assembly sources (head.S etc.).
-//
-// 1:1 with Linux arch/riscv/kernel/asm-offsets.c. The Makefile
-// compiles this to an .s file (not .o) and runs
-// scripts/extract-asm-offsets.sed over the output to produce
-// include/generated/asm-offsets.h.
-//
-// Adding a new offset: include the struct's header, add an OFFSET()
-// or DEFINE() line below, rebuild. head.S can then reference the
-// generated #define directly.
-
-#include <lume/kbuild.h>
-#include <lume/kernel_map.h>
-
-void asm_offsets(void)
-{
- COMMENT("LumeOS asm-offsets — struct kernel_mapping field offsets");
- OFFSET(KERNEL_MAP_VIRT_ADDR, kernel_mapping, virt_addr);
- OFFSET(KERNEL_MAP_VIRT_OFFSET, kernel_mapping, virt_offset);
- OFFSET(KERNEL_MAP_PHYS_ADDR, kernel_mapping, phys_addr);
- OFFSET(KERNEL_MAP_SIZE, kernel_mapping, size);
- OFFSET(KERNEL_MAP_VA_PA_OFFSET, kernel_mapping, va_pa_offset);
- OFFSET(KERNEL_MAP_PAGE_OFFSET, kernel_mapping, page_offset);
- OFFSET(KERNEL_MAP_VA_KERNEL_PA_OFFSET, kernel_mapping, va_kernel_pa_offset);
-}
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
deleted file mode 100644
index e04c44c..0000000
--- a/arch/riscv/kernel/head.S
+++ /dev/null
@@ -1,317 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/* Copyright (C) 2026 Richard Qin */
-
-/*
- * RISC-V kernel entry — Linux-aligned layout.
- *
- * Flow (mirrors arch/riscv/kernel/head.S in Linux):
- *
- * _start [.head.text, byte 0 of image]
- * · 64-byte Boot Protocol Image Header
- * · j real_start
- *
- * real_start [.text]
- * · save a0 (hartid) / a1 (dtb_pa)
- * · setup gp / per-hart sp
- * · BSP/AP election via amoswap
- * · BSP: clear BSS, call setup_vm, then relocate_enable_mmu
- * · AP: spin-wait, then relocate_enable_mmu
- *
- * relocate_enable_mmu [C function, arch/riscv/mm/init.cc]
- * · csrw satp <- trampoline_pg_dir
- * · jump to higher-half VA
- * · csrw satp <- early_pg_dir
- * · slide sp/ra/gp to higher-half
- * · call relocate_kernel (walks .rela.dyn, patches R_RISCV_RELATIVE)
- *
- * real_start (continued in higher-half)
- * · BSP only: call early_cpp_init (walks .init_array)
- * · call kernel_main(hartid, dtb_pa)
- *
- * Register contract from OpenSBI / U-Boot:
- * a0 = hart ID
- * a1 = FDT physical base
- */
-
-#include <lume/config.h>
-
-#define PAGE_OFFSET 0xFFFFFFC000000000
-#define BOOT_STACK_SIZE 8192
-
-/* ========================================================================
- * .head.text — RISC-V Boot Protocol Image Header
- *
- * Layout per Documentation/arch/riscv/boot-image-header.rst:
- * code0/code1 (8 B) : executable code, lands at PC after OpenSBI hand-off
- * text_offset (8 B) : load offset from RAM base
- * image_size (8 B) : effective image size (0 = unknown)
- * flags (8 B) : bit 0: endian
- * version (4 B) : major.minor
- * res1/res2 (4+8) : reserved
- * magic (8 B) : "RISCV\0\0\0"
- * magic2 (4 B) : "RSC\x05"
- * res3 (4 B) : PE/COFF reserved
- * ======================================================================== */
- .section .head.text, "ax"
- .globl _start
-_start:
- j real_start /* code0 */
- .word 0 /* code1 */
- .dword 0x200000 /* text_offset */
- .dword 0 /* image_size (post-link) */
- .dword 0 /* flags */
- .word 0x0002 /* version 0.2 */
- .word 0 /* res1 */
- .dword 0 /* res2 */
- .dword 0x5643534952 /* magic "RISCV\0\0\0" */
- .word 0x05435352 /* magic2 "RSC\x05" */
- .word 0 /* res3 */
-
-/* ========================================================================
- * real_start — all harts land here at physical PC
- * ======================================================================== */
- .text
- .globl real_start
-real_start:
- /* DEBUG: 'R<hartid>\n' — UART direct at 0x10000000, MMU off. */
- li t0, 0x10000000
- li t1, 'R'
- sb t1, 0(t0)
- addi t1, a0, '0'
- sb t1, 0(t0)
- li t1, '\n'
- sb t1, 0(t0)
-
- /* Mask interrupts and supervisor pending bits. */
- csrw sie, zero
- csrw sip, zero
-
- /* gp for medany — relax must be disabled across the `la`. */
- .option push
- .option norelax
- la gp, __global_pointer$
- .option pop
-
- /* per-hart boot stack: sp = boot_stack + (hartid + 1) * STACK_SIZE */
- la t0, boot_stack
- li t1, BOOT_STACK_SIZE
- addi t2, a0, 1
- mul t1, t1, t2
- add sp, t0, t1
-
- /* Save hartid / dtb_pa in callee-saved regs preserved across calls. */
- mv tp, a0 /* tp = hartid */
- mv s0, a1 /* s0 = dtb_pa */
-
- /* BSP/AP election: first hart to swap bsp_elected 0→1 is BSP. */
- la t0, bsp_elected
- li t1, 1
- amoswap.w.aq t2, t1, (t0)
- bnez t2, .Lap_wait /* prev != 0 → we're an AP */
-
- /* === BSP path === */
- la t0, bsp_hart_id
- sw a0, 0(t0)
-
- li t3, 0x10000000
- li t4, 'B'
- sb t4, 0(t3)
- li t4, '\n'
- sb t4, 0(t3)
-
- /* Clear BSS — must precede setup_vm, which writes kernel_map. */
- la t0, _sbss
- la t1, _ebss
-.Lbss_loop:
- bgeu t0, t1, .Lbss_done
- sd zero, 0(t0)
- addi t0, t0, 8
- j .Lbss_loop
-.Lbss_done:
-
- li t3, 0x10000000
- li t4, 'V'
- sb t4, 0(t3)
- li t4, '\n'
- sb t4, 0(t3)
-
- /* ---- BSP-only: pre-MMU PIC fixup of .rela.dyn ----
- *
- * The kernel is built with -fPIE -shared. All global-data accesses
- * compile to GOT-indirect loads (auipc + ld), where the linker
- * emits each .got slot's initial value as the link-time VA and a
- * companion R_RISCV_RELATIVE entry in .rela.dyn. At this point
- * we're running at the physical load address — those link-time VAs
- * are not yet mapped, so any global access would fault.
- *
- * Walk .rela.dyn in pure assembly (PC-relative only — no globals)
- * and patch every R_RISCV_RELATIVE slot to addend + (PA - LINK_VA).
- * After this, setup_vm can dereference kernel_map / early_pg_dir
- * / etc. via the GOT and get correct PA-side pointers.
- *
- * Mirrors Linux arch/riscv/kernel/head.S — same idea, same loop.
- *
- * reloc:
- * t0 = pa_offset = PA(_start) - KERNEL_LINK_ADDR (negative)
- * t1 = &__rela_dyn_start
- * t2 = &__rela_dyn_end
- * for each 24-byte rela in [t1, t2):
- * t3 = r_offset; t4 = r_info; t5 = r_addend
- * if (t4 & 0xFFFFFFFF) != R_RISCV_RELATIVE: skip
- * slot_pa = r_offset + pa_offset
- * *slot_pa = r_addend + pa_offset
- */
-#define R_RISCV_RELATIVE 3
-
- la t0, _start /* PA of _start */
- li t1, 0xFFFFFFC080200000 /* KERNEL_LINK_ADDR (asm/page.h) */
- sub t0, t0, t1 /* t0 = pa_offset (PA - LINK_VA) */
-
- la t1, __rela_dyn_start
- la t2, __rela_dyn_end
-.Lrela_loop:
- bgeu t1, t2, .Lrela_done
- ld t3, 0(t1) /* r_offset */
- ld t4, 8(t1) /* r_info */
- ld t5, 16(t1) /* r_addend */
- /* r_info low 32 bits = type */
- li t6, 0xFFFFFFFF
- and t4, t4, t6
- li t6, R_RISCV_RELATIVE
- bne t4, t6, .Lrela_next
- /* slot_pa = r_offset + pa_offset */
- add t3, t3, t0
- /* value = r_addend + pa_offset */
- add t5, t5, t0
- sd t5, 0(t3)
-.Lrela_next:
- addi t1, t1, 24 /* sizeof(Elf64_Rela) */
- j .Lrela_loop
-.Lrela_done:
-
- /* Memory fence so subsequent loads see the patched slots. */
- fence w, r
-
- li t3, 0x10000000
- li t4, 'P'
- sb t4, 0(t3)
- li t4, '\n'
- sb t4, 0(t3)
-
- /* Call setup_vm(load_pa = PA of _start, dtb_pa = s0).
- * Both args physical at this point — MMU still off. */
- la a0, _start
- mv a1, s0
- call setup_vm
-
- li t3, 0x10000000
- li t4, 'v'
- sb t4, 0(t3)
- li t4, '\n'
- sb t4, 0(t3)
-
- /* Release APs once page tables are built. */
- la t0, boot_sync_flag
- li t1, 1
- amoswap.w.rl zero, t1, (t0)
- j .Lenable_mmu
-
-/* ========================================================================
- * AP path — spin until BSP signals readiness.
- * ======================================================================== */
-.Lap_wait:
- la t0, boot_sync_flag
-.Lap_spin:
- lw t1, 0(t0)
- beqz t1, .Lap_spin
- fence r, rw
-
- /* fall through */
-
-/* ========================================================================
- * .Lenable_mmu — all harts: enable MMU, jump to higher-half, run reloc.
- *
- * relocate_enable_mmu does its own SATP write + higher-half jump in
- * C (with inline asm), then calls relocate_kernel. After it returns,
- * we are at higher-half VA with sp / ra / gp slid up, and .rela.dyn
- * is applied (so .init_array pointers are valid).
- * ======================================================================== */
-.Lenable_mmu:
- la a0, early_pg_dir
- call relocate_enable_mmu
- /* On return: PC, sp, ra, gp are all at higher-half VA. */
-
- li t3, 0x10000000
- li t4, 'M'
- sb t4, 0(t3)
- li t4, '\n'
- sb t4, 0(t3)
-
- /* Mark MMU enabled for console / pmap layers that check this. */
- call console_set_mmu_enabled
-
- /* BSP only: walk __init_array and call each C++ ctor. */
- la t0, bsp_hart_id
- lw t0, 0(t0)
- bne tp, t0, .Lskip_cpp_init
- call early_cpp_init
-.Lskip_cpp_init:
-
- /* Hand off to kernel_main(hartid, dtb_pa). */
- mv a0, tp
- mv a1, s0
- call kernel_main
-
- /* kernel_main should not return. */
-.Lhalt:
- csrc sstatus, 2
- wfi
- j .Lhalt
-
-/* ========================================================================
- * early_cpp_init — walk .init_array and call each constructor.
- *
- * Called only by BSP, after relocate_kernel has patched the function
- * pointers stored in __init_array. Before relocate_kernel runs those
- * pointers are zero-filled by the linker.
- * ======================================================================== */
- .globl early_cpp_init
-early_cpp_init:
- addi sp, sp, -32
- sd ra, 0(sp)
- sd s1, 8(sp)
- sd s2, 16(sp)
-
- la s1, __init_array_start
- la s2, __init_array_end
-.Linit_loop:
- bgeu s1, s2, .Linit_done
- ld t0, 0(s1)
- jalr ra, t0
- addi s1, s1, 8
- j .Linit_loop
-.Linit_done:
- ld ra, 0(sp)
- ld s1, 8(sp)
- ld s2, 16(sp)
- addi sp, sp, 32
- ret
-
-/* ========================================================================
- * Election state — in .data so explicit zero survives the BSP BSS clear
- * (these are read before BSS is cleared on the BSP, and concurrently by
- * APs while BSP is in the clear loop).
- * ======================================================================== */
- .section .data
- .align 2
- .globl boot_sync_flag
-boot_sync_flag:
- .word 0
-
- .globl bsp_elected
-bsp_elected:
- .word 0
-
- .globl bsp_hart_id
-bsp_hart_id:
- .word 0
diff --git a/arch/riscv/kernel/lumeos.lds.S b/arch/riscv/kernel/lumeos.lds.S
deleted file mode 100644
index 9bd083b..0000000
--- a/arch/riscv/kernel/lumeos.lds.S
+++ /dev/null
@@ -1,120 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/* Copyright (C) 2026 Richard Qin */
-
-/*
- * RISC-V Kernel Linker Script Template
- *
- * This is a C-preprocessed linker script (.lds.S). The build system
- * runs it through CPP to produce the final vmlinux.lds which is
- * passed to the linker.
- *
- * Architecture-specific definitions:
- * - OUTPUT_ARCH, ENTRY
- * - PAGE_OFFSET, BASE_ADDRESS, PHYS_BASE
- * - .head.text placement
- * - GP anchor (__global_pointer$ for RISC-V medany)
- * - early_pgdir and boot stacks in .bss
- *
- * Common section macros come from include/lume/vmlinux.lds.h
- *
- * Reference: docs/specs/linker_and_entry.md
- */
-
-#include <lume/lumeos.lds.h>
-
-/* ===== RISC-V Architecture Constants ===== */
-
-OUTPUT_ARCH(riscv)
-
-PAGE_OFFSET = 0xFFFFFFC000000000;
-BASE_ADDRESS = 0xFFFFFFC080200000;
-PHYS_BASE = 0x80200000;
-
-ENTRY(_start)
-
-/* ===== RISC-V: GP anchor in .data (medany model) ===== */
-#define ARCH_DATA_EXTRA \
- . = ALIGN(16); \
- PROVIDE(__global_pointer$ = . + 0x800); \
- *(.sdata .sdata.*)
-
-/* ===== RISC-V: page-table storage + per-CPU boot stacks in .bss =====
- *
- * Linux RISC-V layout (arch/riscv/kernel/vmlinux.lds.S):
- * early_pg_dir — first early page table built by setup_vm,
- * used for the rest of boot after MMU enable
- * trampoline_pg_dir — single-page table used only during the SATP
- * switch from physical to higher-half VA; its
- * identity + virt mappings of _start must both
- * be valid in the same instruction window
- * fixmap_pg_dir — covers the FIXADDR_START range used by the
- * early console (UART MMIO before kernel page
- * table proper is built)
- *
- * All three are allocated here so head.S can take their addresses without
- * a C definition; their PA == VA mapping covers them during setup_vm.
- */
-#define ARCH_BSS_EXTRA \
- . = ALIGN(4096); \
- early_pg_dir = .; \
- . += 4096; \
- trampoline_pg_dir = .; \
- . += 4096; \
- fixmap_pg_dir = .; \
- . += 4096; \
- /* Legacy name retained for any caller still referencing it; */ \
- /* points at the same first 4 KiB as early_pg_dir. */ \
- early_pgdir = early_pg_dir; \
- /* Per-CPU boot stacks: 8KB per CPU, max 8 CPUs */ \
- . = ALIGN(4096); \
- boot_stack = .; \
- . += 8192 * 8; \
- boot_stack_top = .;
-
-/* ===== Layout ===== */
-
-SECTIONS {
- . = BASE_ADDRESS;
-
- /* .head.text: Image Header (must be at byte 0 of the kernel image) */
- .head.text : AT(PHYS_BASE) {
- _start = .;
- KEEP(*(.head.text))
- }
-
- TEXT_SECTION
-
- . = ALIGN(4096);
-
- /* .rela.dyn lives between .text and .rodata so it ends up in the
- * read-only PT_LOAD segment. Mirrors Linux vmlinux.lds.S where
- * .rela.dyn sits at the tail of init data, just before RO_DATA. */
- RELA_DYN_SECTION
-
- . = ALIGN(4096);
-
- RODATA_SECTION
-
- . = ALIGN(4096);
-
- DATA_SECTION
-
- . = ALIGN(8);
-
- /* .got lives right after .data in the RW PT_LOAD. All other
- * dynamic-linker artefacts (.plt, .dynamic, .dynsym, .dynstr,
- * .hash, .gnu.hash, .interp, .dynbss) are discarded by the
- * DISCARDS macro — mirrors Linux arch/riscv/kernel/vmlinux.lds.S. */
- GOT_SECTION
-
- . = ALIGN(4096);
-
- /* End of file-backed image (BSS follows as NOBITS) */
- __lume_image_end = .;
-
- BSS_SECTION
-
- KERNEL_END
-
- DISCARDS
-}
diff --git a/arch/riscv/kernel/signal.cc b/arch/riscv/kernel/signal.cc
deleted file mode 100644
index 39fe34e..0000000
--- a/arch/riscv/kernel/signal.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/* Copyright (C) 2026 Richard Qin */
-
-/*
- * arch/riscv/signal.cc — Signal frame construction and sigreturn
- *
- * Constructs a signal frame on the user stack before returning to
- * the user signal handler. On sigreturn, restores the original
- * registers from the saved frame.
- *
- * Frame layout on user stack (grows downward):
- *
- * +-----------------------+ <- original sp
- * | sigset_t saved_mask | 8 bytes
- * | TrapFrame saved_regs | 296 bytes
- * | kernel_siginfo info | 128 bytes
- * +-----------------------+ <- new sp (16-byte aligned)
- *
- * Reference: Linux arch/riscv/kernel/signal.c
- */
-
-#include <lume/signal.h>
-#include <lume/signal_types.h>
-#include <lume/signal_nr.h>
-#include <lume/task.h>
-#include <lume/uaccess.h>
-#include <lume/errno.h>
-#include <lume/klog.h>
-#include <arch/trapframe.h>
-
-/* ================================================================== */
-/* Signal frame layout */
-/* ================================================================== */
-
-struct rt_sigframe {
- kernel_siginfo info; /* siginfo for SA_SIGINFO handlers */
- arch::TrapFrame saved_regs; /* saved register state */
- sigset_t saved_mask; /* blocked mask to restore on sigreturn */
-};
-
-/* ================================================================== */
-/* Signal trampoline (written to user stack) */
-/* ================================================================== */
-
-/*
- * When the user's signal handler returns (via `ret`), ra points here.
- * This tiny code sequence invokes sys_rt_sigreturn to restore the
- * original execution context.
- *
- * RISC-V instructions (8 bytes):
- * li a7, 139 → addi a7, zero, 139 → 0x08b00893
- * ecall → 0x00000073
- */
-static constexpr uint32 sigreturn_trampoline[2] = {
- 0x08b00893, /* li a7, 139 (SYS_rt_sigreturn) */
- 0x00000073, /* ecall */
-};
-
-/* ================================================================== */
-/* setup_signal_frame */
-/* ================================================================== */
-
-int setup_signal_frame(arch::TrapFrame* tf, int signo,
- kernel_sigaction* ka, kernel_siginfo* info)
-{
- TaskControlBlock* curr = current_task();
- if (!curr) return -EINVAL;
-
- /* Calculate frame location on user stack */
- uint64 sp = tf->sp;
-
- /* Reserve space for the trampoline below the frame */
- sp -= sizeof(sigreturn_trampoline);
- sp &= ~15ULL; /* 16-byte align */
- uint64 trampoline_addr = sp;
-
- /* Reserve space for the signal frame */
- sp -= sizeof(rt_sigframe);
- sp &= ~15ULL; /* 16-byte align */
- uint64 frame_addr = sp;
-
- /* Build the frame in kernel memory, then copy to user stack */
- rt_sigframe frame{};
- if (info) {
- frame.info = *info;
- }
- frame.saved_regs = *tf;
- frame.saved_mask = curr->blocked;
-
- /* Copy frame to user stack */
- int err = copy_to_user(frame_addr, &frame, sizeof(frame));
- if (err < 0) return -EFAULT;
-
- /* Copy trampoline to user stack */
- err = copy_to_user(trampoline_addr, sigreturn_trampoline,
- sizeof(sigreturn_trampoline));
- if (err < 0) return -EFAULT;
-
- /* Set up the trap frame to execute the signal handler */
- tf->epc = ka->sa_handler;
- tf->sp = frame_addr;
-
- /* Arguments to the handler: handler(int signo, siginfo_t*, ucontext_t*) */
- tf->a[0] = static_cast<uint64>(signo);
-
- if (ka->sa_flags & SA_SIGINFO) {
- /* SA_SIGINFO: pass siginfo and ucontext pointers */
- tf->a[1] = frame_addr; /* &info */
- tf->a[2] = frame_addr + sizeof(kernel_siginfo); /* &saved_regs (as ucontext) */
- } else {
- tf->a[1] = 0;
- tf->a[2] = 0;
- }
-
- /* Return address: when the handler does `ret`, jump to trampoline */
- if (ka->sa_flags & SA_RESTORER) {
- tf->ra = ka->sa_restorer;
- } else {
- tf->ra = trampoline_addr;
- }
-
- return 0;
-}
-
-/* ================================================================== */
-/* arch_sigreturn — restore state from signal frame */
-/* ================================================================== */
-
-int64 arch_sigreturn(arch::TrapFrame* tf)
-{
- TaskControlBlock* curr = current_task();
- if (!curr) return -EINVAL;
-
- /*
- * The signal frame is located at the current sp.
- * We need to read it back and restore the original state.
- */
- uint64 frame_addr = tf->sp;
-
- rt_sigframe frame{};
- int err = copy_from_user(&frame, frame_addr, sizeof(frame));
- if (err < 0) {
- printk(KERN_ERR "sigreturn: failed to read signal frame at %llx\n",
- frame_addr);
- task_kill_current(SIGSEGV);
- return -EFAULT;
- }
-
- /* Restore the saved register state */
- *tf = frame.saved_regs;
-
- /* Restore the blocked mask */
- curr->blocked = frame.saved_mask;
- curr->blocked.del(SIGKILL);
- curr->blocked.del(SIGSTOP);
-
- /*
- * Return value: we return the saved a0 from the original context.
- * The syscall dispatch will NOT overwrite a0 because sigreturn
- * is special — it returns via the restored trap frame directly.
- */
- return tf->a[0];
-}