Skip to content

arceos-hypervisor/riscv_vplic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

riscv_vplic

RISC-V Virtual Platform-Level Interrupt Controller

Crates.io Docs.rs Rust License

English | 中文

Introduction

RISC-V Virtual Platform-Level Interrupt Controller, providing a PLIC 1.0.0 compliant interrupt controller emulation for RISC-V Hypervisors. Supports #![no_std], suitable for bare-metal and virtualization development.

This crate exports the following core components:

  • VPlicGlobal — Virtual PLIC global controller, managing interrupt priorities, pending interrupts, and active interrupts
  • PLIC Constants — PLIC 1.0.0 memory map constant definitions (priority, pending, enable, context control, etc.)

Key Features

  • PLIC 1.0.0 compliant memory map
  • Interrupt priority, pending status, and enable management
  • Context-based interrupt handling with Claim/Complete mechanism
  • Integration with Hypervisor device emulation framework (implements BaseDeviceOps trait)

Quick Start

Prerequisites

  • Rust nightly toolchain
  • Rust components: rust-src, clippy, rustfmt
# Install rustup (if not installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install nightly toolchain and components
rustup install nightly
rustup component add rust-src clippy rustfmt --toolchain nightly

Running Checks and Tests

# 1. Clone the repository
git clone https://github.com/arceos-hypervisor/riscv_vplic.git
cd riscv_vplic

# 2. Code check (format check + clippy + build + doc generation)
./scripts/check.sh

# 3. Run tests
# Run all tests (unit tests + integration tests)
./scripts/test.sh

# Run unit tests only
./scripts/test.sh unit

# Run integration tests only
./scripts/test.sh integration

# List all available test suites
./scripts/test.sh list

# Specify unit test target
./scripts/test.sh unit --unit-targets x86_64-unknown-linux-gnu

Integration

Installation

Add to your Cargo.toml:

[dependencies]
riscv_vplic = "0.2.2"

Usage Example

use riscv_vplic::VPlicGlobal;
use axaddrspace::GuestPhysAddr;

fn main() {
    // Create a virtual PLIC with 2 contexts
    let vplic = VPlicGlobal::new(
        GuestPhysAddr::from(0x0c000000),
        Some(0x4000),
        2
    );
    
    // Access PLIC properties
    println!("PLIC address: {:#x}", vplic.addr.as_usize());
    println!("PLIC size: {:#x}", vplic.size);
    println!("Contexts: {}", vplic.contexts_num);
    
    // Check interrupt bitmap status
    assert!(vplic.assigned_irqs.lock().is_empty());
    assert!(vplic.pending_irqs.lock().is_empty());
    assert!(vplic.active_irqs.lock().is_empty());
}

PLIC Memory Map Constants

use riscv_vplic::*;

// Number of interrupt sources (PLIC 1.0.0 defines 1024)
assert_eq!(PLIC_NUM_SOURCES, 1024);

// Memory map offsets
assert_eq!(PLIC_PRIORITY_OFFSET, 0x000000);       // Priority registers
assert_eq!(PLIC_PENDING_OFFSET, 0x001000);        // Pending registers
assert_eq!(PLIC_ENABLE_OFFSET, 0x002000);         // Enable registers
assert_eq!(PLIC_CONTEXT_CTRL_OFFSET, 0x200000);   // Context control registers

// Context strides
assert_eq!(PLIC_ENABLE_STRIDE, 0x80);             // Enable region stride
assert_eq!(PLIC_CONTEXT_STRIDE, 0x1000);          // Context stride

// Context internal control offsets
assert_eq!(PLIC_CONTEXT_THRESHOLD_OFFSET, 0x00);  // Threshold register
assert_eq!(PLIC_CONTEXT_CLAIM_COMPLETE_OFFSET, 0x04); // Claim/Complete register

Documentation

Generate and view API documentation:

cargo doc --no-deps --open

Online documentation: docs.rs/riscv_vplic

Related Projects

Contributing

  1. Fork the repository and create a branch
  2. Run local checks: ./scripts/check.sh
  3. Run local tests: ./scripts/test.sh
  4. Submit a PR and pass CI checks

License

This project is licensed under the Apache License, Version 2.0. See the LICENSE file for details.