Skip to content

Commit

Permalink
aarch64:vfp: fix vfp ctx changed in kernel
Browse files Browse the repository at this point in the history
issue: #16

--------
1 Exception doesn't save VFP registers
2 kernel generate code shouldn't use VFP registers,
  need close -neon and -fp-armv8
3 taskctx need save/restore user application VFP ctx,
  need access VFP registers

After rustc update, it would complain when 2&3 happend,
on this commit :65a4f5896317115cf1edc74800f0da5d92923243,
opened neon when fp_smid enable,it broken 2, so it create
bug; after return user from kernel trap, usr vfp registers
ctx are changed;

This commit close neon when complie kernel, taskctx need access
VFP registers through build.rs to fix

Signed-off-by: guoweikang <[email protected]>
  • Loading branch information
guoweikang authored and Azure-stars committed Jul 31, 2024
1 parent 5642cdd commit 87f6cbc
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 49 deletions.
6 changes: 1 addition & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,7 @@ ifeq ($(ARCH), x86_64)
else ifeq ($(ARCH), riscv64)
TARGET := riscv64gc-unknown-none-elf
else ifeq ($(ARCH), aarch64)
ifeq ($(findstring fp_simd,$(FEATURES)),)
TARGET := aarch64-unknown-none-softfloat
else
TARGET := aarch64-unknown-none
endif
TARGET := aarch64-unknown-none-softfloat
endif

export AX_ARCH=$(ARCH)
Expand Down
3 changes: 0 additions & 3 deletions scripts/make/cargo.mk
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ all_packages := $(shell ls $(CURDIR)/crates)
define cargo_doc
$(call run_cmd,cargo doc,--no-deps --all-features --workspace --exclude "arceos-*" $(verbose))
@# run twice to fix broken hyperlinks
$(foreach p,$(all_packages), \
$(call run_cmd,cargo rustdoc,--all-features -p $(p) $(verbose))
)
@# for some crates, re-generate without `--all-features`
$(call run_cmd,cargo doc,--no-deps -p percpu $(verbose))
endef
49 changes: 49 additions & 0 deletions tools/axlibc/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use std::env;
use std::path::PathBuf;
use std::process::Command;

fn main() {
fn gen_c_to_rust_bindings(in_file: &str, out_file: &str) {
println!("cargo:rerun-if-changed={in_file}");
Expand All @@ -21,4 +25,49 @@ fn main() {
}

gen_c_to_rust_bindings("ctypes.h", "src/libctypes_gen.rs");

let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
if arch == "aarch64" {
aarch64_vfp_compile();
}
}

fn aarch64_vfp_compile() {
// 获取当前 crate 输出目录
let out_dir = env::var("OUT_DIR").unwrap();
// 指定汇编文件路径
let asm_file = PathBuf::from("src/vfp_setjmp.S");
let asm_out_file = PathBuf::from(&out_dir).join("vfp_setjmp.o");

// 编译汇编文件,增加 target-feature 选项
let status = Command::new("clang")
.args(&[
"-c",
asm_file.to_str().unwrap(),
"-o",
asm_out_file.to_str().unwrap(),
"-target",
"aarch64-unknown-none",
"-mfpu=neon",
])
.status()
.expect("failed to execute clang");
assert!(status.success(), "clang failed to compile assembly file");

// 打包对象文件为静态库
let lib_out_file = PathBuf::from(&out_dir).join("libvfp_setjmp.a");
let status = Command::new("ar")
.args(&[
"crus",
lib_out_file.to_str().unwrap(),
asm_out_file.to_str().unwrap(),
])
.status()
.expect("failed to execute ar");
assert!(status.success(), "ar failed to create static library");

// 指示 rustc 链接器链接汇编对象文件
println!("cargo:rerun-if-changed=src/vfp_setjmp.S");
println!("cargo:rustc-link-search={}", out_dir);
println!("cargo:rustc-link-lib=static=vfp_setjmp");
}
65 changes: 24 additions & 41 deletions tools/axlibc/src/setjmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,24 @@ use core::ffi::c_int;

use crate::ctypes;

/// `setjmp` implementation
#[cfg(all(target_arch = "aarch64", feature = "fp_simd"))]
extern "C" {
fn vfp_setjmp(buf: *mut ctypes::__jmp_buf_tag);
fn vfp_longjmp(buf: *mut ctypes::__jmp_buf_tag, _val: c_int) -> !;
}

#[cfg(all(target_arch = "aarch64", feature = "fp_simd"))]
#[no_mangle]
#[allow(missing_docs)]
pub unsafe extern "C" fn setjmp(_buf: *mut ctypes::__jmp_buf_tag) {
vfp_setjmp(_buf);
}

#[cfg(not(all(target_arch = "aarch64", feature = "fp_simd")))]
#[naked]
#[allow(missing_docs)]
#[no_mangle]
pub unsafe extern "C" fn setjmp(_buf: *mut ctypes::__jmp_buf_tag) {
#[cfg(all(target_arch = "aarch64", feature = "fp_simd"))]
core::arch::asm!(
"
stp x19, x20, [x0,#0]
stp x21, x22, [x0,#16]
stp x23, x24, [x0,#32]
stp x25, x26, [x0,#48]
stp x27, x28, [x0,#64]
stp x29, x30, [x0,#80]
mov x2, sp
str x2, [x0,#104]
stp d8, d9, [x0,#112]
stp d10, d11, [x0,#128]
stp d12, d13, [x0,#144]
stp d14, d15, [x0,#160]
mov x0, #0
ret",
options(noreturn),
);
#[cfg(all(target_arch = "aarch64", not(feature = "fp_simd")))]
core::arch::asm!(
"
Expand Down Expand Up @@ -119,30 +114,18 @@ pub unsafe extern "C" fn setjmp(_buf: *mut ctypes::__jmp_buf_tag) {
core::arch::asm!("ret", options(noreturn))
}

/// `longjmp` implementation
#[cfg(all(target_arch = "aarch64", feature = "fp_simd"))]
#[no_mangle]
#[allow(missing_docs)]
pub unsafe extern "C" fn longjmp(_buf: *mut ctypes::__jmp_buf_tag, _val: c_int) {
vfp_longjmp(_buf, _val);
}

#[cfg(not(all(target_arch = "aarch64", feature = "fp_simd")))]
#[allow(missing_docs)]
#[naked]
#[no_mangle]
pub unsafe extern "C" fn longjmp(_buf: *mut ctypes::__jmp_buf_tag, _val: c_int) -> ! {
#[cfg(all(target_arch = "aarch64", feature = "fp_simd"))]
core::arch::asm!(
"ldp x19, x20, [x0,#0]
ldp x21, x22, [x0,#16]
ldp x23, x24, [x0,#32]
ldp x25, x26, [x0,#48]
ldp x27, x28, [x0,#64]
ldp x29, x30, [x0,#80]
ldr x2, [x0,#104]
mov sp, x2
ldp d8 , d9, [x0,#112]
ldp d10, d11, [x0,#128]
ldp d12, d13, [x0,#144]
ldp d14, d15, [x0,#160]
cmp w1, 0
csinc w0, w1, wzr, ne
br x30",
options(noreturn),
);
#[cfg(all(target_arch = "aarch64", not(feature = "fp_simd")))]
core::arch::asm!(
"ldp x19, x20, [x0,#0]
Expand Down
37 changes: 37 additions & 0 deletions tools/axlibc/src/vfp_setjmp.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.section .text
.global vfp_setjmp
vfp_setjmp:
stp x19, x20, [x0,#0]
stp x21, x22, [x0,#16]
stp x23, x24, [x0,#32]
stp x25, x26, [x0,#48]
stp x27, x28, [x0,#64]
stp x29, x30, [x0,#80]
mov x2, sp
str x2, [x0,#104]
stp d8, d9, [x0,#112]
stp d10, d11, [x0,#128]
stp d12, d13, [x0,#144]
stp d14, d15, [x0,#160]
mov x0, #0
ret

.section .text
.global vfp_longjmp
vfp_longjmp:
ldp x19, x20, [x0,#0]
ldp x21, x22, [x0,#16]
ldp x23, x24, [x0,#32]
ldp x25, x26, [x0,#48]
ldp x27, x28, [x0,#64]
ldp x29, x30, [x0,#80]
ldr x2, [x0,#104]
mov sp, x2
ldp d8 , d9, [x0,#112]
ldp d10, d11, [x0,#128]
ldp d12, d13, [x0,#144]
ldp d14, d15, [x0,#160]

cmp w1, 0
csinc w0, w1, wzr, ne
br x30

0 comments on commit 87f6cbc

Please sign in to comment.