RISC-V System Initialization
Relevant source files
Purpose and Scope
This document covers the RISC-V-specific system initialization procedures implemented in the axcpu library. It focuses on the bootstrap sequence for setting up CPU state and trap handling on RISC-V platforms during system startup.
For RISC-V context management structures and switching mechanisms, see RISC-V Context Management. For detailed trap handling implementation after initialization, see RISC-V Trap and Exception Handling. For initialization procedures on other architectures, see x86_64 System Initialization and AArch64 System Initialization.
System Initialization Overview
The RISC-V system initialization is implemented as a minimal bootstrap procedure that configures essential CPU state for trap handling. Unlike other architectures that may require complex descriptor table setup, RISC-V initialization focuses primarily on trap vector configuration.
flowchart TD subgraph subGraph1["External Dependencies"] ASM_MODULE["asm module"] TRAP_ASSEMBLY["trap.S"] end subgraph subGraph0["RISC-V System Bootstrap"] BOOT["System Boot"] INIT_TRAP["init_trap()"] VECTOR_BASE["trap_vector_base()"] WRITE_VECTOR["write_trap_vector_base()"] READY["CPU Ready for Operation"] end BOOT --> INIT_TRAP INIT_TRAP --> ASM_MODULE INIT_TRAP --> VECTOR_BASE INIT_TRAP --> WRITE_VECTOR VECTOR_BASE --> TRAP_ASSEMBLY VECTOR_BASE --> WRITE_VECTOR WRITE_VECTOR --> ASM_MODULE WRITE_VECTOR --> READY
RISC-V Initialization Flow
Sources: src/riscv/init.rs(L1 - L14)
Trap Vector Initialization
The core initialization function init_trap()
establishes the trap vector base address that the RISC-V CPU uses to locate exception handlers. This is a critical step that must be completed before the system can handle any interrupts or exceptions.
flowchart TD subgraph subGraph1["External Symbols"] TRAP_VECTOR["trap_vector_base()"] ASM_WRITE["asm::write_trap_vector_base()"] end subgraph subGraph0["init_trap() Implementation"] FUNC_START["init_trap()"] GET_ADDR["Get trap_vector_base address"] CAST_ADDR["Cast to usize"] WRITE_CSR["write_trap_vector_base()"] COMPLETE["Initialization Complete"] end CAST_ADDR --> WRITE_CSR FUNC_START --> GET_ADDR GET_ADDR --> CAST_ADDR GET_ADDR --> TRAP_VECTOR WRITE_CSR --> ASM_WRITE WRITE_CSR --> COMPLETE
Trap Vector Setup Process
The implementation follows this sequence:
- Vector Address Resolution: The
trap_vector_base
symbol is resolved as an external C function pointer, representing the base address of the trap vector table - Address Conversion: The function pointer is cast to
usize
for use as a memory address - CSR Configuration: The address is written to the appropriate RISC-V Control and Status Register (CSR) via
write_trap_vector_base()
Sources: src/riscv/init.rs(L6 - L13)
Integration with Assembly Layer
The initialization depends on two key external components that bridge to the assembly layer:
Component | Type | Purpose |
---|---|---|
trap_vector_base | External C function | Provides base address of trap vector table |
write_trap_vector_base() | Assembly function | Writes address to RISC-V trap vector CSR |
flowchart TD subgraph subGraph2["Hardware Layer"] TVEC_CSR["RISC-V tvec CSR"] TRAP_TABLE["Trap Vector Table"] end subgraph subGraph1["Assembly Interface"] TRAP_BASE["trap_vector_base symbol"] WRITE_CSR["write_trap_vector_base()"] end subgraph subGraph0["Rust Layer"] INIT_TRAP["init_trap()"] end INIT_TRAP --> TRAP_BASE INIT_TRAP --> WRITE_CSR TRAP_BASE --> TRAP_TABLE TVEC_CSR --> TRAP_TABLE WRITE_CSR --> TVEC_CSR
Assembly Interface Integration
The unsafe
blocks in the implementation reflect the direct hardware manipulation required for system initialization, where incorrect trap vector configuration could compromise system stability.
Sources: src/riscv/init.rs(L7 - L12)
Relationship to Trap Handling Architecture
The initialization establishes the foundation for the RISC-V trap handling system. The configured trap vector base points to assembly routines that will save CPU state into TrapFrame
structures and dispatch to Rust handlers.
flowchart TD subgraph subGraph1["Data Structures"] TRAP_FRAME["TrapFrame"] TASK_CONTEXT["TaskContext"] end subgraph subGraph0["System Lifecycle"] INIT["init_trap()"] VECTOR_SET["Trap Vector Configured"] TRAP_OCCUR["Trap/Exception Occurs"] VECTOR_JUMP["Hardware jumps to trap_vector_base"] SAVE_CONTEXT["Save to TrapFrame"] RUST_HANDLER["Rust trap handler"] end INIT --> VECTOR_SET RUST_HANDLER --> TASK_CONTEXT SAVE_CONTEXT --> RUST_HANDLER SAVE_CONTEXT --> TRAP_FRAME TRAP_OCCUR --> VECTOR_JUMP VECTOR_JUMP --> SAVE_CONTEXT VECTOR_SET --> TRAP_OCCUR
Initialization to Runtime Flow
The initialization creates the linkage between hardware trap events and the software trap handling framework implemented in the broader RISC-V module.
Sources: src/riscv/init.rs(L1 - L14)
Architectural Simplicity
The RISC-V initialization implementation demonstrates the architectural simplicity compared to other platforms. The entire initialization consists of a single function with minimal setup requirements, reflecting RISC-V's streamlined approach to system configuration.
This contrasts with x86_64 initialization which requires GDT and IDT setup, or AArch64 initialization which involves exception level transitions and MMU configuration. The RISC-V approach focuses on the essential trap vector configuration needed for basic system operation.
Sources: src/riscv/init.rs(L1 - L14)