Development and Tooling
Relevant source files
This document covers the development infrastructure, build configuration, testing framework, and tooling used to develop and maintain the RISC-V VCPU hypervisor system. It includes details on the CI/CD pipeline, dependency management, code generation tools, and documentation workflow.
For information about the core VCPU implementation, see Core VCPU Implementation. For details about system architecture components, see System Architecture.
Build System and Dependencies
The RISC-V VCPU system uses Cargo as its primary build system with a carefully curated set of dependencies that provide RISC-V architecture support, hypervisor functionality, and low-level register manipulation capabilities.
Package Configuration
The project is configured as a Rust library crate targeting the 2024 edition with the package name riscv_vcpu
version 0.1.0. The build system is designed specifically for bare-metal RISC-V environments without standard library support.
Dependency Architecture
flowchart TD subgraph subGraph4["riscv_vcpu Implementation"] vcpu_lib["riscv_vcpu Library"] end subgraph subGraph3["ArceOS Framework Dependencies"] axerrno["axerrno:0.1.0Error Handling"] page_table_entry["page_table_entry:0.5Page Table Management"] memory_addr["memory_addr:0.3.1Memory Addressing"] axaddrspace["axaddrspaceAddress Space Management"] axvcpu["axvcpuVCPU Abstractions"] end subgraph subGraph2["SBI and Hypervisor Support"] rustsbi["rustsbi:0.4.0SBI Implementation"] sbi_rt["sbi-rt:0.0.3SBI Runtime"] sbi_spec["sbi-spec:0.0.7SBI Specifications"] end subgraph subGraph1["RISC-V Architecture Support"] riscv_crate["riscvCore RISC-V Support"] riscv_decode["riscv-decodeInstruction Decoding"] tock_registers["tock-registers:0.8.1Register Abstractions"] memoffset["memoffsetMemory Layout"] end subgraph subGraph0["Core Dependencies"] log["log:0.4.19Logging Framework"] cfg_if["cfg-if:1.0Conditional Compilation"] bitflags["bitflags:2.2Flag Types"] bit_field["bit_field:0.10Bit Manipulation"] crate_interface["crate_interface:0.1Interface Definitions"] end axaddrspace --> vcpu_lib axerrno --> vcpu_lib axvcpu --> vcpu_lib bit_field --> vcpu_lib bitflags --> vcpu_lib cfg_if --> vcpu_lib crate_interface --> vcpu_lib log --> vcpu_lib memoffset --> vcpu_lib memory_addr --> vcpu_lib page_table_entry --> vcpu_lib riscv_crate --> vcpu_lib riscv_decode --> vcpu_lib rustsbi --> vcpu_lib sbi_rt --> vcpu_lib sbi_spec --> vcpu_lib tock_registers --> vcpu_lib
Sources: Cargo.toml(L6 - L26)
Key Dependency Categories
Category | Crates | Purpose |
---|---|---|
RISC-V Core | riscv,riscv-decode,tock-registers | Provide RISC-V instruction set support, instruction decoding, and register manipulation primitives |
SBI Interface | rustsbi,sbi-rt,sbi-spec | Implement Supervisor Binary Interface for guest OS communication |
ArceOS Integration | axaddrspace,axvcpu,axerrno | Interface with the ArceOS hypervisor framework |
Low-Level Utilities | bitflags,bit_field,memoffset | Provide bit manipulation and memory layout tools |
CI/CD Pipeline
The continuous integration pipeline ensures code quality, compatibility across Rust toolchains, and automated documentation deployment using GitHub Actions.
Pipeline Architecture
flowchart TD subgraph subGraph3["Documentation Pipeline"] doc_build["cargo docDocumentation Generation"] doc_deploy["GitHub PagesDocumentation Deployment"] end subgraph subGraph2["Quality Checks"] fmt_check["cargo fmt --checkCode Formatting"] clippy_check["cargo clippyLinting Analysis"] build_check["cargo buildCompilation Test"] unit_test["cargo testUnit Testing"] end subgraph subGraph1["CI Job Matrix"] toolchain1["nightly-2024-12-25riscv64gc-unknown-none-elf"] toolchain2["nightlyriscv64gc-unknown-none-elf"] end subgraph subGraph0["Trigger Events"] push["Push Events"] pr["Pull Requests"] end doc_build --> doc_deploy pr --> toolchain1 pr --> toolchain2 push --> toolchain1 push --> toolchain2 toolchain1 --> build_check toolchain1 --> clippy_check toolchain1 --> doc_build toolchain1 --> fmt_check toolchain1 --> unit_test toolchain2 --> build_check toolchain2 --> clippy_check toolchain2 --> fmt_check toolchain2 --> unit_test
Sources: .github/workflows/ci.yml(L1 - L65)
CI Configuration Details
The pipeline runs two primary jobs: ci
for code quality and testing, and doc
for documentation generation and deployment.
Code Quality Matrix
The CI system tests against multiple Rust toolchain versions to ensure compatibility:
- Primary Toolchain:
nightly-2024-12-25
(stable reference) - Latest Toolchain:
nightly
(forward compatibility) - Target Architecture:
riscv64gc-unknown-none-elf
(bare-metal RISC-V 64-bit)
Quality Gates
Stage | Command | Purpose | Failure Handling |
---|---|---|---|
Format Check | cargo fmt --all -- --check | Enforce consistent code formatting | Hard failure |
Linting | cargo clippy --target riscv64gc-unknown-none-elf --all-features | Static analysis and best practices | Continue on error for nightly |
Build | cargo build --target riscv64gc-unknown-none-elf --all-features | Compilation verification | Continue on error for nightly |
Unit Tests | cargo test --target x86_64-unknown-linux-gnu | Functional testing | Hard failure |
Sources: .github/workflows/ci.yml(L20 - L32)
Documentation Workflow
The documentation pipeline automatically generates and deploys API documentation to GitHub Pages for the default branch.
flowchart TD subgraph subGraph1["Deployment Pipeline"] gh_pages["GitHub PagesBranch: gh-pages"] auto_deploy["JamesIves/github-pages-deploy-action"] end subgraph subGraph0["Documentation Generation"] source["Source Codewith Doc Comments"] cargo_doc["cargo doc--no-deps --all-features"] index_gen["Index Page Generation"] end auto_deploy --> gh_pages cargo_doc --> index_gen index_gen --> auto_deploy source --> cargo_doc
Sources: .github/workflows/ci.yml(L34 - L64)
The documentation build includes strict linting with RUSTDOCFLAGS: -D rustdoc::broken_intra_doc_links -D missing-docs
to ensure documentation completeness and link integrity.
Code Generation and Register Definitions
The system employs sophisticated code generation techniques to create type-safe register definitions for RISC-V Control and Status Registers (CSRs).
Register Definition Architecture
flowchart TD subgraph subGraph2["Runtime Usage"] csr_access["CSR Read/WriteOperations"] type_safety["Compile-timeType Safety"] field_manipulation["BitfieldManipulation"] end subgraph subGraph1["Generated CSR Definitions"] csr_constants["CSR Address ConstantsCSR_HSTATUS: 0x600"] register_structs["Register Structshstatus::Register"] field_definitions["Field Definitionsspv, vsxl, vtvm"] field_values["Field Value EnumsUser, Supervisor"] end subgraph subGraph0["Register Definition Generator"] tock_registers["tock-registersMacro Framework"] register_bitfields["register_bitfields!Macro Invocation"] end csr_constants --> csr_access field_definitions --> field_manipulation field_values --> field_manipulation register_bitfields --> csr_constants register_bitfields --> field_definitions register_bitfields --> field_values register_bitfields --> register_structs register_structs --> type_safety tock_registers --> register_bitfields
Sources: def.rs(L1 - L1910)
CSR Definition Structure
The register definitions follow a hierarchical pattern:
- CSR Address Constants: Hexadecimal addresses for each CSR register
- Register Modules: Type-safe wrappers for each register
- Field Definitions: Bit field specifications with masks and offsets
- Value Enumerations: Named constants for field values
Example Register Definition Pattern
The hstatus
register demonstrates the complete pattern:
// CSR address constant
pub const CSR_HSTATUS: u16 = 0x600;
// Register module with fields
pub mod hstatus {
pub struct Register;
// Field definitions with bit positions
pub const spv: Field<usize, Register> = Field::new(mask, offset);
// Field value enumerations
pub mod spv {
pub enum Value {
User = 0,
Supervisor = 1,
}
}
}
Sources: def.rs(L37 - L881)
Generated Register Coverage
Register Category | Examples | Purpose |
---|---|---|
Supervisor CSRs | CSR_SSTATUS,CSR_SIE,CSR_SATP | Guest supervisor mode state |
Virtual Supervisor CSRs | CSR_VSSTATUS,CSR_VSIE,CSR_VSATP | Virtualized supervisor state |
Hypervisor CSRs | CSR_HSTATUS,CSR_HEDELEG,CSR_HIE | Hypervisor control and delegation |
Testing Framework
The testing strategy combines unit testing for functional verification with CI-based integration testing across multiple toolchain versions.
Test Execution Environment
flowchart TD subgraph subGraph1["Test Categories"] functional["Functional TestsCore Logic Verification"] compilation["Compilation TestsCross-platform Build"] linting["Static AnalysisClippy Checks"] formatting["Style Testsrustfmt Validation"] end subgraph subGraph0["Test Environments"] unit_tests["Unit Testsx86_64-unknown-linux-gnu"] integration_tests["Integration Testsriscv64gc-unknown-none-elf"] end integration_tests --> compilation integration_tests --> formatting integration_tests --> linting unit_tests --> functional
Sources: .github/workflows/ci.yml(L30 - L32)
Test Configuration
The test suite runs with specific configurations:
- Unit Tests: Execute on
x86_64-unknown-linux-gnu
for host-based testing - Integration Tests: Build verification on
riscv64gc-unknown-none-elf
target - Test Output: Uses
--nocapture
flag for complete test output visibility
Development Workflow Integration
The development workflow integrates multiple tools and processes to ensure code quality and system reliability.
Development Tool Chain
flowchart TD subgraph Deployment["Deployment"] crate_publish["Crate Publication"] gh_pages["GitHub PagesDocumentation"] end subgraph subGraph2["Automated Validation"] ci_pipeline["CI Pipeline"] quality_gates["Quality Gates"] doc_generation["Documentation"] end subgraph subGraph1["Version Control"] git_commit["Git Commit"] git_push["Git Push"] pull_request["Pull Request"] end subgraph subGraph0["Local Development"] rust_toolchain["Rust Nightly Toolchain"] cargo_fmt["cargo fmtCode Formatting"] cargo_clippy["cargo clippyLinting"] cargo_test["cargo testUnit Testing"] end cargo_clippy --> cargo_test cargo_fmt --> cargo_clippy cargo_test --> git_commit ci_pipeline --> quality_gates doc_generation --> gh_pages git_commit --> git_push git_push --> ci_pipeline pull_request --> ci_pipeline quality_gates --> crate_publish quality_gates --> doc_generation rust_toolchain --> cargo_fmt
Sources: .github/workflows/ci.yml(L1 - L65) Cargo.toml(L1 - L26)
Required Toolchain Components
The development environment requires specific Rust toolchain components:
- Rust Source:
rust-src
for cross-compilation support - Clippy: Static analysis and linting tool
- Rustfmt: Code formatting tool
- Target Support:
riscv64gc-unknown-none-elf
compilation target
Sources: .github/workflows/ci.yml(L18 - L19)