Skip to content

Commit

Permalink
update aarch64 hv part in arceos (#15)
Browse files Browse the repository at this point in the history
* Enable kvm in WSL2

* Implement From<VmFail> for AxError in crates/axerrno

* Export console_putchar&getchar in axhal

* Make handle_irq_extern in axhal public outside crate

* modify arceos to support aarch64 hypervisor: exception and axruntime TODO

* add register for exception handler

* remove some unnecessary modify

* modify some details in hv exception

* change synchronous handler register

* bugfix: fix the pte

Signed-off-by: buhenxihuan <1127751018@qq.com>

* bugfix: modify percpu_macros and platforms/config

Signed-off-by: buhenxihuan <1127751018@qq.com>

* modify lower aarch64 synchronous handler

* change qemu memory size to run aarch64 nimbos

* Fix device_id error in axdriver virtio probe_pci

* Update dependencies versions

* CI: set `continue-on-error = true` on each steps for nightliy build

* Rename organization rcore-os to arceos-org

* Update dependencies versions

---------

Signed-off-by: buhenxihuan <1127751018@qq.com>
Co-authored-by: hky1999 <976929993@qq.com>
Co-authored-by: buhenxihuan <1127751018@qq.com>
Co-authored-by: Yuekai Jia <equation618@gmail.com>
  • Loading branch information
4 people committed Aug 11, 2024
1 parent 3927a45 commit 7de34f6
Show file tree
Hide file tree
Showing 20 changed files with 716 additions and 11 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ VHOST ?= n
IP ?= 10.0.2.15
GW ?= 10.0.2.2

# Hypervisor options
HV ?= n

# App type
ifeq ($(wildcard $(APP)),)
$(error Application path "$(APP)" is not valid)
Expand Down Expand Up @@ -153,6 +156,10 @@ LD_SCRIPT := $(TARGET_DIR)/$(TARGET)/$(MODE)/linker_$(PLATFORM_NAME).lds
OUT_ELF := $(OUT_DIR)/$(APP_NAME)_$(PLATFORM_NAME).elf
OUT_BIN := $(OUT_DIR)/$(APP_NAME)_$(PLATFORM_NAME).bin

ifeq ($(HV), y)
LD_SCRIPT = $(CURDIR)/modules/axhal/linker_$(PLATFORM_NAME)_hv.lds
endif

all: build

include scripts/make/utils.mk
Expand Down
3 changes: 3 additions & 0 deletions api/axfeat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ driver-ramdisk = ["axdriver?/ramdisk", "axfs?/use-ramdisk"]
driver-ixgbe = ["axdriver?/ixgbe"]
driver-bcm2835-sdhci = ["axdriver?/bcm2835-sdhci"]

#Hypervisor support
hv = ["axhal/hv"]

# Logging
log-level-off = ["axlog/log-level-off"]
log-level-error = ["axlog/log-level-error"]
Expand Down
3 changes: 3 additions & 0 deletions modules/axconfig/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ documentation = "https://arceos-org.github.io/arceos/axconfig/index.html"
[build-dependencies]
toml_edit = "0.22"
serde = "1.0"

[features]
hv = []
6 changes: 5 additions & 1 deletion modules/axconfig/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ fn resolve_config_path(platform: Option<&str>) -> Result<PathBuf> {
let path = match platform {
None | Some("") => "defconfig.toml".into(),
Some(plat) if builtin_platforms.contains(&plat.to_string()) => {
config_dir.join(format!("{plat}.toml"))
if cfg!(feature = "hv" ) {
config_dir.join(format!("{plat}-hv.toml"))
}else {
config_dir.join(format!("{plat}.toml"))
}
}
Some(plat) => {
let path = PathBuf::from(&plat);
Expand Down
1 change: 1 addition & 0 deletions modules/axhal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ irq = []
tls = ["alloc"]
rtc = ["x86_rtc", "riscv_goldfish", "arm_pl031"]
default = []
hv = ["paging", "axconfig/hv", "percpu/hv"]

[dependencies]
log = "0.4"
Expand Down
22 changes: 19 additions & 3 deletions modules/axhal/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ fn make_cfg_values(str_list: &[&str]) -> String {
fn main() {
let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let platform = axconfig::PLATFORM;
let is_hv = get_is_hv();
if platform != "dummy" {
gen_linker_script(&arch, platform).unwrap();
gen_linker_script(&arch, platform, is_hv).unwrap();
}

println!("cargo:rustc-cfg=platform=\"{}\"", platform);
Expand All @@ -45,8 +46,11 @@ fn main() {
);
}

fn gen_linker_script(arch: &str, platform: &str) -> Result<()> {
let fname = format!("linker_{}.lds", platform);
fn gen_linker_script(arch: &str, platform: &str, is_hv: bool) -> Result<()> {
let mut fname = format!("linker_{}.lds", platform);
if is_hv {
fname = format!("linker_{}_hv.lds", platform);
}
let output_arch = if arch == "x86_64" {
"i386:x86-64"
} else if arch.contains("riscv") {
Expand All @@ -69,3 +73,15 @@ fn gen_linker_script(arch: &str, platform: &str) -> Result<()> {
std::fs::write(out_path, ld_content)?;
Ok(())
}

fn get_is_hv() -> bool {
let mut is_hv = false;
let hv_env = std::env::var("HV");
if hv_env.is_ok() {
let hv = hv_env.unwrap();
if hv == "y" {
is_hv = true;
}
}
is_hv
}
118 changes: 118 additions & 0 deletions modules/axhal/src/arch/aarch64/hv/exception.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
.macro SAVE_REGS_EL2
sub sp, sp, 34 * 8
stp x0, x1, [sp]
stp x2, x3, [sp, 2 * 8]
stp x4, x5, [sp, 4 * 8]
stp x6, x7, [sp, 6 * 8]
stp x8, x9, [sp, 8 * 8]
stp x10, x11, [sp, 10 * 8]
stp x12, x13, [sp, 12 * 8]
stp x14, x15, [sp, 14 * 8]
stp x16, x17, [sp, 16 * 8]
stp x18, x19, [sp, 18 * 8]
stp x20, x21, [sp, 20 * 8]
stp x22, x23, [sp, 22 * 8]
stp x24, x25, [sp, 24 * 8]
stp x26, x27, [sp, 26 * 8]
stp x28, x29, [sp, 28 * 8]

mov x1, sp
add x1, x1, #(0x110)
stp x30, x1, [sp, 30 * 8]
mrs x10, elr_el2
mrs x11, spsr_el2
stp x10, x11, [sp, 32 * 8]
.endm

.macro RESTORE_REGS_EL2
ldp x10, x11, [sp, 32 * 8]
msr elr_el2, x10
msr spsr_el2, x11

ldr x30, [sp, 30 * 8]
ldp x28, x29, [sp, 28 * 8]
ldp x26, x27, [sp, 26 * 8]
ldp x24, x25, [sp, 24 * 8]
ldp x22, x23, [sp, 22 * 8]
ldp x20, x21, [sp, 20 * 8]
ldp x18, x19, [sp, 18 * 8]
ldp x16, x17, [sp, 16 * 8]
ldp x14, x15, [sp, 14 * 8]
ldp x12, x13, [sp, 12 * 8]
ldp x10, x11, [sp, 10 * 8]
ldp x8, x9, [sp, 8 * 8]
ldp x6, x7, [sp, 6 * 8]
ldp x4, x5, [sp, 4 * 8]
ldp x2, x3, [sp, 2 * 8]
ldp x0, x1, [sp]
add sp, sp, 34 * 8
.endm


.macro INVALID_EXCP_EL2, kind, source
.p2align 7
SAVE_REGS_EL2
mov x0, sp
mov x1, \kind
mov x2, \source
bl invalid_exception_el2
b .Lexception_return_el2
.endm

.macro HANDLE_CURRENT_IRQ
.p2align 7
SAVE_REGS_EL2
mov x0, sp
bl handle_irq_exception
b .Lexception_return_el2
.endm

.macro HANDLE_LOWER_IRQ
.p2align 7
SAVE_REGS_EL2
mov x0, sp
bl invalid_exception_el2
b .Lexception_return_el2
.endm

.macro HANDLE_LOWER_SYNC
.p2align 7
SAVE_REGS_EL2
mov x0, sp
bl lower_aarch64_synchronous
b .Lexception_return_el2
.endm


.section .text
# .section .el2code
.p2align 11
.global exception_vector_base_el2
exception_vector_base_el2:
// current EL, with SP_EL0
INVALID_EXCP_EL2 0 0
INVALID_EXCP_EL2 1 0
INVALID_EXCP_EL2 2 0
INVALID_EXCP_EL2 3 0

// current EL, with SP_ELx
INVALID_EXCP_EL2 0 1
HANDLE_CURRENT_IRQ
INVALID_EXCP_EL2 2 1
INVALID_EXCP_EL2 3 1

// lower EL, aarch64
HANDLE_LOWER_SYNC
HANDLE_LOWER_IRQ
INVALID_EXCP_EL2 2 2
INVALID_EXCP_EL2 3 2

// lower EL, aarch32
INVALID_EXCP_EL2 0 3
INVALID_EXCP_EL2 1 3
INVALID_EXCP_EL2 2 3
INVALID_EXCP_EL2 3 3

.Lexception_return_el2:
RESTORE_REGS_EL2
eret
106 changes: 106 additions & 0 deletions modules/axhal/src/arch/aarch64/hv/exception.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) 2023 Beihang University, Huawei Technologies Co.,Ltd. All rights reserved.
// Rust-Shyper is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.

use super::exception_utils::*;
use core::arch::global_asm;
use tock_registers::interfaces::*;

global_asm!(include_str!("exception.S"));
use crate::arch::TrapFrame;

use core::sync::atomic::{AtomicUsize, Ordering};

type ExceptionHandler = fn(&mut TrapFrame);

const EMPTY_HANDLER_VALUE: AtomicUsize = AtomicUsize::new(0);

static LOWER_AARCH64_HANDLERS: [AtomicUsize; MAX_EXCEPTION_COUNT] =
[EMPTY_HANDLER_VALUE; MAX_EXCEPTION_COUNT];

const MAX_EXCEPTION_COUNT: usize = 64;

#[allow(dead_code)]
pub fn register_exception_handler_aarch64(exception_class: usize, handler: ExceptionHandler) -> bool {
if exception_class < MAX_EXCEPTION_COUNT {
LOWER_AARCH64_HANDLERS[exception_class].store(handler as usize, Ordering::SeqCst);
return true;
}
return false;
}

fn call_handler(exception_class: usize, tf: &mut TrapFrame) -> bool {
if exception_class < MAX_EXCEPTION_COUNT {
let handler = LOWER_AARCH64_HANDLERS[exception_class].load(Ordering::Acquire);
if handler != 0 {
let handler: ExceptionHandler = unsafe { core::mem::transmute(handler) };
handler(tf);
return true;
} else {
return false;
}
}else {
false
}
}

#[repr(u8)]
#[derive(Debug)]
#[allow(dead_code)]
enum TrapKind {
Synchronous = 0,
Irq = 1,
Fiq = 2,
SError = 3,
}

#[repr(u8)]
#[derive(Debug)]
#[allow(dead_code)]
enum TrapSource {
CurrentSpEl0 = 0,
CurrentSpElx = 1,
LowerAArch64 = 2,
LowerAArch32 = 3,
}

/// deal with invalid aarch64 synchronous exception
#[no_mangle]
fn invalid_exception_el2(tf: &mut TrapFrame, kind: TrapKind, source: TrapSource) {
panic!(
"Invalid exception {:?} from {:?}:\n{:#x?}",
kind, source, tf
);
}

// /// deal with lower aarch64 interruption exception
// #[no_mangle]
// fn current_spxel_irq(ctx: &mut TrapFrame) {
// lower_aarch64_irq(ctx);
// }

// /// deal with lower aarch64 interruption exception
// #[no_mangle]
// fn lower_aarch64_irq(ctx: &mut TrapFrame) {
// let (irq, src) = gicc_get_current_irq();
// debug!("src {} id{}", src, irq);
// crate::trap::handle_irq_extern_hv(irq, src, ctx);
// }

/// deal with lower aarch64 synchronous exception
#[no_mangle]
fn lower_aarch64_synchronous(tf: &mut TrapFrame) {
debug!(
"enter lower_aarch64_synchronous exception class:0x{:X}",
exception_class()
);
// 0x16: hvc_handler
// 0x24: data_abort_handler
call_handler(exception_class(), tf);
}
Loading

0 comments on commit 7de34f6

Please sign in to comment.