System Architecture
Relevant source files
This document covers the supporting infrastructure and architectural components that enable the RISC-V VCPU system to function. It focuses on the foundational systems including per-CPU management, hardware detection, and the overall system initialization flow. For detailed coverage of the core VCPU implementation and VM execution lifecycle, see Core VCPU Implementation. For low-level assembly implementations and hardware register definitions, see Low-Level Implementation.
System Initialization and Component Integration
The RISC-V VCPU system follows a layered architecture where hardware detection validates platform capabilities before initializing per-CPU state and enabling hypervisor functionality.
System Startup Flow
flowchart TD Start["System Startup"] LibInit["lib.rs Module Loading"] HWDetect["detect_h_extension()"] HWCheck["Hardware Support?"] PerCPUInit["RISCVPerCpu::new()"] Failed["AxError::Unsupported"] CSRSetup["setup_csrs()"] HedelegConfig["hedeleg::Hedeleg::write()"] HidelegConfig["hideleg::Hideleg::write()"] InterruptClear["hvip::clear_*()"] SIEConfig["sie::set_*()"] VCPUReady["VCPU System Ready"] VCPUCreate["RISCVVCpu Creation"] VMExecution["VM Execution Loop"] End["System Unavailable"] CSRSetup --> HedelegConfig CSRSetup --> HidelegConfig CSRSetup --> InterruptClear CSRSetup --> SIEConfig Failed --> End HWCheck --> Failed HWCheck --> PerCPUInit HWDetect --> HWCheck HedelegConfig --> VCPUReady HidelegConfig --> VCPUReady InterruptClear --> VCPUReady LibInit --> HWDetect PerCPUInit --> CSRSetup SIEConfig --> VCPUReady Start --> LibInit VCPUCreate --> VMExecution VCPUReady --> VCPUCreate
Sources: src/lib.rs(L1 - L46) src/percpu.rs(L15 - L41) src/detect.rs(L15 - L25)
Public Interface Architecture
The system exposes its functionality through a clean public API defined in the main library module:
Component | Type | Purpose |
---|---|---|
RISCVPerCpu | Public Struct | Per-CPU state management |
RISCVVCpu | Public Struct | Virtual CPU implementation |
has_hardware_support() | Function | Hardware capability detection |
RISCVVCpuCreateConfig | Configuration | VCPU creation parameters |
EID_HVC | Constant | Hypercall extension identifier |
The library uses feature gates for no-std operation and RISC-V specific intrinsics, enabling bare-metal hypervisor deployment.
Sources: src/lib.rs(L1 - L46)
Per-CPU State Management Architecture
The RISCVPerCpu<H>
component implements the AxArchPerCpu
trait to provide hardware-specific per-CPU functionality within the ArceOS framework.
Per-CPU Component Structure
flowchart TD subgraph subGraph3["Hardware Detection"] HasHWSupport["has_hardware_support()"] DetectHExt["detect_h_extension()"] end subgraph subGraph2["CSR Management"] SetupCSRs["setup_csrs()"] HedelegSetup["hedeleg::Hedeleg"] HidelegSetup["hideleg::Hideleg"] HVIPClear["hvip::clear_*()"] SIESet["sie::set_*()"] end subgraph subGraph1["RISCVPerCpu Implementation"] RISCVPerCpu["RISCVPerCpu"] NewMethod["new(cpu_id: usize)"] HardwareEnable["hardware_enable()"] IsEnabled["is_enabled()"] HardwareDisable["hardware_disable()"] end subgraph subGraph0["ArceOS Framework Interface"] AxArchPerCpu["AxArchPerCpu Trait"] AxVCpuHal["AxVCpuHal Trait"] end AxArchPerCpu --> RISCVPerCpu AxVCpuHal --> RISCVPerCpu HardwareEnable --> HasHWSupport HasHWSupport --> DetectHExt NewMethod --> SetupCSRs SetupCSRs --> HVIPClear SetupCSRs --> HedelegSetup SetupCSRs --> HidelegSetup SetupCSRs --> SIESet
Sources: src/percpu.rs(L1 - L82)
CSR Initialization Process
The setup_csrs()
function configures critical Control and Status Registers for hypervisor operation:
Exception Delegation Configuration:
- Delegates specific synchronous exceptions via
hedeleg::Hedeleg::write()
- Includes instruction address misalignment, breakpoints, environment calls, and page faults
- Enables guest operating systems to handle these exceptions directly
Interrupt Delegation Configuration:
- Delegates virtual supervisor interrupts through
hideleg::Hideleg::write()
- Covers timer, external, and software interrupts for guest VMs
- Allows efficient interrupt handling without hypervisor intervention
Interrupt State Management:
- Clears all pending virtual supervisor interrupts using
hvip::clear_*()
functions - Configures supervisor interrupt enable via
sie::set_*()
functions - Establishes clean interrupt state for VM execution
Sources: src/percpu.rs(L43 - L81) src/consts.rs(L1 - L50)
Hardware Detection System
The hardware detection subsystem uses a trap-and-emulate approach to safely probe RISC-V H-extension availability without causing system instability.
Detection Mechanism Architecture
flowchart TD subgraph subGraph3["CSR Access Test"] CSRRInstr["asm!(csrr {}, 0x680)"] HGATPRead["hgatp CSR Read"] end subgraph subGraph2["Trap Handler Components"] OnDetectTrap["on_detect_trap()"] RustDetectTrap["rust_detect_trap()"] TrapFrame["TrapFrame struct"] end subgraph subGraph1["Trap Detection Framework"] WithDetectTrap["with_detect_trap()"] InitDetectTrap["init_detect_trap()"] RestoreDetectTrap["restore_detect_trap()"] end subgraph subGraph0["Detection Interface"] DetectHExt["detect_h_extension()"] HasHWSupport["has_hardware_support()"] end CSRRInstr --> HGATPRead DetectHExt --> WithDetectTrap InitDetectTrap --> OnDetectTrap OnDetectTrap --> RustDetectTrap RustDetectTrap --> TrapFrame WithDetectTrap --> CSRRInstr WithDetectTrap --> InitDetectTrap WithDetectTrap --> RestoreDetectTrap
Sources: src/detect.rs(L1 - L218)
Detection Process Flow
The hardware detection operates through controlled exception handling:
- Environment Setup:
init_detect_trap()
disables interrupts and installs custom trap handler - Probe Execution: Attempts to read the
hgatp
CSR (register 0x680) using inline assembly - Exception Analysis:
rust_detect_trap()
examinesscause
to determine if illegal instruction occurred - State Restoration:
restore_detect_trap()
restores original interrupt and trap configuration
The system returns success (true) if the CSR read completes without illegal instruction exception, indicating H-extension support.
Trap Frame Structure
Field | Purpose |
---|---|
ra,tp,a0-a7,t0-t6 | General-purpose register preservation |
sstatus | Supervisor status register state |
sepc | Exception program counter |
scause | Exception cause identification |
stval | Exception value (instruction bits for illegal instruction) |
The trap handler uses instruction length analysis via riscv_illegal_insn_bits()
to correctly advance sepc
past the illegal instruction, ensuring proper execution continuation.
Sources: src/detect.rs(L120 - L144) src/detect.rs(L40 - L77)
Component Integration and Data Flow
The system architecture enables seamless integration between hardware detection, per-CPU management, and the broader ArceOS framework.
Module Dependency Graph
flowchart TD subgraph subGraph1["Internal Modules"] LibRS["lib.rs"] PerCPU["percpu.rs"] Detect["detect.rs"] Consts["consts.rs"] Regs["regs.rs"] Trap["trap.rs"] VCPU["vcpu.rs"] end subgraph subGraph0["External Dependencies"] ArceOS["axvcpu::AxArchPerCpu"] AddrSpace["axaddrspace::GuestPhysAddr"] RISCVRegs["riscv::register::*"] Log["log crate"] end AddrSpace --> LibRS ArceOS --> PerCPU Detect --> Consts LibRS --> Detect LibRS --> PerCPU LibRS --> VCPU Log --> LibRS PerCPU --> Consts PerCPU --> Detect RISCVRegs --> Detect RISCVRegs --> PerCPU VCPU --> Regs VCPU --> Trap
Sources: src/lib.rs(L7 - L20)
Configuration and Error Handling
The system provides robust configuration through RISCVVCpuCreateConfig
:
pub struct RISCVVCpuCreateConfig {
pub hart_id: usize, // CPU core identifier
pub dtb_addr: axaddrspace::GuestPhysAddr, // Device tree blob location
}
Error handling follows ArceOS conventions using AxResult<T>
and AxError
types. Hardware capability failures return AxError::Unsupported
, enabling graceful degradation when H-extension is unavailable.
The hypercall extension identifier EID_HVC
(0x485643, "HVC" in ASCII) provides a standardized interface for guest-hypervisor communication outside the standard SBI specification.
Sources: src/lib.rs(L22 - L45)