Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d5d8ae9
feat(vcpu): add interrupt injection support and enhance system regist…
luodeb Mar 27, 2025
1b8da5e
feat(sysreg): update handle_read and handle_write to use unused param…
luodeb Mar 31, 2025
32866b4
update dependecies
aarkegz Apr 7, 2025
28b357c
Merge remote-tracking branch 'origin/debin/timer_api' into debin/time…
aarkegz Apr 7, 2025
4017f66
update percpu
aarkegz Apr 14, 2025
1b465d2
Merge branch 'master' into debin/timer_api
aarkegz Jun 5, 2025
2143f59
try setting ich_hcr_el2.en
aarkegz Jun 5, 2025
1df97f2
[feat] use 4 level paging for ept
hky1999 Jun 6, 2025
a860bfd
better code and comment for setting ich_hcr_el2
aarkegz Jun 7, 2025
7da58d1
Merge branch 'master' into vgicv3
aarkegz Jun 8, 2025
a9bde35
add error messages for `current_el_sync_handler`
aarkegz Jun 8, 2025
d393aee
pin rust toolchain version
aarkegz Jun 8, 2025
a4f1c10
set `CNTHCTL_EL2::EL1PCEN` and `CNTHCTL_EL2::EL1PTCEN`, unset `HCR_EL…
aarkegz Jun 9, 2025
47f4598
[STINKS] embed vgicv3 devices with HARD-CODED qemu gicv3 address loca…
aarkegz Jun 9, 2025
fcfd6ec
[feat] introduce set_return_value API
hky1999 Jun 10, 2025
1fb5ac1
[WIP!][TOBEREWRITE!] add gic-vdevice cofigs
aarkegz Jun 10, 2025
211289e
Merge remote-tracking branch 'origin/ivc_and_4lpt' into vgicv3
aarkegz Jun 11, 2025
7171d99
fixes after merging ivc code
aarkegz Jun 11, 2025
f8e6514
fix branch names for `axvcpu`
aarkegz Jun 11, 2025
ad1d617
emulate `ICC_SGI1R_EL1`
aarkegz Jun 13, 2025
17f554c
update to newest dependencies
aarkegz Jul 11, 2025
0e36a62
de-coupling `arm_vcpu` and `arm_vgic`, fix some warnings
aarkegz Jul 13, 2025
ce67fce
fix a missing doc
aarkegz Jul 13, 2025
e8eb890
remove `arm_vgic` dependency
aarkegz Jul 14, 2025
a64648e
add `builtin_sysreg_access_handler`, add interrupt and timer passthro…
aarkegz Jul 14, 2025
b3e1169
remove sysreg emu devices
aarkegz Jul 14, 2025
1753965
rollback `tock-registers` to 0.9
aarkegz Jul 14, 2025
2cdca35
reformatted
aarkegz Jul 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ aarch64_sysreg = "0.1.1"

axaddrspace = { git = "https://github.com/arceos-hypervisor/axaddrspace.git" }
axvcpu = { git = "https://github.com/arceos-hypervisor/axvcpu.git" }
axdevice_base = { git = "https://github.com/arceos-hypervisor/axdevice_crates.git" }
axvisor_api = { git = "https://github.com/arceos-hypervisor/axvisor_api.git" }

arm_vgic = { git = "https://github.com/arceos-hypervisor/arm_vgic.git", features = ["vgicv3"]}
8 changes: 8 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[toolchain]
profile = "minimal"
channel = "nightly-2024-12-25"
components = ["rust-src", "llvm-tools", "rustfmt", "clippy"]
targets = [
"aarch64-unknown-none",
"aarch64-unknown-none-softfloat",
]
3 changes: 3 additions & 0 deletions src/context_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ pub struct GuestSystemRegisters {
cntv_ctl_el0: u32,
cntp_tval_el0: u32,
cntv_tval_el0: u32,
pub cnthctl_el2: u64,

// vpidr and vmpidr
vpidr_el2: u32,
Expand Down Expand Up @@ -220,6 +221,7 @@ impl GuestSystemRegisters {
asm!("mrs {0:x}, CNTP_TVAL_EL0", out(reg) self.cntp_tval_el0);
asm!("mrs {0:x}, CNTV_TVAL_EL0", out(reg) self.cntv_tval_el0);
asm!("mrs {0}, CNTVCT_EL0", out(reg) self.cntvct_el0);
asm!("mrs {0}, CNTHCTL_EL2", out(reg) self.cnthctl_el2);
// MRS!("self.vpidr_el2, VPIDR_EL2, "x");
asm!("mrs {0}, VMPIDR_EL2", out(reg) self.vmpidr_el2);

Expand Down Expand Up @@ -265,6 +267,7 @@ impl GuestSystemRegisters {
asm!("msr CNTV_CVAL_EL0, {0}", in(reg) self.cntv_cval_el0);
asm!("msr CNTKCTL_EL1, {0:x}", in (reg) self.cntkctl_el1);
asm!("msr CNTV_CTL_EL0, {0:x}", in (reg) self.cntv_ctl_el0);
asm!("msr CNTHCTL_EL2, {0}", in(reg) self.cnthctl_el2);
// The restoration of SP_EL0 is done in `exception_return_el2`,
// which move the value from `self.ctx.sp_el0` to `SP_EL0`.
// asm!("msr SP_EL0, {0}", in(reg) self.sp_el0);
Expand Down
32 changes: 23 additions & 9 deletions src/exception.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
use aarch64_cpu::registers::{ESR_EL2, HCR_EL2, Readable, SCTLR_EL1, VTCR_EL2, VTTBR_EL2};

use axaddrspace::GuestPhysAddr;
use axaddrspace::device::AccessWidth;
use axerrno::{AxError, AxResult};
use axvcpu::AxVCpuExitReason;

use crate::TrapFrame;
use crate::exception_utils::{
exception_class, exception_class_value, exception_data_abort_access_is_write,
Expand All @@ -15,6 +8,15 @@ use crate::exception_utils::{
exception_sysreg_direction_write, exception_sysreg_gpr,
};

use aarch64_cpu::registers::{ESR_EL2, HCR_EL2, Readable, SCTLR_EL1, VTCR_EL2, VTTBR_EL2};
use axaddrspace::{
GuestPhysAddr,
device::{AccessWidth, SysRegAddr},
};
use axerrno::{AxError, AxResult};
use axvcpu::AxVCpuExitReason;
use log::error;

numeric_enum_macro::numeric_enum! {
#[repr(u8)]
#[derive(Debug)]
Expand Down Expand Up @@ -179,6 +181,7 @@ fn handle_data_abort(context_frame: &mut TrapFrame) -> AxResult<AxVCpuExitReason
width,
reg,
reg_width,
signed_ext: false,
})
}

Expand All @@ -204,11 +207,14 @@ fn handle_system_register(context_frame: &mut TrapFrame) -> AxResult<AxVCpuExitR
context_frame.set_exception_pc(val);
if write {
return Ok(AxVCpuExitReason::SysRegWrite {
addr,
addr: SysRegAddr::new(addr),
value: context_frame.gpr(reg as usize) as u64,
});
}
Ok(AxVCpuExitReason::SysRegRead { addr, reg })
Ok(AxVCpuExitReason::SysRegRead {
addr: SysRegAddr::new(addr),
reg,
})
}

/// Handles HVC or SMC exceptions that serve as psci (Power State Coordination Interface) calls.
Expand Down Expand Up @@ -284,6 +290,14 @@ fn current_el_irq_handler(_tf: &mut TrapFrame) {
/// Handles synchronous exceptions that occur from the current exception level.
#[unsafe(no_mangle)]
fn current_el_sync_handler(tf: &mut TrapFrame) {
let esr = ESR_EL2.extract();
let ec = ESR_EL2.read(ESR_EL2::EC);
let iss = ESR_EL2.read(ESR_EL2::ISS);

error!("ESR_EL2: {:#x}", esr.get());
error!("Exception Class: {:#x}", ec);
error!("Instruction Specific Syndrome: {:#x}", iss);

panic!(
"Unhandled synchronous exception from current EL: {:#x?}",
tf
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ mod exception_utils;
mod exception;
mod pcpu;
mod smc;
mod sysreg;
mod vcpu;

pub use self::pcpu::Aarch64PerCpu;
pub use self::sysreg::get_sysreg_device;
pub use self::vcpu::{Aarch64VCpu, Aarch64VCpuCreateConfig};

/// context frame for aarch64
Expand Down
13 changes: 13 additions & 0 deletions src/pcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ impl<H: AxVCpuHal> AxArchPerCpu for Aarch64PerCpu<H> {
+ HCR_EL2::TSC::EnableTrapEl1SmcToEl2,
);

// Note that `ICH_HCR_EL2` is not the same as `HCR_EL2`.
//
// `ICH_HCR_EL2[0]` controls the virtual CPU interface operation.
//
// We leave it for the virtual GIC implementations to decide whether to enable it or not.
//
// unsafe {
// core::arch::asm! {
// "msr ich_hcr_el2, {value:x}",
// value = in(reg) 0,
// }
// }

Ok(())
}

Expand Down
50 changes: 50 additions & 0 deletions src/sysreg/cntp_ctl_el0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use aarch64_sysreg::SystemRegType;

use axaddrspace::GuestPhysAddrRange;
use axaddrspace::device::{AccessWidth, DeviceAddrRange, SysRegAddr, SysRegAddrRange};
use axdevice_base::EmuDeviceType;
use axdevice_base::{BaseDeviceOps, BaseMmioDeviceOps};
use axerrno::AxResult;

impl BaseDeviceOps<SysRegAddrRange> for SysCntpCtlEl0 {
fn emu_type(&self) -> EmuDeviceType {
EmuDeviceType::Console
}

fn address_range(&self) -> SysRegAddrRange {
SysRegAddrRange {
start: SysRegAddr::new(SystemRegType::CNTP_CTL_EL0 as usize),
end: SysRegAddr::new(SystemRegType::CNTP_CTL_EL0 as usize),
}
}

fn handle_read(
&self,
addr: <SysRegAddrRange as DeviceAddrRange>::Addr,
width: AccessWidth,
) -> AxResult<usize> {
todo!()
}

fn handle_write(
&self,
addr: <SysRegAddrRange as DeviceAddrRange>::Addr,
width: AccessWidth,
val: usize,
) -> AxResult {
info!("Write to emulator register: {:?}, value: {}", addr, val);
Ok(())
}
}

pub struct SysCntpCtlEl0 {
// Fields
}

impl SysCntpCtlEl0 {
pub fn new() -> Self {
Self {
// Initialize fields
}
}
}
67 changes: 67 additions & 0 deletions src/sysreg/cntp_tval_el0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
extern crate alloc;

use aarch64_sysreg::SystemRegType;

use aarch64_cpu::registers::{CNTPCT_EL0, Readable};

use axaddrspace::{
GuestPhysAddrRange,
device::{AccessWidth, DeviceAddrRange, SysRegAddr, SysRegAddrRange},
};
use axdevice_base::{BaseDeviceOps, EmuDeviceType};
use axerrno::AxResult;
use axvisor_api::time::{current_time_nanos, register_timer};

use alloc::boxed::Box;
use core::time::Duration;

impl BaseDeviceOps<SysRegAddrRange> for SysCntpTvalEl0 {
fn emu_type(&self) -> EmuDeviceType {
EmuDeviceType::Console
}

fn address_range(&self) -> SysRegAddrRange {
SysRegAddrRange {
start: SysRegAddr::new(SystemRegType::CNTP_TVAL_EL0 as usize),
end: SysRegAddr::new(SystemRegType::CNTP_TVAL_EL0 as usize),
}
}

fn handle_read(
&self,
_addr: <SysRegAddrRange as DeviceAddrRange>::Addr,
_width: AccessWidth,
) -> AxResult<usize> {
todo!()
}

fn handle_write(
&self,
addr: <SysRegAddrRange as DeviceAddrRange>::Addr,
_width: AccessWidth,
val: usize,
) -> AxResult {
info!("Write to emulator register: {:?}, value: {}", addr, val);
let now = current_time_nanos();
info!("Current time: {}, deadline: {}", now, now + val as u64);
register_timer(
Duration::from_nanos(now + val as u64),
Box::new(|_| {
axvisor_api::arch::hardware_inject_virtual_interrupt(30);
}),
);
Ok(())
}
}

pub struct SysCntpTvalEl0 {
// Fields
}

impl SysCntpTvalEl0 {
pub fn new() -> Self {
Self {
// Initialize fields
}
}
}
55 changes: 55 additions & 0 deletions src/sysreg/cntpct_el0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use aarch64_sysreg::SystemRegType;

use aarch64_cpu::registers::{CNTPCT_EL0, Readable};

use axaddrspace::{
GuestPhysAddrRange,
device::{AccessWidth, DeviceAddrRange, SysRegAddr, SysRegAddrRange},
};

use axdevice_base::{BaseDeviceOps, EmuDeviceType};

use axerrno::AxResult;

impl BaseDeviceOps<SysRegAddrRange> for SysCntpctEl0 {
fn emu_type(&self) -> EmuDeviceType {
EmuDeviceType::Console
}

fn address_range(&self) -> SysRegAddrRange {
SysRegAddrRange {
start: SysRegAddr::new(SystemRegType::CNTPCT_EL0 as usize),
end: SysRegAddr::new(SystemRegType::CNTPCT_EL0 as usize),
}
}

fn handle_read(
&self,
addr: <SysRegAddrRange as DeviceAddrRange>::Addr,
width: AccessWidth,
) -> AxResult<usize> {
Ok(CNTPCT_EL0.get() as usize)
}

fn handle_write(
&self,
addr: <SysRegAddrRange as DeviceAddrRange>::Addr,
width: AccessWidth,
val: usize,
) -> AxResult {
info!("Write to emulator register: {:?}, value: {}", addr, val);
Ok(())
}
}

pub struct SysCntpctEl0 {
// Fields
}

impl SysCntpctEl0 {
pub fn new() -> Self {
Self {
// Initialize fields
}
}
}
23 changes: 23 additions & 0 deletions src/sysreg/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
extern crate alloc;

use alloc::sync::Arc;
use alloc::{vec, vec::Vec};
use axdevice_base::BaseSysRegDeviceOps;

mod cntp_ctl_el0;
pub use cntp_ctl_el0::SysCntpCtlEl0;

mod cntpct_el0;
pub use cntpct_el0::SysCntpctEl0;

mod cntp_tval_el0;
pub use cntp_tval_el0::SysCntpTvalEl0;

/// Create a collection of system register devices.
pub fn get_sysreg_device() -> Vec<Arc<dyn BaseSysRegDeviceOps>> {
vec![
Arc::new(SysCntpCtlEl0::new()),
Arc::new(SysCntpctEl0::new()),
Arc::new(SysCntpTvalEl0::new()),
]
}
Loading