Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly-2024-12-25
- name: Build docs
continue-on-error: ${{ github.ref != env.default-branch && github.event_name != 'pull_request' }}
run: |
Expand Down
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ tock-registers = "0.8"
numeric-enum-macro = "0.2"

axerrno = "0.1.0"
percpu = "0.1.4"
percpu = { version = "0.2.0", features = ["arm-el2"] }
aarch64_sysreg = "0.1.1"

axaddrspace = { git = "https://github.com/arceos-hypervisor/axaddrspace.git" }
axvcpu = { git = "https://github.com/arceos-hypervisor/axvcpu.git" }
axvcpu = { git = "https://github.com/arceos-hypervisor/axvcpu.git", branch = "inject_interrupt" }
axdevice_base = { git = "https://github.com/arceos-hypervisor/axdevice_crates.git", branch = "inject_interrupt" }
axvisor_api = { git = "https://github.com/arceos-hypervisor/axvisor_api.git", branch = "inject_interrupt" }
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
2 changes: 2 additions & 0 deletions src/exception.S
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,15 @@
.macro HANDLE_CURRENT_IRQ
.p2align 7
SAVE_REGS_FROM_EL1
mov x0, sp
bl current_el_irq_handler
b .Lexception_return_el2
.endm

.macro HANDLE_CURRENT_SYNC
.p2align 7
SAVE_REGS_FROM_EL1
mov x0, sp
bl current_el_sync_handler
b .Lexception_return_el2
.endm
Expand Down
15 changes: 9 additions & 6 deletions src/exception.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
use aarch64_cpu::registers::{ESR_EL2, HCR_EL2, Readable, SCTLR_EL1, VTCR_EL2, VTTBR_EL2};

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

use crate::TrapFrame;
use crate::exception_utils::{
exception_class, exception_class_value, exception_data_abort_access_is_write,
Expand All @@ -13,6 +9,10 @@ use crate::exception_utils::{
exception_esr, exception_fault_addr, exception_next_instruction_step, exception_sysreg_addr,
exception_sysreg_direction_write, exception_sysreg_gpr,
};
use axaddrspace::GuestPhysAddr;
use axaddrspace::device::{AccessWidth, SysRegAddr};
use axerrno::{AxError, AxResult};
use axvcpu::AxVCpuExitReason;

numeric_enum_macro::numeric_enum! {
#[repr(u8)]
Expand Down Expand Up @@ -203,11 +203,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
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
49 changes: 49 additions & 0 deletions src/sysreg/cntp_ctl_el0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use aarch64_sysreg::SystemRegType;

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

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

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
}
}
}
62 changes: 62 additions & 0 deletions src/sysreg/cntp_tval_el0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
extern crate alloc;

use aarch64_sysreg::SystemRegType;

use axaddrspace::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::EmuDeviceTConsole
}

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
}
}
}
54 changes: 54 additions & 0 deletions src/sysreg/cntpct_el0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use aarch64_sysreg::SystemRegType;

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

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

use axdevice_base::{BaseDeviceOps, EmuDeviceType};

use axerrno::AxResult;

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

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
}
}
}
22 changes: 22 additions & 0 deletions src/sysreg/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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;

pub fn get_sysreg_device() -> Vec<Arc<dyn BaseSysRegDeviceOps>> {
vec![
Arc::new(SysCntpCtlEl0::new()),
Arc::new(SysCntpctEl0::new()),
Arc::new(SysCntpTvalEl0::new()),
]
}
Loading
Loading