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
hgatpCSR (register 0x680) using inline assembly - Exception Analysis:
rust_detect_trap()examinesscauseto 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)