diff --git a/Cargo.toml b/Cargo.toml index 2319a78d..e56de447 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,8 @@ ksync = { path = "core/ksync" } ktask = { path = "core/ktask" } watchdog = { path = "io/watchdog" } kcpu = { path = "arch/kcpu" } +karch = { path = "arch/karch" } + # x-kernel Crates alloc-engine = { path = "mm/alloc-engine" } @@ -128,7 +130,6 @@ net = { path = "drivers/net" } pci = { path = "drivers/pci" } vsock = { path = "drivers/vsock" } virtio = { path = "drivers/virtio" } -virtio-drivers = { version = "0.12.0", default-features = false } aarch64-pmuv3 = { path = "drivers/aarch64-pmuv3" } fatfs = { path = "fs/fatfs", default-features = false } rsext4 = { path = "fs/rsext4", default-features = false } @@ -144,3 +145,4 @@ kbuild_config = { path = "util/kbuild_config" } kconfig-gen = { path = "xtask/kconfig-gen" } smoltcp = { version = "0.12.0", package = "x-smoltcp", default-features = false } +virtio-drivers = { version = "0.7.4", default-features = false } \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..4bda5e9d --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,69 @@ +#!/usr/bin/env groovy + +pipeline { + agent { + docker { + image 'yeanwang/x-kernel-builder:v1.0' + args '-v /var/run/docker.sock:/var/run/docker.sock --privileged -u root:root' } + } + + environment { + CI = 'true' + TEST_HARNESS_REPO = 'https://gitee.com/openkylin/starry-test-harness' + TEST_HARNESS_BRANCH = 'master' + } + + stages { + stage('Parallel Architecture Verification') { + failFast true + parallel { + stage('Architecture: aarch64') { + steps { + script { executeBuildAndTest('aarch64') } + } + } + stage('Architecture: x86_64') { + steps { + script { executeBuildAndTest('x86_64') } + } + } + } + } + } + + post { + always { + archiveArtifacts artifacts: '**/artifacts/**/*', allowEmptyArchive: true + archiveArtifacts artifacts: '**/logs/**/*', allowEmptyArchive: true + cleanWs() + } + success { + updateGiteeCommitStatus state: 'success', context: 'ci/jenkins' + } + unsuccessful { + updateGiteeCommitStatus state: 'failed', context: 'ci/jenkins' + } + } +} + +def executeBuildAndTest(arch) { + ws("${WORKSPACE}/${arch}") { + echo "Verifying architecture: ${arch}" + + checkout scm + sh "git config --global --add safe.directory ${pwd()}" + dir('test-harness') { + git branch: "${env.TEST_HARNESS_BRANCH}", + url: "${env.TEST_HARNESS_REPO}", + credentialsId: 'gitee-my-token' + + sh "git config --global --add safe.directory ${pwd()}" + } + + dir('test-harness') { + withEnv(["XKERNEL_ROOT=${pwd()}/..", "ARCH=${arch}"]) { + sh "make ci-test run" + } + } + } +} diff --git a/Makefile b/Makefile index c7f2943f..ef14d133 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,8 @@ # Enable unstable features export RUSTC_BOOTSTRAP := 1 export DWARF := y +export DISK_IMG ?= $(PWD)/disk.img +XCONF = env RUSTFLAGS= CARGO_ENCODED_RUSTFLAGS= cargo run --manifest-path xtask/xconfig/Cargo.toml --bin xconf -- V ?= LTO ?= @@ -94,6 +96,9 @@ GDB ?= gdb OUT_DIR ?= $(PWD) LD_SCRIPT ?= $(abspath $(TARGET_DIR)/$(TARGET)/$(MODE)/linker_$(PLAT_NAME).lds) +# Generate Rust const definitions from .config +CONFIG_RS := $(TARGET_DIR)/kbuild/config.rs + APP_NAME := xkernel OUT_ELF := $(OUT_DIR)/$(APP_NAME)_$(PLAT_NAME).elf OUT_BIN := $(patsubst %.elf,%.bin,$(OUT_ELF)) @@ -116,14 +121,14 @@ else ifeq ($(PLAT_NAME), aarch64-bsta1000b) include scripts/make/bsta1000b-fada.mk endif -ROOTFS_URL = https://github.com/Starry-OS/rootfs/releases/download/20250917 +ROOTFS_URL = https://gitee.com/openkylin/x-kernel-image/releases/download/20260302/ ROOTFS_IMG = rootfs-$(ARCH).img endif # end of IS_BUILD menuconfig: - @xconf menuconfig -k Kconfig -s . + @$(XCONF) menuconfig -k Kconfig -s . @if [ -f .config ]; then \ echo "✅ Configuration saved to .config"; \ else \ @@ -142,11 +147,11 @@ teefs: $(MAKE) -C tee_apps ARCH=$(ARCH) defconfig: - @xconf saveconfig -o .config -k Kconfig -s . + @$(XCONF) saveconfig -o .config -k Kconfig -s . @echo "✅ Default configuration saved to .config" saveconfig: - @xconf saveconfig -o .config -k Kconfig -s . + @$(XCONF) saveconfig -o .config -k Kconfig -s . oldconfig: @if [ ! -f .config ]; then \ @@ -154,15 +159,20 @@ oldconfig: echo "Please run 'make defconfig' or 'make menuconfig' first."; \ exit 1; \ fi - @xconf oldconfig -c .config -k Kconfig -s . + @$(XCONF) oldconfig -c .config -k Kconfig -s . -# Generate const definitions before build -gen-const: .config + +# 只在 .config 更新时才生成 +$(CONFIG_RS): .config @echo "📝 Generating Rust const definitions from .config..." - @xconf gen-const + @$(XCONF) gen-const @echo "✅ Generated config.rs" -build: gen-const $(OUT_DIR) $(FINAL_IMG) + +# Generate const definitions before build +gen-const: $(CONFIG_RS) + +build: $(CONFIG_RS) $(OUT_DIR) $(FINAL_IMG) disasm: $(OBJDUMP) $(OUT_ELF) | less @@ -180,7 +190,7 @@ debug: build -ex 'continue' \ -ex 'disp /16i $$pc' -clippy: gen-const +clippy: $(CONFIG_RS) ifeq ($(origin ARCH), command line) $(call cargo_clippy,--target $(TARGET)) else @@ -221,6 +231,8 @@ distclean: clean clean_c:: rm -rf $(app-objs) +# Note: gen-const is kept as PHONY to allow manual invocation, +# but the actual dependency is on $(CONFIG_RS) which is file-based .PHONY: all defconfig oldconfig menuconfig saveconfig gen-const \ build disasm run justrun debug \ clippy doc doc_check_missing fmt fmt_c unittest unittest_no_fail_fast \ diff --git a/api/kapi/src/tee/README.md b/api/kapi/src/tee/README.md new file mode 100644 index 00000000..e8f16f7e --- /dev/null +++ b/api/kapi/src/tee/README.md @@ -0,0 +1,7 @@ +# tee + +rust implement for tee core + +## arch + +hygon_csv_bindings.rs is auto generated by repo https://gitee.com/kylinyubo/rust-csv-guest-module-tools. diff --git a/api/kapi/src/tee/arch/mod.rs b/api/kapi/src/tee/arch/mod.rs index 832557ef..2fe50193 100644 --- a/api/kapi/src/tee/arch/mod.rs +++ b/api/kapi/src/tee/arch/mod.rs @@ -1,2 +1,6 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[cfg(target_arch = "x86_64")] pub mod x86_64; diff --git a/api/kapi/src/tee/arch/x86_64/hygon_csv.rs b/api/kapi/src/tee/arch/x86_64/hygon_csv.rs index bf3406ec..f59b4e4d 100644 --- a/api/kapi/src/tee/arch/x86_64/hygon_csv.rs +++ b/api/kapi/src/tee/arch/x86_64/hygon_csv.rs @@ -93,7 +93,7 @@ pub fn get_huk_key(huk_key: &mut [u8]) -> TeeResult { let salt = "Hygon CSV Sealing Key"; Hkdf::hkdf(MdType::SM3, &salt.as_bytes(), sealing_key, &[], huk_key) .map_err(|_| TEE_ERROR_BAD_PARAMETERS)?; - warn!("get_huk_key: huk_key: {:?}", slice_fmt(huk_key)); + // warn!("get_huk_key: huk_key: {:?}", slice_fmt(huk_key)); Ok(()) } diff --git a/api/kapi/src/tee/arch/x86_64/hygon_csv_bindings.rs b/api/kapi/src/tee/arch/x86_64/hygon_csv_bindings.rs index 4d19dc4f..a97c2099 100644 --- a/api/kapi/src/tee/arch/x86_64/hygon_csv_bindings.rs +++ b/api/kapi/src/tee/arch/x86_64/hygon_csv_bindings.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + // automatically generated by rust-bindgen 0.69.5 #[repr(C)] diff --git a/api/kapi/src/tee/arch/x86_64/mod.rs b/api/kapi/src/tee/arch/x86_64/mod.rs index 48398ccb..3707c056 100644 --- a/api/kapi/src/tee/arch/x86_64/mod.rs +++ b/api/kapi/src/tee/arch/x86_64/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[cfg(feature = "x86_csv")] pub mod hygon_csv; #[cfg(feature = "x86_csv")] diff --git a/api/kapi/src/tee/crypto_temp/aes_ecb.rs b/api/kapi/src/tee/crypto_temp/aes_ecb.rs deleted file mode 100644 index 1b457906..00000000 --- a/api/kapi/src/tee/crypto_temp/aes_ecb.rs +++ /dev/null @@ -1,220 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -use alloc::boxed::Box; - -use mbedtls_sys_auto::{ - AES_DECRYPT, AES_ENCRYPT, aes_context, aes_crypt_ecb, aes_free, aes_init, aes_setkey_dec, - aes_setkey_enc, -}; -use tee_raw_sys::{TEE_ERROR_BAD_PARAMETERS, TEE_ERROR_BAD_STATE, TEE_OperationMode}; - -use super::crypto_hash_temp::{CryptoCipherCtx, CryptoCipherOps}; -use crate::tee::{TeeResult, common::array, utee_defines::TEE_AES_BLOCK_SIZE, utils::slice_fmt}; - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct MbedAesEcbCtx { - mbed_mode: i32, - aes_ctx: aes_context, -} - -fn mbed_aes_ecb_init( - ctx: &mut MbedAesEcbCtx, - mode: TEE_OperationMode, - key1: Option<&[u8]>, - _key2: Option<&[u8]>, - _iv: Option<&[u8]>, -) -> TeeResult { - tee_debug!("mbed_aes_ecb_init: mode: {:?}, key1: {:?}", mode, key1); - let (key1_ptr, key1_len) = array::get_const_ptr_and_len(key1); - - unsafe { aes_init(&mut ctx.aes_ctx) }; - - let mbed_res = match mode { - TEE_OperationMode::TEE_MODE_ENCRYPT => { - ctx.mbed_mode = AES_ENCRYPT; - unsafe { aes_setkey_enc(&mut ctx.aes_ctx, key1_ptr, key1_len as u32 * 8) } - } - TEE_OperationMode::TEE_MODE_DECRYPT => { - ctx.mbed_mode = AES_DECRYPT; - unsafe { aes_setkey_dec(&mut ctx.aes_ctx, key1_ptr, key1_len as u32 * 8) } - } - _ => { - return Err(TEE_ERROR_BAD_PARAMETERS); - } - }; - - if mbed_res != 0 { - return Err(TEE_ERROR_BAD_STATE); - } - - Ok(()) -} - -fn mbed_aes_ecb_update( - ctx: &mut MbedAesEcbCtx, - _last_block: bool, - data: Option<&[u8]>, - dst: Option<&mut [u8]>, -) -> TeeResult { - let (data_ptr, data_len) = array::get_const_ptr_and_len(data); - let (dst_ptr, _dst_len) = array::get_mut_ptr_and_len(dst); - - if data_len % TEE_AES_BLOCK_SIZE != 0 { - return Err(TEE_ERROR_BAD_PARAMETERS); - } - - tee_debug!( - "mbed_aes_ecb_update: mode: {:?}, data_len: {:?}, dst_len: {:?}", - ctx.mbed_mode, - data_len, - _dst_len - ); - - // AES ECB processes one block (16 bytes) at a time - let num_blocks = data_len / TEE_AES_BLOCK_SIZE; - for i in 0..num_blocks { - let input_block = unsafe { data_ptr.add(i * TEE_AES_BLOCK_SIZE) }; - let output_block = unsafe { dst_ptr.add(i * TEE_AES_BLOCK_SIZE) }; - - let mbed_res = - unsafe { aes_crypt_ecb(&mut ctx.aes_ctx, ctx.mbed_mode, input_block, output_block) }; - - if mbed_res != 0 { - return Err(TEE_ERROR_BAD_STATE); - } - } - - Ok(()) -} - -fn mbed_aes_ecb_final(ctx: &mut MbedAesEcbCtx) { - unsafe { aes_free(&mut ctx.aes_ctx as *mut aes_context) }; -} - -// optee_os, the context is allocated by function crypto_aes_ecb_alloc_ctx, so need free it manually. -// in libmbedtls, the context is owned by Box with function alloc_cipher_ctx, freed automatically -// when it goes out of scope. -// So this function is a no-op in this case. -fn mbed_aes_ecb_free_ctx(_ctx: &mut MbedAesEcbCtx) {} - -fn mbed_aes_ecb_copy_state(dst_ctx: &mut MbedAesEcbCtx, src_ctx: &MbedAesEcbCtx) { - dst_ctx.mbed_mode = src_ctx.mbed_mode; - dst_ctx.aes_ctx = src_ctx.aes_ctx; -} - -impl CryptoCipherOps for MbedAesEcbCtx { - fn init( - &mut self, - mode: TEE_OperationMode, - key1: Option<&[u8]>, - key2: Option<&[u8]>, - iv: Option<&[u8]>, - ) -> TeeResult { - mbed_aes_ecb_init(self, mode, key1, key2, iv) - } - - fn update( - &mut self, - last_block: bool, - data: Option<&[u8]>, - dst: Option<&mut [u8]>, - ) -> TeeResult { - mbed_aes_ecb_update(self, last_block, data, dst) - } - - fn finalize(&mut self) { - mbed_aes_ecb_final(self) - } - - fn free_ctx(&mut self) { - mbed_aes_ecb_free_ctx(self) - } - - fn copy_state(&self, dst_ctx: &mut MbedAesEcbCtx) { - mbed_aes_ecb_copy_state(dst_ctx, self); - } -} - -impl CryptoCipherCtx for MbedAesEcbCtx { - type Context = MbedAesEcbCtx; - - fn alloc_cipher_ctx() -> Result, TeeResult> { - let ctx = MbedAesEcbCtx { - mbed_mode: 0, - aes_ctx: aes_context::default(), - }; - - Ok(Box::new(ctx)) - } -} - -#[cfg(feature = "tee_test")] -pub mod tests_aes_ecb { - use hashbrown::hash_map::Keys; - use unittest::{ - test_fn, test_framework::TestDescriptor, test_framework_basic::TestResult, tests_name, - }; - - use super::*; - use crate::tee::utils::random_bytes; - - test_fn! { - using TestResult; - - fn test_tee_aes_ecb_init_update_final() { - // test encrypt - let plaintext = [1u8; 16]; - let Key = [2u8; 16]; - let mut ciphertext = [0u8; 16]; - let mut ctx = MbedAesEcbCtx::alloc_cipher_ctx().expect("Failed to allocate AES ECB context"); - let _ = ctx.init(TEE_OperationMode::TEE_MODE_ENCRYPT, Some(&Key), None, None).expect("Failed to initialize AES ECB context"); - let _ = ctx.update(true, Some(&plaintext), Some(&mut ciphertext)).expect("Failed to update AES ECB context"); - ctx.finalize(); - tee_debug!("ciphertext: {:?}", slice_fmt(&ciphertext)); - // test decrypt - let mut decrypted_text = [0u8; 16]; - let _ = ctx.init(TEE_OperationMode::TEE_MODE_DECRYPT, Some(&Key), None, None).expect("Failed to initialize AES ECB context"); - let _ = ctx.update(true, Some(&ciphertext), Some(&mut decrypted_text)).expect("Failed to update AES ECB context"); - ctx.finalize(); - tee_debug!("decrypted_text: {:?}", slice_fmt(&decrypted_text)); - assert_eq!(decrypted_text, plaintext); - } - } - - test_fn! { - using TestResult; - - fn test_tee_aes_ecb_init_update_final_long() { - // test encrypt - let mut plaintext = [1u8; 256]; - // randomize the plaintext, using randChacha - random_bytes(&mut plaintext); - - let Key = [2u8; 16]; - let mut ciphertext = [0u8; 256]; - let mut ctx = MbedAesEcbCtx::alloc_cipher_ctx().expect("Failed to allocate AES ECB context"); - let _ = ctx.init(TEE_OperationMode::TEE_MODE_ENCRYPT, Some(&Key), None, None).expect("Failed to initialize AES ECB context"); - let _ = ctx.update(true, Some(&plaintext), Some(&mut ciphertext)).expect("Failed to update AES ECB context"); - ctx.finalize(); - // tee_debug!("ciphertext: {:?}", slice_fmt(&ciphertext)); - // test decrypt - let mut decrypted_text = [0u8; 256]; - let _ = ctx.init(TEE_OperationMode::TEE_MODE_DECRYPT, Some(&Key), None, None).expect("Failed to initialize AES ECB context"); - let _ = ctx.update(true, Some(&ciphertext), Some(&mut decrypted_text)).expect("Failed to update AES ECB context"); - ctx.finalize(); - tee_debug!("decrypted_text: {:?}", slice_fmt(&decrypted_text)); - assert_eq!(decrypted_text, plaintext); - } - } - - tests_name! { - TEST_TEE_AES_ECB; - //------------------------ - aes_ecb; - test_tee_aes_ecb_init_update_final, - test_tee_aes_ecb_init_update_final_long, - } -} diff --git a/api/kapi/src/tee/crypto_temp/crypto_hash_temp.rs b/api/kapi/src/tee/crypto_temp/crypto_hash_temp.rs deleted file mode 100644 index 2cd03d8e..00000000 --- a/api/kapi/src/tee/crypto_temp/crypto_hash_temp.rs +++ /dev/null @@ -1,259 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -use alloc::boxed::Box; - -use mbedtls::hash::{Md, Type}; -use tee_raw_sys::{ - TEE_ALG_AES_ECB_NOPAD, TEE_ALG_HMAC_MD5, TEE_ALG_HMAC_SHA1, TEE_ALG_HMAC_SHA256, - TEE_ALG_HMAC_SHA512, TEE_ALG_HMAC_SM3, TEE_ALG_MD5, TEE_ALG_SHA256, TEE_ALG_SHA512, - TEE_ALG_SM3, TEE_ALG_SM4_ECB_NOPAD, TEE_ERROR_BAD_PARAMETERS, TEE_ERROR_BAD_STATE, - TEE_ERROR_NOT_IMPLEMENTED, TEE_OperationMode, -}; - -use crate::tee::{ - TeeResult, - crypto_temp::{aes_ecb::MbedAesEcbCtx, sm4_ecb::MbedSm4EcbCtx}, - utee_defines::TeeAlg, -}; - -pub trait HashOps { - fn init(&mut self, key: &[u8]) -> TeeResult; - fn update(&mut self, data: &[u8]) -> TeeResult; - fn finalize(&mut self, digest: &mut [u8]) -> TeeResult; - fn free_ctx(&mut self); - fn copy_state(&self, dst_ctx: &mut dyn HashOps) -> TeeResult; -} - -// 添加MacAlgorithmTrait trait -pub trait MacAlgorithmTrait { - type Context: HashOps + 'static; - - fn alloc_hash() -> Result; -} - -pub trait HashAlgorithm { - type Ops: HashOps + 'static; - - fn get_ops() -> &'static Self::Ops; - // fn get_md_type() -> mbedtls_md_type_t; -} - -pub struct MbedCtx; - -// 具体的MAC算法实现 -// HMAC-SHA256 -#[allow(dead_code)] -pub struct HmacSha256 { - inner: MbedCtx, -} -#[allow(dead_code)] -pub struct HmacSha512 { - inner: MbedCtx, -} - -impl HashOps for HmacSha256 { - fn init(&mut self, _key: &[u8]) -> TeeResult { - debug!("HashOps with HmacSha256"); - Ok(()) - } - - fn update(&mut self, _data: &[u8]) -> TeeResult { - Ok(()) - } - - fn finalize(&mut self, _digest: &mut [u8]) -> TeeResult { - Ok(()) - } - - fn free_ctx(&mut self) { - // 这里应该释放资源,但返回类型是() - } - - fn copy_state(&self, _dst_ctx: &mut dyn HashOps) -> TeeResult { - Ok(()) - } -} - -// 为HmacSha256实现MacAlgorithmTrait -impl MacAlgorithmTrait for HmacSha256 { - type Context = HmacSha256; - - fn alloc_hash() -> Result { - Ok(HmacSha256 { inner: MbedCtx }) - } -} - -impl HashOps for HmacSha512 { - fn init(&mut self, _key: &[u8]) -> TeeResult { - Ok(()) - } - - fn update(&mut self, _data: &[u8]) -> TeeResult { - Ok(()) - } - - fn finalize(&mut self, _digest: &mut [u8]) -> TeeResult { - Ok(()) - } - - fn free_ctx(&mut self) { - // 这里应该释放资源,但返回类型是() - } - - fn copy_state(&self, _dst_ctx: &mut dyn HashOps) -> TeeResult { - Ok(()) - } -} - -// 为HmacSha512实现MacAlgorithmTrait -impl MacAlgorithmTrait for HmacSha512 { - type Context = HmacSha512; - - fn alloc_hash() -> Result { - Ok(HmacSha512 { inner: MbedCtx }) - } -} - -// 工厂方法:根据hash_id生成不同的HMAC实例 -pub fn crypto_mac_alloc_ctx(algorithm: TeeAlg) -> Result, TeeResult> { - match algorithm { - TEE_ALG_HMAC_SHA256 => { - let ctx: HmacSha256 = HmacSha256::alloc_hash()?; - Ok(Box::new(ctx)) - } - TEE_ALG_HMAC_SHA512 => { - let ctx = HmacSha512::alloc_hash()?; - Ok(Box::new(ctx)) - } - _ => Err(Err(TEE_ERROR_BAD_PARAMETERS)), - } -} - -pub trait CryptoCipherOps { - fn init( - &mut self, - mode: TEE_OperationMode, - key1: Option<&[u8]>, - key2: Option<&[u8]>, - iv: Option<&[u8]>, - ) -> TeeResult; - fn update( - &mut self, - last_block: bool, - data: Option<&[u8]>, - dst: Option<&mut [u8]>, - ) -> TeeResult; - fn finalize(&mut self); - fn free_ctx(&mut self); - fn copy_state(&self, dst_ctx: &mut MbedAesEcbCtx); -} - -pub trait CryptoCipherCtx { - type Context; - - fn alloc_cipher_ctx() -> Result, TeeResult>; -} -pub trait CryptoHashOps { - fn init(&mut self) -> TeeResult; - fn update(&mut self, data: Option<&[u8]>) -> TeeResult; - fn finalize(&mut self, digest: Option<&mut [u8]>) -> TeeResult; - fn free_ctx(&mut self); - fn copy_state(&self, dst_ctx: &mut Self); -} - -// pub fn crypto_mac_alloc_ctx() -> Result { -// A::alloc_ctx() -// } - -/// Convert TeeAlg to mbedtls::hash::Type -/// This is a helper function instead of TryFrom implementation due to Rust's orphan rule -fn tee_alg_to_hash_type(value: TeeAlg) -> Result { - match value { - TEE_ALG_MD5 => Ok(Type::Md5), - TEE_ALG_SHA256 => Ok(Type::Sha256), - TEE_ALG_SHA512 => Ok(Type::Sha512), - TEE_ALG_SM3 => Ok(Type::SM3), - _ => Err(TEE_ERROR_NOT_IMPLEMENTED), - } -} - -/// Convert TeeAlg to mbedtls::hash::Type -/// This is a helper function instead of TryFrom implementation due to Rust's orphan rule -pub fn tee_alg_to_hmac_type(value: TeeAlg) -> TeeResult { - match value { - TEE_ALG_HMAC_MD5 => Ok(Type::Md5), - TEE_ALG_HMAC_SHA1 => Ok(Type::Sha1), - TEE_ALG_HMAC_SHA256 => Ok(Type::Sha256), - TEE_ALG_HMAC_SHA512 => Ok(Type::Sha512), - TEE_ALG_HMAC_SM3 => Ok(Type::SM3), - _ => Err(TEE_ERROR_NOT_IMPLEMENTED), - } -} - -pub fn crypto_cipher_alloc_ctx(algo: TeeAlg) -> Result, TeeResult> { - match algo { - TEE_ALG_AES_ECB_NOPAD => { - let ctx: MbedAesEcbCtx = *MbedAesEcbCtx::alloc_cipher_ctx()?; - Ok(Box::new(ctx)) - } - TEE_ALG_SM4_ECB_NOPAD => { - let ctx: MbedSm4EcbCtx = *MbedSm4EcbCtx::alloc_cipher_ctx()?; - Ok(Box::new(ctx)) - } - _ => Err(Err(TEE_ERROR_NOT_IMPLEMENTED)), - } -} - -pub fn crypto_hash_free_ctx(ctx: &mut H) -where - H: CryptoHashOps, -{ - ctx.free_ctx(); -} - -// pub fn crypto_hash_copy_state(src: &H, dst: &mut H) -// where -// H: CryptoHashOps, -// { -// src.copy_state(dst) -// } - -// pub fn crypto_hash_alloc_ctx(t : Type) -> Result { -// let mut md = Md::new(t).map_err(|e| TeeResultCode::ErrorBadState)?; -// -// Ok(md) -// } - -pub fn crypto_hash_alloc_ctx(alg: TeeAlg) -> TeeResult { - let t = tee_alg_to_hash_type(alg)?; - let md = Md::new(t).map_err(|_| TEE_ERROR_BAD_STATE)?; - - Ok(md) -} - -pub fn crypto_hash_init(_md: &mut Md) -> TeeResult { - // initialized in Md.new - Ok(()) -} - -pub fn crypto_hash_update(md: &mut Md, data: &[u8]) -> TeeResult { - tee_debug!( - "crypto_hash_update: data length: {:?}, data: {:X?}", - data.len(), - hex::encode(data) - ); - md.update(data).map_err(|_| TEE_ERROR_BAD_STATE)?; - Ok(()) -} - -pub fn crypto_hash_final(md: Md, digest: &mut [u8]) -> TeeResult { - tee_debug!( - "crypto_hash_final: digest length: {:?}, digest: {:X?}", - digest.len(), - hex::encode(&digest) - ); - md.finish(digest).map_err(|_| TEE_ERROR_BAD_STATE)?; - Ok(()) -} diff --git a/api/kapi/src/tee/crypto_temp/hash.rs b/api/kapi/src/tee/crypto_temp/hash.rs deleted file mode 100644 index 129ce6ae..00000000 --- a/api/kapi/src/tee/crypto_temp/hash.rs +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -use tee_raw_sys::{TEE_ERROR_BAD_PARAMETERS, TEE_ERROR_BAD_STATE}; - -use super::crypto_hash_temp::CryptoHashOps; -use crate::tee::{TeeResult, common::array, utee_defines::TEE_MAX_HASH_SIZE}; -//--------------------from rust-mbedtls bindings.rs -------------------- -#[allow(non_camel_case_types)] -pub struct md_info_t {} -#[allow(dead_code)] -#[allow(non_camel_case_types)] -pub struct md_context_t<'a> { - md_info: &'a md_info_t, -} -#[allow(dead_code)] -pub fn md_starts(_ctx: *mut md_context_t) -> i32 { - 0 -} -#[allow(dead_code)] -pub fn md_update(_ctx: *mut md_context_t, _input: *const u8, _ilen: usize) -> u32 { - 0 -} -#[allow(dead_code)] -pub fn md_get_size(_md_info: *const md_info_t) -> u8 { - 32 // 假设返回 SHA-256 的大小 -} -#[allow(dead_code)] -pub fn md_finish(_ctx: *mut md_context_t, _output: *mut u8) -> i32 { - 0 -} -#[allow(dead_code)] -pub fn md_free(_ctx: *mut md_context_t) {} -#[allow(dead_code)] -pub fn md_clone(_dst: *mut md_context_t, _src: *const md_context_t) -> i32 { - 0 -} - -//-------------------- end rust-mbedtls bindings.rs -------------------- -#[allow(dead_code)] -pub struct MbedHashCtx<'a> { - md_context: md_context_t<'a>, -} - -impl CryptoHashOps for MbedHashCtx<'_> { - fn init(&mut self) -> TeeResult { - if md_starts(&mut self.md_context) != 0 { - Err(TEE_ERROR_BAD_STATE) - } else { - Ok(()) - } - } - - fn update(&mut self, buf: Option<&[u8]>) -> TeeResult { - let (buf_ptr, buf_len) = array::get_const_ptr_and_len(buf); - - if md_update(&mut self.md_context, buf_ptr, buf_len) != 0 { - Err(TEE_ERROR_BAD_STATE) - } else { - Ok(()) - } - } - - fn finalize(&mut self, digest: Option<&mut [u8]>) -> TeeResult { - let hash_size = md_get_size(self.md_context.md_info) as usize; - let mut block_digest = [0u8; TEE_MAX_HASH_SIZE]; // 内部的临时哈希缓冲区 - - if hash_size > block_digest.len() { - return Err(TEE_ERROR_BAD_STATE); - } - - match digest { - Some(user_buf) => { - let target_ptr = if user_buf.len() >= hash_size { - user_buf.as_mut_ptr() - } else { - block_digest.as_mut_ptr() - }; - - if md_finish(&mut self.md_context, target_ptr) != 0 { - return Err(TEE_ERROR_BAD_STATE); - } - - if user_buf.len() < hash_size { - let copy_len = user_buf.len(); - user_buf[..copy_len].copy_from_slice(&block_digest[..copy_len]); - } - } - None => { - return Err(TEE_ERROR_BAD_PARAMETERS); - } - } - - Ok(()) - } - - fn free_ctx(&mut self) { - md_free(&mut self.md_context); - } - - fn copy_state(&self, dst_ctx: &mut Self) { - if md_clone(&mut dst_ctx.md_context, &self.md_context) != 0 { - // TODO panic - } - } -} diff --git a/api/kapi/src/tee/crypto_temp/mod.rs b/api/kapi/src/tee/crypto_temp/mod.rs deleted file mode 100644 index 195723b3..00000000 --- a/api/kapi/src/tee/crypto_temp/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -// NOTE: !!!Temporary file for crypto operations.!!! -// !!! DO NOT ADD NEW FUNCTIONS TO THIS FILE !!! -// TODO: Remove this file after the crypto module are implemented. - -pub mod aes_ecb; -pub mod crypto_hash_temp; -pub mod hash; -pub mod sm4_ecb; diff --git a/api/kapi/src/tee/crypto_temp/sm4_ecb.rs b/api/kapi/src/tee/crypto_temp/sm4_ecb.rs deleted file mode 100644 index 01aacd27..00000000 --- a/api/kapi/src/tee/crypto_temp/sm4_ecb.rs +++ /dev/null @@ -1,156 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -use alloc::boxed::Box; - -use mbedtls_sys_auto::{ - sm4_context, sm4_crypt_ecb, sm4_free, sm4_init, sm4_setkey_dec, sm4_setkey_enc, -}; -use tee_raw_sys::{TEE_ERROR_BAD_PARAMETERS, TEE_ERROR_BAD_STATE, TEE_OperationMode}; - -use super::crypto_hash_temp::{CryptoCipherCtx, CryptoCipherOps}; -use crate::tee::{ - TeeResult, common::array, crypto_temp::aes_ecb::MbedAesEcbCtx, utee_defines::TEE_SM4_BLOCK_SIZE, -}; - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct MbedSm4EcbCtx { - mbed_mode: i32, // 1 for encrypt, 0 for decrypt - sm4_ctx: sm4_context, -} - -fn mbed_sm4_ecb_init( - ctx: &mut MbedSm4EcbCtx, - mode: TEE_OperationMode, - key1: Option<&[u8]>, - _key2: Option<&[u8]>, - _iv: Option<&[u8]>, -) -> TeeResult { - tee_debug!("mbed_sm4_ecb_init: mode: {:?}, key1: {:?}", mode, key1); - let (key1_ptr, key1_len) = array::get_const_ptr_and_len(key1); - - // if key1_len != 16 { - // return Err(TEE_ERROR_BAD_PARAMETERS); - // } - - unsafe { sm4_init(&mut ctx.sm4_ctx) }; - - let mbed_res = match mode { - TEE_OperationMode::TEE_MODE_ENCRYPT => { - ctx.mbed_mode = 1; // SM4_ENCRYPT - unsafe { sm4_setkey_enc(&mut ctx.sm4_ctx, key1_ptr, 128) } - } - TEE_OperationMode::TEE_MODE_DECRYPT => { - ctx.mbed_mode = 0; // SM4_DECRYPT - unsafe { sm4_setkey_dec(&mut ctx.sm4_ctx, key1_ptr, 128) } - } - _ => { - return Err(TEE_ERROR_BAD_PARAMETERS); - } - }; - - if mbed_res != 0 { - return Err(TEE_ERROR_BAD_STATE); - } - - Ok(()) -} - -fn mbed_sm4_ecb_update( - ctx: &mut MbedSm4EcbCtx, - _last_block: bool, - data: Option<&[u8]>, - dst: Option<&mut [u8]>, -) -> TeeResult { - let (data_ptr, data_len) = array::get_const_ptr_and_len(data); - let (dst_ptr, _dst_len) = array::get_mut_ptr_and_len(dst); - - if data_len % TEE_SM4_BLOCK_SIZE != 0 { - return Err(TEE_ERROR_BAD_PARAMETERS); - } - - tee_debug!( - "mbed_sm4_ecb_update: mode: {:?}, data_len: {:?}, dst_len: {:?}", - ctx.mbed_mode, - data_len, - _dst_len - ); - - // SM4 ECB processes one block (16 bytes) at a time - let num_blocks = data_len / TEE_SM4_BLOCK_SIZE; - for i in 0..num_blocks { - let input_block = unsafe { data_ptr.add(i * TEE_SM4_BLOCK_SIZE) }; - let output_block = unsafe { dst_ptr.add(i * TEE_SM4_BLOCK_SIZE) }; - - let mbed_res = - unsafe { sm4_crypt_ecb(&mut ctx.sm4_ctx, ctx.mbed_mode, input_block, output_block) }; - - if mbed_res != 0 { - return Err(TEE_ERROR_BAD_STATE); - } - } - - Ok(()) -} - -fn mbed_sm4_ecb_final(ctx: &mut MbedSm4EcbCtx) { - unsafe { sm4_free(&mut ctx.sm4_ctx as *mut sm4_context) }; -} - -fn mbed_sm4_ecb_free_ctx(_ctx: &mut MbedSm4EcbCtx) {} - -fn mbed_sm4_ecb_copy_state(dst_ctx: &mut MbedSm4EcbCtx, src_ctx: &MbedSm4EcbCtx) { - dst_ctx.mbed_mode = src_ctx.mbed_mode; - dst_ctx.sm4_ctx = src_ctx.sm4_ctx; -} - -impl CryptoCipherOps for MbedSm4EcbCtx { - fn init( - &mut self, - mode: TEE_OperationMode, - key1: Option<&[u8]>, - key2: Option<&[u8]>, - iv: Option<&[u8]>, - ) -> TeeResult { - mbed_sm4_ecb_init(self, mode, key1, key2, iv).inspect_err(|e| { - error!("mbed_sm4_ecb_init failed: {:X?}", e); - }) - } - - fn update( - &mut self, - last_block: bool, - data: Option<&[u8]>, - dst: Option<&mut [u8]>, - ) -> TeeResult { - mbed_sm4_ecb_update(self, last_block, data, dst) - } - - fn finalize(&mut self) { - mbed_sm4_ecb_final(self) - } - - fn free_ctx(&mut self) { - mbed_sm4_ecb_free_ctx(self) - } - - fn copy_state(&self, _dst_ctx: &mut MbedAesEcbCtx) { - // TODO: SM4 copy_state not implemented yet - // This is a placeholder implementation - } -} - -impl CryptoCipherCtx for MbedSm4EcbCtx { - type Context = MbedSm4EcbCtx; - - fn alloc_cipher_ctx() -> Result, TeeResult> { - let ctx = MbedSm4EcbCtx { - mbed_mode: 0, - sm4_ctx: sm4_context::default(), - }; - - Ok(Box::new(ctx)) - } -} diff --git a/api/kapi/src/tee/fs_htree.rs b/api/kapi/src/tee/fs_htree.rs index d72071a1..c04997cf 100644 --- a/api/kapi/src/tee/fs_htree.rs +++ b/api/kapi/src/tee/fs_htree.rs @@ -10,15 +10,16 @@ use cfg_if::cfg_if; use mbedtls::{ cipher::{Authenticated, Cipher, CipherData, Decryption, Encryption, Fresh, Operation, raw}, error::HiError::PemAllocFailed, - hash::Md, + hash::{Md, Type}, }; use memoffset::offset_of; use subtle::ConstantTimeEq; use tee_raw_sys::{ - TEE_ALG_AES_ECB_NOPAD, TEE_ALG_AES_GCM, TEE_ALG_HMAC_SHA256, TEE_ALG_HMAC_SM3, TEE_ALG_SHA256, - TEE_ALG_SM3, TEE_ALG_SM4_ECB_NOPAD, TEE_ALG_SM4_GCM, TEE_ERROR_BAD_PARAMETERS, - TEE_ERROR_CORRUPT_OBJECT, TEE_ERROR_GENERIC, TEE_ERROR_MAC_INVALID, TEE_ERROR_NOT_SUPPORTED, - TEE_ERROR_SECURITY, TEE_ERROR_SHORT_BUFFER, TEE_OperationMode, TEE_UUID, + TEE_ALG_AES_ECB_NOPAD, TEE_ALG_AES_GCM, TEE_ALG_HMAC_SHA256, TEE_ALG_HMAC_SM3, TEE_ALG_MD5, + TEE_ALG_SHA256, TEE_ALG_SHA512, TEE_ALG_SM3, TEE_ALG_SM4_ECB_NOPAD, TEE_ALG_SM4_GCM, + TEE_ERROR_BAD_PARAMETERS, TEE_ERROR_BAD_STATE, TEE_ERROR_CORRUPT_OBJECT, TEE_ERROR_GENERIC, + TEE_ERROR_MAC_INVALID, TEE_ERROR_NOT_IMPLEMENTED, TEE_ERROR_NOT_SUPPORTED, TEE_ERROR_SECURITY, + TEE_ERROR_SHORT_BUFFER, TEE_OperationMode, TEE_UUID, }; use super::utee_defines::{ @@ -27,9 +28,6 @@ use super::utee_defines::{ use crate::tee::{ TeeResult, common::file_ops::FileVariant, - crypto_temp::crypto_hash_temp::{ - crypto_hash_alloc_ctx, crypto_hash_final, crypto_hash_init, crypto_hash_update, - }, rng_software::crypto_rng_read, tee_fs_key_manager::{TEE_FS_KM_FEK_SIZE, tee_fs_fek_crypt}, tee_ree_fs::{BLOCK_SIZE, TeeFsFdAux, TeeFsHtreeStorageOps}, @@ -308,6 +306,48 @@ impl Debug for TeeFsHtree { } } +fn tee_alg_to_hash_type(value: TeeAlg) -> Result { + match value { + TEE_ALG_MD5 => Ok(Type::Md5), + TEE_ALG_SHA256 => Ok(Type::Sha256), + TEE_ALG_SHA512 => Ok(Type::Sha512), + TEE_ALG_SM3 => Ok(Type::SM3), + _ => Err(TEE_ERROR_NOT_IMPLEMENTED), + } +} + +fn crypto_hash_alloc_ctx(alg: TeeAlg) -> TeeResult { + let t = tee_alg_to_hash_type(alg)?; + let md = Md::new(t).map_err(|_| TEE_ERROR_BAD_STATE)?; + + Ok(md) +} + +fn crypto_hash_init(_md: &mut Md) -> TeeResult { + // initialized in Md.new + Ok(()) +} + +fn crypto_hash_update(md: &mut Md, data: &[u8]) -> TeeResult { + tee_debug!( + "crypto_hash_update: data length: {:?}, data: {:X?}", + data.len(), + hex::encode(data) + ); + md.update(data).map_err(|_| TEE_ERROR_BAD_STATE)?; + Ok(()) +} + +fn crypto_hash_final(md: Md, digest: &mut [u8]) -> TeeResult { + tee_debug!( + "crypto_hash_final: digest length: {:?}, digest: {:X?}", + digest.len(), + hex::encode(&digest) + ); + md.finish(digest).map_err(|_| TEE_ERROR_BAD_STATE)?; + Ok(()) +} + /// read the data from the storage /// /// # Arguments diff --git a/api/kapi/src/tee/mod.rs b/api/kapi/src/tee/mod.rs index 923d68e9..951d4c35 100644 --- a/api/kapi/src/tee/mod.rs +++ b/api/kapi/src/tee/mod.rs @@ -58,7 +58,6 @@ mod bitstring; mod common; mod config; mod crypto; -mod crypto_temp; mod fs_dirfile; mod fs_htree; #[cfg(feature = "tee_test")] diff --git a/api/kapi/src/tee/tee_fs_key_manager.rs b/api/kapi/src/tee/tee_fs_key_manager.rs index 149cbb62..918a9ff6 100644 --- a/api/kapi/src/tee/tee_fs_key_manager.rs +++ b/api/kapi/src/tee/tee_fs_key_manager.rs @@ -8,7 +8,12 @@ use core::mem::size_of; use cfg_if::cfg_if; use ksync::Mutex; use lazy_static::lazy_static; -use mbedtls::hash; +use mbedtls::{ + cipher, + cipher::raw::{Cipher, CipherId, CipherMode, Operation}, + hash, + hash::Type, +}; use static_assertions::const_assert; use tee_raw_sys::{ TEE_ALG_AES_ECB_NOPAD, TEE_ALG_HMAC_SHA256, TEE_ALG_HMAC_SM3, TEE_ALG_SM4_ECB_NOPAD, @@ -21,11 +26,7 @@ use super::{ huk_subkey::{HUK_SUBKEY_MAX_LEN, HukSubkeyUsage, huk_subkey_derive}, otp_stubs::{TeeHwUniqueKey, tee_otp_get_hw_unique_key}, utee_defines::{TEE_SHA256_HASH_SIZE, TEE_SM3_HASH_SIZE, TeeAlg}, -}; -use crate::tee::crypto_temp::{ - aes_ecb::MbedAesEcbCtx, - crypto_hash_temp::{CryptoCipherCtx, CryptoCipherOps, tee_alg_to_hmac_type}, - sm4_ecb::MbedSm4EcbCtx, + utils::slice_fmt, }; const TEE_FS_KM_CHIP_ID_LENGTH: usize = 32; @@ -82,17 +83,58 @@ lazy_static! { static ref TEE_FS_SSK: Mutex = Mutex::new(init_ssk()); } -pub fn crypto_cipher_alloc_ctx(algo: TeeAlg) -> Result, TeeResult> { - match algo { - TEE_ALG_AES_ECB_NOPAD => { - let ctx: MbedAesEcbCtx = *MbedAesEcbCtx::alloc_cipher_ctx()?; - Ok(Box::new(ctx)) - } - TEE_ALG_SM4_ECB_NOPAD => { - let ctx: MbedSm4EcbCtx = *MbedSm4EcbCtx::alloc_cipher_ctx()?; - Ok(Box::new(ctx)) - } - _ => Err(Err(TEE_ERROR_NOT_IMPLEMENTED)), +pub fn crypto_cipher_ecb_nopad( + algo: TeeAlg, + mode: TEE_OperationMode, + key: &[u8], + input: &[u8], + output: &mut [u8], +) -> TeeResult { + debug_assert!(key.len() >= 16); + + let (cipher_id, key_bytes) = match algo { + TEE_ALG_AES_ECB_NOPAD => (CipherId::Aes, key.len()), + TEE_ALG_SM4_ECB_NOPAD => (CipherId::SM4, 16), + _ => return Err(TEE_ERROR_NOT_IMPLEMENTED), + }; + + // 根据模式确定操作类型 + let operation = match mode { + TEE_OperationMode::TEE_MODE_ENCRYPT => Operation::Encrypt, + TEE_OperationMode::TEE_MODE_DECRYPT => Operation::Decrypt, + _ => return Err(TEE_ERROR_BAD_PARAMETERS), + }; + + // 使用 raw 接口创建 Cipher 实例 + let mut cipher_ctx = Cipher::setup(cipher_id, CipherMode::ECB, (key_bytes * 8) as u32) + .map_err(|_| TEE_ERROR_BAD_PARAMETERS)?; + + // 设置密钥 + cipher_ctx + .set_key(operation, &key[..key_bytes]) + .map_err(|_| TEE_ERROR_BAD_PARAMETERS)?; + + // 根据模式执行加密或解密 + let _len = match mode { + TEE_OperationMode::TEE_MODE_ENCRYPT => cipher_ctx.encrypt(input, output), + TEE_OperationMode::TEE_MODE_DECRYPT => cipher_ctx.decrypt(input, output), + _ => return Err(TEE_ERROR_BAD_PARAMETERS), + } + .map_err(|_| TEE_ERROR_BAD_PARAMETERS)?; + + Ok(()) +} + +/// Convert TeeAlg to mbedtls::hash::Type +/// This is a helper function instead of TryFrom implementation due to Rust's orphan rule +fn tee_alg_to_hmac_type(value: TeeAlg) -> TeeResult { + match value { + TEE_ALG_HMAC_MD5 => Ok(Type::Md5), + TEE_ALG_HMAC_SHA1 => Ok(Type::Sha1), + TEE_ALG_HMAC_SHA256 => Ok(Type::Sha256), + TEE_ALG_HMAC_SHA512 => Ok(Type::Sha512), + TEE_ALG_HMAC_SM3 => Ok(Type::SM3), + _ => Err(TEE_ERROR_NOT_IMPLEMENTED), } } @@ -171,27 +213,78 @@ pub fn tee_fs_fek_crypt( let dummy = [0u8, 1]; do_hmac(&mut tsk, ssk_key_slice, &dummy)?; } - match crypto_cipher_alloc_ctx(TEE_FS_KM_ENC_FEK_ALG) { - Ok(mut ctx) => { - ctx.init(mode, Some(&tsk), None, None).inspect_err(|_| { - error!("tee_fs_fek_crypt: ctx.init failed"); - })?; - ctx.update(true, Some(in_key_slice), Some(&mut dst_key)) - .inspect_err(|_| { - error!("tee_fs_fek_crypt: ctx.update failed"); - })?; - ctx.finalize(); - if let Some(out_key) = out_key { - out_key.copy_from_slice(&dst_key); - tee_debug!( - "tee_fs_fek_crypt: in_key: {:?}, out_key: {:?}", - hex::encode(in_key_slice), - hex::encode(out_key) - ); - } - } - Err(e) => return e, - }; + + // 使用 crypto_cipher_ecb_nopad 函数进行加密或解密 + crypto_cipher_ecb_nopad( + TEE_FS_KM_ENC_FEK_ALG, + mode, + &tsk, + in_key_slice, + &mut dst_key, + ) + .inspect_err(|e| { + error!("tee_fs_fek_crypt: crypto_cipher_ecb_nopad failed: {:X?}", e); + })?; + + if let Some(out_key) = out_key { + out_key.copy_from_slice(&dst_key); + tee_debug!( + "tee_fs_fek_crypt: in_key: {:?}, out_key: {:?}", + hex::encode(in_key_slice), + hex::encode(out_key) + ); + } Ok(()) } + +#[cfg(feature = "tee_test")] +pub mod tests_tee_fs_key_manager { + use unittest::{ + test_fn, test_framework::TestDescriptor, test_framework_basic::TestResult, tests_name, + }; + + use super::*; + use crate::tee::utils::slice_fmt; + + test_fn! { + using TestResult; + + fn test_crypto_cipher_encrypt() { + // aes encrypt + let algo = TEE_ALG_AES_ECB_NOPAD; + let key = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10]; + let plain = [0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20]; + let mut cipher = [0u8; 16]; + let result = crypto_cipher_ecb_nopad(algo, TEE_OperationMode::TEE_MODE_ENCRYPT, &key, &plain, &mut cipher); + tee_debug!("test_crypto_cipher_encrypt: key: {:?}, plain: {:?}, cipher: {:?}", slice_fmt(&key), slice_fmt(&plain), slice_fmt(&cipher)); + assert!(result.is_ok()); + assert_eq!("D721A0F194231822F398706DD1FFF2B7", hex::encode_upper(&cipher)); + + // aes decrypt + let mut decrypted = [0u8; 16]; + let result = crypto_cipher_ecb_nopad(algo, TEE_OperationMode::TEE_MODE_DECRYPT, &key, &cipher, &mut decrypted); + assert!(result.is_ok()); + assert_eq!(plain, decrypted); + + // sm4 encrypt + let algo = TEE_ALG_SM4_ECB_NOPAD; + let result = crypto_cipher_ecb_nopad(algo, TEE_OperationMode::TEE_MODE_ENCRYPT, &key, &plain, &mut cipher); + tee_debug!("test_crypto_cipher_encrypt: key: {:?}, plain: {:?}, cipher: {:?}", slice_fmt(&key), slice_fmt(&plain), slice_fmt(&cipher)); + assert!(result.is_ok()); + assert_eq!("4329A6241E39AD7A9A404A814A7EDD32", hex::encode_upper(&cipher)); + + // sm4 decrypt + let result = crypto_cipher_ecb_nopad(algo, TEE_OperationMode::TEE_MODE_DECRYPT, &key, &cipher, &mut decrypted); + assert!(result.is_ok()); + assert_eq!(plain, decrypted); + } + } + + tests_name! { + TEST_TEE_FS_KEY_MANAGER; + tee_fs_key_manager; + //------------------------ + test_crypto_cipher_encrypt, + } +} diff --git a/api/kapi/src/tee/tee_svc_cryp2.rs b/api/kapi/src/tee/tee_svc_cryp2.rs index c5e23b14..412b82d4 100644 --- a/api/kapi/src/tee/tee_svc_cryp2.rs +++ b/api/kapi/src/tee/tee_svc_cryp2.rs @@ -1078,7 +1078,7 @@ pub fn syscall_authenc_init( _arg5: usize, ) -> TeeResult { let nonce_ptr = arg1 as *const u8; - let nonce_len = arg2 as usize; + let nonce_len = arg2; let nonce_slice = unsafe { core::slice::from_raw_parts(nonce_ptr, nonce_len) }; let nonce = bb_memdup_user(nonce_slice)?; @@ -1107,7 +1107,7 @@ pub fn tee_cryp_authenc_update_aad(id: u32, aad: &[u8]) -> TeeResult { pub fn syscall_authenc_update_aad(arg0: usize, arg1: usize, arg2: usize) -> TeeResult { let aad_ptr = arg1 as *const u8; - let aad_len = arg2 as usize; + let aad_len = arg2; let aad_slice = unsafe { core::slice::from_raw_parts(aad_ptr, aad_len) }; let aad = bb_memdup_user(aad_slice)?; @@ -1164,7 +1164,7 @@ pub fn syscall_authenc_enc_final( arg6: usize, ) -> TeeResult { let src_ptr = arg1 as *const u8; - let src_len = arg2 as usize; + let src_len = arg2; // 输入的dst_len长度应该为缓冲区长度,最后函数返回值为实际长度 let dst_ptr = arg3 as *mut u8; @@ -1244,7 +1244,7 @@ pub fn syscall_authenc_dec_final( arg6: usize, ) -> TeeResult { let src_ptr = arg1 as *const u8; - let src_len = arg2 as usize; + let src_len = arg2; // 输入的dst_len长度应该为缓冲区长度,最后函数返回值为实际长度 let dst_ptr = arg3 as *mut u8; @@ -1267,7 +1267,7 @@ pub fn syscall_authenc_dec_final( let mut dst = bb_memdup_user(dst_slice)?; let tag_ptr = arg5 as *const u8; - let mut tag_len = arg6 as usize; + let mut tag_len = arg6; if tag_ptr.is_null() || tag_len == 0 { return Err(TEE_ERROR_BAD_PARAMETERS); @@ -1380,7 +1380,7 @@ pub fn syscall_asymm_operate( arg6: usize, ) -> TeeResult { let src_ptr = arg3 as *const u8; - let src_len = arg4 as usize; + let src_len = arg4; // 输入的dst_len长度应该为缓冲区长度,最后函数返回值为实际长度 let dst_ptr = arg5 as *mut u8; @@ -1460,10 +1460,10 @@ pub fn syscall_asymm_verify( arg6: usize, ) -> TeeResult { let data_ptr = arg3 as *const u8; - let data_len = arg4 as usize; + let data_len = arg4; let sig_ptr = arg5 as *mut u8; - let mut sig_len = arg6 as usize; + let mut sig_len = arg6; let data = if data_ptr.is_null() || data_len == 0 { return Err(TEE_ERROR_BAD_PARAMETERS); @@ -1478,7 +1478,7 @@ pub fn syscall_asymm_verify( let sig_slice = unsafe { core::slice::from_raw_parts_mut(sig_ptr, sig_len) }; let mut sig = bb_memdup_user(sig_slice)?; - tee_cryp_asymm_verify(arg0 as _, &data, &mut sig)?; + tee_cryp_asymm_verify(arg0 as _, &data, &sig)?; // Copy to user unsafe { copy_to_user(sig_slice, &sig, sig_len * size_of::())? }; diff --git a/api/kapi/src/tee/test_unit_test.rs b/api/kapi/src/tee/test_unit_test.rs index 93d15156..7299a0f5 100644 --- a/api/kapi/src/tee/test_unit_test.rs +++ b/api/kapi/src/tee/test_unit_test.rs @@ -15,14 +15,14 @@ use crate::tee::arch::x86_64::hygon_csv::tests_hygon_csv_get_sealing_key::TEST_H use crate::tee::{ bitstring::tests_bitstring::TEST_BITSTRING, common::file_ops::tests_file_ops::TEST_FILE_OPS, crypto::crypto_impl::tests_tee_crypto_impl::TEST_TEE_CRYPTO_IMPL, - crypto_temp::aes_ecb::tests_aes_ecb::TEST_TEE_AES_ECB, fs_dirfile::tests_tee_fs_dirfile::TEST_TEE_FS_DIRFILE, fs_htree::tests_fs_htree::TEST_FS_HTREE, fs_htree_tests::tests_fs_htree_tests::TEST_FS_HTREE_TESTS, huk_subkey::tests_huk_subkey::TEST_HUK_SUBKEY_DERIVE, libmbedtls::bignum::tests_tee_bignum::TEST_TEE_BIGNUM, - rng_software::tests_rng_software::TEST_RNG_SOFTWARE, tee_misc::tests_tee_misc::TEST_TEE_MISC, - tee_obj::tests_tee_obj::TEST_TEE_OBJ, tee_pobj::tests_tee_pobj::TEST_TEE_POBJ, - tee_ree_fs::tests_tee_ree_fs::TEST_TEE_REE_FS, + rng_software::tests_rng_software::TEST_RNG_SOFTWARE, + tee_fs_key_manager::tests_tee_fs_key_manager::TEST_TEE_FS_KEY_MANAGER, + tee_misc::tests_tee_misc::TEST_TEE_MISC, tee_obj::tests_tee_obj::TEST_TEE_OBJ, + tee_pobj::tests_tee_pobj::TEST_TEE_POBJ, tee_ree_fs::tests_tee_ree_fs::TEST_TEE_REE_FS, tee_session::tests_tee_session::TEST_TEE_SESSION, tee_svc_cryp::tests_tee_svc_cryp::TEST_TEE_SVC_CRYP, tee_svc_cryp2::tests_cryp::TEST_TEE_CRYP, tee_svc_storage::tests_tee_svc_storage::TEST_TEE_SVC_STORAGE, @@ -55,8 +55,8 @@ pub fn tee_unit_test() { TEST_FS_HTREE_TESTS, TEST_RNG_SOFTWARE, TEST_TEE_CRYPTO_IMPL, - TEST_TEE_AES_ECB, TEST_TEE_CRYP, + TEST_TEE_FS_KEY_MANAGER, ] ); #[cfg(all(target_arch = "x86_64", feature = "x86_csv", feature = "tee_test"))] diff --git a/arch/karch/Cargo.toml b/arch/karch/Cargo.toml new file mode 100644 index 00000000..e98c5b45 --- /dev/null +++ b/arch/karch/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "karch" +description = "Lightweight architecture-specific low-level operations (TLB flush, cache maintenance, CPU halt, interrupt management, thread pointer access)" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[features] +default = [] +arm-el2 = [] + +[dependencies] +cfg-if = "1.0" +memaddr = { workspace = true } + +[target.'cfg(target_arch = "x86_64")'.dependencies] +x86 = "0.52" +x86_64 = { workspace = true } + +[target.'cfg(target_arch = "aarch64")'.dependencies] +aarch64-cpu = "10.0" + +[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies] +riscv = "0.14" + +[target.'cfg(target_arch = "loongarch64")'.dependencies] +loongArch64 = "0.2.4" + +[package.metadata.docs.rs] +all-features = true +targets = [ + "x86_64-unknown-none", + "aarch64-unknown-none-softfloat", + "riscv64gc-unknown-none-elf", + "loongarch64-unknown-none-softfloat", +] diff --git a/arch/karch/README.md b/arch/karch/README.md new file mode 100644 index 00000000..f16afce0 --- /dev/null +++ b/arch/karch/README.md @@ -0,0 +1,46 @@ +# karch + +Lightweight architecture-specific low-level operations for the x-kernel project. + +This crate provides a uniform API across all supported architectures (AArch64, x86_64, RISC-V, LoongArch64, ARM) for: + +- **TLB flush**: `flush_tlb(vaddr: Option)` +- **Cache maintenance** (AArch64): `flush_icache_all()`, `flush_dcache_line(vaddr)` +- **CPU control**: `stop_cpu()`, `await_interrupts()` +- **Local interrupt management**: + - `enable_local_irq()`, `disable_local_irq()`, `local_irq_enabled()` + - `save_irq_and_disable() -> usize` — atomically save interrupt state and disable local interrupts + - `restore_irq(flags: usize)` — restore previously saved interrupt state +- **Thread pointer (TLS)**: `read_thread_pointer()`, `write_thread_pointer(val)` +- **FP/SIMD enable** (AArch64, LoongArch64): `enable_fp()` +- **LSX extension** (LoongArch64): `enable_lsx()` +- **MMU / Page table root**: + - `read_kernel_page_table() -> PhysAddr` + - `read_user_page_table() -> PhysAddr` + - `unsafe fn write_kernel_page_table(root_paddr: PhysAddr)` + - `unsafe fn write_user_page_table(root_paddr: PhysAddr)` +- **Trap / exception vector** (AArch64, RISC-V, LoongArch64): + - `unsafe fn write_trap_vector_base(addr: usize)` +- **Hypercall** (x86_64): `fn hypercall(nr: u64, a0: u64, a1: u64) -> i64` +- **Page walk controller** (LoongArch64): `unsafe fn write_pwc(pwcl: u32, pwch: u32)` + +## Deprecated names + +The following names are deprecated and will be removed in a future release. Use the replacements shown: + +| Deprecated | Replacement | +|---|---| +| `enable_irq()` | `enable_local_irq()` | +| `disable_irq()` | `disable_local_irq()` | +| `irq_enabled()` | `local_irq_enabled()` | + +## Design + +`karch` is intentionally kept lightweight: it only depends on `memaddr`, `cfg-if`, and +architecture-specific register libraries (`aarch64-cpu`, `x86`/`x86_64`, `riscv`, +`loongArch64`). It has **no** OS-level dependencies, making it suitable as a low-level +building block for other crates. + +## Features + +- `arm-el2`: Enable AArch64 EL2 (hypervisor) variants of TLB flush, page table root, and trap vector operations. diff --git a/arch/karch/src/aarch64/cache.rs b/arch/karch/src/aarch64/cache.rs new file mode 100644 index 00000000..1427e119 --- /dev/null +++ b/arch/karch/src/aarch64/cache.rs @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Cache maintenance operations for AArch64. + +use core::arch::asm; + +use memaddr::VirtAddr; + +/// Flushes the entire instruction cache. +#[inline] +pub fn flush_icache_all() { + unsafe { asm!("ic iallu; dsb sy; isb") }; +} + +/// Flushes the data cache line at the given virtual address. +/// +/// Uses the `DC IVAC` instruction (Data Cache Invalidate by Virtual Address to +/// Point of Coherency). The cache line size is implementation-defined; 64 bytes +/// is typical for AArch64 but may vary across CPU implementations. +#[inline] +pub fn flush_dcache_line(vaddr: VirtAddr) { + unsafe { asm!("dc ivac, {0:x}; dsb sy; isb", in(reg) vaddr.as_usize()) }; +} diff --git a/arch/karch/src/aarch64/cpu.rs b/arch/karch/src/aarch64/cpu.rs new file mode 100644 index 00000000..a015cc8d --- /dev/null +++ b/arch/karch/src/aarch64/cpu.rs @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! CPU control operations for AArch64. + +use super::irq::disable_local_irq; + +/// Halt the current CPU. +/// +/// Disables interrupts then executes WFI. Since interrupts are disabled, +/// this should stop execution until reset. +#[inline] +pub fn stop_cpu() { + disable_local_irq(); + aarch64_cpu::asm::wfi(); +} + +/// Relaxes the current CPU and waits for interrupts. +/// +/// It must be called with interrupts enabled, otherwise it will never return. +#[inline] +pub fn await_interrupts() { + aarch64_cpu::asm::wfi(); +} diff --git a/arch/karch/src/aarch64/fp.rs b/arch/karch/src/aarch64/fp.rs new file mode 100644 index 00000000..28bb09ca --- /dev/null +++ b/arch/karch/src/aarch64/fp.rs @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Floating-point/SIMD operations for AArch64. + +use aarch64_cpu::{ + asm::barrier, + registers::{CPACR_EL1, Writeable}, +}; + +/// Enable FP/SIMD instructions by setting the `FPEN` field in `CPACR_EL1`. +#[inline] +pub fn enable_fp() { + CPACR_EL1.write(CPACR_EL1::FPEN::TrapNothing); + barrier::isb(barrier::SY); +} diff --git a/arch/karch/src/aarch64/irq.rs b/arch/karch/src/aarch64/irq.rs new file mode 100644 index 00000000..d4bdb2ac --- /dev/null +++ b/arch/karch/src/aarch64/irq.rs @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Interrupt control operations for AArch64. + +use core::arch::asm; + +use aarch64_cpu::registers::{DAIF, Readable, Writeable}; + +/// Allows the current CPU to respond to interrupts (clears DAIF.I). +#[inline] +pub fn enable_local_irq() { + DAIF.write(DAIF::I::Unmasked); +} + +/// Makes the current CPU ignore interrupts (sets DAIF.I). +#[inline] +pub fn disable_local_irq() { + DAIF.write(DAIF::I::Masked); +} + +/// Returns whether the current CPU is allowed to respond to interrupts. +#[inline] +pub fn local_irq_enabled() -> bool { + !DAIF.is_set(DAIF::I) +} + +/// Deprecated: use [`enable_local_irq`] instead. +#[deprecated(note = "Use `enable_local_irq` instead")] +#[inline] +pub fn enable_irq() { + enable_local_irq() +} + +/// Deprecated: use [`disable_local_irq`] instead. +#[deprecated(note = "Use `disable_local_irq` instead")] +#[inline] +pub fn disable_irq() { + disable_local_irq() +} + +/// Deprecated: use [`local_irq_enabled`] instead. +#[deprecated(note = "Use `local_irq_enabled` instead")] +#[inline] +pub fn irq_enabled() -> bool { + local_irq_enabled() +} + +/// Saves the current local interrupt state and disables interrupts atomically. +/// +/// Returns the saved DAIF register value. Pass it to [`restore_irq`] to +/// restore the previous interrupt state. +#[inline] +pub fn save_irq_and_disable() -> usize { + let flags: usize; + unsafe { + asm!("mrs {}, daif", out(reg) flags, options(nomem, nostack, preserves_flags)); + asm!("msr daifset, #2", options(nomem, nostack)); + } + flags +} + +/// Restores local interrupt state from a value previously returned by +/// [`save_irq_and_disable`]. +#[inline] +pub fn restore_irq(flags: usize) { + unsafe { + asm!("msr daif, {}", in(reg) flags, options(nomem, nostack)); + } +} diff --git a/arch/karch/src/aarch64/mmu.rs b/arch/karch/src/aarch64/mmu.rs new file mode 100644 index 00000000..ff075984 --- /dev/null +++ b/arch/karch/src/aarch64/mmu.rs @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! MMU/page table operations for AArch64. + +use aarch64_cpu::registers::{Readable, TTBR0_EL1, TTBR1_EL1, Writeable}; +use memaddr::PhysAddr; + +/// Reads the current page table root register for kernel space. +/// +/// When the `arm-el2` feature is enabled, reads `TTBR0_EL2`; otherwise +/// reads `TTBR1_EL1`. +/// +/// Returns the physical address of the page table root. +#[inline] +pub fn read_kernel_page_table() -> PhysAddr { + let pt_root_reg: usize; + + #[cfg(not(feature = "arm-el2"))] + { + pt_root_reg = TTBR1_EL1.get() as usize; + } + + #[cfg(feature = "arm-el2")] + { + use aarch64_cpu::registers::TTBR0_EL2; + pt_root_reg = TTBR0_EL2.get() as usize; + } + + PhysAddr::from(pt_root_reg) +} + +/// Reads the current page table root register for user space (`TTBR0_EL1`). +/// +/// Returns the physical address of the page table root. +#[inline] +pub fn read_user_page_table() -> PhysAddr { + let val = TTBR0_EL1.get(); + PhysAddr::from(val as usize) +} + +/// Writes the register to update the current page table root for kernel space. +/// +/// When the `arm-el2` feature is enabled, writes `TTBR0_EL2`; otherwise +/// writes `TTBR1_EL1`. +/// +/// Note that the TLB is **NOT** flushed after this operation. +/// +/// # Safety +/// +/// This function is unsafe as it changes the virtual memory address space. +#[inline] +pub unsafe fn write_kernel_page_table(root_paddr: PhysAddr) { + #[cfg(not(feature = "arm-el2"))] + { + TTBR1_EL1.set(root_paddr.as_usize() as _); + } + + #[cfg(feature = "arm-el2")] + { + use aarch64_cpu::registers::TTBR0_EL2; + TTBR0_EL2.set(root_paddr.as_usize() as _); + } +} + +/// Writes the register to update the current page table root for user space +/// (`TTBR0_EL1`). +/// +/// Note that the TLB is **NOT** flushed after this operation. +/// +/// # Safety +/// +/// This function is unsafe as it changes the virtual memory address space. +#[inline] +pub unsafe fn write_user_page_table(root_paddr: PhysAddr) { + TTBR0_EL1.set(root_paddr.as_usize() as _); +} diff --git a/arch/karch/src/aarch64/mod.rs b/arch/karch/src/aarch64/mod.rs new file mode 100644 index 00000000..1500ac7f --- /dev/null +++ b/arch/karch/src/aarch64/mod.rs @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! AArch64 low-level architecture operations. + +mod cache; +mod cpu; +mod fp; +mod irq; +mod mmu; +mod tlb; +mod tls; +mod trap; + +pub use cache::{flush_dcache_line, flush_icache_all}; +pub use cpu::{await_interrupts, stop_cpu}; +pub use fp::enable_fp; +#[allow(deprecated)] +pub use irq::{ + disable_irq, disable_local_irq, enable_irq, enable_local_irq, irq_enabled, local_irq_enabled, + restore_irq, save_irq_and_disable, +}; +pub use mmu::{ + read_kernel_page_table, read_user_page_table, write_kernel_page_table, write_user_page_table, +}; +pub use tlb::flush_tlb; +pub use tls::{read_thread_pointer, write_thread_pointer}; +pub use trap::write_trap_vector_base; diff --git a/arch/karch/src/aarch64/tlb.rs b/arch/karch/src/aarch64/tlb.rs new file mode 100644 index 00000000..1c4f42be --- /dev/null +++ b/arch/karch/src/aarch64/tlb.rs @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! TLB maintenance operations for AArch64. + +use core::arch::asm; + +use memaddr::VirtAddr; + +/// Flushes the TLB. +/// +/// If `vaddr` is [`None`], flushes the entire TLB. Otherwise, flushes the TLB +/// entry that maps the given virtual address. +#[inline] +pub fn flush_tlb(vaddr: Option) { + if let Some(vaddr) = vaddr { + const VA_MASK: usize = (1 << 44) - 1; // VA[55:12] => bits[43:0] + let operand = (vaddr.as_usize() >> 12) & VA_MASK; + + #[cfg(not(feature = "arm-el2"))] + unsafe { + // TLB Invalidate by VA, All ASID, EL1, Inner Shareable + asm!("tlbi vaae1is, {}; dsb sy; isb", in(reg) operand) + } + #[cfg(feature = "arm-el2")] + unsafe { + // TLB Invalidate by VA, EL2, Inner Shareable + asm!("tlbi vae2is, {}; dsb sy; isb", in(reg) operand) + } + } else { + // flush the entire TLB + #[cfg(not(feature = "arm-el2"))] + unsafe { + // TLB Invalidate by VMID, All at stage 1, EL1 + asm!("dsb sy; isb; tlbi vmalle1; dsb sy; isb") + } + #[cfg(feature = "arm-el2")] + unsafe { + // TLB Invalidate All, EL2 + asm!("tlbi alle2; dsb sy; isb") + } + } +} diff --git a/arch/karch/src/aarch64/tls.rs b/arch/karch/src/aarch64/tls.rs new file mode 100644 index 00000000..3338ba52 --- /dev/null +++ b/arch/karch/src/aarch64/tls.rs @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Thread-local storage operations for AArch64. + +use aarch64_cpu::registers::{Readable, TPIDR_EL0, Writeable}; + +/// Reads the thread pointer of the current CPU (`TPIDR_EL0`). +/// +/// It is used to implement TLS (Thread Local Storage). +#[inline] +pub fn read_thread_pointer() -> usize { + TPIDR_EL0.get() as usize +} + +/// Writes the thread pointer of the current CPU (`TPIDR_EL0`). +/// +/// It is used to implement TLS (Thread Local Storage). +/// +/// # Safety +/// +/// This function is unsafe as it changes the current CPU states. +#[inline] +pub unsafe fn write_thread_pointer(val: usize) { + TPIDR_EL0.set(val as _) +} diff --git a/arch/karch/src/aarch64/trap.rs b/arch/karch/src/aarch64/trap.rs new file mode 100644 index 00000000..d1dbca68 --- /dev/null +++ b/arch/karch/src/aarch64/trap.rs @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Exception/trap vector operations for AArch64. + +use aarch64_cpu::registers::Writeable; + +/// Writes the exception vector base address register (`VBAR_EL1` or `VBAR_EL2`). +/// +/// When the `arm-el2` feature is enabled, writes `VBAR_EL2`; otherwise +/// writes `VBAR_EL1`. +/// +/// # Safety +/// +/// This function is unsafe as it changes the exception handling behavior of the +/// current CPU. +#[inline] +pub unsafe fn write_trap_vector_base(addr: usize) { + #[cfg(not(feature = "arm-el2"))] + { + use aarch64_cpu::registers::VBAR_EL1; + VBAR_EL1.set(addr as _); + } + #[cfg(feature = "arm-el2")] + { + use aarch64_cpu::registers::VBAR_EL2; + VBAR_EL2.set(addr as _); + } +} diff --git a/arch/karch/src/arm/irq.rs b/arch/karch/src/arm/irq.rs new file mode 100644 index 00000000..95b6cd62 --- /dev/null +++ b/arch/karch/src/arm/irq.rs @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Interrupt control operations for ARM. + +use core::arch::asm; + +/// Interrupt Disable bit (bit 7) in CPSR. +const IRQ_DISABLE_BIT: usize = 1 << 7; + +/// Saves the current local interrupt state and disables interrupts atomically. +/// +/// Returns the saved CPSR value with the IRQ disable bit. Pass it to +/// [`restore_irq`] to restore the previous interrupt state. +#[inline] +pub fn save_irq_and_disable() -> usize { + let flags: usize; + unsafe { + asm!( + "mrs {0}, cpsr", + "cpsid i", + out(reg) flags, + options(nomem, nostack, preserves_flags) + ); + } + flags & IRQ_DISABLE_BIT +} + +/// Restores local interrupt state from a value previously returned by +/// [`save_irq_and_disable`]. +/// +/// In ARM CPSR, bit 7 = 0 means IRQs enabled, bit 7 = 1 means IRQs disabled. +/// If the saved flags had bit 7 clear (IRQs were enabled), re-enable them. +#[inline] +pub fn restore_irq(flags: usize) { + if flags & IRQ_DISABLE_BIT == 0 { + // IRQ_DISABLE_BIT was clear in saved flags → IRQs were enabled before; re-enable them. + unsafe { + asm!("cpsie i", options(nomem, nostack)); + } + } + // If IRQ_DISABLE_BIT was set → IRQs were already disabled; leave them disabled. +} diff --git a/arch/karch/src/arm/mod.rs b/arch/karch/src/arm/mod.rs new file mode 100644 index 00000000..eca897f0 --- /dev/null +++ b/arch/karch/src/arm/mod.rs @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! ARM low-level architecture operations. + +mod irq; + +pub use irq::{restore_irq, save_irq_and_disable}; diff --git a/arch/karch/src/lib.rs b/arch/karch/src/lib.rs new file mode 100644 index 00000000..b18d8544 --- /dev/null +++ b/arch/karch/src/lib.rs @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Lightweight architecture-specific low-level operations. +//! +//! This crate provides a uniform API across all supported architectures for +//! TLB flush, cache maintenance, CPU halt, interrupt management, thread pointer +//! access, and FP/SIMD enable operations. +#![doc = include_str!("../README.md")] +#![no_std] + +cfg_if::cfg_if! { + if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { + mod riscv; + pub use self::riscv::*; + } else if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "loongarch64")] { + mod loongarch64; + pub use self::loongarch64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } +} diff --git a/arch/karch/src/loongarch64/cpu.rs b/arch/karch/src/loongarch64/cpu.rs new file mode 100644 index 00000000..700ffa80 --- /dev/null +++ b/arch/karch/src/loongarch64/cpu.rs @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! CPU control operations for LoongArch64. + +use super::irq::disable_local_irq; + +/// Halt the current CPU. +#[inline] +pub fn stop_cpu() { + disable_local_irq(); + unsafe { loongArch64::asm::idle() } +} + +/// Relaxes the current CPU and waits for interrupts. +/// +/// It must be called with interrupts enabled, otherwise it will never return. +#[inline] +pub fn await_interrupts() { + unsafe { loongArch64::asm::idle() } +} diff --git a/arch/karch/src/loongarch64/fp.rs b/arch/karch/src/loongarch64/fp.rs new file mode 100644 index 00000000..dc614866 --- /dev/null +++ b/arch/karch/src/loongarch64/fp.rs @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Floating-point/SIMD operations for LoongArch64. + +/// Enables floating-point instructions by setting `EUEN.FPE`. +/// +/// - `EUEN`: +#[inline] +pub fn enable_fp() { + loongArch64::register::euen::set_fpe(true); +} + +/// Enables LSX extension by setting `EUEN.LSX`. +/// +/// - `EUEN`: +#[inline] +pub fn enable_lsx() { + loongArch64::register::euen::set_sxe(true); +} diff --git a/arch/karch/src/loongarch64/irq.rs b/arch/karch/src/loongarch64/irq.rs new file mode 100644 index 00000000..26dd3fe1 --- /dev/null +++ b/arch/karch/src/loongarch64/irq.rs @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Interrupt control operations for LoongArch64. + +use core::arch::asm; + +use loongArch64::register::crmd; + +/// Allows the current CPU to respond to interrupts. +#[inline] +pub fn enable_local_irq() { + crmd::set_ie(true) +} + +/// Makes the current CPU ignore interrupts. +#[inline] +pub fn disable_local_irq() { + crmd::set_ie(false) +} + +/// Returns whether the current CPU is allowed to respond to interrupts. +#[inline] +pub fn local_irq_enabled() -> bool { + crmd::read().ie() +} + +/// Deprecated: use [`enable_local_irq`] instead. +#[deprecated(note = "Use `enable_local_irq` instead")] +#[inline] +pub fn enable_irq() { + enable_local_irq() +} + +/// Deprecated: use [`disable_local_irq`] instead. +#[deprecated(note = "Use `disable_local_irq` instead")] +#[inline] +pub fn disable_irq() { + disable_local_irq() +} + +/// Deprecated: use [`local_irq_enabled`] instead. +#[deprecated(note = "Use `local_irq_enabled` instead")] +#[inline] +pub fn irq_enabled() -> bool { + local_irq_enabled() +} + +/// Saves the current local interrupt state and disables interrupts atomically. +/// +/// Returns the saved CRMD value with the IE bit. Pass it to [`restore_irq`] +/// to restore the previous interrupt state. +#[inline] +pub fn save_irq_and_disable() -> usize { + /// Interrupt Enable bit mask in CRMD. + const IE_MASK: usize = 1 << 2; + let mut flags: usize = 0; + // csrxchg atomically reads CRMD and clears the IE bit + unsafe { asm!("csrxchg {}, {}, 0x0", inout(reg) flags, in(reg) IE_MASK) }; + flags & IE_MASK +} + +/// Restores local interrupt state from a value previously returned by +/// [`save_irq_and_disable`]. +#[inline] +pub fn restore_irq(flags: usize) { + /// Interrupt Enable bit mask in CRMD. + const IE_MASK: usize = 1 << 2; + // csrxchg atomically restores the IE bit + unsafe { asm!("csrxchg {}, {}, 0x0", in(reg) flags, in(reg) IE_MASK) }; +} diff --git a/arch/karch/src/loongarch64/mmu.rs b/arch/karch/src/loongarch64/mmu.rs new file mode 100644 index 00000000..03eebdf8 --- /dev/null +++ b/arch/karch/src/loongarch64/mmu.rs @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! MMU/page table operations for LoongArch64. + +use core::arch::asm; + +use loongArch64::register::{pgdh, pgdl}; +use memaddr::PhysAddr; + +/// Reads the current page table root register for user space (`PGDL`). +/// +/// Returns the physical address of the page table root. +#[inline] +pub fn read_user_page_table() -> PhysAddr { + PhysAddr::from(pgdl::read().base()) +} + +/// Reads the current page table root register for kernel space (`PGDH`). +/// +/// Returns the physical address of the page table root. +#[inline] +pub fn read_kernel_page_table() -> PhysAddr { + PhysAddr::from(pgdh::read().base()) +} + +/// Writes the register to update the current page table root for user space +/// (`PGDL`). +/// +/// Note that the TLB is **NOT** flushed after this operation. +/// +/// # Safety +/// +/// This function is unsafe as it changes the virtual memory address space. +#[inline] +pub unsafe fn write_user_page_table(root_paddr: PhysAddr) { + pgdl::set_base(root_paddr.as_usize() as _); +} + +/// Writes the register to update the current page table root for kernel space +/// (`PGDH`). +/// +/// Note that the TLB is **NOT** flushed after this operation. +/// +/// # Safety +/// +/// This function is unsafe as it changes the virtual memory address space. +#[inline] +pub unsafe fn write_kernel_page_table(root_paddr: PhysAddr) { + pgdh::set_base(root_paddr.as_usize()); +} + +/// Writes the Page Walk Controller registers (`PWCL` and `PWCH`). +/// +/// The CSR numbers are inlined as numeric constants: +/// - `PWCL` = CSR 0x1c (lower-half page walk controller) +/// - `PWCH` = CSR 0x1d (higher-half page walk controller) +/// +/// # Safety +/// +/// This function is unsafe as it changes the page walk configuration such as +/// levels and starting bits. +/// +/// - `PWCL` (CSR 0x1c): +/// - `PWCH` (CSR 0x1d): +#[inline] +pub unsafe fn write_pwc(pwcl: u32, pwch: u32) { + unsafe { + asm!( + "csrwr {}, 0x1c", + "csrwr {}, 0x1d", + in(reg) pwcl, + in(reg) pwch + ) + } +} diff --git a/arch/karch/src/loongarch64/mod.rs b/arch/karch/src/loongarch64/mod.rs new file mode 100644 index 00000000..9dcc0234 --- /dev/null +++ b/arch/karch/src/loongarch64/mod.rs @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! LoongArch64 low-level architecture operations. + +mod cpu; +mod fp; +mod irq; +mod mmu; +mod tlb; +mod tls; +mod trap; + +pub use cpu::{await_interrupts, stop_cpu}; +pub use fp::{enable_fp, enable_lsx}; +#[allow(deprecated)] +pub use irq::{ + disable_irq, disable_local_irq, enable_irq, enable_local_irq, irq_enabled, local_irq_enabled, + restore_irq, save_irq_and_disable, +}; +pub use mmu::{ + read_kernel_page_table, read_user_page_table, write_kernel_page_table, write_pwc, + write_user_page_table, +}; +pub use tlb::flush_tlb; +pub use tls::{read_thread_pointer, write_thread_pointer}; +pub use trap::write_trap_vector_base; diff --git a/arch/karch/src/loongarch64/tlb.rs b/arch/karch/src/loongarch64/tlb.rs new file mode 100644 index 00000000..5363d5f3 --- /dev/null +++ b/arch/karch/src/loongarch64/tlb.rs @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! TLB maintenance operations for LoongArch64. + +use core::arch::asm; + +use memaddr::VirtAddr; + +/// Flushes the TLB. +/// +/// If `vaddr` is [`None`], flushes the entire TLB. Otherwise, flushes the TLB +/// entry that maps the given virtual address. +#[inline] +pub fn flush_tlb(vaddr: Option) { + unsafe { + if let Some(vaddr) = vaddr { + // + // + // Only after all previous load/store access operations are completely + // executed, the DBAR 0 instruction can be executed; and only after the + // execution of DBAR 0 is completed, all subsequent load/store access + // operations can be executed. + // + // + // + // formats: invtlb op, asid, addr + // + // op 0x5: Clear all page table entries with G=0 and ASID equal to the + // register specified ASID, and VA equal to the register specified VA. + // + // When the operation indicated by op does not require an ASID, the + // general register rj should be set to r0. + asm!("dbar 0; invtlb 0x05, $r0, {reg}", reg = in(reg) vaddr.as_usize()); + } else { + // op 0x0: Clear all page table entries + asm!("dbar 0; invtlb 0x00, $r0, $r0"); + } + } +} diff --git a/arch/karch/src/loongarch64/tls.rs b/arch/karch/src/loongarch64/tls.rs new file mode 100644 index 00000000..d3799bf5 --- /dev/null +++ b/arch/karch/src/loongarch64/tls.rs @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Thread-local storage operations for LoongArch64. + +use core::arch::asm; + +/// Reads the thread pointer of the current CPU (`$tp`). +/// +/// It is used to implement TLS (Thread Local Storage). +#[inline] +pub fn read_thread_pointer() -> usize { + let tp; + unsafe { asm!("move {}, $tp", out(reg) tp) }; + tp +} + +/// Writes the thread pointer of the current CPU (`$tp`). +/// +/// It is used to implement TLS (Thread Local Storage). +/// +/// # Safety +/// +/// This function is unsafe as it changes the CPU states. +#[inline] +pub unsafe fn write_thread_pointer(val: usize) { + unsafe { asm!("move $tp, {}", in(reg) val) } +} diff --git a/arch/karch/src/loongarch64/trap.rs b/arch/karch/src/loongarch64/trap.rs new file mode 100644 index 00000000..97847b28 --- /dev/null +++ b/arch/karch/src/loongarch64/trap.rs @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Exception/trap vector operations for LoongArch64. + +use loongArch64::register::{ecfg, eentry}; + +/// Writes the Exception Entry Base Address register (`EENTRY`). +/// +/// It also sets the Exception Configuration register (`ECFG`) to `VS=0`. +/// +/// - ECFG: +/// - EENTRY: +/// +/// # Safety +/// +/// This function is unsafe as it changes the exception handling behavior of the +/// current CPU. +#[inline] +pub unsafe fn write_trap_vector_base(addr: usize) { + ecfg::set_vs(0); + eentry::set_eentry(addr); +} diff --git a/arch/karch/src/riscv/cpu.rs b/arch/karch/src/riscv/cpu.rs new file mode 100644 index 00000000..b76c16fb --- /dev/null +++ b/arch/karch/src/riscv/cpu.rs @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! CPU control operations for RISC-V. + +use super::irq::disable_local_irq; + +/// Halt the current CPU. +#[inline] +pub fn stop_cpu() { + disable_local_irq(); + riscv::asm::wfi(); // should never return +} + +/// Relaxes the current CPU and waits for interrupts. +/// +/// It must be called with interrupts enabled, otherwise it will never return. +#[inline] +pub fn await_interrupts() { + riscv::asm::wfi() +} diff --git a/arch/karch/src/riscv/irq.rs b/arch/karch/src/riscv/irq.rs new file mode 100644 index 00000000..2d9d13b0 --- /dev/null +++ b/arch/karch/src/riscv/irq.rs @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Interrupt control operations for RISC-V. + +use riscv::register::sstatus; + +/// Allows the current CPU to respond to interrupts. +#[inline] +pub fn enable_local_irq() { + unsafe { sstatus::set_sie() } +} + +/// Makes the current CPU ignore interrupts. +#[inline] +pub fn disable_local_irq() { + unsafe { sstatus::clear_sie() } +} + +/// Returns whether the current CPU is allowed to respond to interrupts. +#[inline] +pub fn local_irq_enabled() -> bool { + sstatus::read().sie() +} + +/// Deprecated: use [`enable_local_irq`] instead. +#[deprecated(note = "Use `enable_local_irq` instead")] +#[inline] +pub fn enable_irq() { + enable_local_irq() +} + +/// Deprecated: use [`disable_local_irq`] instead. +#[deprecated(note = "Use `disable_local_irq` instead")] +#[inline] +pub fn disable_irq() { + disable_local_irq() +} + +/// Deprecated: use [`local_irq_enabled`] instead. +#[deprecated(note = "Use `local_irq_enabled` instead")] +#[inline] +pub fn irq_enabled() -> bool { + local_irq_enabled() +} + +/// Saves the current local interrupt state and disables interrupts atomically. +/// +/// Returns the saved sstatus value with the SIE bit. Pass it to +/// [`restore_irq`] to restore the previous interrupt state. +#[inline] +pub fn save_irq_and_disable() -> usize { + /// Supervisor Interrupt Enable bit in sstatus. + const SIE_BIT: usize = 1 << 1; + let flags: usize; + // csrrc: atomically clear the SIE bit and return the old sstatus value + unsafe { core::arch::asm!("csrrc {}, sstatus, {}", out(reg) flags, const SIE_BIT) }; + flags & SIE_BIT +} + +/// Restores local interrupt state from a value previously returned by +/// [`save_irq_and_disable`]. +#[inline] +pub fn restore_irq(flags: usize) { + // csrrs: set the bits from `flags` back into sstatus + unsafe { core::arch::asm!("csrrs x0, sstatus, {}", in(reg) flags) }; +} diff --git a/arch/karch/src/riscv/mmu.rs b/arch/karch/src/riscv/mmu.rs new file mode 100644 index 00000000..e7447ff9 --- /dev/null +++ b/arch/karch/src/riscv/mmu.rs @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! MMU/page table operations for RISC-V. + +use memaddr::PhysAddr; +use riscv::register::satp; + +/// Reads the current page table root register for user space (`satp`). +/// +/// RISC-V does not have a separate page table root register for user and +/// kernel space, so this operation is the same as [`read_kernel_page_table`]. +/// +/// Returns the physical address of the page table root. +#[inline] +pub fn read_user_page_table() -> PhysAddr { + PhysAddr::from(satp::read().ppn() << 12) +} + +/// Reads the current page table root register for kernel space (`satp`). +/// +/// RISC-V does not have a separate page table root register for user and +/// kernel space, so this operation is the same as [`read_user_page_table`]. +/// +/// Returns the physical address of the page table root. +#[inline] +pub fn read_kernel_page_table() -> PhysAddr { + read_user_page_table() +} + +/// Writes the register to update the current page table root for user space +/// (`satp`). +/// +/// RISC-V does not have a separate page table root register for user +/// and kernel space, so this operation is the same as [`write_kernel_page_table`]. +/// +/// Note that the TLB is **NOT** flushed after this operation. +/// +/// # Safety +/// +/// This function is unsafe as it changes the virtual memory address space. +#[inline] +pub unsafe fn write_user_page_table(root_paddr: PhysAddr) { + unsafe { satp::set(satp::Mode::Sv39, 0, root_paddr.as_usize() >> 12) }; +} + +/// Writes the register to update the current page table root for kernel space +/// (`satp`). +/// +/// RISC-V does not have a separate page table root register for user +/// and kernel space, so this operation is the same as [`write_user_page_table`]. +/// +/// Note that the TLB is **NOT** flushed after this operation. +/// +/// # Safety +/// +/// This function is unsafe as it changes the virtual memory address space. +#[inline] +pub unsafe fn write_kernel_page_table(root_paddr: PhysAddr) { + unsafe { write_user_page_table(root_paddr) }; +} diff --git a/arch/karch/src/riscv/mod.rs b/arch/karch/src/riscv/mod.rs new file mode 100644 index 00000000..78ab8655 --- /dev/null +++ b/arch/karch/src/riscv/mod.rs @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! RISC-V low-level architecture operations. + +mod cpu; +mod irq; +mod mmu; +mod tlb; +mod tls; +mod trap; + +pub use cpu::{await_interrupts, stop_cpu}; +#[allow(deprecated)] +pub use irq::{ + disable_irq, disable_local_irq, enable_irq, enable_local_irq, irq_enabled, local_irq_enabled, + restore_irq, save_irq_and_disable, +}; +pub use mmu::{ + read_kernel_page_table, read_user_page_table, write_kernel_page_table, write_user_page_table, +}; +pub use tlb::flush_tlb; +pub use tls::{read_thread_pointer, write_thread_pointer}; +pub use trap::write_trap_vector_base; diff --git a/arch/karch/src/riscv/tlb.rs b/arch/karch/src/riscv/tlb.rs new file mode 100644 index 00000000..0f7e0e79 --- /dev/null +++ b/arch/karch/src/riscv/tlb.rs @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! TLB maintenance operations for RISC-V. + +use memaddr::VirtAddr; +use riscv::asm; + +/// Flushes the TLB. +/// +/// If `vaddr` is [`None`], flushes the entire TLB. Otherwise, flushes the TLB +/// entry that maps the given virtual address. +#[inline] +pub fn flush_tlb(vaddr: Option) { + if let Some(vaddr) = vaddr { + asm::sfence_vma(0, vaddr.as_usize()) + } else { + asm::sfence_vma_all(); + } +} diff --git a/arch/karch/src/riscv/tls.rs b/arch/karch/src/riscv/tls.rs new file mode 100644 index 00000000..c75f27c2 --- /dev/null +++ b/arch/karch/src/riscv/tls.rs @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Thread-local storage operations for RISC-V. + +/// Reads the thread pointer of the current CPU (`tp`). +/// +/// It is used to implement TLS (Thread Local Storage). +#[inline] +pub fn read_thread_pointer() -> usize { + let tp; + unsafe { core::arch::asm!("mv {}, tp", out(reg) tp) }; + tp +} + +/// Writes the thread pointer of the current CPU (`tp`). +/// +/// It is used to implement TLS (Thread Local Storage). +/// +/// # Safety +/// +/// This function is unsafe as it changes the CPU states. +#[inline] +pub unsafe fn write_thread_pointer(val: usize) { + unsafe { core::arch::asm!("mv tp, {}", in(reg) val) } +} diff --git a/arch/karch/src/riscv/trap.rs b/arch/karch/src/riscv/trap.rs new file mode 100644 index 00000000..c71e6bde --- /dev/null +++ b/arch/karch/src/riscv/trap.rs @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Exception/trap vector operations for RISC-V. + +use riscv::register::stvec; + +/// Writes the Supervisor Trap Vector Base Address register (`stvec`). +/// +/// # Safety +/// +/// This function is unsafe as it changes the exception handling behavior of the +/// current CPU. +#[inline] +pub unsafe fn write_trap_vector_base(addr: usize) { + let mut reg = stvec::read(); + reg.set_address(addr); + reg.set_trap_mode(stvec::TrapMode::Direct); + unsafe { stvec::write(reg) } +} diff --git a/arch/karch/src/x86_64/cpu.rs b/arch/karch/src/x86_64/cpu.rs new file mode 100644 index 00000000..a7da5b25 --- /dev/null +++ b/arch/karch/src/x86_64/cpu.rs @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! CPU control operations for x86_64. + +use core::arch::asm; + +use super::irq::disable_local_irq; + +/// Halt the current CPU. +#[inline] +pub fn stop_cpu() { + disable_local_irq(); + await_interrupts(); // should never return +} + +/// Relaxes the current CPU and waits for interrupts. +/// +/// It must be called with interrupts enabled, otherwise it will never return. +#[inline] +pub fn await_interrupts() { + if cfg!(target_os = "none") { + unsafe { asm!("hlt") } + } else { + core::hint::spin_loop() + } +} diff --git a/arch/karch/src/x86_64/hypercall.rs b/arch/karch/src/x86_64/hypercall.rs new file mode 100644 index 00000000..6a2fa3a7 --- /dev/null +++ b/arch/karch/src/x86_64/hypercall.rs @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Hypervisor call operations for x86_64. + +use core::arch::asm; + +/// Performs a hypercall to the hypervisor using the `vmmcall` instruction. +/// +/// This is used on AMD/Hygon platforms for KVM hypercalls. +/// For Intel platforms, `vmcall` would be used instead. +/// +/// # Arguments +/// * `nr` - Hypercall number (passed in RAX) +/// * `a0` - First argument (passed in RBX) +/// * `a1` - Second argument (passed in RCX) +/// +/// # Returns +/// The return value from the hypervisor (from RAX). +#[inline] +pub fn hypercall(nr: u64, a0: u64, a1: u64) -> i64 { + let ret: i64; + unsafe { + // Note: rbx is reserved by LLVM, so we need to save/restore it manually + asm!( + "push rbx", + "mov rbx, {a0}", + "vmmcall", + "pop rbx", + a0 = in(reg) a0, + inout("rax") nr => ret, + in("rcx") a1, + options() + ); + } + ret +} diff --git a/arch/karch/src/x86_64/irq.rs b/arch/karch/src/x86_64/irq.rs new file mode 100644 index 00000000..893403a6 --- /dev/null +++ b/arch/karch/src/x86_64/irq.rs @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Interrupt control operations for x86_64. + +use core::arch::asm; + +use x86_64::instructions::interrupts; + +/// Allows the current CPU to respond to interrupts. +#[inline] +pub fn enable_local_irq() { + #[cfg(target_os = "none")] + interrupts::enable() +} + +/// Makes the current CPU ignore interrupts. +#[inline] +pub fn disable_local_irq() { + #[cfg(target_os = "none")] + interrupts::disable() +} + +/// Returns whether the current CPU is allowed to respond to interrupts. +#[inline] +pub fn local_irq_enabled() -> bool { + interrupts::are_enabled() +} + +/// Deprecated: use [`enable_local_irq`] instead. +#[deprecated(note = "Use `enable_local_irq` instead")] +#[inline] +pub fn enable_irq() { + enable_local_irq() +} + +/// Deprecated: use [`disable_local_irq`] instead. +#[deprecated(note = "Use `disable_local_irq` instead")] +#[inline] +pub fn disable_irq() { + disable_local_irq() +} + +/// Deprecated: use [`local_irq_enabled`] instead. +#[deprecated(note = "Use `local_irq_enabled` instead")] +#[inline] +pub fn irq_enabled() -> bool { + local_irq_enabled() +} + +/// Saves the current local interrupt state and disables interrupts atomically. +/// +/// Returns the saved EFLAGS value with the IF bit. Pass it to [`restore_irq`] +/// to restore the previous interrupt state. +#[inline] +pub fn save_irq_and_disable() -> usize { + #[cfg(target_os = "none")] + { + /// Interrupt Enable Flag (IF). + const IF_BIT: usize = 1 << 9; + let flags: usize; + unsafe { asm!("pushf; pop {}; cli", out(reg) flags) }; + flags & IF_BIT + } + #[cfg(not(target_os = "none"))] + 0 +} + +/// Restores local interrupt state from a value previously returned by +/// [`save_irq_and_disable`]. +#[inline] +pub fn restore_irq(flags: usize) { + #[cfg(target_os = "none")] + { + if flags != 0 { + unsafe { asm!("sti") }; + } else { + unsafe { asm!("cli") }; + } + } + #[cfg(not(target_os = "none"))] + let _ = flags; +} diff --git a/arch/karch/src/x86_64/mmu.rs b/arch/karch/src/x86_64/mmu.rs new file mode 100644 index 00000000..8acf639e --- /dev/null +++ b/arch/karch/src/x86_64/mmu.rs @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! MMU/page table operations for x86_64. + +use memaddr::{MemoryAddr, PhysAddr}; +use x86::controlregs; + +/// Reads the current page table root register for user space (`CR3`). +/// +/// x86_64 does not have a separate page table root register for user and +/// kernel space, so this operation is the same as [`read_kernel_page_table`]. +/// +/// Returns the physical address of the page table root. +#[inline] +pub fn read_user_page_table() -> PhysAddr { + PhysAddr::from(unsafe { controlregs::cr3() } as usize).align_down_4k() +} + +/// Reads the current page table root register for kernel space (`CR3`). +/// +/// x86_64 does not have a separate page table root register for user and +/// kernel space, so this operation is the same as [`read_user_page_table`]. +/// +/// Returns the physical address of the page table root. +#[inline] +pub fn read_kernel_page_table() -> PhysAddr { + read_user_page_table() +} + +/// Writes the register to update the current page table root for user space +/// (`CR3`). +/// +/// x86_64 does not have a separate page table root register for user +/// and kernel space, so this operation is the same as [`write_kernel_page_table`]. +/// +/// Note that the TLB will be **flushed** after this operation. +/// +/// # Safety +/// +/// This function is unsafe as it changes the virtual memory address space. +#[inline] +pub unsafe fn write_user_page_table(root_paddr: PhysAddr) { + unsafe { controlregs::cr3_write(root_paddr.as_usize() as _) } +} + +/// Writes the register to update the current page table root for kernel space +/// (`CR3`). +/// +/// x86_64 does not have a separate page table root register for user +/// and kernel space, so this operation is the same as [`write_user_page_table`]. +/// +/// Note that the TLB will be **flushed** after this operation. +/// +/// # Safety +/// +/// This function is unsafe as it changes the virtual memory address space. +#[inline] +pub unsafe fn write_kernel_page_table(root_paddr: PhysAddr) { + unsafe { write_user_page_table(root_paddr) } +} diff --git a/arch/karch/src/x86_64/mod.rs b/arch/karch/src/x86_64/mod.rs new file mode 100644 index 00000000..03ca60ff --- /dev/null +++ b/arch/karch/src/x86_64/mod.rs @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! x86_64 low-level architecture operations. + +mod cpu; +mod hypercall; +mod irq; +mod mmu; +mod tlb; +mod tls; + +pub use cpu::{await_interrupts, stop_cpu}; +pub use hypercall::hypercall; +#[allow(deprecated)] +pub use irq::{ + disable_irq, disable_local_irq, enable_irq, enable_local_irq, irq_enabled, local_irq_enabled, + restore_irq, save_irq_and_disable, +}; +pub use mmu::{ + read_kernel_page_table, read_user_page_table, write_kernel_page_table, write_user_page_table, +}; +pub use tlb::flush_tlb; +pub use tls::{read_thread_pointer, write_thread_pointer}; diff --git a/arch/karch/src/x86_64/tlb.rs b/arch/karch/src/x86_64/tlb.rs new file mode 100644 index 00000000..f86ff31a --- /dev/null +++ b/arch/karch/src/x86_64/tlb.rs @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! TLB maintenance operations for x86_64. + +use memaddr::VirtAddr; +use x86::tlb; + +/// Flushes the TLB. +/// +/// If `vaddr` is [`None`], flushes the entire TLB. Otherwise, flushes the TLB +/// entry that maps the given virtual address. +#[inline] +pub fn flush_tlb(vaddr: Option) { + if let Some(vaddr) = vaddr { + unsafe { tlb::flush(vaddr.into()) } + } else { + unsafe { tlb::flush_all() } + } +} diff --git a/arch/karch/src/x86_64/tls.rs b/arch/karch/src/x86_64/tls.rs new file mode 100644 index 00000000..24e644b6 --- /dev/null +++ b/arch/karch/src/x86_64/tls.rs @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + +//! Thread-local storage operations for x86_64. + +use x86::msr; + +/// Reads the thread pointer of the current CPU (`FS_BASE`). +/// +/// It is used to implement TLS (Thread Local Storage). +#[inline] +pub fn read_thread_pointer() -> usize { + unsafe { msr::rdmsr(msr::IA32_FS_BASE) as usize } +} + +/// Writes the thread pointer of the current CPU (`FS_BASE`). +/// +/// It is used to implement TLS (Thread Local Storage). +/// +/// # Safety +/// +/// This function is unsafe as it changes the CPU states. +#[inline] +pub unsafe fn write_thread_pointer(val: usize) { + unsafe { msr::wrmsr(msr::IA32_FS_BASE, val as u64) } +} diff --git a/arch/kcpu/Cargo.toml b/arch/kcpu/Cargo.toml index 845d58f5..33f5b6f3 100644 --- a/arch/kcpu/Cargo.toml +++ b/arch/kcpu/Cargo.toml @@ -13,10 +13,11 @@ default = [] fp-simd = [] tls = [] uspace = [] -arm-el2 = [] +arm-el2 = ["karch/arm-el2"] [dependencies] backtrace = { workspace = true } +karch = { workspace = true } kplat = { workspace = true } linkme = "0.3" log = "0.4" diff --git a/arch/kcpu/src/aarch64/boot.rs b/arch/kcpu/src/aarch64/boot.rs index 6e2b7a3e..27ef3973 100644 --- a/arch/kcpu/src/aarch64/boot.rs +++ b/arch/kcpu/src/aarch64/boot.rs @@ -91,7 +91,7 @@ pub unsafe fn init_mmu(root_paddr: PhysAddr) { TTBR1_EL1.set(root_paddr); // Flush the entire TLB - crate::instrs::flush_tlb(None); + karch::flush_tlb(None); // Enable the MMU and turn on I-cache and D-cache SCTLR_EL1.modify(SCTLR_EL1::M::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::I::Cacheable); @@ -111,7 +111,7 @@ pub fn init_trap() { fn exception_vector_base(); } unsafe { - crate::instrs::write_exception_vector_base(exception_vector_base as *const () as usize); - crate::instrs::write_user_page_table(0.into()); + karch::write_trap_vector_base(exception_vector_base as *const () as usize); + karch::write_user_page_table(0.into()); } } diff --git a/arch/kcpu/src/aarch64/ctx.rs b/arch/kcpu/src/aarch64/ctx.rs index 4a0618f9..949f4be5 100644 --- a/arch/kcpu/src/aarch64/ctx.rs +++ b/arch/kcpu/src/aarch64/ctx.rs @@ -253,8 +253,8 @@ impl TaskContext { pub fn switch_to(&mut self, next_ctx: &Self) { #[cfg(feature = "tls")] { - self.tpidr_el0 = crate::instrs::read_thread_pointer() as _; - unsafe { crate::instrs::write_thread_pointer(next_ctx.tpidr_el0 as _) }; + self.tpidr_el0 = karch::read_thread_pointer() as _; + unsafe { karch::write_thread_pointer(next_ctx.tpidr_el0 as _) }; } #[cfg(feature = "fp-simd")] { @@ -263,8 +263,8 @@ impl TaskContext { } #[cfg(feature = "uspace")] if self.ttbr0_el1 != next_ctx.ttbr0_el1 { - unsafe { crate::instrs::write_user_page_table(next_ctx.ttbr0_el1) }; - crate::instrs::flush_tlb(None); // currently flush the entire TLB + unsafe { karch::write_user_page_table(next_ctx.ttbr0_el1) }; + karch::flush_tlb(None); // currently flush the entire TLB } unsafe { context_switch(self, next_ctx) } } diff --git a/arch/kcpu/src/aarch64/instrs.rs b/arch/kcpu/src/aarch64/instrs.rs index 13b16965..1caf938d 100644 --- a/arch/kcpu/src/aarch64/instrs.rs +++ b/arch/kcpu/src/aarch64/instrs.rs @@ -4,193 +4,6 @@ //! Wrapper functions for assembly instructions. -use core::arch::asm; - -use aarch64_cpu::{asm::barrier, registers::*}; -pub use kplat::interrupts::{disable_local, enable_local, is_enabled}; -use memaddr::{PhysAddr, VirtAddr}; - -/// Halt the current CPU. -#[inline] -pub fn stop_cpu() { - disable_local(); - // Execute WFI (Wait For Interrupt) instruction - // Since interrupts are disabled, this should stop execution until reset - aarch64_cpu::asm::wfi(); -} - -/// Relaxes the current CPU and waits for interrupts. -/// -/// It must be called with interrupts enabled, otherwise it will never return. -#[inline] -pub fn await_interrupts() { - aarch64_cpu::asm::wfi(); -} - -/// Reads the current page table root register for kernel space (`TTBR1_EL1`). -/// -/// When the "arm-el2" feature is enabled, -/// TTBR0_EL2 is dedicated to the Hypervisor's Stage-2 page table base address. -/// -/// Returns the physical address of the page table root. -#[inline] -pub fn kernel_pt_root() -> PhysAddr { - let pt_root_reg: usize; - - #[cfg(not(feature = "arm-el2"))] - { - pt_root_reg = TTBR1_EL1.get() as usize; - } - - #[cfg(feature = "arm-el2")] - { - pt_root_reg = TTBR0_EL2.get() as usize; - } - - pa!(pt_root_reg) -} - -/// Reads the current page table root register for user space (`TTBR0_EL1`). -/// -/// When the "arm-el2" feature is enabled, for user-mode programs, -/// virtualization is completely transparent to them, so there is no need to modify -/// -/// Returns the physical address of the page table root. -#[inline] -pub fn user_pt_root() -> PhysAddr { - let val = TTBR0_EL1.get(); - pa!(val as usize) -} - -/// Writes the register to update the current page table root for kernel space -/// (`TTBR1_EL1`). -/// -/// When the "arm-el2" feature is enabled, -/// TTBR0_EL2 is dedicated to the Hypervisor's Stage-2 page table base address. -/// -/// Note that the TLB is **NOT** flushed after this operation. -/// -/// # Safety -/// -/// This function is unsafe as it changes the virtual memory address space. -#[inline] -pub unsafe fn write_kernel_page_table(root_paddr: PhysAddr) { - #[cfg(not(feature = "arm-el2"))] - { - // kernel space page table use TTBR1 (0xffff_0000_0000_0000..0xffff_ffff_ffff_ffff) - TTBR1_EL1.set(root_paddr.as_usize() as _); - } - - #[cfg(feature = "arm-el2")] - { - // kernel space page table at EL2 use TTBR0_EL2 (0x0000_0000_0000_0000..0x0000_ffff_ffff_ffff) - TTBR0_EL2.set(root_paddr.as_usize() as _); - } -} - -/// Writes the register to update the current page table root for user space -/// (`TTBR1_EL0`). -/// When the "arm-el2" feature is enabled, for user-mode programs, -/// virtualization is completely transparent to them, so there is no need to modify -/// -/// Note that the TLB is **NOT** flushed after this operation. -/// -/// # Safety -/// -/// This function is unsafe as it changes the virtual memory address space. -#[inline] -pub unsafe fn write_user_page_table(root_paddr: PhysAddr) { - TTBR0_EL1.set(root_paddr.as_usize() as _); -} - -/// Flushes the TLB. -/// -/// If `vaddr` is [`None`], flushes the entire TLB. Otherwise, flushes the TLB -/// entry that maps the given virtual address. -#[inline] -pub fn flush_tlb(vaddr: Option) { - if let Some(vaddr) = vaddr { - const VA_MASK: usize = (1 << 44) - 1; // VA[55:12] => bits[43:0] - let operand = (vaddr.as_usize() >> 12) & VA_MASK; - - #[cfg(not(feature = "arm-el2"))] - unsafe { - // TLB Invalidate by VA, All ASID, EL1, Inner Shareable - asm!("tlbi vaae1is, {}; dsb sy; isb", in(reg) operand) - } - #[cfg(feature = "arm-el2")] - unsafe { - // TLB Invalidate by VA, EL2, Inner Shareable - asm!("tlbi vae2is, {}; dsb sy; isb", in(reg) operand) - } - } else { - // flush the entire TLB - #[cfg(not(feature = "arm-el2"))] - unsafe { - // TLB Invalidate by VMID, All at stage 1, EL1 - asm!("dsb sy; isb; tlbi vmalle1; dsb sy; isb") - } - #[cfg(feature = "arm-el2")] - unsafe { - // TLB Invalidate All, EL2 - asm!("tlbi alle2; dsb sy; isb") - } - } -} - -/// Flushes the entire instruction cache. -#[inline] -pub fn flush_icache_all() { - unsafe { asm!("ic iallu; dsb sy; isb") }; -} - -/// Flushes the data cache line (64 bytes) at the given virtual address -#[inline] -pub fn flush_dcache_line(vaddr: VirtAddr) { - unsafe { asm!("dc ivac, {0:x}; dsb sy; isb", in(reg) vaddr.as_usize()) }; -} - -/// Writes exception vector base address register (`VBAR_EL1`). -/// -/// # Safety -/// -/// This function is unsafe as it changes the exception handling behavior of the -/// current CPU. -#[inline] -pub unsafe fn write_exception_vector_base(vbar: usize) { - #[cfg(not(feature = "arm-el2"))] - VBAR_EL1.set(vbar as _); - #[cfg(feature = "arm-el2")] - VBAR_EL2.set(vbar as _); -} - -/// Reads the thread pointer of the current CPU (`TPIDR_EL0`). -/// -/// It is used to implement TLS (Thread Local Storage). -#[inline] -pub fn read_thread_pointer() -> usize { - TPIDR_EL0.get() as usize -} - -/// Writes the thread pointer of the current CPU (`TPIDR_EL0`). -/// -/// It is used to implement TLS (Thread Local Storage). -/// -/// # Safety -/// -/// This function is unsafe as it changes the current CPU states. -#[inline] -pub unsafe fn write_thread_pointer(tpidr_el0: usize) { - TPIDR_EL0.set(tpidr_el0 as _) -} - -/// Enable FP/SIMD instructions by setting the `FPEN` field in `CPACR_EL1`. -#[inline] -pub fn enable_fp() { - CPACR_EL1.write(CPACR_EL1::FPEN::TrapNothing); - barrier::isb(barrier::SY); -} - #[cfg(feature = "uspace")] core::arch::global_asm!(include_str!("copy_user.S")); diff --git a/arch/kcpu/src/aarch64/userspace.rs b/arch/kcpu/src/aarch64/userspace.rs index 59caecea..3d4745ca 100644 --- a/arch/kcpu/src/aarch64/userspace.rs +++ b/arch/kcpu/src/aarch64/userspace.rs @@ -85,7 +85,7 @@ impl UserContext { unsafe fn enter_user(uctx: &mut UserContext) -> ArchTrap; } - crate::instrs::disable_local(); // updated module reference from asm -> instrs + karch::disable_local_irq(); // updated module reference from asm -> instrs let trap_kind = unsafe { enter_user(self) }; let ret = match trap_kind { @@ -125,7 +125,7 @@ impl UserContext { } }; - crate::instrs::enable_local(); + karch::enable_local_irq(); ret } } diff --git a/arch/kcpu/src/loongarch64/boot.rs b/arch/kcpu/src/loongarch64/boot.rs index 6b1c0533..8724146d 100644 --- a/arch/kcpu/src/loongarch64/boot.rs +++ b/arch/kcpu/src/loongarch64/boot.rs @@ -30,11 +30,11 @@ pub fn init_mmu(root_paddr: PhysAddr, phys_virt_offset: usize) { // Configure page table walking unsafe { - crate::instrs::write_pwc(LA64MetaData::PWCL_VALUE, LA64MetaData::PWCH_VALUE); - crate::instrs::write_kernel_page_table(root_paddr); - crate::instrs::write_user_page_table(pa!(0)); + karch::write_pwc(LA64MetaData::PWCL_VALUE, LA64MetaData::PWCH_VALUE); + karch::write_kernel_page_table(root_paddr); + karch::write_user_page_table(pa!(0)); } - crate::instrs::flush_tlb(None); + karch::flush_tlb(None); // Enable mapped address translation mode crmd::set_pg(true); @@ -51,6 +51,6 @@ pub fn init_trap() { fn exception_entry_base(); } core::arch::asm!(include_asm_macros!(), "csrwr $r0, KSAVE_KSP"); - crate::instrs::write_exception_entry_base(exception_entry_base as usize); + karch::write_trap_vector_base(exception_entry_base as usize); } } diff --git a/arch/kcpu/src/loongarch64/ctx.rs b/arch/kcpu/src/loongarch64/ctx.rs index 9a7594cf..549454d7 100644 --- a/arch/kcpu/src/loongarch64/ctx.rs +++ b/arch/kcpu/src/loongarch64/ctx.rs @@ -301,14 +301,14 @@ impl TaskContext { pub fn switch_to(&mut self, next_ctx: &Self) { #[cfg(feature = "tls")] { - self.tp = crate::instrs::read_thread_pointer(); - unsafe { crate::instrs::write_thread_pointer(next_ctx.tp) }; + self.tp = karch::read_thread_pointer(); + unsafe { karch::write_thread_pointer(next_ctx.tp) }; } #[cfg(feature = "uspace")] { if self.pgdl != next_ctx.pgdl { - unsafe { crate::instrs::write_user_page_table(pa!(next_ctx.pgdl)) }; - crate::instrs::flush_tlb(None); // currently flush the entire TLB + unsafe { karch::write_user_page_table(pa!(next_ctx.pgdl)) }; + karch::flush_tlb(None); // currently flush the entire TLB } } #[cfg(feature = "fp-simd")] diff --git a/arch/kcpu/src/loongarch64/instrs.rs b/arch/kcpu/src/loongarch64/instrs.rs index 6a8e0aca..6821423d 100644 --- a/arch/kcpu/src/loongarch64/instrs.rs +++ b/arch/kcpu/src/loongarch64/instrs.rs @@ -4,190 +4,11 @@ //! Wrapper functions for assembly instructions. -use core::arch::asm; - -use loongArch64::register::{crmd, ecfg, eentry, pgdh, pgdl}; -use memaddr::{PhysAddr, VirtAddr}; - -/// Allows the current CPU to respond to interrupts. -#[inline] -pub fn enable_local() { - crmd::set_ie(true) -} - -/// Makes the current CPU to ignore interrupts. -#[inline] -pub fn disable_local() { - crmd::set_ie(false) -} - -/// Returns whether the current CPU is allowed to respond to interrupts. -#[inline] -pub fn is_enabled() -> bool { - crmd::read().ie() -} - -/// Relaxes the current CPU and waits for interrupts. -/// -/// It must be called with interrupts enabled, otherwise it will never return. -#[inline] -pub fn await_interrupts() { - unsafe { loongArch64::asm::idle() } -} - -/// Halt the current CPU. -#[inline] -pub fn stop_cpu() { - disable_local(); - unsafe { loongArch64::asm::idle() } -} - -/// Reads the current page table root register for user space (`PGDL`). -/// -/// Returns the physical address of the page table root. -#[inline] -pub fn read_user_page_table() -> PhysAddr { - PhysAddr::from(pgdl::read().base()) -} - -/// Reads the current page table root register for kernel space (`PGDH`). -/// -/// Returns the physical address of the page table root. -#[inline] -pub fn read_kernel_page_table() -> PhysAddr { - PhysAddr::from(pgdh::read().base()) -} - -/// Writes the register to update the current page table root for user space -/// (`PGDL`). -/// -/// Note that the TLB is **NOT** flushed after this operation. -/// -/// # Safety -/// -/// This function is unsafe as it changes the virtual memory address space. -pub unsafe fn write_user_page_table(root_paddr: PhysAddr) { - pgdl::set_base(root_paddr.as_usize() as _); -} - -/// Writes the register to update the current page table root for kernel space -/// (`PGDH`). -/// -/// Note that the TLB is **NOT** flushed after this operation. -/// -/// # Safety -/// -/// This function is unsafe as it changes the virtual memory address space. -pub unsafe fn write_kernel_page_table(root_paddr: PhysAddr) { - pgdh::set_base(root_paddr.as_usize()); -} - -/// Flushes the TLB. -/// -/// If `vaddr` is [`None`], flushes the entire TLB. Otherwise, flushes the TLB -/// entry that maps the given virtual address. -#[inline] -pub fn flush_tlb(vaddr: Option) { - unsafe { - if let Some(vaddr) = vaddr { - // - // - // Only after all previous load/store access operations are completely - // executed, the DBAR 0 instruction can be executed; and only after the - // execution of DBAR 0 is completed, all subsequent load/store access - // operations can be executed. - // - // - // - // formats: invtlb op, asid, addr - // - // op 0x5: Clear all page table entries with G=0 and ASID equal to the - // register specified ASID, and VA equal to the register specified VA. - // - // When the operation indicated by op does not require an ASID, the - // general register rj should be set to r0. - asm!("dbar 0; invtlb 0x05, $r0, {reg}", reg = in(reg) vaddr.as_usize()); - } else { - // op 0x0: Clear all page table entries - asm!("dbar 0; invtlb 0x00, $r0, $r0"); - } - } -} - -/// Writes the Exception Entry Base Address register (`EENTRY`). -/// -/// It also set the Exception Configuration register (`ECFG`) to `VS=0`. -/// -/// - ECFG: -/// - EENTRY: -/// -/// # Safety -/// -/// This function is unsafe as it changes the exception handling behavior of the -/// current CPU. +/// Deprecated: use [`karch::write_trap_vector_base`] instead. +#[deprecated(note = "Use `karch::write_trap_vector_base` instead")] #[inline] pub unsafe fn write_exception_entry_base(eentry: usize) { - ecfg::set_vs(0); - eentry::set_eentry(eentry); -} - -/// Writes the Page Walk Controller registers (`PWCL` and `PWCH`). -/// -/// # Safety -/// -/// This function is unsafe as it changes the page walk configuration such as -/// levels and starting bits. -/// -/// - `PWCL`: -/// - `PWCH`: -#[inline] -pub unsafe fn write_pwc(pwcl: u32, pwch: u32) { - unsafe { - asm!( - include_asm_macros!(), - "csrwr {}, LA_CSR_PWCL", - "csrwr {}, LA_CSR_PWCH", - in(reg) pwcl, - in(reg) pwch - ) - } -} - -/// Reads the thread pointer of the current CPU (`$tp`). -/// -/// It is used to implement TLS (Thread Local Storage). -#[inline] -pub fn read_thread_pointer() -> usize { - let tp; - unsafe { asm!("move {}, $tp", out(reg) tp) }; - tp -} - -/// Writes the thread pointer of the current CPU (`$tp`). -/// -/// It is used to implement TLS (Thread Local Storage). -/// -/// # Safety -/// -/// This function is unsafe as it changes the CPU states. -#[inline] -pub unsafe fn write_thread_pointer(tp: usize) { - unsafe { asm!("move $tp, {}", in(reg) tp) } -} - -/// Enables floating-point instructions by setting `EUEN.FPE`. -/// -/// - `EUEN`: -#[inline] -pub fn enable_fp() { - loongArch64::register::euen::set_fpe(true); -} - -/// Enables LSX extension by setting `EUEN.LSX`. -/// -/// - `EUEN`: -pub fn enable_lsx() { - loongArch64::register::euen::set_sxe(true); + unsafe { karch::write_trap_vector_base(eentry) } } #[cfg(feature = "uspace")] diff --git a/arch/kcpu/src/loongarch64/userspace.rs b/arch/kcpu/src/loongarch64/userspace.rs index 2d0ad397..d5ed15d8 100644 --- a/arch/kcpu/src/loongarch64/userspace.rs +++ b/arch/kcpu/src/loongarch64/userspace.rs @@ -45,7 +45,7 @@ impl UserContext { fn enter_user(uctx: &mut UserContext); } - crate::instrs::disable_local(); + karch::disable_local_irq(); unsafe { enter_user(self) }; let estat = estat::read(); @@ -78,7 +78,7 @@ impl UserContext { _ => ReturnReason::Unknown, }; - crate::instrs::enable_local(); + karch::enable_local_irq(); ret } } diff --git a/arch/kcpu/src/riscv/boot.rs b/arch/kcpu/src/riscv/boot.rs index 64c4bf88..c77768ab 100644 --- a/arch/kcpu/src/riscv/boot.rs +++ b/arch/kcpu/src/riscv/boot.rs @@ -16,6 +16,6 @@ pub fn init_trap() { unsafe { #[cfg(feature = "uspace")] riscv::register::sstatus::set_sum(); - crate::instrs::write_trap_vector_base(trap_vector_base as *const () as usize); + karch::write_trap_vector_base(trap_vector_base as *const () as usize); } } diff --git a/arch/kcpu/src/riscv/ctx.rs b/arch/kcpu/src/riscv/ctx.rs index 902f9e62..a5160958 100644 --- a/arch/kcpu/src/riscv/ctx.rs +++ b/arch/kcpu/src/riscv/ctx.rs @@ -353,7 +353,7 @@ impl TaskContext { pub fn new() -> Self { Self { #[cfg(feature = "uspace")] - satp: crate::instrs::read_kernel_page_table(), + satp: karch::read_kernel_page_table(), ..Default::default() } } @@ -382,13 +382,13 @@ impl TaskContext { pub fn switch_to(&mut self, next_ctx: &Self) { #[cfg(feature = "tls")] { - self.tp = crate::instrs::read_thread_pointer(); - unsafe { crate::instrs::write_thread_pointer(next_ctx.tp) }; + self.tp = karch::read_thread_pointer(); + unsafe { karch::write_thread_pointer(next_ctx.tp) }; } #[cfg(feature = "uspace")] if self.satp != next_ctx.satp { - unsafe { crate::instrs::write_user_page_table(next_ctx.satp) }; - crate::instrs::flush_tlb(None); // currently flush the entire TLB + unsafe { karch::write_user_page_table(next_ctx.satp) }; + karch::flush_tlb(None); // currently flush the entire TLB } #[cfg(feature = "fp-simd")] { diff --git a/arch/kcpu/src/riscv/instrs.rs b/arch/kcpu/src/riscv/instrs.rs index f1d0ca07..b4df8292 100644 --- a/arch/kcpu/src/riscv/instrs.rs +++ b/arch/kcpu/src/riscv/instrs.rs @@ -4,148 +4,6 @@ //! Wrapper functions for assembly instructions. -use memaddr::{PhysAddr, VirtAddr}; -use riscv::{ - asm, - register::{satp, sstatus, stvec}, -}; - -/// Allows the current CPU to respond to interrupts. -#[inline] -pub fn enable_local() { - unsafe { sstatus::set_sie() } -} - -/// Makes the current CPU to ignore interrupts. -#[inline] -pub fn disable_local() { - unsafe { sstatus::clear_sie() } -} - -/// Returns whether the current CPU is allowed to respond to interrupts. -#[inline] -pub fn is_enabled() -> bool { - sstatus::read().sie() -} - -/// Relaxes the current CPU and waits for interrupts. -/// -/// It must be called with interrupts enabled, otherwise it will never return. -#[inline] -pub fn await_interrupts() { - riscv::asm::wfi() -} - -/// Halt the current CPU. -#[inline] -pub fn stop_cpu() { - disable_local(); - riscv::asm::wfi() // should never return -} - -/// Reads the current page table root register for user space (`satp`). -/// -/// RISC-V does not have a separate page table root register for user and -/// kernel space, so this operation is the same as [`read_kernel_page_table`]. -/// -/// Returns the physical address of the page table root. -#[inline] -pub fn read_user_page_table() -> PhysAddr { - pa!(satp::read().ppn() << 12) -} - -/// Reads the current page table root register for kernel space (`satp`). -/// -/// RISC-V does not have a separate page table root register for user and -/// kernel space, so this operation is the same as [`read_user_page_table`]. -/// -/// Returns the physical address of the page table root. -#[inline] -pub fn read_kernel_page_table() -> PhysAddr { - read_user_page_table() -} - -/// Writes the register to update the current page table root for user space -/// (`satp`). -/// -/// RISC-V does not have a separate page table root register for user -/// and kernel space, so this operation is the same as [`write_kernel_page_table`]. -/// -/// Note that the TLB is **NOT** flushed after this operation. -/// -/// # Safety -/// -/// This function is unsafe as it changes the virtual memory address space. -#[inline] -pub unsafe fn write_user_page_table(root_paddr: PhysAddr) { - unsafe { satp::set(satp::Mode::Sv39, 0, root_paddr.as_usize() >> 12) }; -} - -/// Writes the register to update the current page table root for user space -/// (`satp`). -/// -/// RISC-V does not have a separate page table root register for user -/// and kernel space, so this operation is the same as [`write_user_page_table`]. -/// -/// Note that the TLB is **NOT** flushed after this operation. -/// -/// # Safety -/// -/// This function is unsafe as it changes the virtual memory address space. -#[inline] -pub unsafe fn write_kernel_page_table(root_paddr: PhysAddr) { - unsafe { write_user_page_table(root_paddr) }; -} - -/// Flushes the TLB. -/// -/// If `vaddr` is [`None`], flushes the entire TLB. Otherwise, flushes the TLB -/// entry that maps the given virtual address. -#[inline] -pub fn flush_tlb(vaddr: Option) { - if let Some(vaddr) = vaddr { - asm::sfence_vma(0, vaddr.as_usize()) - } else { - asm::sfence_vma_all(); - } -} - -/// Writes the Supervisor Trap Vector Base Address register (`stvec`). -/// -/// # Safety -/// -/// This function is unsafe as it changes the exception handling behavior of the -/// current CPU. -#[inline] -pub unsafe fn write_trap_vector_base(stvec: usize) { - let mut reg = stvec::read(); - reg.set_address(stvec); - reg.set_trap_mode(stvec::TrapMode::Direct); - unsafe { stvec::write(reg) } -} - -/// Reads the thread pointer of the current CPU (`tp`). -/// -/// It is used to implement TLS (Thread Local Storage). -#[inline] -pub fn read_thread_pointer() -> usize { - let tp; - unsafe { core::arch::asm!("mv {}, tp", out(reg) tp) }; - tp -} - -/// Writes the thread pointer of the current CPU (`tp`). -/// -/// It is used to implement TLS (Thread Local Storage). -/// -/// # Safety -/// -/// This function is unsafe as it changes the CPU states. -#[inline] -pub unsafe fn write_thread_pointer(tp: usize) { - unsafe { core::arch::asm!("mv tp, {}", in(reg) tp) } -} - #[cfg(feature = "uspace")] core::arch::global_asm!(include_asm_macros!(), include_str!("copy_user.S")); diff --git a/arch/kcpu/src/riscv/userspace.rs b/arch/kcpu/src/riscv/userspace.rs index fba3d23c..34379a24 100644 --- a/arch/kcpu/src/riscv/userspace.rs +++ b/arch/kcpu/src/riscv/userspace.rs @@ -57,7 +57,7 @@ impl UserContext { fn enter_user(uctx: &mut UserContext); } - crate::instrs::disable_local(); + karch::disable_local_irq(); unsafe { enter_user(self) }; let scause = scause::read(); @@ -89,7 +89,7 @@ impl UserContext { ReturnReason::Unknown }; - crate::instrs::enable_local(); + karch::enable_local_irq(); ret } } diff --git a/arch/kcpu/src/x86_64/ctx.rs b/arch/kcpu/src/x86_64/ctx.rs index 13288527..3ece55c6 100644 --- a/arch/kcpu/src/x86_64/ctx.rs +++ b/arch/kcpu/src/x86_64/ctx.rs @@ -299,7 +299,7 @@ impl TaskContext { rsp: 0, fs_base: 0, #[cfg(feature = "uspace")] - cr3: crate::instrs::read_kernel_page_table(), + cr3: karch::read_kernel_page_table(), #[cfg(feature = "fp-simd")] ext_state: ExtendedState::default(), } @@ -348,13 +348,13 @@ impl TaskContext { } #[cfg(feature = "tls")] unsafe { - self.fs_base = crate::instrs::read_thread_pointer(); - crate::instrs::write_thread_pointer(next_ctx.fs_base); + self.fs_base = karch::read_thread_pointer(); + karch::write_thread_pointer(next_ctx.fs_base); } #[cfg(feature = "uspace")] unsafe { if next_ctx.cr3 != self.cr3 { - crate::instrs::write_user_page_table(next_ctx.cr3); + karch::write_user_page_table(next_ctx.cr3); // writing to CR3 has flushed the TLB } } diff --git a/arch/kcpu/src/x86_64/instrs.rs b/arch/kcpu/src/x86_64/instrs.rs index 3fa38d4f..4aa3ec2e 100644 --- a/arch/kcpu/src/x86_64/instrs.rs +++ b/arch/kcpu/src/x86_64/instrs.rs @@ -4,146 +4,6 @@ //! Wrapper functions for assembly instructions. -use core::arch::asm; - -use memaddr::{MemoryAddr, PhysAddr, VirtAddr}; -use x86::{controlregs, msr, tlb}; -use x86_64::instructions::interrupts; - -/// Allows the current CPU to respond to interrupts. -#[inline] -pub fn enable_local() { - #[cfg(not(target_os = "none"))] - { - warn!("enable_local: not implemented"); - } - #[cfg(target_os = "none")] - interrupts::enable() -} - -/// Makes the current CPU to ignore interrupts. -#[inline] -pub fn disable_local() { - #[cfg(not(target_os = "none"))] - { - warn!("disable_local: not implemented"); - } - #[cfg(target_os = "none")] - interrupts::disable() -} - -/// Returns whether the current CPU is allowed to respond to interrupts. -#[inline] -pub fn is_enabled() -> bool { - interrupts::are_enabled() -} - -/// Relaxes the current CPU and waits for interrupts. -/// -/// It must be called with interrupts enabled, otherwise it will never return. -#[inline] -pub fn await_interrupts() { - if cfg!(target_os = "none") { - unsafe { asm!("hlt") } - } else { - core::hint::spin_loop() - } -} - -/// Halt the current CPU. -#[inline] -pub fn stop_cpu() { - disable_local(); - await_interrupts(); // should never return -} - -/// Reads the current page table root register for user space (`CR3`). -/// -/// x86_64 does not have a separate page table root register for user and -/// kernel space, so this operation is the same as [`read_kernel_page_table`]. -/// -/// Returns the physical address of the page table root. -#[inline] -pub fn read_user_page_table() -> PhysAddr { - pa!(unsafe { controlregs::cr3() } as usize).align_down_4k() -} - -/// Reads the current page table root register for kernel space (`CR3`). -/// -/// x86_64 does not have a separate page table root register for user and -/// kernel space, so this operation is the same as [`read_user_page_table`]. -/// -/// Returns the physical address of the page table root. -#[inline] -pub fn read_kernel_page_table() -> PhysAddr { - read_user_page_table() -} - -/// Writes the register to update the current page table root for user space -/// (`CR3`). -/// -/// x86_64 does not have a separate page table root register for user -/// and kernel space, so this operation is the same as [`write_kernel_page_table`]. -/// -/// Note that the TLB will be **flushed** after this operation. -/// -/// # Safety -/// -/// This function is unsafe as it changes the virtual memory address space. -#[inline] -pub unsafe fn write_user_page_table(root_paddr: PhysAddr) { - unsafe { controlregs::cr3_write(root_paddr.as_usize() as _) } -} - -/// Writes the register to update the current page table root for kernel space -/// (`CR3`). -/// -/// x86_64 does not have a separate page table root register for user -/// and kernel space, so this operation is the same as [`write_user_page_table`]. -/// -/// Note that the TLB will be **flushed** after this operation. -/// -/// # Safety -/// -/// This function is unsafe as it changes the virtual memory address space. -#[inline] -pub unsafe fn write_kernel_page_table(root_paddr: PhysAddr) { - unsafe { write_user_page_table(root_paddr) } -} - -/// Flushes the TLB. -/// -/// If `vaddr` is [`None`], flushes the entire TLB. Otherwise, flushes the TLB -/// entry that maps the given virtual address. -#[inline] -pub fn flush_tlb(vaddr: Option) { - if let Some(vaddr) = vaddr { - unsafe { tlb::flush(vaddr.into()) } - } else { - unsafe { tlb::flush_all() } - } -} - -/// Reads the thread pointer of the current CPU (`FS_BASE`). -/// -/// It is used to implement TLS (Thread Local Storage). -#[inline] -pub fn read_thread_pointer() -> usize { - unsafe { msr::rdmsr(msr::IA32_FS_BASE) as usize } -} - -/// Writes the thread pointer of the current CPU (`FS_BASE`). -/// -/// It is used to implement TLS (Thread Local Storage). -/// -/// # Safety -/// -/// This function is unsafe as it changes the CPU states. -#[inline] -pub unsafe fn write_thread_pointer(fs_base: usize) { - unsafe { msr::wrmsr(msr::IA32_FS_BASE, fs_base as u64) } -} - #[cfg(feature = "uspace")] core::arch::global_asm!(include_str!("copy_user.S")); @@ -160,34 +20,3 @@ unsafe extern "C" { /// while a value > 0 indicates failure. pub fn user_copy(dst: *mut u8, src: *const u8, size: usize) -> usize; } - -/// Performs a hypercall to the hypervisor using the `vmmcall` instruction. -/// -/// This is used on AMD/Hygon platforms for KVM hypercalls. -/// For Intel platforms, `vmcall` would be used instead. -/// -/// # Arguments -/// * `nr` - Hypercall number (passed in RAX) -/// * `a0` - First argument (passed in RBX) -/// * `a1` - Second argument (passed in RCX) -/// -/// # Returns -/// The return value from the hypervisor (from RAX). -#[inline] -pub fn hypercall(nr: u64, a0: u64, a1: u64) -> i64 { - let ret: i64; - unsafe { - // Note: rbx is reserved by LLVM, so we need to save/restore it manually - core::arch::asm!( - "push rbx", - "mov rbx, {a0}", - "vmmcall", - "pop rbx", - a0 = in(reg) a0, - inout("rax") nr => ret, - in("rcx") a1, - options() - ); - } - ret -} diff --git a/arch/kcpu/src/x86_64/mod.rs b/arch/kcpu/src/x86_64/mod.rs index cac20ab4..3e26f0a3 100644 --- a/arch/kcpu/src/x86_64/mod.rs +++ b/arch/kcpu/src/x86_64/mod.rs @@ -10,7 +10,7 @@ mod idt; pub mod instrs; pub use instrs as asm; -pub use instrs::hypercall; +pub use karch::hypercall; pub mod boot; mod excp; diff --git a/arch/kcpu/src/x86_64/userspace.rs b/arch/kcpu/src/x86_64/userspace.rs index 4c9a8f43..6caf6676 100644 --- a/arch/kcpu/src/x86_64/userspace.rs +++ b/arch/kcpu/src/x86_64/userspace.rs @@ -18,7 +18,6 @@ use x86_64::{ use super::{ TrapFrame, - asm::{read_thread_pointer, write_thread_pointer}, excp::{IRQ_VECTOR_END, IRQ_VECTOR_START, LEGACY_SYSCALL_VECTOR, err_code_to_flags}, gdt, }; @@ -79,17 +78,17 @@ impl UserContext { assert_eq!(self.cs, gdt::UCODE64.0 as _); assert_eq!(self.ss, gdt::UDATA.0 as _); - crate::instrs::disable_local(); + karch::disable_local_irq(); - let kernel_fs_base = read_thread_pointer(); - unsafe { write_thread_pointer(self.fs_base as _) }; + let kernel_fs_base = karch::read_thread_pointer(); + unsafe { karch::write_thread_pointer(self.fs_base as _) }; KernelGsBase::write(x86_64::VirtAddr::new_truncate(self.gs_base)); unsafe { enter_user(self) }; self.gs_base = KernelGsBase::read().as_u64(); - self.fs_base = read_thread_pointer() as _; - unsafe { write_thread_pointer(kernel_fs_base) }; + self.fs_base = karch::read_thread_pointer() as _; + unsafe { karch::write_thread_pointer(kernel_fs_base) }; let cr2 = Cr2::read().unwrap().as_u64() as usize; let vector = self.vector as u8; @@ -112,7 +111,7 @@ impl UserContext { }), }; - crate::instrs::enable_local(); + karch::enable_local_irq(); ret } } diff --git a/arch/khal/src/dummy.rs b/arch/khal/src/dummy.rs index 5cf697ab..91c9b763 100644 --- a/arch/khal/src/dummy.rs +++ b/arch/khal/src/dummy.rs @@ -142,18 +142,4 @@ impl IntrManager for DummyIrq { fn notify_cpu(_irq: usize, _target: TargetCpu) {} fn set_prio(_irq: usize, _priority: u8) {} - - fn save_disable() -> usize { - 0 - } - - fn restore(_flag: usize) {} - - fn enable_local() {} - - fn disable_local() {} - - fn is_enabled() -> bool { - false - } } diff --git a/arch/khal/src/irq.rs b/arch/khal/src/irq.rs index 2c1926b1..c15bb961 100644 --- a/arch/khal/src/irq.rs +++ b/arch/khal/src/irq.rs @@ -12,8 +12,7 @@ use kcpu::excp::{IRQ, register_trap_handler}; #[cfg(feature = "ipi")] pub use kplat::interrupts::{TargetCpu, notify_cpu}; pub use kplat::interrupts::{ - dispatch_irq, enable, reg_handler as register, restore, save_disable, set_prio, - unreg_handler as unregister, + dispatch_irq, enable, reg_handler as register, set_prio, unreg_handler as unregister, }; static IRQ_HOOK: AtomicUsize = AtomicUsize::new(0); diff --git a/core/kernel_elf_parser/src/auxv.rs b/core/kernel_elf_parser/src/auxv.rs index cff6c854..48f178da 100644 --- a/core/kernel_elf_parser/src/auxv.rs +++ b/core/kernel_elf_parser/src/auxv.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use zerocopy::{Immutable, IntoBytes}; /// Represents the type of an auxiliary vector entry. diff --git a/core/kernel_elf_parser/src/info.rs b/core/kernel_elf_parser/src/info.rs index 8710390a..28c7685f 100644 --- a/core/kernel_elf_parser/src/info.rs +++ b/core/kernel_elf_parser/src/info.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! ELF information parsed from the ELF file use alloc::vec::Vec; diff --git a/core/kernel_elf_parser/src/lib.rs b/core/kernel_elf_parser/src/lib.rs index 425eafb6..d8dc4b4a 100644 --- a/core/kernel_elf_parser/src/lib.rs +++ b/core/kernel_elf_parser/src/lib.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #![cfg_attr(not(test), no_std)] #![doc = include_str!("../README.md")] diff --git a/core/kernel_elf_parser/src/user_stack.rs b/core/kernel_elf_parser/src/user_stack.rs index b59715e8..545084ba 100644 --- a/core/kernel_elf_parser/src/user_stack.rs +++ b/core/kernel_elf_parser/src/user_stack.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Initialize the user stack for the application //! //! The structure of the user stack is described in the following figure: diff --git a/core/kernel_elf_parser/tests/test_dynamic.rs b/core/kernel_elf_parser/tests/test_dynamic.rs index b5754296..cc764533 100644 --- a/core/kernel_elf_parser/tests/test_dynamic.rs +++ b/core/kernel_elf_parser/tests/test_dynamic.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[test] fn test_elf_parser() { let elf_bytes = include_bytes!("ld-linux-x86-64.so.2"); diff --git a/core/kernel_elf_parser/tests/test_static.rs b/core/kernel_elf_parser/tests/test_static.rs index af01ed59..cc065293 100644 --- a/core/kernel_elf_parser/tests/test_static.rs +++ b/core/kernel_elf_parser/tests/test_static.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use kernel_elf_parser::ELFParser; #[test] diff --git a/core/kpoll/src/tests.rs b/core/kpoll/src/tests.rs index d0131c1e..3f429b48 100644 --- a/core/kpoll/src/tests.rs +++ b/core/kpoll/src/tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for kpoll using the unittest framework. #![cfg(unittest)] diff --git a/core/ksync/src/tests.rs b/core/ksync/src/tests.rs index bc6fa006..81cf3cbf 100644 --- a/core/ksync/src/tests.rs +++ b/core/ksync/src/tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for ksync using the unittest framework. #![cfg(unittest)] diff --git a/core/ktask/Cargo.toml b/core/ktask/Cargo.toml index df8279d6..fb75553f 100644 --- a/core/ktask/Cargo.toml +++ b/core/ktask/Cargo.toml @@ -46,3 +46,4 @@ memaddr = { workspace = true } percpu = { workspace = true } kplat = { workspace = true } kbuild_config = { workspace = true } +karch = { workspace = true } diff --git a/core/ktask/src/api.rs b/core/ktask/src/api.rs index 6ee7d198..58ddcf22 100644 --- a/core/ktask/src/api.rs +++ b/core/ktask/src/api.rs @@ -67,14 +67,6 @@ impl kspin::KernelGuardIf for KernelGuardIfImpl { curr.enable_preempt(true); } } - - fn save_disable() -> usize { - khal::irq::save_disable() - } - - fn restore(flags: usize) { - khal::irq::restore(flags); - } } /// Gets the current task, or returns [`None`] if the current task is not @@ -242,7 +234,7 @@ pub fn run_idle() -> ! { loop { yield_now(); trace!("idle task: waiting for IRQs..."); - khal::asm::await_interrupts(); + karch::await_interrupts(); } } diff --git a/core/ktask/src/run_queue.rs b/core/ktask/src/run_queue.rs index f344841d..13ddb245 100644 --- a/core/ktask/src/run_queue.rs +++ b/core/ktask/src/run_queue.rs @@ -521,7 +521,7 @@ impl RunQueue { fn switch_to(&mut self, prev_task: CurrentTask, next_task: KtaskRef) { // Make sure that IRQs are disabled by kernel guard or other means. assert!( - !khal::asm::is_enabled(), + !karch::local_irq_enabled(), "IRQs must be disabled during scheduling" ); trace!( diff --git a/core/ktask/src/task.rs b/core/ktask/src/task.rs index 4ad6a845..672846b6 100644 --- a/core/ktask/src/task.rs +++ b/core/ktask/src/task.rs @@ -693,7 +693,7 @@ extern "C" fn task_entry() -> ! { crate::run_queue::clear_prev_task_on_cpu(); } // Enable irq (if feature "irq" is enabled) before running the task entry function. - khal::asm::enable_local(); + karch::enable_local_irq(); let task = crate::current(); if let Some(entry) = task.entry.take() { entry() diff --git a/core/ktypes/src/lazy.rs b/core/ktypes/src/lazy.rs index 94083e98..7b4d4b87 100644 --- a/core/ktypes/src/lazy.rs +++ b/core/ktypes/src/lazy.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Synchronization primitives for lazy evaluation. //! //! Implementation adapted from the `SyncLazy` type of the standard library. See: diff --git a/core/slab_allocator/src/lib.rs b/core/slab_allocator/src/lib.rs index 1d89c68d..82110ddf 100644 --- a/core/slab_allocator/src/lib.rs +++ b/core/slab_allocator/src/lib.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Slab allocator for `no_std` systems. It uses multiple slabs with blocks of //! different sizes and a [buddy_system_allocator] for blocks larger than 4096 //! bytes. diff --git a/core/slab_allocator/src/slab.rs b/core/slab_allocator/src/slab.rs index 428c4e46..46302c41 100644 --- a/core/slab_allocator/src/slab.rs +++ b/core/slab_allocator/src/slab.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use alloc::alloc::{AllocError, Layout}; use super::SET_SIZE; diff --git a/core/slab_allocator/src/tests.rs b/core/slab_allocator/src/tests.rs index e99c6b9f..ad7dd3ea 100644 --- a/core/slab_allocator/src/tests.rs +++ b/core/slab_allocator/src/tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use alloc::alloc::Layout; use core::mem::{align_of, size_of}; diff --git a/drivers/aarch64-pmuv3/src/lib.rs b/drivers/aarch64-pmuv3/src/lib.rs index cda2f75f..55eeb0e8 100644 --- a/drivers/aarch64-pmuv3/src/lib.rs +++ b/drivers/aarch64-pmuv3/src/lib.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #![no_std] pub mod pmuv3; diff --git a/drivers/aarch64-pmuv3/src/pmuv3.rs b/drivers/aarch64-pmuv3/src/pmuv3.rs index 1533157d..f4e225fc 100644 --- a/drivers/aarch64-pmuv3/src/pmuv3.rs +++ b/drivers/aarch64-pmuv3/src/pmuv3.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! PMU Counter Configuration Module use core::sync::atomic::{AtomicBool, Ordering}; diff --git a/drivers/aarch64-pmuv3/src/regs/macros.rs b/drivers/aarch64-pmuv3/src/regs/macros.rs index 2d8a2627..04f3e4fe 100644 --- a/drivers/aarch64-pmuv3/src/regs/macros.rs +++ b/drivers/aarch64-pmuv3/src/regs/macros.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + // Move to ARM register from system coprocessor register. // MRS Xd, sysreg "Xd = sysreg" #[macro_export] diff --git a/drivers/aarch64-pmuv3/src/regs/mod.rs b/drivers/aarch64-pmuv3/src/regs/mod.rs index 744c29ba..115a548d 100644 --- a/drivers/aarch64-pmuv3/src/regs/mod.rs +++ b/drivers/aarch64-pmuv3/src/regs/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[macro_use] pub mod macros; diff --git a/drivers/aarch64-pmuv3/src/regs/pmccfiltr_el0.rs b/drivers/aarch64-pmuv3/src/regs/pmccfiltr_el0.rs index 5d08086a..61fafb18 100644 --- a/drivers/aarch64-pmuv3/src/regs/pmccfiltr_el0.rs +++ b/drivers/aarch64-pmuv3/src/regs/pmccfiltr_el0.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use tock_registers::{ interfaces::{Readable, Writeable}, register_bitfields, diff --git a/drivers/aarch64-pmuv3/src/regs/pmcr_el0.rs b/drivers/aarch64-pmuv3/src/regs/pmcr_el0.rs index bcb905b7..8ed93dfa 100644 --- a/drivers/aarch64-pmuv3/src/regs/pmcr_el0.rs +++ b/drivers/aarch64-pmuv3/src/regs/pmcr_el0.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use tock_registers::{ interfaces::{Readable, Writeable}, register_bitfields, diff --git a/drivers/aarch64-pmuv3/src/regs/pmuserenr_el0.rs b/drivers/aarch64-pmuv3/src/regs/pmuserenr_el0.rs index 81678928..46a82bf2 100644 --- a/drivers/aarch64-pmuv3/src/regs/pmuserenr_el0.rs +++ b/drivers/aarch64-pmuv3/src/regs/pmuserenr_el0.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use tock_registers::{ interfaces::{Readable, Writeable}, register_bitfields, diff --git a/drivers/aarch64-pmuv3/src/regs/regs.rs b/drivers/aarch64-pmuv3/src/regs/regs.rs index 467f69f8..50d6492c 100644 --- a/drivers/aarch64-pmuv3/src/regs/regs.rs +++ b/drivers/aarch64-pmuv3/src/regs/regs.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use crate::define_pmu_register; // define_pmu_register!(pmccfiltr_el0, PMCCFILTR_EL0, "PMCCFILTR_EL0"); define_pmu_register!(pmccntr_el0, PMCCNTR_EL0, "PMCCNTR_EL0"); diff --git a/drivers/display/src/tests.rs b/drivers/display/src/tests.rs index 3b0992fb..adb50736 100644 --- a/drivers/display/src/tests.rs +++ b/drivers/display/src/tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for display drivers using the unittest framework. #![cfg(unittest)] diff --git a/drivers/kdriver/src/bus/pci.rs b/drivers/kdriver/src/bus/pci.rs index 05929a69..6fa71c3f 100644 --- a/drivers/kdriver/src/bus/pci.rs +++ b/drivers/kdriver/src/bus/pci.rs @@ -5,8 +5,7 @@ //! PCI bus probing and BAR configuration. use khal::mem::p2v; use pci::{ - BarInfo, Cam, Command, ConfigurationAccess, DeviceFunction, HeaderType, MemoryBarType, MmioCam, - PciRangeAllocator, PciRoot, + BarInfo, Cam, Command, DeviceFunction, HeaderType, MemoryBarType, PciRangeAllocator, PciRoot, }; use crate::{AllDevices, prelude::*}; @@ -14,20 +13,14 @@ use crate::{AllDevices, prelude::*}; const PCI_BAR_NUM: u8 = 6; /// Configure PCI BARs and enable the device. -fn config_pci_device( - root: &mut PciRoot, +fn config_pci_device( + root: &mut PciRoot, bdf: DeviceFunction, allocator: &mut Option, ) -> DriverResult { let mut bar = 0; while bar < PCI_BAR_NUM { - let info = match root.bar_info(bdf, bar).unwrap() { - Some(info) => info, - None => { - bar += 1; - continue; - } - }; + let info = root.bar_info(bdf, bar).unwrap(); if let BarInfo::Memory { address_type, address, @@ -51,14 +44,7 @@ fn config_pci_device( } // read the BAR info again after assignment. - let info = match root.bar_info(bdf, bar).unwrap() { - Some(info) => info, - None => { - bar += 1; - continue; - } - }; - let takes_two = info.takes_two_entries(); + let info = root.bar_info(bdf, bar).unwrap(); match info { BarInfo::IO { address, size } => { if address > 0 && size > 0 { @@ -76,7 +62,7 @@ fn config_pci_device( " BAR {}: MEM [{:#x}, {:#x}){}{}", bar, address, - address + size, + address + size as u64, if address_type == MemoryBarType::Width64 { " 64bit" } else { @@ -89,7 +75,7 @@ fn config_pci_device( } bar += 1; - if takes_two { + if info.takes_two_entries() { bar += 1; } } @@ -110,13 +96,11 @@ impl AllDevices { let mut root = { #[cfg(feature = "pci-mmio")] { - let cam = unsafe { MmioCam::new(base_vaddr.as_mut_ptr(), Cam::MmioCam) }; - PciRoot::new(cam) + unsafe { PciRoot::new(base_vaddr.as_mut_ptr(), Cam::MmioCam) } } #[cfg(not(feature = "pci-mmio"))] { - let cam = unsafe { MmioCam::new(base_vaddr.as_mut_ptr(), Cam::Ecam) }; - PciRoot::new(cam) + unsafe { PciRoot::new(base_vaddr.as_mut_ptr(), Cam::Ecam) } } }; diff --git a/drivers/kdriver/src/drivers.rs b/drivers/kdriver/src/drivers.rs index ab85a393..50118379 100644 --- a/drivers/kdriver/src/drivers.rs +++ b/drivers/kdriver/src/drivers.rs @@ -8,7 +8,7 @@ use driver_base::DeviceKind; #[cfg(feature = "bus-pci")] -use pci::{ConfigurationAccess, DeviceFunction, DeviceFunctionInfo, PciRoot}; +use pci::{DeviceFunction, DeviceFunctionInfo, PciRoot}; pub use super::dummy::*; use crate::DeviceEnum; @@ -30,8 +30,8 @@ pub trait DriverProbe { #[cfg(bus = "pci")] /// Probe a PCI device described by BDF and device info. - fn probe_pci( - _root: &mut PciRoot, + fn probe_pci( + _root: &mut PciRoot, _bdf: DeviceFunction, _dev_info: &DeviceFunctionInfo, ) -> Option { @@ -171,8 +171,8 @@ cfg_if::cfg_if! { register_net_driver!(IxgbeDriver, net::ixgbe::IxgbeNic); impl DriverProbe for IxgbeDriver { #[cfg(bus = "pci")] - fn probe_pci( - root: &mut pci::PciRoot, + fn probe_pci( + root: &mut pci::PciRoot, bdf: pci::DeviceFunction, dev_info: &pci::DeviceFunctionInfo, ) -> Option { diff --git a/drivers/kdriver/src/virtio.rs b/drivers/kdriver/src/virtio.rs index 66a31c5b..ef4e181d 100644 --- a/drivers/kdriver/src/virtio.rs +++ b/drivers/kdriver/src/virtio.rs @@ -16,10 +16,10 @@ use crate::{DeviceEnum, drivers::DriverProbe}; cfg_if! { if #[cfg(bus = "pci")] { - use pci::{ConfigurationAccess, DeviceFunction, DeviceFunctionInfo, PciRoot}; + use pci::{PciRoot, DeviceFunction, DeviceFunctionInfo}; type VirtIoTransport = virtio::PciTransport; } else if #[cfg(bus = "mmio")] { - type VirtIoTransport = virtio::MmioTransport<'static>; + type VirtIoTransport = virtio::MmioTransport; } } @@ -139,8 +139,8 @@ impl DriverProbe for VirtIoDriver { } #[cfg(bus = "pci")] - fn probe_pci( - root: &mut PciRoot, + fn probe_pci( + root: &mut PciRoot, bdf: DeviceFunction, dev_info: &DeviceFunctionInfo, ) -> Option { @@ -157,7 +157,7 @@ impl DriverProbe for VirtIoDriver { } if let Some((ty, transport, irq)) = - virtio::probe_pci_device::(root, bdf, dev_info) + virtio::probe_pci_device::(root, bdf, dev_info) && ty == D::DEVICE_TYPE { match D::try_new(transport, Some(irq)) { @@ -214,7 +214,7 @@ unsafe impl VirtIoHal for VirtIoHalImpl { let layout = Layout::from_size_align(size, PAGE_SIZE).unwrap(); let dma_info = kdma::DMAInfo { cpu_addr: vaddr, - bus_addr: kdma::DmaBusAddress::new(paddr), + bus_addr: kdma::DmaBusAddress::new(paddr as u64), }; unsafe { kdma::deallocate_dma_memory(dma_info, layout) }; #[cfg(feature = "crosvm")] @@ -226,8 +226,7 @@ unsafe impl VirtIoHal for VirtIoHalImpl { #[inline] unsafe fn mmio_phys_to_virt(paddr: PhysAddr, _size: usize) -> NonNull { - let paddr_usize = paddr as usize; - NonNull::new(p2v(paddr_usize.into()).as_mut_ptr()).unwrap() + NonNull::new(p2v(paddr.into()).as_mut_ptr()).unwrap() } #[allow(unused_variables)] @@ -277,8 +276,7 @@ unsafe impl VirtIoHal for VirtIoHalImpl { #[cfg(not(any(feature = "crosvm", feature = "sev")))] { let vaddr = buffer.as_ptr() as *mut u8 as usize; - let paddr_usize: usize = khal::mem::v2p(vaddr.into()).into(); - paddr_usize as PhysAddr + khal::mem::v2p(vaddr.into()).into() } } @@ -298,8 +296,7 @@ unsafe impl VirtIoHal for VirtIoHalImpl { // If data flows from device to driver, copy back from shared buffer if direction != BufferDirection::DriverToDevice { - let paddr_usize = paddr as usize; - let shared_ptr = p2v(paddr_usize.into()).as_ptr(); + let shared_ptr = p2v(paddr.into()).as_ptr(); unsafe { core::ptr::copy_nonoverlapping(shared_ptr, buffer.as_ptr() as *mut u8, len); } @@ -317,10 +314,7 @@ unsafe impl VirtIoHal for VirtIoHalImpl { // Free the bounce buffer via kdma let layout = Layout::from_size_align(aligned_size, PAGE_SIZE).unwrap(); let dma_info = kdma::DMAInfo { - cpu_addr: { - let paddr_usize = paddr as usize; - NonNull::new(p2v(paddr_usize.into()).as_mut_ptr()).unwrap() - }, + cpu_addr: NonNull::new(p2v(paddr.into()).as_mut_ptr()).unwrap(), bus_addr: kdma::DmaBusAddress::new(paddr as u64), }; unsafe { kdma::deallocate_dma_memory(dma_info, layout) }; diff --git a/drivers/net/Cargo.toml b/drivers/net/Cargo.toml index 00217f64..2b548132 100644 --- a/drivers/net/Cargo.toml +++ b/drivers/net/Cargo.toml @@ -19,5 +19,5 @@ driver_base = { workspace = true } # fxmac_rs = { git = "https://github.com/elliott10/fxmac_rs.git", rev = "0dbc3916", optional = true } # ixgbe-driver = { git = "https://github.com/KuangjuX/ixgbe-driver.git", rev = "8e5eb74", optional = true } log = { workspace = true } -spin = "0.9" +ksync = { workspace = true } unittest = { workspace = true } diff --git a/drivers/net/src/net_buf.rs b/drivers/net/src/net_buf.rs index 8db1bacb..8fa3410e 100644 --- a/drivers/net/src/net_buf.rs +++ b/drivers/net/src/net_buf.rs @@ -6,7 +6,7 @@ use alloc::{boxed::Box, sync::Arc, vec, vec::Vec}; use core::ptr::NonNull; -use spin::Mutex; +use ksync::Mutex; use crate::{DriverError, DriverResult}; diff --git a/drivers/pci/Cargo.toml b/drivers/pci/Cargo.toml index 73d2caf7..2c85df34 100644 --- a/drivers/pci/Cargo.toml +++ b/drivers/pci/Cargo.toml @@ -12,5 +12,4 @@ repository.workspace = true categories.workspace = true [dependencies] -virtio-drivers.workspace = true -kbuild_config.workspace = true +virtio-drivers = { workspace = true } diff --git a/drivers/pci/src/lib.rs b/drivers/pci/src/lib.rs index 100d7f08..177c0c4b 100644 --- a/drivers/pci/src/lib.rs +++ b/drivers/pci/src/lib.rs @@ -13,8 +13,8 @@ #![no_std] pub use virtio_drivers::transport::pci::bus::{ - BarInfo, Cam, CapabilityInfo, Command, ConfigurationAccess, DeviceFunction, DeviceFunctionInfo, - HeaderType, MemoryBarType, MmioCam, PciError, PciRoot, Status, + BarInfo, Cam, CapabilityInfo, Command, DeviceFunction, DeviceFunctionInfo, HeaderType, + MemoryBarType, PciError, PciRoot, Status, }; /// Used to allocate MMIO regions for PCI BARs. diff --git a/drivers/virtio/Cargo.toml b/drivers/virtio/Cargo.toml index 5a0c66a6..7fb60303 100644 --- a/drivers/virtio/Cargo.toml +++ b/drivers/virtio/Cargo.toml @@ -27,6 +27,5 @@ input = { workspace = true, optional = true } net = { workspace = true, optional = true } vsock = { workspace = true, optional = true } log = { workspace = true } -virtio-drivers.workspace = true +virtio-drivers = { workspace = true } unittest = { workspace = true } -zerocopy = "0.8" diff --git a/drivers/virtio/src/input.rs b/drivers/virtio/src/input.rs index 08ba4663..92203285 100644 --- a/drivers/virtio/src/input.rs +++ b/drivers/virtio/src/input.rs @@ -75,8 +75,7 @@ impl InputDriverOps for VirtIoInputDev { fn get_event_bits(&mut self, ty: EventType, out: &mut [u8]) -> DriverResult { let read = self .inner - .query_config_select(InputConfigSelect::EvBits, ty as u8, out) - .map_err(as_driver_error)?; + .query_config_select(InputConfigSelect::EvBits, ty as u8, out); Ok(read != 0) } diff --git a/drivers/virtio/src/lib.rs b/drivers/virtio/src/lib.rs index fa0b6e4c..9ae77335 100644 --- a/drivers/virtio/src/lib.rs +++ b/drivers/virtio/src/lib.rs @@ -56,7 +56,7 @@ pub use virtio_drivers::{ }, }; -use self::pci::{ConfigurationAccess, DeviceFunction, DeviceFunctionInfo, PciRoot}; +use self::pci::{DeviceFunction, DeviceFunctionInfo, PciRoot}; #[cfg(feature = "socket")] pub use self::socket::VirtIoSocketDev; @@ -66,14 +66,14 @@ pub use self::socket::VirtIoSocketDev; /// for later operations. Otherwise, returns [`None`]. pub fn probe_mmio_device( reg_base: *mut u8, - reg_size: usize, -) -> Option<(DeviceKind, MmioTransport<'static>)> { + _reg_size: usize, +) -> Option<(DeviceKind, MmioTransport)> { use core::ptr::NonNull; use virtio_drivers::transport::mmio::VirtIOHeader; let header = NonNull::new(reg_base as *mut VirtIOHeader).unwrap(); - let transport = unsafe { MmioTransport::new(header, reg_size) }.ok()?; + let transport = unsafe { MmioTransport::new(header) }.ok()?; let dev_kind = as_device_kind(transport.device_type())?; Some((dev_kind, transport)) } @@ -82,8 +82,8 @@ pub fn probe_mmio_device( /// /// If the device is recognized, returns the device type and a transport object /// for later operations. Otherwise, returns [`None`]. -pub fn probe_pci_device( - root: &mut PciRoot, +pub fn probe_pci_device( + root: &mut PciRoot, bdf: DeviceFunction, dev_info: &DeviceFunctionInfo, ) -> Option<(DeviceKind, PciTransport, usize)> { @@ -99,7 +99,7 @@ pub fn probe_pci_device( const PCI_IRQ_BASE: usize = 0x23; let dev_kind = virtio_device_type(dev_info).and_then(as_device_kind)?; - let transport = PciTransport::new::(root, bdf).ok()?; + let transport = PciTransport::new::(root, bdf).ok()?; let irq = PCI_IRQ_BASE + (bdf.device & 3) as usize; Some((dev_kind, transport, irq)) } @@ -137,7 +137,9 @@ pub(crate) const fn as_driver_error(e: virtio_drivers::Error) -> DriverError { OutputBufferTooShort(_) | BufferTooShort | BufferTooLong(..) => { DriverError::InvalidInput } - UnexpectedDataInPacket | PeerSocketShutdown => DriverError::Io, + UnexpectedDataInPacket | PeerSocketShutdown | NoResponseReceived | ConnectionFailed => { + DriverError::Io + } InsufficientBufferSpaceInPeer => DriverError::WouldBlock, RecycledWrongBuffer => DriverError::BadState, }, diff --git a/drivers/virtio/src/mock_virtio.rs b/drivers/virtio/src/mock_virtio.rs index aab9d2c2..f8465be6 100644 --- a/drivers/virtio/src/mock_virtio.rs +++ b/drivers/virtio/src/mock_virtio.rs @@ -1,10 +1,13 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use core::{cell::RefCell, ptr::NonNull}; use virtio_drivers::{ - BufferDirection, Error, Hal, PhysAddr, Result, - transport::{DeviceStatus, DeviceType, InterruptStatus, Transport}, + BufferDirection, Hal, PhysAddr, Result, + transport::{DeviceStatus, DeviceType, Transport}, }; -use zerocopy::{FromBytes, Immutable, IntoBytes}; extern crate alloc; use alloc::alloc::{Layout, alloc, dealloc}; @@ -20,7 +23,7 @@ unsafe impl Hal for MockHal { panic!("MockHal: dma_alloc failed"); } unsafe { ptr.write_bytes(0, pages * 4096) }; // Zero memory - (ptr as PhysAddr, NonNull::new(ptr).unwrap()) + (ptr as usize, NonNull::new(ptr).unwrap()) } unsafe fn dma_dealloc(paddr: PhysAddr, _vaddr: NonNull, pages: usize) -> i32 { @@ -111,50 +114,14 @@ impl Transport for MockTransport { false } - fn ack_interrupt(&mut self) -> InterruptStatus { - InterruptStatus::empty() - } - - fn read_config_generation(&self) -> u32 { - 0 + fn ack_interrupt(&mut self) -> bool { + false } - fn read_config_space(&self, offset: usize) -> Result { - let size = core::mem::size_of::(); - let config = self.config_space.borrow(); - if offset - .checked_add(size) - .is_none_or(|end| end > config.len()) - { - return Err(Error::ConfigSpaceTooSmall); - } - - let mut value = core::mem::MaybeUninit::::uninit(); + fn config_space(&self) -> Result> { unsafe { - core::ptr::copy_nonoverlapping( - config.as_ptr().add(offset), - value.as_mut_ptr() as *mut u8, - size, - ); - Ok(value.assume_init()) - } - } - - fn write_config_space( - &mut self, - offset: usize, - value: T, - ) -> Result<()> { - let bytes = value.as_bytes(); - let mut config = self.config_space.borrow_mut(); - if offset - .checked_add(bytes.len()) - .is_none_or(|end| end > config.len()) - { - return Err(Error::ConfigSpaceTooSmall); + let ptr = self.config_space.borrow_mut().as_mut_ptr() as *mut T; + Ok(NonNull::new_unchecked(ptr)) } - - config[offset..offset + bytes.len()].copy_from_slice(bytes); - Ok(()) } } diff --git a/fs/fatfs/src/boot_sector.rs b/fs/fatfs/src/boot_sector.rs index f41a3157..d5f1e6d2 100644 --- a/fs/fatfs/src/boot_sector.rs +++ b/fs/fatfs/src/boot_sector.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use core::slice; use crate::{ diff --git a/fs/fatfs/src/dir.rs b/fs/fatfs/src/dir.rs index 1e5f9a67..80809a83 100644 --- a/fs/fatfs/src/dir.rs +++ b/fs/fatfs/src/dir.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[cfg(all(not(feature = "std"), feature = "alloc", feature = "lfn"))] use alloc::vec::Vec; #[cfg(feature = "lfn")] diff --git a/fs/fatfs/src/dir_entry.rs b/fs/fatfs/src/dir_entry.rs index 9bb1fb5c..4f8d6bb7 100644 --- a/fs/fatfs/src/dir_entry.rs +++ b/fs/fatfs/src/dir_entry.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[cfg(all(not(feature = "std"), feature = "alloc"))] use alloc::string::String; #[cfg(not(feature = "unicode"))] diff --git a/fs/fatfs/src/error.rs b/fs/fatfs/src/error.rs index ab2c4119..0749d034 100644 --- a/fs/fatfs/src/error.rs +++ b/fs/fatfs/src/error.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + /// Error enum with all errors that can be returned by functions from this crate /// /// Generic parameter `T` is a type of external error returned by the user provided storage diff --git a/fs/fatfs/src/file.rs b/fs/fatfs/src/file.rs index 0ddbe88f..d2ae76fb 100644 --- a/fs/fatfs/src/file.rs +++ b/fs/fatfs/src/file.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use core::convert::TryFrom; use crate::{ diff --git a/fs/fatfs/src/fs.rs b/fs/fatfs/src/fs.rs index cb677c51..b5d87c5e 100644 --- a/fs/fatfs/src/fs.rs +++ b/fs/fatfs/src/fs.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[cfg(all(not(feature = "std"), feature = "alloc"))] use alloc::string::String; use core::{ diff --git a/fs/fatfs/src/io.rs b/fs/fatfs/src/io.rs index 7e873700..b4bfe853 100644 --- a/fs/fatfs/src/io.rs +++ b/fs/fatfs/src/io.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use crate::error::IoError; /// Provides IO error as an associated type. diff --git a/fs/fatfs/src/lib.rs b/fs/fatfs/src/lib.rs index df68299b..4ec9374f 100644 --- a/fs/fatfs/src/lib.rs +++ b/fs/fatfs/src/lib.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! A FAT filesystem library implemented in Rust. //! //! # Usage diff --git a/fs/fatfs/src/log_macros.rs b/fs/fatfs/src/log_macros.rs index 36a195dc..5cb9eb48 100644 --- a/fs/fatfs/src/log_macros.rs +++ b/fs/fatfs/src/log_macros.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! This module offers a convenient way to enable only a subset of logging levels //! for just this `fatfs` crate only without changing the logging levels //! of other crates in a given project. diff --git a/fs/fatfs/src/table.rs b/fs/fatfs/src/table.rs index abd345f4..eeed24f5 100644 --- a/fs/fatfs/src/table.rs +++ b/fs/fatfs/src/table.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use core::{borrow::BorrowMut, marker::PhantomData}; use crate::{ diff --git a/fs/fatfs/src/time.rs b/fs/fatfs/src/time.rs index daa72a20..259d935f 100644 --- a/fs/fatfs/src/time.rs +++ b/fs/fatfs/src/time.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[cfg(feature = "chrono")] use core::convert::TryFrom; use core::fmt::Debug; diff --git a/fs/fs-ng-vfs/src/test_path.rs b/fs/fs-ng-vfs/src/test_path.rs index eef065a6..56ac6b1f 100644 --- a/fs/fs-ng-vfs/src/test_path.rs +++ b/fs/fs-ng-vfs/src/test_path.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for Path and PathBuf. #![cfg(unittest)] diff --git a/fs/fs-ng-vfs/src/test_types.rs b/fs/fs-ng-vfs/src/test_types.rs index a40d0f74..556fd1cb 100644 --- a/fs/fs-ng-vfs/src/test_types.rs +++ b/fs/fs-ng-vfs/src/test_types.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #![cfg(unittest)] use unittest::{assert_eq, def_test}; diff --git a/fs/kfs/src/fs/ext4/lwext4/fs.rs b/fs/kfs/src/fs/ext4/lwext4/fs.rs index 5d1e5ecc..d6eefb53 100644 --- a/fs/kfs/src/fs/ext4/lwext4/fs.rs +++ b/fs/kfs/src/fs/ext4/lwext4/fs.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use alloc::sync::Arc; use core::cell::OnceCell; diff --git a/fs/kfs/src/fs/ext4/lwext4/inode.rs b/fs/kfs/src/fs/ext4/lwext4/inode.rs index d701a2c2..84a2fed3 100644 --- a/fs/kfs/src/fs/ext4/lwext4/inode.rs +++ b/fs/kfs/src/fs/ext4/lwext4/inode.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use alloc::{borrow::ToOwned, string::String, sync::Arc}; use core::{any::Any, task::Context}; diff --git a/fs/kfs/src/fs/ext4/lwext4/mod.rs b/fs/kfs/src/fs/ext4/lwext4/mod.rs index 26c6fd34..a5986b37 100644 --- a/fs/kfs/src/fs/ext4/lwext4/mod.rs +++ b/fs/kfs/src/fs/ext4/lwext4/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + mod fs; mod inode; mod util; diff --git a/fs/kfs/src/fs/ext4/lwext4/util.rs b/fs/kfs/src/fs/ext4/lwext4/util.rs index d6806f81..0f5cb541 100644 --- a/fs/kfs/src/fs/ext4/lwext4/util.rs +++ b/fs/kfs/src/fs/ext4/lwext4/util.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use fs_ng_vfs::{NodeType, VfsError}; use kerrno::LinuxError; use lwext4_rust::{Ext4Error, InodeType, SystemHal}; diff --git a/fs/kfs/src/fs/ext4/mod.rs b/fs/kfs/src/fs/ext4/mod.rs index 0e02f325..40edad9e 100644 --- a/fs/kfs/src/fs/ext4/mod.rs +++ b/fs/kfs/src/fs/ext4/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[cfg(feature = "ext4-rsext4")] mod rsext4; diff --git a/fs/kfs/src/test_path_resolver.rs b/fs/kfs/src/test_path_resolver.rs index 9bdf7e0b..e5886fab 100644 --- a/fs/kfs/src/test_path_resolver.rs +++ b/fs/kfs/src/test_path_resolver.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for PathResolver. #![cfg(unittest)] diff --git a/fs/kfs/src/test_working_context.rs b/fs/kfs/src/test_working_context.rs index 962f4cb7..0ae90bed 100644 --- a/fs/kfs/src/test_working_context.rs +++ b/fs/kfs/src/test_working_context.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for WorkingContext. #![cfg(unittest)] diff --git a/fs/rsext4/src/api.rs b/fs/rsext4/src/api.rs index 593bddfb..01ffe5c7 100644 --- a/fs/rsext4/src/api.rs +++ b/fs/rsext4/src/api.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # ext4 API //! //! 提供 ext4 文件系统的高级 API 接口,包括文件系统挂载、文件操作等功能。 diff --git a/fs/rsext4/src/bitmap.rs b/fs/rsext4/src/bitmap.rs index 72e42641..343b5934 100644 --- a/fs/rsext4/src/bitmap.rs +++ b/fs/rsext4/src/bitmap.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 位图操作模块 //! //! 提供对块和inode位图的操作,用于跟踪块和inode的分配状态。 diff --git a/fs/rsext4/src/bitmap_cache.rs b/fs/rsext4/src/bitmap_cache.rs index e03066db..d1cec8f8 100644 --- a/fs/rsext4/src/bitmap_cache.rs +++ b/fs/rsext4/src/bitmap_cache.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! 位图缓存模块 use alloc::{collections::BTreeMap, vec::Vec}; diff --git a/fs/rsext4/src/blockdev.rs b/fs/rsext4/src/blockdev.rs index 1daa2412..870bd378 100644 --- a/fs/rsext4/src/blockdev.rs +++ b/fs/rsext4/src/blockdev.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 块设备实现 //! //! 定义了块设备的抽象接口和实现,为文件系统提供底层存储支持 diff --git a/fs/rsext4/src/blockgroup_description.rs b/fs/rsext4/src/blockgroup_description.rs index 882ff2bb..1193c8ec 100644 --- a/fs/rsext4/src/blockgroup_description.rs +++ b/fs/rsext4/src/blockgroup_description.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 块组描述符模块 //! //! 定义了 ext4 文件系统的块组描述符结构和相关操作。 diff --git a/fs/rsext4/src/bmalloc.rs b/fs/rsext4/src/bmalloc.rs index b5e7c8b7..782d5a4e 100644 --- a/fs/rsext4/src/bmalloc.rs +++ b/fs/rsext4/src/bmalloc.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! 位图分配器模块 use crate::{bitmap::*, blockgroup_description::*, superblock::*}; diff --git a/fs/rsext4/src/config.rs b/fs/rsext4/src/config.rs index e82071f6..de2299f6 100644 --- a/fs/rsext4/src/config.rs +++ b/fs/rsext4/src/config.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 配置常量定义 //! //! 定义了 ext4 文件系统实现中使用的各种配置常量,包括块大小、 diff --git a/fs/rsext4/src/datablock_cache.rs b/fs/rsext4/src/datablock_cache.rs index 4cb471f0..65097320 100644 --- a/fs/rsext4/src/datablock_cache.rs +++ b/fs/rsext4/src/datablock_cache.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! 数据块缓存模块 //! //! 提供文件和目录数据块的缓存管理,支持延迟写回和LRU淘汰 diff --git a/fs/rsext4/src/dir.rs b/fs/rsext4/src/dir.rs index 72a80af6..5ae903dc 100644 --- a/fs/rsext4/src/dir.rs +++ b/fs/rsext4/src/dir.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 目录操作模块 //! //! 提供对 ext4 文件系统中目录的创建、删除、遍历等操作功能。 diff --git a/fs/rsext4/src/disknode.rs b/fs/rsext4/src/disknode.rs index aac26f37..88588715 100644 --- a/fs/rsext4/src/disknode.rs +++ b/fs/rsext4/src/disknode.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 磁盘节点模块 //! //! 定义了 ext4 文件系统的 inode 结构和相关操作。 diff --git a/fs/rsext4/src/endian.rs b/fs/rsext4/src/endian.rs index ee85cfb3..58e76d7a 100644 --- a/fs/rsext4/src/endian.rs +++ b/fs/rsext4/src/endian.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 字节序转换辅助模块 //! //! Ext4 磁盘格式使用小端序(Little Endian) diff --git a/fs/rsext4/src/entries.rs b/fs/rsext4/src/entries.rs index b742ec41..69a79847 100644 --- a/fs/rsext4/src/entries.rs +++ b/fs/rsext4/src/entries.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 目录条目模块 //! //! 定义了 ext4 文件系统中目录条目的数据结构和操作。 diff --git a/fs/rsext4/src/error.rs b/fs/rsext4/src/error.rs index 06956b5f..4bbbbcc2 100644 --- a/fs/rsext4/src/error.rs +++ b/fs/rsext4/src/error.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 错误处理模块 //! //! 定义了 rsext4 库中使用的所有错误类型,提供清晰的错误信息以便调试和处理 diff --git a/fs/rsext4/src/ext4.rs b/fs/rsext4/src/ext4.rs index 4a45de6f..337014de 100644 --- a/fs/rsext4/src/ext4.rs +++ b/fs/rsext4/src/ext4.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # Ext4 文件系统主调用入口 //! //! 提供 ext4 文件系统的核心实现,包括文件系统挂载、卸载、文件操作等高层接口。 diff --git a/fs/rsext4/src/extents_tree.rs b/fs/rsext4/src/extents_tree.rs index e9e2add5..8be3cee3 100644 --- a/fs/rsext4/src/extents_tree.rs +++ b/fs/rsext4/src/extents_tree.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # Extents 树模块 //! //! 实现 ext4 文件系统的 extents 功能,用于高效管理文件的连续块分配。 diff --git a/fs/rsext4/src/file.rs b/fs/rsext4/src/file.rs index e60d7a92..235517c6 100644 --- a/fs/rsext4/src/file.rs +++ b/fs/rsext4/src/file.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 文件操作模块 //! //! 提供对 ext4 文件系统中文件的读写、创建、删除等操作功能。 diff --git a/fs/rsext4/src/hashtree.rs b/fs/rsext4/src/hashtree.rs index 1e9d9d3e..470e983a 100644 --- a/fs/rsext4/src/hashtree.rs +++ b/fs/rsext4/src/hashtree.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 目录条目 HashTree 实现 //! //! 提供基于哈希树的目录查找功能,替代线性搜索以提高大型目录的性能 diff --git a/fs/rsext4/src/inodetable_cache.rs b/fs/rsext4/src/inodetable_cache.rs index 5788c288..4cc26566 100644 --- a/fs/rsext4/src/inodetable_cache.rs +++ b/fs/rsext4/src/inodetable_cache.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Inode表缓存模块 //! //! 提供inode结构的缓存管理,支持延迟写回和LRU淘汰 diff --git a/fs/rsext4/src/jbd2/jbd2.rs b/fs/rsext4/src/jbd2/jbd2.rs index d4883052..8d0d9a93 100644 --- a/fs/rsext4/src/jbd2/jbd2.rs +++ b/fs/rsext4/src/jbd2/jbd2.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # JBD2 日志系统实现 //! //! 实现了 ext4 文件系统的日志功能,确保事务的原子性和一致性。 diff --git a/fs/rsext4/src/jbd2/jbdstruct.rs b/fs/rsext4/src/jbd2/jbdstruct.rs index 3d5edb9a..9104a509 100644 --- a/fs/rsext4/src/jbd2/jbdstruct.rs +++ b/fs/rsext4/src/jbd2/jbdstruct.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # JBD2 数据结构定义 //! //! 定义了 JBD2 日志系统使用的各种数据结构。 diff --git a/fs/rsext4/src/jbd2/mod.rs b/fs/rsext4/src/jbd2/mod.rs index 28572694..132e6119 100644 --- a/fs/rsext4/src/jbd2/mod.rs +++ b/fs/rsext4/src/jbd2/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # JBD2 日志系统模块 //! //! 提供 ext4 文件系统的日志功能,确保文件系统的一致性和可靠性。 diff --git a/fs/rsext4/src/lib.rs b/fs/rsext4/src/lib.rs index ec2053bb..123537e1 100644 --- a/fs/rsext4/src/lib.rs +++ b/fs/rsext4/src/lib.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # ext4_backend //! //! ext4 文件系统的核心实现模块,提供对 ext4 文件系统的底层操作支持。 diff --git a/fs/rsext4/src/loopfile.rs b/fs/rsext4/src/loopfile.rs index 6cde2bfe..c1a637dc 100644 --- a/fs/rsext4/src/loopfile.rs +++ b/fs/rsext4/src/loopfile.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 文件遍历和操作模块 //! //! 提供文件内容读取、块解析等功能。 diff --git a/fs/rsext4/src/superblock.rs b/fs/rsext4/src/superblock.rs index cb82f7c0..8a7a8d9b 100644 --- a/fs/rsext4/src/superblock.rs +++ b/fs/rsext4/src/superblock.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 超级块实现模块 //! //! 定义了 ext4 文件系统的超级块结构,包含文件系统的基本元数据和参数。 diff --git a/fs/rsext4/src/tool.rs b/fs/rsext4/src/tool.rs index 2010ca27..3e6dd7ed 100644 --- a/fs/rsext4/src/tool.rs +++ b/fs/rsext4/src/tool.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! # 工具函数模块 //! //! 提供各种辅助函数,如 UUID 生成等。 diff --git a/init/kruntime/Cargo.toml b/init/kruntime/Cargo.toml index 71e82037..0d5f24af 100644 --- a/init/kruntime/Cargo.toml +++ b/init/kruntime/Cargo.toml @@ -54,3 +54,4 @@ kinit_setup.workspace = true indoc = "2" percpu.workspace = true kbuild_config = { workspace = true } +karch = { workspace = true } diff --git a/init/kruntime/src/lib.rs b/init/kruntime/src/lib.rs index 67151deb..88bc9658 100644 --- a/init/kruntime/src/lib.rs +++ b/init/kruntime/src/lib.rs @@ -320,5 +320,5 @@ fn init_interrupt() { }); // Enable IRQs before starting app - khal::asm::enable_local(); + karch::enable_local_irq(); } diff --git a/init/kruntime/src/mp.rs b/init/kruntime/src/mp.rs index a20b2a0d..6e0c1f8d 100644 --- a/init/kruntime/src/mp.rs +++ b/init/kruntime/src/mp.rs @@ -66,7 +66,7 @@ pub fn rust_main_secondary(cpu_id: usize) -> ! { #[cfg(feature = "pmu")] khal::irq::enable(kbuild_config::PMU_IRQ, true); - khal::asm::enable_local(); + karch::enable_local_irq(); #[cfg(feature = "watchdog")] watchdog::init_secondary(); diff --git a/io/kio/src/test_cursor.rs b/io/kio/src/test_cursor.rs index 476da5aa..f9a0c7d3 100644 --- a/io/kio/src/test_cursor.rs +++ b/io/kio/src/test_cursor.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for Cursor. #![cfg(unittest)] diff --git a/io/kio/src/test_iobuf.rs b/io/kio/src/test_iobuf.rs index e122abad..53d7c047 100644 --- a/io/kio/src/test_iobuf.rs +++ b/io/kio/src/test_iobuf.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for IoBuf and IoBufMut. #![cfg(unittest)] diff --git a/io/kio/src/test_seek.rs b/io/kio/src/test_seek.rs index d019f70d..37a56a05 100644 --- a/io/kio/src/test_seek.rs +++ b/io/kio/src/test_seek.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for Seek operations. #![cfg(unittest)] diff --git a/mm/memspace/Cargo.toml b/mm/memspace/Cargo.toml index 36d5aa31..6060ad99 100644 --- a/mm/memspace/Cargo.toml +++ b/mm/memspace/Cargo.toml @@ -28,3 +28,4 @@ memset = { workspace = true } page_table = { workspace = true, optional = true } unittest.workspace = true kbuild_config = { workspace = true } +karch = { workspace = true } diff --git a/mm/memspace/src/lib.rs b/mm/memspace/src/lib.rs index 5d570a86..ccb41a51 100644 --- a/mm/memspace/src/lib.rs +++ b/mm/memspace/src/lib.rs @@ -106,16 +106,16 @@ pub fn init_memory_management() { debug!("root: {:?}", root); } } - unsafe { khal::asm::write_kernel_page_table(root) }; + unsafe { karch::write_kernel_page_table(root) }; // flush all TLB - khal::asm::flush_tlb(None); + karch::flush_tlb(None); } /// Initializes kernel paging for secondary CPUs. pub fn init_memory_management_secondary() { - unsafe { khal::asm::write_kernel_page_table(kernel_page_table_root()) }; + unsafe { karch::write_kernel_page_table(kernel_page_table_root()) }; // flush all TLB - khal::asm::flush_tlb(None); + karch::flush_tlb(None); } #[cfg(unittest)] diff --git a/mm/page_table/Cargo.toml b/mm/page_table/Cargo.toml index cf9264db..00176e89 100644 --- a/mm/page_table/Cargo.toml +++ b/mm/page_table/Cargo.toml @@ -20,18 +20,8 @@ bitmaps = { version = "3.2", default-features = false, optional = true } log = "0.4" memaddr = { workspace = true } kerrno = { workspace = true, optional = true } +karch = { workspace = true } unittest.workspace = true [target.'cfg(target_arch = "x86_64")'.dependencies] x86_64 = { workspace = true } - -[target.'cfg(target_arch = "aarch64")'.dependencies] -aarch64-cpu = "10.0" - -[target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies] -riscv = "0.14" - -[target.'cfg(target_arch = "loongarch64")'.dependencies] -loongArch64 = "0.2.4" -aarch64-cpu = "9.4" -tock-registers = "0.9" diff --git a/mm/page_table/src/arch/aarch64.rs b/mm/page_table/src/arch/aarch64.rs index d766e3f4..67eb2cfc 100644 --- a/mm/page_table/src/arch/aarch64.rs +++ b/mm/page_table/src/arch/aarch64.rs @@ -2,7 +2,7 @@ // Copyright 2025 KylinSoft Co., Ltd. // See LICENSES for license details. -use core::{arch::asm, fmt}; +use core::fmt; use memaddr::{PhysAddr, VirtAddr}; @@ -226,14 +226,7 @@ impl PagingMetaData for A64PagingMetaData { #[inline] fn flush_tlb(vaddr: Option) { - unsafe { - if let Some(vaddr) = vaddr { - const VA_MASK: usize = (1 << 44) - 1; - asm!("dsb ishst; tlbi vaae1is, {}; dsb ish; isb", in(reg) ((vaddr.as_usize() >> 12) & VA_MASK)) - } else { - asm!("dsb ishst; tlbi vmalle1is; dsb ish; isb") - } - } + karch::flush_tlb(vaddr); } } diff --git a/mm/page_table/src/arch/loongarch64.rs b/mm/page_table/src/arch/loongarch64.rs index 5c155b9e..5dcc9884 100644 --- a/mm/page_table/src/arch/loongarch64.rs +++ b/mm/page_table/src/arch/loongarch64.rs @@ -2,7 +2,7 @@ // Copyright 2025 KylinSoft Co., Ltd. // See LICENSES for license details. -use core::{arch::asm, fmt}; +use core::fmt; use memaddr::{PhysAddr, VirtAddr}; @@ -177,15 +177,7 @@ impl PagingMetaData for LA64MetaData { const VA_MAX_BITS: usize = 48; fn flush_tlb(vaddr: Option) { - if let Some(vaddr) = vaddr { - unsafe { - asm!("invtlb 0x01, $r0, {}", in(reg) vaddr.as_usize()); - } - } else { - unsafe { - asm!("invtlb 0x00, $r0, $r0"); - } - } + karch::flush_tlb(vaddr); } } diff --git a/mm/page_table/src/arch/riscv.rs b/mm/page_table/src/arch/riscv.rs index 145a2152..40e1e1f6 100644 --- a/mm/page_table/src/arch/riscv.rs +++ b/mm/page_table/src/arch/riscv.rs @@ -146,11 +146,7 @@ pub trait SvVirtAddr: memaddr::MemoryAddr + Send + Sync { impl SvVirtAddr for VirtAddr { #[inline] fn flush_tlb(vaddr: Option) { - if let Some(vaddr) = vaddr { - riscv::asm::sfence_vma(0, vaddr.as_usize()); - } else { - riscv::asm::sfence_vma_all(); - } + karch::flush_tlb(vaddr); } } diff --git a/mm/page_table/src/arch/x86_64.rs b/mm/page_table/src/arch/x86_64.rs index 42a4ca10..08a909aa 100644 --- a/mm/page_table/src/arch/x86_64.rs +++ b/mm/page_table/src/arch/x86_64.rs @@ -187,11 +187,7 @@ impl PagingMetaData for X64PagingMetaData { #[inline] fn flush_tlb(vaddr: Option) { - if let Some(vaddr) = vaddr { - x86_64::instructions::tlb::flush(x86_64::VirtAddr::new(vaddr.as_usize() as u64)); - } else { - x86_64::instructions::tlb::flush_all(); - } + karch::flush_tlb(vaddr); } } diff --git a/net/knet/src/test_options.rs b/net/knet/src/test_options.rs index e28948db..16e85531 100644 --- a/net/knet/src/test_options.rs +++ b/net/knet/src/test_options.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for socket options. #![cfg(unittest)] diff --git a/net/knet/src/test_state.rs b/net/knet/src/test_state.rs index 23142622..618c89e5 100644 --- a/net/knet/src/test_state.rs +++ b/net/knet/src/test_state.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for socket state management. #![cfg(unittest)] diff --git a/platforms/aarch64-crosvm-virt/Cargo.toml b/platforms/aarch64-crosvm-virt/Cargo.toml index 5f3cf026..c01d1783 100644 --- a/platforms/aarch64-crosvm-virt/Cargo.toml +++ b/platforms/aarch64-crosvm-virt/Cargo.toml @@ -19,14 +19,15 @@ page_table = { workspace = true } kspin = "0.1" dw_apb_uart = "0.1" kcpu = { workspace = true } +karch = { workspace = true } kplat = { workspace = true } aarch64-peripherals = { workspace = true, default-features = false, features = ["gicv3"] } aarch64-cpu = "10.0" rs_fdtree = { workspace = true } -spin = "0.9" lazyinit = "0.2" arm-gic.workspace = true kbuild_config = { workspace = true } +ktypes = { workspace = true } [package.metadata.docs.rs] targets = ["aarch64-unknown-none"] diff --git a/platforms/aarch64-crosvm-virt/src/boot.rs b/platforms/aarch64-crosvm-virt/src/boot.rs index 2b3558b5..5a47edf2 100644 --- a/platforms/aarch64-crosvm-virt/src/boot.rs +++ b/platforms/aarch64-crosvm-virt/src/boot.rs @@ -61,7 +61,7 @@ extern "C" fn kernel_main_test() { /// Enable FP/SIMD usage if supported by build features. unsafe fn enable_fp() { #[cfg(feature = "fp-simd")] - kcpu::instrs::enable_fp(); + karch::enable_fp(); } #[unsafe(naked)] #[unsafe(no_mangle)] diff --git a/platforms/aarch64-crosvm-virt/src/fdt.rs b/platforms/aarch64-crosvm-virt/src/fdt.rs index 671d3a3a..e8481fe9 100644 --- a/platforms/aarch64-crosvm-virt/src/fdt.rs +++ b/platforms/aarch64-crosvm-virt/src/fdt.rs @@ -4,9 +4,9 @@ //! Device tree parsing helpers for the platform. use kplat::memory::{VirtAddr, p2v, pa}; +use ktypes::Once; use log::*; use rs_fdtree::{InterruptController, LinuxFdt}; -use spin::Once; pub static FDT: Once = Once::new(); /// Parse and cache the FDT pointed to by the bootloader. pub(crate) fn init_fdt(fdt_paddr: VirtAddr) { diff --git a/platforms/aarch64-crosvm-virt/src/gicv3.rs b/platforms/aarch64-crosvm-virt/src/gicv3.rs index 1570a5f2..fdc73904 100644 --- a/platforms/aarch64-crosvm-virt/src/gicv3.rs +++ b/platforms/aarch64-crosvm-virt/src/gicv3.rs @@ -3,10 +3,7 @@ // See LICENSES for license details. //! GICv3 initialization and IRQ routing helpers. -use core::{ - arch::asm, - sync::atomic::{AtomicBool, Ordering}, -}; +use core::sync::atomic::{AtomicBool, Ordering}; use aarch64_cpu::registers::*; use arm_gic::gicv3::*; @@ -228,29 +225,6 @@ pub fn dispatch_irq_irq(_unused: usize) -> Option { } Some(irq) } -#[inline] -pub fn enable_local() { - unsafe { asm!("msr daifclr, #2") }; -} -#[inline] -pub fn disable_local() { - unsafe { asm!("msr daifset, #2") }; -} -#[inline] -pub fn is_enabled() -> bool { - !DAIF.matches_all(DAIF::I::Masked) -} -#[inline] -pub fn save_disable() -> usize { - let flags: usize; - unsafe { asm!("mrs {}, daif", out(reg) flags) }; - disable_local(); - flags -} -#[inline] -pub fn restore(flags: usize) { - unsafe { asm!("msr daif, {}", in(reg) flags) }; -} #[macro_export] macro_rules! irq_if_impl { ($name:ident) => { @@ -280,26 +254,6 @@ macro_rules! irq_if_impl { fn set_prio(_irq: usize, _priority: u8) { todo!() } - - fn save_disable() -> usize { - $crate::gicv3::save_disable() - } - - fn restore(flag: usize) { - $crate::gicv3::restore(flag); - } - - fn enable_local() { - $crate::gicv3::enable_local(); - } - - fn disable_local() { - $crate::gicv3::disable_local(); - } - - fn is_enabled() -> bool { - $crate::gicv3::is_enabled() - } } }; } diff --git a/platforms/aarch64-crosvm-virt/src/mem.rs b/platforms/aarch64-crosvm-virt/src/mem.rs index e79bfd29..04269f31 100644 --- a/platforms/aarch64-crosvm-virt/src/mem.rs +++ b/platforms/aarch64-crosvm-virt/src/mem.rs @@ -7,8 +7,8 @@ use core::sync::atomic::{AtomicUsize, Ordering}; use kbuild_config::{MMIO_RANGES, PHYS_MEM_BASE, PHYS_MEM_SIZE, PHYS_VIRT_OFFSET}; use kplat::memory::{HwMemory, MemRange, PhysAddr, VirtAddr, pa, va}; +use ktypes::Once; use rs_fdtree::LinuxFdt; -use spin::Once; const FDT_MEM_SIZE: usize = 0x20_0000; static FDT_MEM_BASE: AtomicUsize = AtomicUsize::new(0); diff --git a/platforms/aarch64-crosvm-virt/src/psci.rs b/platforms/aarch64-crosvm-virt/src/psci.rs index 5d92e078..1208fdae 100644 --- a/platforms/aarch64-crosvm-virt/src/psci.rs +++ b/platforms/aarch64-crosvm-virt/src/psci.rs @@ -4,7 +4,7 @@ //! PSCI wrappers and KVM guard-granule helpers. use kplat::psci::PsciOp; -use spin::Once; +use ktypes::Once; use crate::serial::{boot_print_str, boot_print_usize}; pub static GUARD_GRANULE: Once = Once::new(); diff --git a/platforms/aarch64-peripherals/Cargo.toml b/platforms/aarch64-peripherals/Cargo.toml index ec4a2e8d..8b92f390 100644 --- a/platforms/aarch64-peripherals/Cargo.toml +++ b/platforms/aarch64-peripherals/Cargo.toml @@ -29,6 +29,7 @@ arm-gic-driver = "0.15" uart_16550 = "0.4" arm_pl031 = "0.2" kcpu = { workspace = true } +karch = { workspace = true } kplat = { workspace = true } aarch64-pmuv3 = { workspace = true, optional = true } percpu = { workspace = true } diff --git a/platforms/aarch64-peripherals/src/gic.rs b/platforms/aarch64-peripherals/src/gic.rs index 8e9612c1..5b2aacb2 100644 --- a/platforms/aarch64-peripherals/src/gic.rs +++ b/platforms/aarch64-peripherals/src/gic.rs @@ -3,11 +3,11 @@ // See LICENSES for license details. //! GIC interrupt controller integration for AArch64 platforms. +#[cfg(feature = "pmr")] use core::arch::asm; #[cfg(feature = "pmr")] use core::sync::atomic::{AtomicBool, Ordering}; -use aarch64_cpu::registers::{DAIF, Readable}; #[cfg(all(feature = "gicv2", not(feature = "gicv3")))] use arm_gic_driver::v2::*; #[cfg(feature = "gicv3")] @@ -244,82 +244,6 @@ pub fn notify_cpu(interrupt_id: usize, target: TargetCpu) { } } } -/// Enable local IRQ handling. -#[cfg(not(feature = "pmr"))] -#[inline] -pub fn enable_local() { - unsafe { asm!("msr daifclr, #2") }; -} -/// Disable local IRQ handling. -#[cfg(not(feature = "pmr"))] -#[inline] -pub fn disable_local() { - unsafe { asm!("msr daifset, #2") }; -} -/// Test whether local IRQs are enabled. -#[cfg(not(feature = "pmr"))] -#[inline] -pub fn is_enabled() -> bool { - !DAIF.matches_all(DAIF::I::Masked) -} -/// Save flags and disable local IRQ handling. -#[cfg(not(feature = "pmr"))] -#[inline] -pub fn save_disable() -> usize { - let flags: usize; - unsafe { asm!("mrs {}, daif", out(reg) flags) }; - disable_local(); - flags -} -/// Restore local IRQ flags previously saved. -#[cfg(not(feature = "pmr"))] -#[inline] -pub fn restore(flags: usize) { - unsafe { asm!("msr daif, {}", in(reg) flags) }; -} -/// Enable local IRQ handling with PMR unmasking. -#[cfg(feature = "pmr")] -#[inline] -pub fn enable_local() { - set_prio_mask(0xff); - unsafe { asm!("msr daifclr, #2") }; -} -/// Disable local IRQ handling while keeping PMR state. -#[cfg(feature = "pmr")] -#[inline] -pub fn disable_local() { - open_high_priority_irq_mode(); -} -/// Test whether local IRQs are enabled given PMR state. -#[cfg(feature = "pmr")] -#[inline] -pub fn is_enabled() -> bool { - !DAIF.matches_all(DAIF::I::Masked) && get_priority_mask() > 0xa0 -} -/// Save PMR/flags and disable local IRQ handling. -#[cfg(feature = "pmr")] -#[inline] -pub fn save_disable() -> usize { - if is_gic_initialized() { - let pmr = get_priority_mask(); - set_prio_mask(0x80); - pmr as usize - } else { - let flags: usize; - unsafe { asm!("mrs {}, daif; msr daifset, #2", out(reg) flags) }; - flags - } -} -/// Restore PMR/flags previously saved. -#[cfg(feature = "pmr")] -#[inline] -pub fn restore(flags: usize) { - if is_gic_initialized() { - set_prio_mask(flags as u8); - } else { - unsafe { asm!("msr daif, {}", in(reg) flags) }; - } -} /// Implement `kplat::interrupts::IntrManager` using this GIC backend. #[allow(clippy::crate_in_macro_def)] #[macro_export] @@ -352,26 +276,6 @@ macro_rules! irq_if_impl { fn set_prio(irq: usize, priority: u8) { $crate::gic::set_prio(irq, priority); } - - fn save_disable() -> usize { - $crate::gic::save_disable() - } - - fn restore(flag: usize) { - $crate::gic::restore(flag); - } - - fn enable_local() { - $crate::gic::enable_local(); - } - - fn disable_local() { - $crate::gic::disable_local(); - } - - fn is_enabled() -> bool { - $crate::gic::is_enabled() - } } }; } diff --git a/platforms/aarch64-peripherals/src/psci.rs b/platforms/aarch64-peripherals/src/psci.rs index abe8cae6..60d108cd 100644 --- a/platforms/aarch64-peripherals/src/psci.rs +++ b/platforms/aarch64-peripherals/src/psci.rs @@ -99,7 +99,7 @@ pub fn shutdown() -> ! { psci_call(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0).ok(); warn!("It should shutdown!"); loop { - kcpu::instrs::stop_cpu(); + karch::stop_cpu(); } } /// Power on a target CPU with the given entry point and argument. diff --git a/platforms/aarch64-qemu-virt/Cargo.toml b/platforms/aarch64-qemu-virt/Cargo.toml index c1b8ceb4..e5b13ce0 100644 --- a/platforms/aarch64-qemu-virt/Cargo.toml +++ b/platforms/aarch64-qemu-virt/Cargo.toml @@ -20,6 +20,7 @@ log = "0.4" page_table = { workspace = true } aarch64-peripherals = { workspace = true, default-features = false, features = ["gicv2"]} kcpu = { workspace = true } +karch = { workspace = true } kplat = { workspace = true } kbuild_config = { workspace = true } diff --git a/platforms/aarch64-qemu-virt/src/boot.rs b/platforms/aarch64-qemu-virt/src/boot.rs index 828298ba..d3dacd3b 100644 --- a/platforms/aarch64-qemu-virt/src/boot.rs +++ b/platforms/aarch64-qemu-virt/src/boot.rs @@ -32,7 +32,7 @@ unsafe fn init_boot_page_table() { } unsafe fn enable_fp() { #[cfg(feature = "fp-simd")] - kcpu::instrs::enable_fp(); + karch::enable_fp(); } #[unsafe(naked)] #[unsafe(no_mangle)] diff --git a/platforms/aarch64-raspi/Cargo.toml b/platforms/aarch64-raspi/Cargo.toml index 24740f46..8c7f393b 100644 --- a/platforms/aarch64-raspi/Cargo.toml +++ b/platforms/aarch64-raspi/Cargo.toml @@ -19,6 +19,7 @@ aarch64-cpu = "10.0" page_table = { workspace = true } aarch64-peripherals = { version = "0.3.0", path = "../kplat-aarch64-peripherals" } kcpu = { workspace = true } +karch = { workspace = true } kplat = { workspace = true } kbuild_config = { workspace = true } diff --git a/platforms/aarch64-raspi/src/boot.rs b/platforms/aarch64-raspi/src/boot.rs index bf02c59f..f4fbede8 100644 --- a/platforms/aarch64-raspi/src/boot.rs +++ b/platforms/aarch64-raspi/src/boot.rs @@ -39,7 +39,7 @@ unsafe fn init_boot_page_table() { } unsafe fn enable_fp() { #[cfg(feature = "fp-simd")] - kcpu::instrs::enable_fp(); + karch::enable_fp(); } /// Primary CPU entry point from the boot loader. #[unsafe(naked)] diff --git a/platforms/aarch64-raspi/src/mp.rs b/platforms/aarch64-raspi/src/mp.rs index 72465c78..e8d7c3f9 100644 --- a/platforms/aarch64-raspi/src/mp.rs +++ b/platforms/aarch64-raspi/src/mp.rs @@ -24,10 +24,10 @@ pub fn start_secondary_cpu(cpu_id: usize, stack_top: PhysAddr) { let entry_paddr = v2p(va!(modify_stack_and_start as usize)).as_usize(); let stack_top_ptr = &raw mut SECONDARY_STACK_TOP; unsafe { stack_top_ptr.write_volatile(stack_top.as_usize()) }; - kcpu::instrs::flush_dcache_line(va!(stack_top_ptr as usize)); + karch::flush_dcache_line(va!(stack_top_ptr as usize)); let spintable_vaddr = p2v(CPU_SPIN_TABLE[cpu_id]); let release_ptr = spintable_vaddr.as_mut_ptr() as *mut usize; unsafe { release_ptr.write_volatile(entry_paddr) }; - kcpu::instrs::flush_dcache_line(spintable_vaddr); + karch::flush_dcache_line(spintable_vaddr); aarch64_cpu::asm::sev(); } diff --git a/platforms/aarch64-raspi/src/power.rs b/platforms/aarch64-raspi/src/power.rs index b8fbb7d5..b948d56a 100644 --- a/platforms/aarch64-raspi/src/power.rs +++ b/platforms/aarch64-raspi/src/power.rs @@ -14,7 +14,7 @@ impl SysCtrl for PowerImpl { fn shutdown() -> ! { log::info!("Shutting down..."); loop { - kcpu::instrs::stop_cpu(); + karch::stop_cpu(); } } } diff --git a/platforms/kplat/src/interrupts.rs b/platforms/kplat/src/interrupts.rs index 2605b170..221217b8 100644 --- a/platforms/kplat/src/interrupts.rs +++ b/platforms/kplat/src/interrupts.rs @@ -35,16 +35,4 @@ pub trait IntrManager { fn notify_cpu(id: usize, target: TargetCpu); /// Sets the priority for the given interrupt. fn set_prio(id: usize, prio: u8); - - /// Saves and disables local interrupt state. - fn save_disable() -> usize; - /// Restores local interrupt state saved by `save_disable`. - fn restore(flags: usize); - - /// Enables local interrupts on the current CPU. - fn enable_local(); - /// Disables local interrupts on the current CPU. - fn disable_local(); - /// Returns whether local interrupts are enabled. - fn is_enabled() -> bool; } diff --git a/platforms/loongarch64-qemu-virt/Cargo.toml b/platforms/loongarch64-qemu-virt/Cargo.toml index d0fa07e3..52f07db8 100644 --- a/platforms/loongarch64-qemu-virt/Cargo.toml +++ b/platforms/loongarch64-qemu-virt/Cargo.toml @@ -20,6 +20,7 @@ lazyinit = "0.2" log = "0.4" kcpu = { workspace = true } +karch = { workspace = true } kplat = { workspace = true } kbuild_config = { workspace = true } diff --git a/platforms/loongarch64-qemu-virt/src/boot.rs b/platforms/loongarch64-qemu-virt/src/boot.rs index 562df8f0..5bc5a680 100644 --- a/platforms/loongarch64-qemu-virt/src/boot.rs +++ b/platforms/loongarch64-qemu-virt/src/boot.rs @@ -46,8 +46,8 @@ unsafe fn init_boot_page_table() { fn enable_fp_simd() { #[cfg(feature = "fp-simd")] { - kcpu::instrs::enable_fp(); - kcpu::instrs::enable_lsx(); + karch::enable_fp(); + karch::enable_lsx(); } } fn init_mmu() { diff --git a/platforms/loongarch64-qemu-virt/src/irq.rs b/platforms/loongarch64-qemu-virt/src/irq.rs index faa5ef80..62c6b04f 100644 --- a/platforms/loongarch64-qemu-virt/src/irq.rs +++ b/platforms/loongarch64-qemu-virt/src/irq.rs @@ -114,24 +114,4 @@ impl IntrManager for IntrManagerImpl { fn set_prio(irq: usize, priority: u8) { todo!() } - - fn save_disable() -> usize { - todo!() - } - - fn restore(flag: usize) { - todo!() - } - - fn enable_local() { - todo!() - } - - fn disable_local() { - todo!() - } - - fn is_enabled() -> bool { - todo!() - } } diff --git a/platforms/loongarch64-qemu-virt/src/power.rs b/platforms/loongarch64-qemu-virt/src/power.rs index 9c447046..11a2ca00 100644 --- a/platforms/loongarch64-qemu-virt/src/power.rs +++ b/platforms/loongarch64-qemu-virt/src/power.rs @@ -20,10 +20,10 @@ impl SysCtrl for PowerImpl { let halt_addr = p2v(pa!(GED_PADDR)).as_mut_ptr(); info!("Shutting down..."); unsafe { halt_addr.write_volatile(0x34) }; - kcpu::instrs::stop_cpu(); + karch::stop_cpu(); warn!("It should shutdown!"); loop { - kcpu::instrs::stop_cpu(); + karch::stop_cpu(); } } } diff --git a/platforms/riscv64-qemu-virt/Cargo.toml b/platforms/riscv64-qemu-virt/Cargo.toml index 4b7db09a..346e45d1 100644 --- a/platforms/riscv64-qemu-virt/Cargo.toml +++ b/platforms/riscv64-qemu-virt/Cargo.toml @@ -20,6 +20,7 @@ log = "0.4" percpu = { workspace = true } kcpu = { workspace = true } +karch = { workspace = true } kplat = { workspace = true } kbuild_config = { workspace = true } diff --git a/platforms/riscv64-qemu-virt/src/boot.rs b/platforms/riscv64-qemu-virt/src/boot.rs index 3f19a0c6..6d7dd080 100644 --- a/platforms/riscv64-qemu-virt/src/boot.rs +++ b/platforms/riscv64-qemu-virt/src/boot.rs @@ -20,8 +20,8 @@ unsafe fn init_boot_page_table() { } unsafe fn init_mmu() { unsafe { - kcpu::instrs::write_kernel_page_table(pa!(&raw const BOOT_PT_SV39 as usize)); - kcpu::instrs::flush_tlb(None); + karch::write_kernel_page_table(pa!(&raw const BOOT_PT_SV39 as usize)); + karch::flush_tlb(None); } } #[unsafe(naked)] diff --git a/platforms/riscv64-qemu-virt/src/irq.rs b/platforms/riscv64-qemu-virt/src/irq.rs index 21cad78d..ff50379d 100644 --- a/platforms/riscv64-qemu-virt/src/irq.rs +++ b/platforms/riscv64-qemu-virt/src/irq.rs @@ -214,24 +214,4 @@ impl IntrManager for IntrManagerImpl { fn set_prio(_irq: usize, _priority: u8) { todo!() } - - fn save_disable() -> usize { - todo!() - } - - fn restore(_flag: usize) { - todo!() - } - - fn enable_local() { - todo!() - } - - fn disable_local() { - todo!() - } - - fn is_enabled() -> bool { - todo!() - } } diff --git a/platforms/riscv64-qemu-virt/src/power.rs b/platforms/riscv64-qemu-virt/src/power.rs index f3742d20..14714031 100644 --- a/platforms/riscv64-qemu-virt/src/power.rs +++ b/platforms/riscv64-qemu-virt/src/power.rs @@ -22,7 +22,7 @@ impl SysCtrl for PowerImpl { sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::NoReason); warn!("It should shutdown!"); loop { - kcpu::instrs::stop_cpu(); + karch::stop_cpu(); } } } diff --git a/platforms/x86-csv/Cargo.toml b/platforms/x86-csv/Cargo.toml index c87944ed..55316d4b 100644 --- a/platforms/x86-csv/Cargo.toml +++ b/platforms/x86-csv/Cargo.toml @@ -23,6 +23,7 @@ int_ratio = "0.1" percpu = { workspace = true } heapless = "0.9" kcpu = { workspace = true } +karch = { workspace = true } kplat = { workspace = true } kbuild_config = { workspace = true } diff --git a/platforms/x86-csv/src/apic.rs b/platforms/x86-csv/src/apic.rs index 480615f8..1e6ffbb8 100644 --- a/platforms/x86-csv/src/apic.rs +++ b/platforms/x86-csv/src/apic.rs @@ -144,25 +144,5 @@ mod irq_impl { fn set_prio(_irq: usize, _priority: u8) { todo!() } - - fn save_disable() -> usize { - todo!() - } - - fn restore(_flag: usize) { - todo!() - } - - fn enable_local() { - todo!() - } - - fn disable_local() { - todo!() - } - - fn is_enabled() -> bool { - todo!() - } } } diff --git a/platforms/x86-csv/src/power.rs b/platforms/x86-csv/src/power.rs index ac10a0b7..d0f19e0b 100644 --- a/platforms/x86-csv/src/power.rs +++ b/platforms/x86-csv/src/power.rs @@ -23,10 +23,10 @@ impl SysCtrl for PowerImpl { } else { unsafe { PortWriteOnly::new(0x604).write(0x2000u16) }; } - kcpu::instrs::stop_cpu(); + karch::stop_cpu(); warn!("It should shutdown!"); loop { - kcpu::instrs::stop_cpu(); + karch::stop_cpu(); } } } diff --git a/platforms/x86_64-qemu-virt/Cargo.toml b/platforms/x86_64-qemu-virt/Cargo.toml index c1933c06..755eb0c4 100644 --- a/platforms/x86_64-qemu-virt/Cargo.toml +++ b/platforms/x86_64-qemu-virt/Cargo.toml @@ -23,6 +23,7 @@ int_ratio = "0.1" percpu = { workspace = true } heapless = "0.9" kcpu = { workspace = true } +karch = { workspace = true } kplat = { workspace = true } kbuild_config = { workspace = true } diff --git a/platforms/x86_64-qemu-virt/src/apic.rs b/platforms/x86_64-qemu-virt/src/apic.rs index 17165ea5..6e427723 100644 --- a/platforms/x86_64-qemu-virt/src/apic.rs +++ b/platforms/x86_64-qemu-virt/src/apic.rs @@ -153,25 +153,5 @@ mod irq_impl { fn set_prio(_irq: usize, _priority: u8) { todo!() } - - fn save_disable() -> usize { - todo!() - } - - fn restore(_flag: usize) { - todo!() - } - - fn enable_local() { - todo!() - } - - fn disable_local() { - todo!() - } - - fn is_enabled() -> bool { - todo!() - } } } diff --git a/platforms/x86_64-qemu-virt/src/power.rs b/platforms/x86_64-qemu-virt/src/power.rs index 1f1660b3..fb31090a 100644 --- a/platforms/x86_64-qemu-virt/src/power.rs +++ b/platforms/x86_64-qemu-virt/src/power.rs @@ -25,10 +25,10 @@ impl SysCtrl for PowerImpl { } else { unsafe { PortWriteOnly::new(0x604).write(0x2000u16) }; } - kcpu::instrs::stop_cpu(); + karch::stop_cpu(); warn!("It should shutdown!"); loop { - kcpu::instrs::stop_cpu(); + karch::stop_cpu(); } } } diff --git a/process/kprocess/src/tests.rs b/process/kprocess/src/tests.rs index 5bdaf1e2..722f8957 100644 --- a/process/kprocess/src/tests.rs +++ b/process/kprocess/src/tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for kprocess #![cfg(unittest)] diff --git a/process/ksignal/src/tests.rs b/process/ksignal/src/tests.rs index 0fe7d2e4..52df8094 100644 --- a/process/ksignal/src/tests.rs +++ b/process/ksignal/src/tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for ksignal #![cfg(unittest)] diff --git a/process/osvm/src/tests.rs b/process/osvm/src/tests.rs index 0543e373..37decc69 100644 --- a/process/osvm/src/tests.rs +++ b/process/osvm/src/tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Unit tests for osvm #![cfg(unittest)] diff --git a/scripts/check_header.py b/scripts/check_header.py new file mode 100644 index 00000000..def31543 --- /dev/null +++ b/scripts/check_header.py @@ -0,0 +1,61 @@ +import os + +EXPECTED_HEADER = """// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details.""" + +def check_rs_file_headers(root_dir="."): + """ + 检查指定目录下的所有 .rs 文件是否包含预期的文件头。 + 返回一个缺失文件头的文件路径列表。 + """ + missing_headers_list = [] + + for root, dirs, files in os.walk(root_dir): + # 忽略 target 目录以加快搜索速度 + if 'target' in dirs: + dirs.remove('target') + + for file in files: + if file.endswith(".rs"): + file_path = os.path.join(root, file) + try: + with open(file_path, 'r', encoding='utf-8') as f: + # 读取文件的前几行(假设头信息在前 10 行内),以避免读取整个大文件 + lines = [f.readline() for _ in range(10)] + content_head = "".join(lines) + + if EXPECTED_HEADER not in content_head: + missing_headers_list.append(file_path) + except Exception as e: + print(f"无法读取文件 {file_path}: {e}") + + return missing_headers_list + +def add_missing_headers(missing_list): + """ + 为缺失文件头的文件添加版权头信息。 + """ + if not missing_list: + print("🎉 恭喜!所有的 .rs 文件都包含了指定的版权头信息。") + return + + print(f"⚠️ 发现 {len(missing_list)} 个 .rs 文件缺失指定的版权头信息,正在添加...") + print("-" * 50) + for path in missing_list: + try: + with open(path, 'r', encoding='utf-8') as f: + content = f.read() + + with open(path, 'w', encoding='utf-8') as f: + f.write(EXPECTED_HEADER + "\n\n" + content) + print(f"已添加: {path}") + except Exception as e: + print(f"❌ 无法处理文件 {path}: {e}") + print("-" * 50) + print("✅ 处理完成!") + +if __name__ == "__main__": + # 指定项目根目录运行,默认为当前目录 '.' + missing_files = check_rs_file_headers(".") + add_missing_headers(missing_files) \ No newline at end of file diff --git a/scripts/make/deps.mk b/scripts/make/deps.mk index 5cadd336..51524788 100644 --- a/scripts/make/deps.mk +++ b/scripts/make/deps.mk @@ -1,11 +1,5 @@ # Necessary dependencies for the build system -# Tool to generate xconfig -ifeq ($(shell xconfig --version 2>/dev/null),) - $(info Installing xconfig...) - $(shell cargo install --path xtask/xconfig) -endif - # Cargo binutils ifeq ($(shell cargo install --list | grep cargo-binutils),) $(info Installing cargo-binutils...) diff --git a/sync/kspin/Cargo.toml b/sync/kspin/Cargo.toml index cb5c8c22..ff0f9b31 100644 --- a/sync/kspin/Cargo.toml +++ b/sync/kspin/Cargo.toml @@ -18,4 +18,5 @@ default = [] [dependencies] cfg-if = { workspace = true } crate_interface = {workspace = true} +karch = { workspace = true } unittest.workspace = true diff --git a/sync/kspin/README.md b/sync/kspin/README.md index a1467428..a26ffd81 100644 --- a/sync/kspin/README.md +++ b/sync/kspin/README.md @@ -129,14 +129,6 @@ impl KernelGuardIf for MyKernelGuard { fn disable_preempt() { // Your implementation } - - fn local_irq_save_and_disable() -> usize { - 0 // Your implementation - } - - fn local_irq_restore(flags: usize) { - // Your implementation - } } ``` diff --git a/sync/kspin/src/guard/arch/aarch64.rs b/sync/kspin/src/guard/arch/aarch64.rs deleted file mode 100644 index 819f1c20..00000000 --- a/sync/kspin/src/guard/arch/aarch64.rs +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -/// Save IRQ state and disable local interrupts. -#[inline] -pub fn save_disable() -> usize { - crate_interface::call_interface!(crate::guard::KernelGuardIf::save_disable) -} - -/// Restore local interrupt state from saved flags. -#[inline] -pub fn restore(flags: usize) { - crate_interface::call_interface!(crate::guard::KernelGuardIf::restore(flags)) -} diff --git a/sync/kspin/src/guard/arch/arm.rs b/sync/kspin/src/guard/arch/arm.rs deleted file mode 100644 index 1a574b0d..00000000 --- a/sync/kspin/src/guard/arch/arm.rs +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -//! ARM IRQ save/restore helpers. -use core::arch::asm; - -/// Bit 7: IRQ disable bit in CPSR -const IRQ_DISABLE_BIT: usize = 1 << 7; - -/// Save CPSR and disable IRQs. -#[inline] -pub fn save_disable() -> usize { - let flags: usize; - unsafe { - // Save CPSR and disable IRQs by setting the I bit - asm!( - "mrs {0}, cpsr", - "cpsid i", - out(reg) flags, - options(nomem, nostack, preserves_flags) - ); - } - flags & IRQ_DISABLE_BIT -} - -/// Restore IRQ state according to saved CPSR flags. -#[inline] -pub fn restore(flags: usize) { - if flags & IRQ_DISABLE_BIT == 0 { - // IRQs were enabled before, re-enable them - unsafe { - asm!("cpsie i", options(nomem, nostack)); - } - } -} diff --git a/sync/kspin/src/guard/arch/loongarch64.rs b/sync/kspin/src/guard/arch/loongarch64.rs deleted file mode 100644 index ecfca2db..00000000 --- a/sync/kspin/src/guard/arch/loongarch64.rs +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -//! LoongArch64 IRQ save/restore helpers. -use core::arch::asm; - -const IE_MASK: usize = 1 << 2; - -/// Save IE and disable interrupts. -#[inline] -pub fn save_disable() -> usize { - let mut flags: usize = 0; - // clear the `IE` bit, and return the old CSR - unsafe { asm!("csrxchg {}, {}, 0x0", inout(reg) flags, in(reg) IE_MASK) }; - flags & IE_MASK -} - -/// Restore IE according to saved flags. -#[inline] -pub fn restore(flags: usize) { - // restore the `IE` bit - unsafe { asm!("csrxchg {}, {}, 0x0", in(reg) flags, in(reg) IE_MASK) }; -} diff --git a/sync/kspin/src/guard/arch/mod.rs b/sync/kspin/src/guard/arch/mod.rs index a175a3d5..3956b0e6 100644 --- a/sync/kspin/src/guard/arch/mod.rs +++ b/sync/kspin/src/guard/arch/mod.rs @@ -3,23 +3,19 @@ // See LICENSES for license details. //! Architecture-specific IRQ save/restore helpers. -#![cfg_attr(not(target_os = "none"), allow(dead_code, unused_imports))] +//! +//! Delegates to [`karch`] for a unified implementation across all supported +//! architectures. +#![cfg_attr(not(target_os = "none"), allow(dead_code))] -cfg_if::cfg_if! { - if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { - mod x86; - pub use self::x86::*; - } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { - mod riscv; - pub use self::riscv::*; - } else if #[cfg(target_arch = "aarch64")] { - mod aarch64; - pub use self::aarch64::*; - } else if #[cfg(target_arch = "loongarch64")] { - mod loongarch64; - pub use self::loongarch64::*; - } else if #[cfg(target_arch = "arm")] { - mod arm; - pub use self::arm::*; - } +/// Saves and disables local interrupts, returning the saved state. +#[inline] +pub fn save_disable() -> usize { + karch::save_irq_and_disable() +} + +/// Restores local interrupt state from the saved flags. +#[inline] +pub fn restore(flags: usize) { + karch::restore_irq(flags) } diff --git a/sync/kspin/src/guard/arch/riscv.rs b/sync/kspin/src/guard/arch/riscv.rs deleted file mode 100644 index ef2faf84..00000000 --- a/sync/kspin/src/guard/arch/riscv.rs +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -//! RISC-V IRQ save/restore helpers. -use core::arch::asm; - -/// Bit 1: Supervisor Interrupt Enable -const SIE_BIT: usize = 1 << 1; - -/// Save SIE and disable interrupts. -#[inline] -pub fn save_disable() -> usize { - let flags: usize; - // clear the `SIE` bit, and return the old CSR - unsafe { asm!("csrrc {}, sstatus, {}", out(reg) flags, const SIE_BIT) }; - flags & SIE_BIT -} - -/// Restore SIE according to saved flags. -#[inline] -pub fn restore(flags: usize) { - // restore the `SIE` bit - unsafe { asm!("csrrs x0, sstatus, {}", in(reg) flags) }; -} diff --git a/sync/kspin/src/guard/arch/x86.rs b/sync/kspin/src/guard/arch/x86.rs deleted file mode 100644 index 312a3b24..00000000 --- a/sync/kspin/src/guard/arch/x86.rs +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2025 KylinSoft Co., Ltd. -// See LICENSES for license details. - -//! x86/x86_64 IRQ save/restore helpers. -use core::arch::asm; - -/// Interrupt Enable Flag (IF) -const IF_BIT: usize = 1 << 9; - -/// Save IF and disable interrupts. -#[inline] -pub fn save_disable() -> usize { - let flags: usize; - unsafe { asm!("pushf; pop {}; cli", out(reg) flags) }; - flags & IF_BIT -} - -/// Restore IF according to saved flags. -#[inline] -pub fn restore(flags: usize) { - if flags != 0 { - unsafe { asm!("sti") }; - } else { - unsafe { asm!("cli") }; - } -} diff --git a/sync/kspin/src/guard/mod.rs b/sync/kspin/src/guard/mod.rs index 5e0b25ca..762b3b40 100644 --- a/sync/kspin/src/guard/mod.rs +++ b/sync/kspin/src/guard/mod.rs @@ -15,12 +15,6 @@ pub trait KernelGuardIf { /// Disable kernel preemption. fn disable_preempt(); - - /// Save and disable local interrupts, returning saved flags. - fn save_disable() -> usize; - - /// Restore local interrupts from saved flags. - fn restore(flags: usize); } /// Base trait for all guard types. diff --git a/sync/kspin/src/lib.rs b/sync/kspin/src/lib.rs index 2f63aef4..1c3acd97 100644 --- a/sync/kspin/src/lib.rs +++ b/sync/kspin/src/lib.rs @@ -81,15 +81,6 @@ //! fn disable_preempt() { //! // Your implementation //! } -//! -//! fn save_disable() -> usize { -//! // Your implementation -//! 0 -//! } -//! -//! fn restore(flags: usize) { -//! // Your implementation -//! } //! } //! ``` diff --git a/tee_apps/sh/src/main.rs b/tee_apps/sh/src/main.rs index 24850a02..592b5cd0 100644 --- a/tee_apps/sh/src/main.rs +++ b/tee_apps/sh/src/main.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::process::{Child, Command, Stdio}; fn spawn_app(path: &str) -> Option { diff --git a/tee_apps/tee_app1/src/main.rs b/tee_apps/tee_app1/src/main.rs index 373b8f01..1788a928 100644 --- a/tee_apps/tee_app1/src/main.rs +++ b/tee_apps/tee_app1/src/main.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + fn main() { println!("Hello, tee_app1!"); let mut count = 0u64; diff --git a/tee_apps/tee_app2/src/main.rs b/tee_apps/tee_app2/src/main.rs index bdcbd026..ccda0b56 100644 --- a/tee_apps/tee_app2/src/main.rs +++ b/tee_apps/tee_app2/src/main.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + fn main() { println!("Hello, tee_app2!"); let mut count = 0u64; diff --git a/util/kbuild_config/build.rs b/util/kbuild_config/build.rs index 1a629cf9..2994c04c 100644 --- a/util/kbuild_config/build.rs +++ b/util/kbuild_config/build.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{env, fs, path::Path}; fn main() { diff --git a/util/kbuild_config/src/lib.rs b/util/kbuild_config/src/lib.rs index b292f19b..142973bd 100644 --- a/util/kbuild_config/src/lib.rs +++ b/util/kbuild_config/src/lib.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + // Auto-generated kbuild configuration module // // This module provides access to configuration constants from .config file diff --git a/xtask/crate_rootfs/src/args.rs b/xtask/crate_rootfs/src/args.rs index 8789e7a9..6755ca18 100644 --- a/xtask/crate_rootfs/src/args.rs +++ b/xtask/crate_rootfs/src/args.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use clap::Parser; diff --git a/xtask/crate_rootfs/src/blockdev.rs b/xtask/crate_rootfs/src/blockdev.rs index 5305b5ec..f7ae6460 100644 --- a/xtask/crate_rootfs/src/blockdev.rs +++ b/xtask/crate_rootfs/src/blockdev.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{ fs::File, io::{Read, Seek, SeekFrom, Write}, diff --git a/xtask/crate_rootfs/src/main.rs b/xtask/crate_rootfs/src/main.rs index c607195f..1cb633c8 100644 --- a/xtask/crate_rootfs/src/main.rs +++ b/xtask/crate_rootfs/src/main.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + mod args; mod blockdev; mod rootfs; diff --git a/xtask/crate_rootfs/src/rootfs.rs b/xtask/crate_rootfs/src/rootfs.rs index 90be4ff0..7a580e4d 100644 --- a/xtask/crate_rootfs/src/rootfs.rs +++ b/xtask/crate_rootfs/src/rootfs.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{ fs::{File, OpenOptions}, io::Read, diff --git a/xtask/crate_rootfs/src/util.rs b/xtask/crate_rootfs/src/util.rs index 03665d37..79f5d1b1 100644 --- a/xtask/crate_rootfs/src/util.rs +++ b/xtask/crate_rootfs/src/util.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::Path; /// Align up to the next multiple of `align`. diff --git a/xtask/src/main.rs b/xtask/src/main.rs index b9543968..cdea0691 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + fn main() { println!("Hello, xtask!"); } \ No newline at end of file diff --git a/xtask/xconfig/Cargo.toml b/xtask/xconfig/Cargo.toml index 40ce2acc..74c19b6a 100644 --- a/xtask/xconfig/Cargo.toml +++ b/xtask/xconfig/Cargo.toml @@ -34,11 +34,3 @@ path = "src/main.rs" [[bench]] name = "parser_bench" harness = false - -[profile.release] -opt-level = 3 -lto = true -codegen-units = 1 - -[profile.bench] -inherits = "release" diff --git a/xtask/xconfig/benches/parser_bench.rs b/xtask/xconfig/benches/parser_bench.rs index 21d11d1a..200ad84c 100644 --- a/xtask/xconfig/benches/parser_bench.rs +++ b/xtask/xconfig/benches/parser_bench.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use criterion::{Criterion, black_box, criterion_group, criterion_main}; diff --git a/xtask/xconfig/src/cli/commands.rs b/xtask/xconfig/src/cli/commands.rs index 7d306d59..ef832790 100644 --- a/xtask/xconfig/src/cli/commands.rs +++ b/xtask/xconfig/src/cli/commands.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use clap::{Parser as ClapParser, Subcommand}; diff --git a/xtask/xconfig/src/cli/defconfig.rs b/xtask/xconfig/src/cli/defconfig.rs index b790a7c4..72fd4bd4 100644 --- a/xtask/xconfig/src/cli/defconfig.rs +++ b/xtask/xconfig/src/cli/defconfig.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use crate::error::Result; diff --git a/xtask/xconfig/src/cli/gen_const.rs b/xtask/xconfig/src/cli/gen_const.rs index 3baa438c..d22c5bae 100644 --- a/xtask/xconfig/src/cli/gen_const.rs +++ b/xtask/xconfig/src/cli/gen_const.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{ collections::HashMap, fs, diff --git a/xtask/xconfig/src/cli/menuconfig.rs b/xtask/xconfig/src/cli/menuconfig.rs index fbeb43fa..b630572e 100644 --- a/xtask/xconfig/src/cli/menuconfig.rs +++ b/xtask/xconfig/src/cli/menuconfig.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{io, path::PathBuf}; use crossterm::{ diff --git a/xtask/xconfig/src/cli/mod.rs b/xtask/xconfig/src/cli/mod.rs index 6b521ae2..1bf6ef76 100644 --- a/xtask/xconfig/src/cli/mod.rs +++ b/xtask/xconfig/src/cli/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + pub mod commands; pub mod defconfig; pub mod gen_const; diff --git a/xtask/xconfig/src/cli/oldconfig.rs b/xtask/xconfig/src/cli/oldconfig.rs index ce379f04..0c9ef8da 100644 --- a/xtask/xconfig/src/cli/oldconfig.rs +++ b/xtask/xconfig/src/cli/oldconfig.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use crate::{ diff --git a/xtask/xconfig/src/cli/saveconfig.rs b/xtask/xconfig/src/cli/saveconfig.rs index 0802fe0d..160916a7 100644 --- a/xtask/xconfig/src/cli/saveconfig.rs +++ b/xtask/xconfig/src/cli/saveconfig.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use crate::{ diff --git a/xtask/xconfig/src/config/generator.rs b/xtask/xconfig/src/config/generator.rs index 47bec42f..bd0e8dda 100644 --- a/xtask/xconfig/src/config/generator.rs +++ b/xtask/xconfig/src/config/generator.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{collections::HashMap, fs::File, io::Write, path::Path}; use crate::{ diff --git a/xtask/xconfig/src/config/mod.rs b/xtask/xconfig/src/config/mod.rs index ddac4425..aeb11bf8 100644 --- a/xtask/xconfig/src/config/mod.rs +++ b/xtask/xconfig/src/config/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + pub mod generator; pub mod oldconfig; pub mod reader; diff --git a/xtask/xconfig/src/config/oldconfig.rs b/xtask/xconfig/src/config/oldconfig.rs index 6111d993..4e672c06 100644 --- a/xtask/xconfig/src/config/oldconfig.rs +++ b/xtask/xconfig/src/config/oldconfig.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{collections::HashSet, path::Path}; use crate::{ diff --git a/xtask/xconfig/src/config/reader.rs b/xtask/xconfig/src/config/reader.rs index 44933e71..fcdc2ce4 100644 --- a/xtask/xconfig/src/config/reader.rs +++ b/xtask/xconfig/src/config/reader.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{collections::HashMap, fs, path::Path}; use crate::error::Result; diff --git a/xtask/xconfig/src/config/writer.rs b/xtask/xconfig/src/config/writer.rs index 1cde8cc9..f9f54fb1 100644 --- a/xtask/xconfig/src/config/writer.rs +++ b/xtask/xconfig/src/config/writer.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{fs::File, io::Write, path::Path}; use crate::{error::Result, kconfig::SymbolTable}; diff --git a/xtask/xconfig/src/error.rs b/xtask/xconfig/src/error.rs index dae5a3bf..8245e368 100644 --- a/xtask/xconfig/src/error.rs +++ b/xtask/xconfig/src/error.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use thiserror::Error; diff --git a/xtask/xconfig/src/kconfig/ast.rs b/xtask/xconfig/src/kconfig/ast.rs index 8781f715..8f9ab4a5 100644 --- a/xtask/xconfig/src/kconfig/ast.rs +++ b/xtask/xconfig/src/kconfig/ast.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; #[derive(Debug, Clone, PartialEq)] diff --git a/xtask/xconfig/src/kconfig/expr.rs b/xtask/xconfig/src/kconfig/expr.rs index 0e45751f..439853e1 100644 --- a/xtask/xconfig/src/kconfig/expr.rs +++ b/xtask/xconfig/src/kconfig/expr.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use crate::{ error::{KconfigError, Result}, kconfig::{ast::Expr, shell_expr::evaluate_shell_expr, symbol::SymbolTable}, diff --git a/xtask/xconfig/src/kconfig/lexer.rs b/xtask/xconfig/src/kconfig/lexer.rs index 785f15d1..1158fa65 100644 --- a/xtask/xconfig/src/kconfig/lexer.rs +++ b/xtask/xconfig/src/kconfig/lexer.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use crate::error::{KconfigError, Result}; diff --git a/xtask/xconfig/src/kconfig/mod.rs b/xtask/xconfig/src/kconfig/mod.rs index e322f26b..93224572 100644 --- a/xtask/xconfig/src/kconfig/mod.rs +++ b/xtask/xconfig/src/kconfig/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + pub mod ast; pub mod expr; pub mod lexer; diff --git a/xtask/xconfig/src/kconfig/parser.rs b/xtask/xconfig/src/kconfig/parser.rs index 1051ef41..0b50d2d0 100644 --- a/xtask/xconfig/src/kconfig/parser.rs +++ b/xtask/xconfig/src/kconfig/parser.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{ collections::HashSet, fs, diff --git a/xtask/xconfig/src/kconfig/shell_expr.rs b/xtask/xconfig/src/kconfig/shell_expr.rs index 145660ad..649998c2 100644 --- a/xtask/xconfig/src/kconfig/shell_expr.rs +++ b/xtask/xconfig/src/kconfig/shell_expr.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use crate::{ error::{KconfigError, Result}, kconfig::symbol::SymbolTable, diff --git a/xtask/xconfig/src/kconfig/symbol.rs b/xtask/xconfig/src/kconfig/symbol.rs index c038a0e1..ddcb3ddf 100644 --- a/xtask/xconfig/src/kconfig/symbol.rs +++ b/xtask/xconfig/src/kconfig/symbol.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::collections::HashMap; use crate::kconfig::ast::SymbolType; diff --git a/xtask/xconfig/src/lib.rs b/xtask/xconfig/src/lib.rs index e2c707ef..b3638585 100644 --- a/xtask/xconfig/src/lib.rs +++ b/xtask/xconfig/src/lib.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + pub mod cli; pub mod config; pub mod error; diff --git a/xtask/xconfig/src/log.rs b/xtask/xconfig/src/log.rs index c293b7d1..93fe4eda 100644 --- a/xtask/xconfig/src/log.rs +++ b/xtask/xconfig/src/log.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[cfg(unix)] use std::os::unix::fs::OpenOptionsExt; use std::sync::OnceLock; diff --git a/xtask/xconfig/src/main.rs b/xtask/xconfig/src/main.rs index 02ea0cbd..468d9c69 100644 --- a/xtask/xconfig/src/main.rs +++ b/xtask/xconfig/src/main.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use xconfig::cli::run_cli; fn main() { diff --git a/xtask/xconfig/src/ui/app.rs b/xtask/xconfig/src/ui/app.rs index feeac043..a1a84165 100644 --- a/xtask/xconfig/src/ui/app.rs +++ b/xtask/xconfig/src/ui/app.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{io::Write, time::Duration}; use crossterm::event::{self, Event, KeyCode, KeyEvent}; diff --git a/xtask/xconfig/src/ui/dependency_resolver.rs b/xtask/xconfig/src/ui/dependency_resolver.rs index 7aef3e86..f1c6fa3b 100644 --- a/xtask/xconfig/src/ui/dependency_resolver.rs +++ b/xtask/xconfig/src/ui/dependency_resolver.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::collections::HashMap; use crate::kconfig::{ diff --git a/xtask/xconfig/src/ui/events/handler.rs b/xtask/xconfig/src/ui/events/handler.rs index c7b34a96..683571e2 100644 --- a/xtask/xconfig/src/ui/events/handler.rs +++ b/xtask/xconfig/src/ui/events/handler.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum EventResult { Continue, diff --git a/xtask/xconfig/src/ui/events/mod.rs b/xtask/xconfig/src/ui/events/mod.rs index 4bc7dc7f..fb7ced11 100644 --- a/xtask/xconfig/src/ui/events/mod.rs +++ b/xtask/xconfig/src/ui/events/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + pub mod handler; pub use handler::{EventHandler, EventResult}; diff --git a/xtask/xconfig/src/ui/mod.rs b/xtask/xconfig/src/ui/mod.rs index 4d9e6cda..8eee578b 100644 --- a/xtask/xconfig/src/ui/mod.rs +++ b/xtask/xconfig/src/ui/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + pub mod app; pub mod dependency_resolver; pub mod events; diff --git a/xtask/xconfig/src/ui/rendering/mod.rs b/xtask/xconfig/src/ui/rendering/mod.rs index 3104c3fe..2760024b 100644 --- a/xtask/xconfig/src/ui/rendering/mod.rs +++ b/xtask/xconfig/src/ui/rendering/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + pub mod theme; pub use theme::Theme; diff --git a/xtask/xconfig/src/ui/rendering/theme.rs b/xtask/xconfig/src/ui/rendering/theme.rs index cc6399f6..ad177444 100644 --- a/xtask/xconfig/src/ui/rendering/theme.rs +++ b/xtask/xconfig/src/ui/rendering/theme.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use ratatui::style::{Color, Modifier, Style}; #[derive(Debug, Clone)] diff --git a/xtask/xconfig/src/ui/state/mod.rs b/xtask/xconfig/src/ui/state/mod.rs index 921375c9..ce5f7007 100644 --- a/xtask/xconfig/src/ui/state/mod.rs +++ b/xtask/xconfig/src/ui/state/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::{collections::HashMap, io::Write}; use crate::{ diff --git a/xtask/xconfig/src/ui/utils/fuzzy_search.rs b/xtask/xconfig/src/ui/utils/fuzzy_search.rs index 520c7a99..517f155d 100644 --- a/xtask/xconfig/src/ui/utils/fuzzy_search.rs +++ b/xtask/xconfig/src/ui/utils/fuzzy_search.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use crate::ui::state::MenuItem; pub struct FuzzySearcher { diff --git a/xtask/xconfig/src/ui/utils/mod.rs b/xtask/xconfig/src/ui/utils/mod.rs index 9a85027e..a666f9b7 100644 --- a/xtask/xconfig/src/ui/utils/mod.rs +++ b/xtask/xconfig/src/ui/utils/mod.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + pub mod fuzzy_search; pub use fuzzy_search::{FuzzySearcher, SearchResult}; diff --git a/xtask/xconfig/tests/arch_config_bugs_test.rs b/xtask/xconfig/tests/arch_config_bugs_test.rs index d68230f7..6cca3d9b 100644 --- a/xtask/xconfig/tests/arch_config_bugs_test.rs +++ b/xtask/xconfig/tests/arch_config_bugs_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + /// Tests for Bug 1: ARCH config value is incorrect when loading defconfig with ARCH_X86_64=y /// Tests for Bug 2: Cross-architecture configuration pollution from defconfig use std::fs; diff --git a/xtask/xconfig/tests/choice_defaults_test.rs b/xtask/xconfig/tests/choice_defaults_test.rs index e7fd9300..0a8ab5d8 100644 --- a/xtask/xconfig/tests/choice_defaults_test.rs +++ b/xtask/xconfig/tests/choice_defaults_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::fs; use tempfile::TempDir; diff --git a/xtask/xconfig/tests/choice_mutual_exclusion_test.rs b/xtask/xconfig/tests/choice_mutual_exclusion_test.rs index 2638d5b6..bafe5ce9 100644 --- a/xtask/xconfig/tests/choice_mutual_exclusion_test.rs +++ b/xtask/xconfig/tests/choice_mutual_exclusion_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::io::Write; use tempfile::NamedTempFile; diff --git a/xtask/xconfig/tests/config_tests.rs b/xtask/xconfig/tests/config_tests.rs index e77e9a45..4d07b3f2 100644 --- a/xtask/xconfig/tests/config_tests.rs +++ b/xtask/xconfig/tests/config_tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::fs; use tempfile::TempDir; diff --git a/xtask/xconfig/tests/dependency_display_test.rs b/xtask/xconfig/tests/dependency_display_test.rs index 3d41603d..48d15262 100644 --- a/xtask/xconfig/tests/dependency_display_test.rs +++ b/xtask/xconfig/tests/dependency_display_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use xconfig::{kconfig::Parser, ui::state::ConfigState}; diff --git a/xtask/xconfig/tests/dependency_not_operator_test.rs b/xtask/xconfig/tests/dependency_not_operator_test.rs index 7d582b5c..b7247803 100644 --- a/xtask/xconfig/tests/dependency_not_operator_test.rs +++ b/xtask/xconfig/tests/dependency_not_operator_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use xconfig::{ diff --git a/xtask/xconfig/tests/dependency_tests.rs b/xtask/xconfig/tests/dependency_tests.rs index aa65baf0..70a2fabb 100644 --- a/xtask/xconfig/tests/dependency_tests.rs +++ b/xtask/xconfig/tests/dependency_tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use xconfig::{ diff --git a/xtask/xconfig/tests/end_to_end_range_test.rs b/xtask/xconfig/tests/end_to_end_range_test.rs index b333df83..16d54d13 100644 --- a/xtask/xconfig/tests/end_to_end_range_test.rs +++ b/xtask/xconfig/tests/end_to_end_range_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::fs; use tempfile::TempDir; diff --git a/xtask/xconfig/tests/if_block_test.rs b/xtask/xconfig/tests/if_block_test.rs index e363ac54..d24e4bfa 100644 --- a/xtask/xconfig/tests/if_block_test.rs +++ b/xtask/xconfig/tests/if_block_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::fs; use tempfile::TempDir; diff --git a/xtask/xconfig/tests/integration_tests.rs b/xtask/xconfig/tests/integration_tests.rs index eb9bcf22..1a5adec5 100644 --- a/xtask/xconfig/tests/integration_tests.rs +++ b/xtask/xconfig/tests/integration_tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use tempfile::TempDir; diff --git a/xtask/xconfig/tests/lexer_tests.rs b/xtask/xconfig/tests/lexer_tests.rs index ce4e43d4..ca7fa2d1 100644 --- a/xtask/xconfig/tests/lexer_tests.rs +++ b/xtask/xconfig/tests/lexer_tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use xconfig::kconfig::{Lexer, Token}; diff --git a/xtask/xconfig/tests/menu_navigation_test.rs b/xtask/xconfig/tests/menu_navigation_test.rs index 83fb3b40..64158f24 100644 --- a/xtask/xconfig/tests/menu_navigation_test.rs +++ b/xtask/xconfig/tests/menu_navigation_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use xconfig::{ diff --git a/xtask/xconfig/tests/menuconfig_defaults_test.rs b/xtask/xconfig/tests/menuconfig_defaults_test.rs index a414fa14..7a1b2334 100644 --- a/xtask/xconfig/tests/menuconfig_defaults_test.rs +++ b/xtask/xconfig/tests/menuconfig_defaults_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use xconfig::{ config::ConfigReader, kconfig::{SymbolTable, SymbolType}, diff --git a/xtask/xconfig/tests/menuconfig_ghost_filter_test.rs b/xtask/xconfig/tests/menuconfig_ghost_filter_test.rs index 1b9b8159..261e4460 100644 --- a/xtask/xconfig/tests/menuconfig_ghost_filter_test.rs +++ b/xtask/xconfig/tests/menuconfig_ghost_filter_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Tests for ghost config filtering in menuconfig //! //! Verifies that configs with unsatisfied dependencies are cleared when loading .config diff --git a/xtask/xconfig/tests/parser_tests.rs b/xtask/xconfig/tests/parser_tests.rs index baf4138d..dc43a192 100644 --- a/xtask/xconfig/tests/parser_tests.rs +++ b/xtask/xconfig/tests/parser_tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use xconfig::kconfig::Parser; diff --git a/xtask/xconfig/tests/range_array_tests.rs b/xtask/xconfig/tests/range_array_tests.rs index 2abf114e..d13a747b 100644 --- a/xtask/xconfig/tests/range_array_tests.rs +++ b/xtask/xconfig/tests/range_array_tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use xconfig::kconfig::{ diff --git a/xtask/xconfig/tests/range_test.rs b/xtask/xconfig/tests/range_test.rs index a2246fbc..5ac3b29d 100644 --- a/xtask/xconfig/tests/range_test.rs +++ b/xtask/xconfig/tests/range_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::fs; use tempfile::TempDir; diff --git a/xtask/xconfig/tests/search_navigation_test.rs b/xtask/xconfig/tests/search_navigation_test.rs index 4f5bd9eb..7a14ca16 100644 --- a/xtask/xconfig/tests/search_navigation_test.rs +++ b/xtask/xconfig/tests/search_navigation_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use xconfig::{kconfig::Parser, ui::app::MenuConfigApp}; diff --git a/xtask/xconfig/tests/source_tests.rs b/xtask/xconfig/tests/source_tests.rs index 405f7fc7..5b2e57d2 100644 --- a/xtask/xconfig/tests/source_tests.rs +++ b/xtask/xconfig/tests/source_tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use xconfig::kconfig::Parser; diff --git a/xtask/xconfig/tests/stable_ordering_test.rs b/xtask/xconfig/tests/stable_ordering_test.rs index f989e23d..bef65357 100644 --- a/xtask/xconfig/tests/stable_ordering_test.rs +++ b/xtask/xconfig/tests/stable_ordering_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::fs; use tempfile::TempDir; diff --git a/xtask/xconfig/tests/ui_checkbox_sync_test.rs b/xtask/xconfig/tests/ui_checkbox_sync_test.rs index dbe2122e..caf5a324 100644 --- a/xtask/xconfig/tests/ui_checkbox_sync_test.rs +++ b/xtask/xconfig/tests/ui_checkbox_sync_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + //! Tests for checkbox state synchronization in MenuConfigApp //! //! # Testing Limitations diff --git a/xtask/xconfig/tests/ui_tests.rs b/xtask/xconfig/tests/ui_tests.rs index d8559a77..bbb87dfd 100644 --- a/xtask/xconfig/tests/ui_tests.rs +++ b/xtask/xconfig/tests/ui_tests.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::path::PathBuf; use xconfig::{ diff --git a/xtask/xconfig/tests/visibility_filtering_test.rs b/xtask/xconfig/tests/visibility_filtering_test.rs index 3cd7a35e..4a8e2dcb 100644 --- a/xtask/xconfig/tests/visibility_filtering_test.rs +++ b/xtask/xconfig/tests/visibility_filtering_test.rs @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2025 KylinSoft Co., Ltd. +// See LICENSES for license details. + use std::fs; use tempfile::TempDir;