diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-10-16 02:39:56 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-10-16 02:39:56 +0800 |
| commit | 8cace3f05003c6cb4d38c36890055f03151c2ad4 (patch) | |
| tree | aa739deaac0266f17c4e91b333957501cb1ea2e9 /arch/riscv/include | |
| parent | 3ad39e9878310e5317ee73c9b353c1e2c1c5c4ee (diff) | |
| download | lume-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/include')
| -rw-r--r-- | arch/riscv/include/arch/config.h | 106 | ||||
| -rw-r--r-- | arch/riscv/include/arch/context.h | 33 | ||||
| -rw-r--r-- | arch/riscv/include/arch/cpu.h | 95 | ||||
| -rw-r--r-- | arch/riscv/include/arch/extable.h | 55 | ||||
| -rw-r--r-- | arch/riscv/include/arch/fpstate.h | 94 | ||||
| -rw-r--r-- | arch/riscv/include/arch/mmu.h | 78 | ||||
| -rw-r--r-- | arch/riscv/include/arch/pmap.h | 49 | ||||
| -rw-r--r-- | arch/riscv/include/arch/random.h | 27 | ||||
| -rw-r--r-- | arch/riscv/include/arch/sbi.h | 111 | ||||
| -rw-r--r-- | arch/riscv/include/arch/tlb.h | 19 | ||||
| -rw-r--r-- | arch/riscv/include/arch/trap.h | 94 | ||||
| -rw-r--r-- | arch/riscv/include/arch/trapframe.h | 140 | ||||
| -rw-r--r-- | arch/riscv/include/asm/csr.h | 37 | ||||
| -rw-r--r-- | arch/riscv/include/asm/page.h | 62 | ||||
| -rw-r--r-- | arch/riscv/include/asm/pgtable.h | 55 | ||||
| -rw-r--r-- | arch/riscv/include/asm/sections.h | 50 |
16 files changed, 0 insertions, 1105 deletions
diff --git a/arch/riscv/include/arch/config.h b/arch/riscv/include/arch/config.h deleted file mode 100644 index 8ae0502..0000000 --- a/arch/riscv/include/arch/config.h +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -/* - * RISC-V Architecture Configuration - * - * These constants define the architecture-specific memory layout. - * Each arch/ implementation must provide this header with the same symbols. - * - * KASLR: At boot, kaslr_init() randomises g_direct_map_base and - * g_vmemmap_base. All MI code must read these runtime variables - * (via pa_to_va / vmm helpers) rather than the static defaults. - */ - -#include <lume/types.h> - -namespace arch { - -/* ================================================================ - * Default (compile-time) virtual addresses - * - * SV39 gives a 512GB virtual address space. - * Higher-half layout (defaults before KASLR): - * - * 0xFFFFFFC0_00000000 (256) Direct map (PA+offset) - * 0xFFFFFFD0_00000000 (320) Vmemmap (Page array) - * - * The 64GB gap between them is the KASLR slide range. - * ================================================================ */ -inline constexpr uint64 kDirectMapBaseDefault = 0xFFFFFFC000000000ULL; -inline constexpr uint64 kVmemmapBaseDefault = 0xFFFFFFD000000000ULL; - -/* Physical memory base (where RAM starts on RISC-V virt platform) */ -inline constexpr uint64 kPhysBase = 0x80000000ULL; - -/* Kernel physical load address (= PHYS_BASE in linker script). - * Everything in [kPhysBase, kPhysStart) is firmware territory (PMP-protected). - * Analogous to Linux's CONFIG_PHYSICAL_START. */ -inline constexpr uint64 kPhysStart = 0x80200000ULL; - -/* ================================================================ - * Runtime (post-KASLR) virtual addresses - * - * These start equal to the defaults above. If CONFIG_KASLR is - * enabled, kaslr_init() adds a random, 1GB-aligned offset - * to each, sliding both regions upward in VA space. - * ================================================================ */ -extern uint64 g_direct_map_base; -extern uint64 g_vmemmap_base; - -/* ================================================================ - * KASLR Layout Structure (Phase A: Unified KASLR State) - * - * This struct holds all KASLR results: the random seed, derived - * hash, selected slot, and the randomised virtual address bases. - * It serves as the single source of truth for all KASLR decisions - * and is filled once during boot and read-only thereafter. - * ================================================================ */ - -enum class KaslrSeedSource : uint8 { - kFdt = 0, /* Loaded from FDT /random node */ - kHardware = 1, /* From hardware RNG (e.g., RDRAND) */ - kCycle = 2, /* Fallback: CPU cycle counter */ -}; - -struct KaslrLayout { - /* Seed and provenance */ - uint64 seed; /* 64-bit random seed value */ - uint64 seed_hash; /* Non-plaintext derived hash (splitmix64) */ - KaslrSeedSource source; /* Seed provenance (fdt/hw/cycle) */ - - /* Randomisation parameters */ - uint64 slot; /* Slot index: [0, 63] */ - uint64 slide_bytes; /* Byte offset: slot * 1GB */ - - /* Build-time policy */ - uint32 policy_id; /* CONFIG_KASLR_POLICY_ID at build time */ - - /* Randomised base addresses (post-KASLR) */ - uint64 direct_map_base; /* Direct map VA (kDirectMapBaseDefault + slide) */ - uint64 vmemmap_base; /* Vmemmap VA (kVmemmapBaseDefault + slide) */ - - /* Validation flags (for debug logging) */ - bool canonical_ok; /* All VA ranges passed canonical check */ - bool overlap_ok; /* No overlaps detected between regions */ -}; - -/* ================================================================ - * KASLR entry point - * - * Must be called AFTER random_early_init() and BEFORE vmm_init(). - * Fills g_kaslr_layout with randomised bases and self-check results. - * When CONFIG_KASLR is disabled this is a no-op. - * ================================================================ */ -extern KaslrLayout g_kaslr_layout; - -void kaslr_init(); - -/* Helper to query the KASLR layout safely */ -static inline const KaslrLayout& kaslr_layout_get() { - return g_kaslr_layout; -} - -} // namespace arch diff --git a/arch/riscv/include/arch/context.h b/arch/riscv/include/arch/context.h deleted file mode 100644 index 3d935fa..0000000 --- a/arch/riscv/include/arch/context.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -/* - * Context Switch Structure (RISC-V 64) - * - * Holds only callee-saved registers for voluntary (non-preemptive) - * context switches between kernel threads / tasks. - * - * Used by: arch::context_switch() in swtch.S - * Reference: docs/specs/arch_abstraction.md §3.1 - */ - -#include <lume/types.h> - -namespace arch { - -struct Context { - uint64 ra; // 0: Return address - uint64 sp; // 8: Stack pointer - uint64 s[12]; // 16: s0-s11 (callee-saved registers) -}; - -static_assert(sizeof(Context) == 112); - -// Assembly-implemented context switch. -// Saves current CPU registers to old_ctx, loads next_ctx into CPU. -// Defined in arch/riscv/trap/swtch.S -extern "C" void context_switch(Context* old_ctx, Context* next_ctx); - -} // namespace arch diff --git a/arch/riscv/include/arch/cpu.h b/arch/riscv/include/arch/cpu.h deleted file mode 100644 index 8c573ec..0000000 --- a/arch/riscv/include/arch/cpu.h +++ /dev/null @@ -1,95 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -/* - * CPU Control & Status Primitives (RISC-V 64) - * - * Provides interrupt enable/disable, CPU ID, timer, and halt. - * All functions are static inline — zero call overhead. - * - * Precondition: tp register must be initialized with CPU ID - * by entry.S before any of these functions are called. - * - * Reference: docs/specs/arch_abstraction.md §4.1 - */ - -#include <lume/types.h> - -/* RISC-V sstatus register bit definitions */ -#define SSTATUS_SIE (1UL << 1) /* Supervisor Interrupt Enable */ -#define SSTATUS_SPIE (1UL << 5) /* Supervisor Previous Interrupt Enable */ -#define SSTATUS_SPP (1UL << 8) /* Supervisor Previous Privilege (0=U, 1=S) */ - -/* RISC-V sie register bit definitions */ -#define SIE_SSIE (1UL << 1) /* Supervisor Software Interrupt Enable */ -#define SIE_STIE (1UL << 5) /* Supervisor Timer Interrupt Enable */ -#define SIE_SEIE (1UL << 9) /* Supervisor External Interrupt Enable */ - -namespace arch::cpu { - -// Get current CPU ID (from tp register, set by entry.S) -static inline uint64 id() { - uint64 val; - __asm__ volatile("mv %0, tp" : "=r"(val)); - return val; -} - -// Enable interrupts (set sstatus.SIE = 1) -static inline void intr_on() { - __asm__ volatile("csrs sstatus, %0" :: "r"(SSTATUS_SIE)); -} - -// Disable interrupts (clear sstatus.SIE = 0) -static inline void intr_off() { - __asm__ volatile("csrc sstatus, %0" :: "r"(SSTATUS_SIE)); -} - -// Check if interrupts are currently enabled -static inline bool intr_enabled() { - uint64 sstatus; - __asm__ volatile("csrr %0, sstatus" : "=r"(sstatus)); - return (sstatus & SSTATUS_SIE) != 0; -} - -// Halt CPU until next interrupt (wfi instruction) -static inline void halt_until_interrupt() { - __asm__ volatile("wfi"); -} - -// Read hardware monotonic timer (rdtime instruction) -// Returns ticks since boot; frequency from FDT timebase-frequency. -static inline uint64 read_time() { - uint64 val; - __asm__ volatile("rdtime %0" : "=r"(val)); - return val; -} - -// Enable timer interrupt in sie (sie.STIE = 1) -static inline void timer_intr_on() { - __asm__ volatile("csrs sie, %0" :: "r"(SIE_STIE)); -} - -// Disable timer interrupt in sie (sie.STIE = 0) -static inline void timer_intr_off() { - __asm__ volatile("csrc sie, %0" :: "r"(SIE_STIE)); -} - -// Enable software interrupt in sie (sie.SSIE = 1) — needed for IPI -static inline void software_intr_on() { - __asm__ volatile("csrs sie, %0" :: "r"(SIE_SSIE)); -} - -// Enable external interrupt in sie (sie.SEIE = 1) — needed for PLIC (UART, etc.) -static inline void external_intr_on() { - __asm__ volatile("csrs sie, %0" :: "r"(SIE_SEIE)); -} - -// Clear S-mode software interrupt pending bit (sip.SSIP = 0) -// Must be called in the IPI handler to acknowledge the interrupt. -static inline void clear_sip_ssip() { - __asm__ volatile("csrc sip, %0" :: "r"(1UL << 1)); -} - -} // namespace arch::cpu diff --git a/arch/riscv/include/arch/extable.h b/arch/riscv/include/arch/extable.h deleted file mode 100644 index eb2daac..0000000 --- a/arch/riscv/include/arch/extable.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -#ifndef __ASSEMBLER__ - -#include <lume/types.h> - -/* - * Exception table entry. - * insn: offset from this struct to the faulting instruction. - * fixup: offset from this struct to the fixup code. - * - * Using relative offsets avoids absolute relocations and saves space. - */ -struct ExceptionTableEntry { - int32 insn; - int32 fixup; -}; - -/* Search the exception table for a given PC. Returns fixup address, or 0 if not found. */ -uint64 search_extable(uint64 pc); - -/* Sorts the exception table at boot for binary search O(log N). */ -void extable_init(); - -#endif /* __ASSEMBLER__ */ - -/* - * EXTABLE macro for assembly usage. - * Appends an entry to the .extable section. - */ -#ifdef __ASSEMBLER__ - -#define EXTABLE(insn, fixup) \ - .pushsection .extable, "a"; \ - .balign 4; \ - .long insn - .; \ - .long fixup - .; \ - .popsection - -#else /* !__ASSEMBLER__ */ - -/* Stringified macro for inline assembly */ -#define _ASM_EXTABLE(insn, fixup) \ - ".pushsection .extable, \"a\"\n" \ - ".balign 4\n" \ - ".long " #insn " - .\n" \ - ".long " #fixup " - .\n" \ - ".popsection\n" - -#define EXTABLE(insn, fixup) _ASM_EXTABLE(insn, fixup) - -#endif /* __ASSEMBLER__ */ diff --git a/arch/riscv/include/arch/fpstate.h b/arch/riscv/include/arch/fpstate.h deleted file mode 100644 index 4b42a22..0000000 --- a/arch/riscv/include/arch/fpstate.h +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -/* - * FPU State — Floating-Point Register Context - * - * Pre-reserved structure for RISC-V F/D extension floating-point state. - * MUST be allocated in every TaskControlBlock so that future FPU - * save/restore logic has a stable destination without restructuring TCB. - * - * RISC-V F/D extension state: - * - 32 FP registers (f0-f31), each 64 bits for D extension - * - fcsr (Floating-point Control and Status Register) - * - * sstatus.FS field management: - * - FS=0 (Off): FPU disabled, any FP instruction traps - * - FS=1 (Initial): FPU enabled, registers are initial state - * - FS=2 (Clean): FPU enabled, registers not modified since last save - * - FS=3 (Dirty): FPU enabled, registers modified (need save) - * - * Current status: Structure defined, save/restore NOT implemented. - * When implemented, trap_dispatch and swtch.S will use lazy - * save/restore based on sstatus.FS dirty tracking. - * - * Reference: RISC-V ISA Manual §3.1.6.5 (FS field) - */ - -#include <lume/types.h> - -namespace arch { - -struct FpState { - uint64 f[32]; // f0-f31 (64-bit each for D extension) - uint32 fcsr; // Floating-point CSR (frm + fflags) - uint32 _pad; // Alignment padding -}; - -static_assert(sizeof(FpState) == 32 * 8 + 8, "FpState must be 264 bytes"); - -/* - * sstatus.FS field constants - */ -inline constexpr uint64 kSstatusFS_Off = 0ULL << 13; -inline constexpr uint64 kSstatusFS_Initial = 1ULL << 13; -inline constexpr uint64 kSstatusFS_Clean = 2ULL << 13; -inline constexpr uint64 kSstatusFS_Dirty = 3ULL << 13; -inline constexpr uint64 kSstatusFS_Mask = 3ULL << 13; - -/* - * Check if sstatus indicates FPU state is dirty (needs save). - */ -inline bool fpu_state_dirty(uint64 sstatus) { - return (sstatus & kSstatusFS_Mask) == kSstatusFS_Dirty; -} - -/* - * Check if FPU is enabled (FS != Off). - */ -inline bool fpu_enabled(uint64 sstatus) { - return (sstatus & kSstatusFS_Mask) != kSstatusFS_Off; -} - -} // namespace arch - -/* Assembly routines for FPU register save/restore (fpu.S) */ -extern "C" void fpu_save(arch::FpState* state); -extern "C" void fpu_restore(arch::FpState* state); - -namespace arch { - -/* - * Read sstatus.FS field (current FPU state) - */ -inline uint64 fpu_get_fs() { - uint64 sstatus; - __asm__ volatile("csrr %0, sstatus" : "=r"(sstatus)); - return sstatus & kSstatusFS_Mask; -} - -/* - * Set sstatus.FS field. - * @fs: one of kSstatusFS_Off, kSstatusFS_Initial, kSstatusFS_Clean, kSstatusFS_Dirty - */ -inline void fpu_set_fs(uint64 fs) { - __asm__ volatile( - "csrc sstatus, %0\n" - "csrs sstatus, %1\n" - :: "r"(kSstatusFS_Mask), "r"(fs) - ); -} - -} // namespace arch diff --git a/arch/riscv/include/arch/mmu.h b/arch/riscv/include/arch/mmu.h deleted file mode 100644 index f4c9b26..0000000 --- a/arch/riscv/include/arch/mmu.h +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -/* - * MMU Hardware Primitives (RISC-V SV39) - * - * Page table switching, TLB flushing, and fault address reading. - * All functions are static inline — zero call overhead. - * - * Note on SMP: flush_tlb_page() only flushes the LOCAL CPU's TLB. - * Cross-CPU TLB shootdown via IPI is not yet implemented. - * - * Reference: docs/specs/arch_abstraction.md §4.2 - */ - -#include <lume/types.h> - -/* SATP register: mode field for SV39 */ -#define SATP_SV39 (8UL << 60) - -/* SATP PPN mask (bits 43:0) */ -#define SATP_PPN_MASK ((1UL << 44) - 1) - -namespace arch::mmu { - -// Read the faulting virtual address from stval (set by HW on page fault) -static inline uint64 get_fault_address() { - uint64 val; - __asm__ volatile("csrr %0, stval" : "=r"(val)); - return val; -} - -// Switch the top-level page table. -// Takes a PHYSICAL ADDRESS (not PPN); internally shifts right by 12 -// and combines with SV39 mode bits before writing to satp. -static inline void set_page_table(uint64 physical_pgdir_addr) { - uint64 ppn = physical_pgdir_addr >> 12; - uint64 satp_val = SATP_SV39 | ppn; - __asm__ volatile("csrw satp, %0" :: "r"(satp_val)); - // Note: caller should call flush_tlb_all() after this -} - -// Read the current page table physical address. -// Extracts PPN from satp and converts back to physical address. -static inline uint64 get_page_table() { - uint64 satp_val; - __asm__ volatile("csrr %0, satp" : "=r"(satp_val)); - return (satp_val & SATP_PPN_MASK) << 12; -} - -// Read the raw satp CSR value (mode + PPN). -// Used when the caller needs the exact register value (e.g. for TrapFrame metadata). -static inline uint64 read_satp() { - uint64 val; - __asm__ volatile("csrr %0, satp" : "=r"(val)); - return val; -} - -// Flush the entire TLB (all ASIDs, all addresses) -static inline void flush_tlb_all() { - __asm__ volatile("sfence.vma zero, zero" ::: "memory"); -} - -// Flush a single TLB entry for the given virtual address -static inline void flush_tlb_page(uint64 vaddr) { - __asm__ volatile("sfence.vma %0, zero" :: "r"(vaddr) : "memory"); -} - -// Flush the instruction cache. -// Required after loading executable code into memory (e.g. ELF loading). -// sfence.vma only flushes the TLB; fence.i is needed for the I-cache. -static inline void flush_icache() { - __asm__ volatile("fence.i" ::: "memory"); -} - -} // namespace arch::mmu diff --git a/arch/riscv/include/arch/pmap.h b/arch/riscv/include/arch/pmap.h deleted file mode 100644 index 0b43b9e..0000000 --- a/arch/riscv/include/arch/pmap.h +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -/* - * pmap — SV39 page table interface (MD layer) - * - * Namespace functions, zero runtime overhead. - * Implementation: arch/riscv/mm/pmap.cc - * - * Reference: docs/specs/vmm.md §3.2 - */ - -#include <lume/types.h> - -namespace pmap { - -/* PTE permission bits */ -inline constexpr uint64 PTE_V = 1ULL << 0; -inline constexpr uint64 PTE_R = 1ULL << 1; -inline constexpr uint64 PTE_W = 1ULL << 2; -inline constexpr uint64 PTE_X = 1ULL << 3; -inline constexpr uint64 PTE_U = 1ULL << 4; -inline constexpr uint64 PTE_G = 1ULL << 5; -inline constexpr uint64 PTE_A = 1ULL << 6; -inline constexpr uint64 PTE_D = 1ULL << 7; -inline constexpr uint64 PTE_COW = 1ULL << 8; /* Custom RSW bit for Copy-On-Write */ - -uint64 create(); -void destroy(uint64 root_pa); -int map(uint64 root_pa, uint64 va, uint64 pa, uint64 perm); -int map_2mb(uint64 root_pa, uint64 va, uint64 pa, uint64 perm); -void unmap(uint64 root_pa, uint64 va); -int protect(uint64 root_pa, uint64 va, uint64 perm); -int protect_range(uint64 root_pa, uint64 start, uint64 end, uint64 perm); -bool lookup(uint64 root_pa, uint64 va, uint64* pa_out); -uint64 lookup_pte(uint64 root_pa, uint64 va); -bool is_cow(uint64 root_pa, uint64 va); -int make_cow(uint64 root_pa, uint64 va); -void activate(uint64 root_pa); - -/* - * Translate MI-layer VM_* permission flags to hardware PTE bits. - * Called by vma.cc when faulting in a page. - */ -uint64 vm_perm_to_pte(uint64 vm_perm); - -} // namespace pmap diff --git a/arch/riscv/include/arch/random.h b/arch/riscv/include/arch/random.h deleted file mode 100644 index 8c8c051..0000000 --- a/arch/riscv/include/arch/random.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -#include <lume/types.h> - -namespace arch { - -/* - * Get a random 64-bit value from the hardware TRNG. - * Returns true if supported and successful, false otherwise. - */ -bool get_hw_random(uint64& value); - -/* - * Get the current high-resolution hardware cycle counter. - * Used as an entropy fallback (Jitter/Timer). - */ -inline uint64 get_cycles() -{ - uint64 cycles; - __asm__ volatile("rdcycle %0" : "=r"(cycles)); - return cycles; -} - -} // namespace arch diff --git a/arch/riscv/include/arch/sbi.h b/arch/riscv/include/arch/sbi.h deleted file mode 100644 index 80a6d7c..0000000 --- a/arch/riscv/include/arch/sbi.h +++ /dev/null @@ -1,111 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -/* - * sbi.h — RISC-V Supervisor Binary Interface (SBI) wrappers - * - * Provides inline ecall wrappers for SBI calls from S-mode. - * Uses the SBI v1.0+ extension-based calling convention. - * - * Reference: RISC-V SBI Specification v2.0 - */ - -#include <lume/types.h> - -namespace arch::sbi { - -struct sbiret { - long error; - long value; -}; - -/* SBI error codes */ -inline constexpr long SBI_SUCCESS = 0; -inline constexpr long SBI_ERR_NOT_SUPPORTED = -2; - -/* Extension IDs */ -inline constexpr int SBI_EXT_TIME = 0x54494D45; /* "TIME" */ -inline constexpr int SBI_EXT_IPI = 0x735049; /* "sPI" */ -inline constexpr int SBI_EXT_RFENCE = 0x52464E43; /* "RFNC" */ -inline constexpr int SBI_EXT_HSM = 0x48534D; /* "HSM" */ - -static inline sbiret sbi_ecall(int ext, int fid, uint64 arg0 = 0, - uint64 arg1 = 0, uint64 arg2 = 0, - uint64 arg3 = 0, uint64 arg4 = 0, - uint64 arg5 = 0) { - sbiret ret; - register uint64 a0 asm("a0") = arg0; - register uint64 a1 asm("a1") = arg1; - register uint64 a2 asm("a2") = arg2; - register uint64 a3 asm("a3") = arg3; - register uint64 a4 asm("a4") = arg4; - register uint64 a5 asm("a5") = arg5; - register uint64 a6 asm("a6") = fid; - register uint64 a7 asm("a7") = ext; - __asm__ volatile("ecall" - : "+r"(a0), "+r"(a1) - : "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(a6), "r"(a7) - : "memory"); - ret.error = static_cast<long>(a0); - ret.value = static_cast<long>(a1); - return ret; -} - -/* ---- Timer Extension (EID 0x54494D45) ---- */ - -static inline void set_timer(uint64 stime_value) { - sbi_ecall(SBI_EXT_TIME, 0, stime_value); -} - -/* ---- IPI Extension (EID 0x735049) ---- */ - -/* - * sbi_send_ipi — Send S-mode software interrupt to target harts - * - * @hart_mask: bitmask of target harts (relative to hart_mask_base) - * @hart_mask_base: base hart ID for the mask (0 = harts 0-63) - */ -static inline sbiret sbi_send_ipi(uint64 hart_mask, - uint64 hart_mask_base = 0) { - return sbi_ecall(SBI_EXT_IPI, 0, hart_mask, hart_mask_base); -} - -/* ---- Remote Fence Extension (EID 0x52464E43) ---- */ - -/* - * sbi_remote_sfence_vma — Execute SFENCE.VMA on target harts - * - * @hart_mask/base: target harts - * @start_addr: start of VA range to invalidate - * @size: size of range (use ~0UL for full flush) - */ -static inline sbiret sbi_remote_sfence_vma(uint64 hart_mask, - uint64 hart_mask_base, - uint64 start_addr, - uint64 size) { - return sbi_ecall(SBI_EXT_RFENCE, 1, - hart_mask, hart_mask_base, - start_addr, size); -} - -/* ---- HSM Extension (EID 0x48534D) ---- */ - -/* - * sbi_hart_start — Start (wake) a hart that is in STOPPED state - * - * @hartid: target hart ID to start - * @start_addr: PHYSICAL address where the hart should begin execution - * @opaque: passed in a1 register to the hart (e.g. FDT pointer) - * - * OpenSBI v1.0+ parks non-boot harts; they must be explicitly started. - */ -static inline sbiret sbi_hart_start(uint64 hartid, - uint64 start_addr, - uint64 opaque) { - return sbi_ecall(SBI_EXT_HSM, 0, hartid, start_addr, opaque); -} - -} // namespace arch::sbi - diff --git a/arch/riscv/include/arch/tlb.h b/arch/riscv/include/arch/tlb.h deleted file mode 100644 index 46c6b97..0000000 --- a/arch/riscv/include/arch/tlb.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -#include <lume/types.h> - -namespace arch::tlb { - -/* - * Perform a cross-CPU TLB flush (shootdown). - * - * @param cpu_mask: Bitmask of CPUs to target. - * @param start: Start virtual address, or 0 for full address space. - * @param size: Size in bytes, or ~0ULL for full address space. - */ -void flush_remote(uint64 cpu_mask, uint64 start, uint64 size); - -} // namespace arch::tlb diff --git a/arch/riscv/include/arch/trap.h b/arch/riscv/include/arch/trap.h deleted file mode 100644 index 8e55250..0000000 --- a/arch/riscv/include/arch/trap.h +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -/* - * Trap Vector Control Primitives (RISC-V 64) - * - * Set/read the S-mode trap vector (stvec), trap cause (scause), - * and trap value (stval) registers. - * - * Reference: docs/specs/arch_abstraction.md §4.3 - */ - -#include <lume/types.h> - -/* scause interrupt bit (bit 63): 1 = interrupt, 0 = exception */ -#define SCAUSE_INTERRUPT (1UL << 63) - -/* Exception cause codes (scause with bit 63 = 0) */ -#define EXC_INST_MISALIGNED 0 -#define EXC_INST_ACCESS_FAULT 1 -#define EXC_ILLEGAL_INST 2 -#define EXC_BREAKPOINT 3 -#define EXC_LOAD_MISALIGNED 4 -#define EXC_LOAD_ACCESS_FAULT 5 -#define EXC_STORE_MISALIGNED 6 -#define EXC_STORE_ACCESS_FAULT 7 -#define EXC_ECALL_FROM_U 8 -#define EXC_ECALL_FROM_S 9 -#define EXC_INST_PAGE_FAULT 12 -#define EXC_LOAD_PAGE_FAULT 13 -#define EXC_STORE_PAGE_FAULT 15 - -/* Interrupt cause codes (scause with bit 63 = 1, lower bits) */ -#define IRQ_S_SOFTWARE 1 -#define IRQ_S_TIMER 5 -#define IRQ_S_EXTERNAL 9 - -namespace arch::trap { - -// Set S-mode trap vector base address (writes stvec). -// Mode: Direct (all traps go to handler_addr). -static inline void set_vector(uint64 handler_addr) { - // Lowest 2 bits of stvec = mode. 0 = Direct. - __asm__ volatile("csrw stvec, %0" :: "r"(handler_addr)); -} - -// Read current trap vector base address -static inline uint64 get_vector() { - uint64 val; - __asm__ volatile("csrr %0, stvec" : "=r"(val)); - return val; -} - -// Read trap cause register (scause) -// Bit 63: 1=interrupt, 0=exception. Lower bits: cause code. -static inline uint64 get_cause() { - uint64 val; - __asm__ volatile("csrr %0, scause" : "=r"(val)); - return val; -} - -// Read trap value register (stval) -// Contains faulting address (page faults) or faulting instruction. -static inline uint64 get_value() { - uint64 val; - __asm__ volatile("csrr %0, stval" : "=r"(val)); - return val; -} - -// Check if a scause value represents an interrupt (vs exception) -static inline bool is_interrupt(uint64 cause) { - return (cause & SCAUSE_INTERRUPT) != 0; -} - -// Extract the cause code (strip the interrupt bit) -static inline uint64 cause_code(uint64 cause) { - return cause & ~SCAUSE_INTERRUPT; -} - -// Enable Supervisor User Memory access (set SUM bit in sstatus). -// When SUM=1, S-mode can read/write pages marked PTE_U. -// This is needed for syscall handlers to access user-space buffers. -static inline void enable_sum() { - __asm__ volatile("csrs sstatus, %0" :: "r"(1UL << 18)); -} - -// Disable Supervisor User Memory access (clear SUM bit in sstatus). -static inline void disable_sum() { - __asm__ volatile("csrc sstatus, %0" :: "r"(1UL << 18)); -} - -} // namespace arch::trap diff --git a/arch/riscv/include/arch/trapframe.h b/arch/riscv/include/arch/trapframe.h deleted file mode 100644 index b198646..0000000 --- a/arch/riscv/include/arch/trapframe.h +++ /dev/null @@ -1,140 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#pragma once - -/* - * Trap Frame Structure (RISC-V 64) - * - * Saved/restored by the assembly trap_vector on every interrupt, - * exception, or system call. Contains the full CPU snapshot needed - * to resume execution after trap handling. - * - * Layout must match the assembly offsets in trap_vector.S exactly. - * Reference: docs/specs/arch_abstraction.md §3.2 - */ - -/* - * TrapFrame field offsets for use in assembly. - * These must be kept in sync with the struct layout below. - * Placed before any C++ code so assembly can #include this file. - */ -#define TF_KERNEL_SATP 0 -#define TF_KERNEL_SP 8 -#define TF_KERNEL_TRAP 16 -#define TF_KERNEL_CPUID 24 -#define TF_EPC 32 -#define TF_SSTATUS 40 -#define TF_RA 48 -#define TF_SP 56 -#define TF_GP 64 -#define TF_TP 72 -#define TF_T0 80 -#define TF_T1 88 -#define TF_T2 96 -#define TF_T3 104 -#define TF_T4 112 -#define TF_T5 120 -#define TF_T6 128 -#define TF_S0 136 -#define TF_S1 144 -#define TF_S2 152 -#define TF_S3 160 -#define TF_S4 168 -#define TF_S5 176 -#define TF_S6 184 -#define TF_S7 192 -#define TF_S8 200 -#define TF_S9 208 -#define TF_S10 216 -#define TF_S11 224 -#define TF_A0 232 -#define TF_A1 240 -#define TF_A2 248 -#define TF_A3 256 -#define TF_A4 264 -#define TF_A5 272 -#define TF_A6 280 -#define TF_A7 288 -#define TF_SIZE 296 - -#ifndef __ASSEMBLER__ - -#include <lume/types.h> -#include <arch/cpu.h> - -namespace arch { - -struct TrapFrame { - /* ---- Kernel metadata (offset 0-39) ---- */ - uint64 kernel_satp; // 0: Kernel page table (written to satp on trap entry) - uint64 kernel_sp; // 8: Top of kernel stack for this task - uint64 kernel_trap; // 16: Address of C++ trap_handler function - uint64 kernel_cpu_id; // 24: CPU ID (loaded into tp on trap entry) - uint64 epc; // 32: Interrupted instruction address (sepc) - - /* ---- CSR backup (offset 40-47) ---- */ - uint64 sstatus; // 40: Privilege status (SPP, SPIE bits) - - /* ---- General-purpose registers (offset 48-295) ---- */ - uint64 ra; // 48: x1 - Return address - uint64 sp; // 56: x2 - User stack pointer - uint64 gp; // 64: x3 - Global pointer - uint64 tp; // 72: x4 - Thread pointer - uint64 t[7]; // 80: x5-x7, x28-x31 (t0-t6, caller-saved temporaries) - uint64 s[12]; // 136: x8-x9, x18-x27 (s0-s11, callee-saved) - uint64 a[8]; // 232: x10-x17 (a0-a7, arguments / syscall params) -}; - -static_assert(sizeof(TrapFrame) == 296, "TrapFrame size mismatch with assembly offsets"); - -} // namespace arch - -/* Forward declaration — defined in trap_md.cc. - * Must be after TrapFrame definition. */ -extern "C" [[noreturn]] void trap_dispatch(arch::TrapFrame*); - -namespace arch { - -/* - * trapframe_init_user — prepare a TrapFrame for returning to user mode. - * - * Sets arch-specific sstatus: - * SPP = 0 (return to U-mode on sret) - * SPIE = 1 (enable interrupts in U-mode) - * FS = Initial (allow FP instructions) - * - * Called from MI exec.cc instead of setting sstatus directly. - */ -static inline void trapframe_init_user(TrapFrame* tf, uint64 entry, uint64 sp) -{ - /* Clear all registers */ - for (auto& t : tf->t) { t = 0; } - for (auto& s : tf->s) { s = 0; } - for (auto& a : tf->a) { a = 0; } - tf->ra = 0; - tf->gp = 0; - tf->tp = 0; - - tf->epc = entry; - tf->sp = sp; - - /* sstatus: SPP=0 (U-mode), SPIE=1 (interrupts), FS=Initial (FP ok) */ - constexpr uint64 kSPIE = (1ULL << 5); - constexpr uint64 kFS_Initial = (1ULL << 13); - tf->sstatus = kSPIE | kFS_Initial; - - /* Kernel metadata used by trap_vector.S on every trap from U-mode. - * These are RISC-V specific — trap_vector reads them from the - * TrapFrame to switch to kernel context. */ - uint64 satp; - asm volatile("csrr %0, satp" : "=r"(satp)); - tf->kernel_satp = satp; - tf->kernel_sp = reinterpret_cast<uint64>(tf); - tf->kernel_trap = reinterpret_cast<uint64>(&trap_dispatch); - tf->kernel_cpu_id = cpu::id(); -} - -} // namespace arch - -#endif /* __ASSEMBLER__ */ diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h deleted file mode 100644 index 42f1eb4..0000000 --- a/arch/riscv/include/asm/csr.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#ifndef _ASM_RISCV_CSR_H -#define _ASM_RISCV_CSR_H - -/* - * RISC-V CSR (Control & Status Register) definitions used by the early - * boot / MMU-switch path. - * - * LumeOS-native subset of Linux arch/riscv/include/asm/csr.h. Only the - * symbols head.S and mm/init.cc actually reference are defined — adding - * the rest is straightforward when new code needs them, and skipping the - * Linux ALTERNATIVE / vendor-extension machinery keeps the cascade flat. - */ - -/* SATP (Supervisor Address Translation and Protection) layout — RV64 */ -#define SATP_PPN_MASK 0x00000FFFFFFFFFFFUL /* bits [43:0] = root PPN */ -#define SATP_ASID_SHIFT 44 -#define SATP_MODE_SHIFT 60 - -/* SATP MODE encodings (RV64) */ -#define SATP_MODE_BARE (0UL << SATP_MODE_SHIFT) -#define SATP_MODE_SV39 (8UL << SATP_MODE_SHIFT) -#define SATP_MODE_SV48 (9UL << SATP_MODE_SHIFT) - -/* Compose a SATP value from a page-table physical address. - * Result: MODE | (root_ppn) where root_ppn = pgd_pa >> PAGE_SHIFT. */ -#define MAKE_SATP(mode, pgd_pa) ((mode) | (((pgd_pa) >> 12) & SATP_PPN_MASK)) - -/* SSTATUS bits we touch at boot — disable FP / vector at entry so that an - * accidental FP / V instruction in early code traps cleanly rather than - * silently using dirty state from before reset. */ -#define SR_FS_OFF (0UL << 13) -#define SR_VS_OFF (0UL << 9) - -#endif /* _ASM_RISCV_CSR_H */ diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h deleted file mode 100644 index 7b9f155..0000000 --- a/arch/riscv/include/asm/page.h +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#ifndef _ASM_RISCV_PAGE_H -#define _ASM_RISCV_PAGE_H - -/* - * RISC-V page / virtual-memory layout constants. - * - * Mirrors the subset of Linux arch/riscv/include/asm/page.h that LumeOS's - * early boot path needs: - * - PAGE_SIZE / PAGE_SHIFT / PAGE_MASK - * - PAGE_OFFSET (start of the higher-half direct map) - * - KERNEL_LINK_ADDR (link-time VA of _start) - * - SV39 PTE flag bits - * - PTRS_PER_PGD (512 for SV39) - * - * Values match Linux RISC-V SV39 defaults so that struct kernel_mapping - * (filled by setup_vm in arch/riscv/mm/init.cc) carries the same numeric - * relations Linux's mm/init.c maintains. - */ - -#define PAGE_SHIFT 12 -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE - 1)) - -/* Higher-half base of the kernel direct map. Bottom of the SV39 supervisor - * address space minus the unmapped guard region. Identical to Linux's - * CONFIG_PAGE_OFFSET default on RV64. */ -#define PAGE_OFFSET 0xFFFFFFC000000000UL - -/* Where _start was linked. OpenSBI hands control to PHYS_BASE; the kernel - * runs at KERNEL_LINK_ADDR after relocate_enable_mmu jumps to higher-half. */ -#define PHYS_BASE 0x80200000UL -#define KERNEL_LINK_ADDR 0xFFFFFFC080200000UL - -/* SATP mode field — SV39 = 8, shifted to bits [63:60]. */ -#define SATP_MODE_SV39 (8UL << 60) - -#define PTRS_PER_PGD 512 - -/* 1 GB superpage size — entry.S used to build the early page table with - * these; setup_vm in arch/riscv/mm/init.cc now does the same. */ -#define PGDIR_SHIFT 30 -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE - 1)) - -/* SV39 PTE flag bits (one byte). */ -#define _PAGE_PRESENT (1UL << 0) /* aka VALID — historic Linux name */ -#define _PAGE_READ (1UL << 1) -#define _PAGE_WRITE (1UL << 2) -#define _PAGE_EXEC (1UL << 3) -#define _PAGE_USER (1UL << 4) -#define _PAGE_GLOBAL (1UL << 5) -#define _PAGE_ACCESSED (1UL << 6) -#define _PAGE_DIRTY (1UL << 7) - -#define PAGE_KERNEL_EXEC \ - (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC | \ - _PAGE_ACCESSED | _PAGE_DIRTY) - -#endif /* _ASM_RISCV_PAGE_H */ diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h deleted file mode 100644 index 28fc4c5..0000000 --- a/arch/riscv/include/asm/pgtable.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#ifndef _ASM_RISCV_PGTABLE_H -#define _ASM_RISCV_PGTABLE_H - -/* - * Early page-table construction API used by arch/riscv/mm/init.cc::setup_vm. - * - * Mirrors the create_pgd_mapping interface from Linux's - * arch/riscv/mm/init.c — same name, same semantics: - * - * create_pgd_mapping(pgdir, va, pa, sz, prot) - * - * pgdir : root of the page table to populate - * va : virtual address to map - * pa : physical address to map to - * sz : mapping size — must be a supported leaf size (PAGE_SIZE, - * 2 MiB megapage, or 1 GiB gigapage) - * prot : PTE flag bits (PAGE_KERNEL_EXEC etc., from <asm/page.h>) - * - * The boot-time variant in this file only supports gigapage (1 GiB) - * mappings — that is all setup_vm needs for the early_pg_dir / trampoline_pg_dir - * built before the slab allocator exists. Finer-grained mappings come - * later via vmm_init(). - */ - -#include <lume/types.h> -#include <asm/page.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { unsigned long pgd; } pgd_t; - -/* Linker-provided early page-table storage (defined in lumeos.lds.S - * ARCH_BSS_EXTRA, lives in .bss so it's zero-initialized). Allocating - * them in the linker script — not in C — mirrors Linux and keeps the - * symbols visible from head.S without a forward C decl mismatch. */ -extern pgd_t early_pg_dir[PTRS_PER_PGD]; -extern pgd_t trampoline_pg_dir[PTRS_PER_PGD]; -extern pgd_t fixmap_pg_dir[PTRS_PER_PGD]; - -/* Install a single PGD entry mapping `va` → `pa` with size `sz` and PTE - * flags `prot`. Only sz == PGDIR_SIZE (1 GiB) is supported in this early - * variant — vmm_init() takes over with create_pgd_mapping_pmd later. */ -void create_pgd_mapping(pgd_t *pgdir, unsigned long va, unsigned long pa, - unsigned long sz, unsigned long prot); - -#ifdef __cplusplus -} -#endif - -#endif /* _ASM_RISCV_PGTABLE_H */ diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h deleted file mode 100644 index 7067444..0000000 --- a/arch/riscv/include/asm/sections.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* Copyright (C) 2026 Richard Qin */ - -#ifndef _ASM_RISCV_SECTIONS_H -#define _ASM_RISCV_SECTIONS_H - -/* - * Linker-emitted symbols that bracket each section of the kernel image. - * - * The lumeos.lds.S linker script defines these as the start / end - * addresses of contiguous regions. Code that walks a section - * (relocate_kernel walks .rela.dyn, the C++ ctor loop walks - * .init_array, the VMM mapping code walks .text vs .rodata, ...) - * imports the pair via this header. - * - * Mirrors Linux arch/riscv/include/asm/sections.h / asm-generic/sections.h. - * Each name and pair is identical to Linux so that direct ports of mm/init.c - * relocate_kernel logic compile unchanged against LumeOS. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern char _start[]; -extern char _kernel_end[]; - -extern char _stext[]; -extern char _etext[]; -extern char _srodata[]; -extern char _erodata[]; -extern char _sdata[]; -extern char _edata[]; -extern char _sbss[]; -extern char _ebss[]; - -extern char __init_array_start[]; -extern char __init_array_end[]; - -/* .rela.dyn — array of Elf64_Rela entries emitted by the linker under - * `-shared -Bsymbolic`. relocate_kernel walks this range and patches - * each R_RISCV_RELATIVE slot. */ -extern char __rela_dyn_start[]; -extern char __rela_dyn_end[]; - -#ifdef __cplusplus -} -#endif - -#endif /* _ASM_RISCV_SECTIONS_H */ |
