diff --git a/Makefile b/Makefile index 81189c725a..0003fab0db 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,8 @@ else ifeq ($(ARCH), riscv64) TARGET := riscv64gc-unknown-none-elf else ifeq ($(ARCH), loongarch64) TARGET := loongarch64-unknown-none-softfloat +else ifeq ($(ARCH), arm) + TARGET := armv7a-none-eabi else $(error "ARCH" must be one of "x86_64", "riscv64", "aarch64" or "loongarch64") endif diff --git a/modules/axhal/src/paging.rs b/modules/axhal/src/paging.rs index 3275aee159..fa67ffefa2 100644 --- a/modules/axhal/src/paging.rs +++ b/modules/axhal/src/paging.rs @@ -25,6 +25,18 @@ impl PagingHandler for PagingHandlerImpl { global_allocator().dealloc_pages(phys_to_virt(paddr).as_usize(), 1) } + fn alloc_frame_contiguous(num_pages: usize, align_pow2: usize) -> Option { + global_allocator() + .alloc_pages(num_pages, align_pow2) + .map(|vaddr| virt_to_phys(vaddr.into())) + .ok() + } + + fn dealloc_frame_contiguous(paddr: PhysAddr, num_pages: usize) { + let vaddr = phys_to_virt(paddr); + global_allocator().dealloc_pages(vaddr.as_usize(), num_pages) + } + #[inline] fn phys_to_virt(paddr: PhysAddr) -> VirtAddr { phys_to_virt(paddr) @@ -44,5 +56,8 @@ cfg_if::cfg_if! { } else if #[cfg(target_arch = "loongarch64")] { /// The architecture-specific page table. pub type PageTable = page_table_multiarch::loongarch64::LA64PageTable; + } else if #[cfg(target_arch = "arm")] { + /// The architecture-specific page table. + pub type PageTable = page_table_multiarch::arm::A32PageTable; } } diff --git a/modules/axhal/src/percpu.rs b/modules/axhal/src/percpu.rs index 69de832a45..d73d5d9390 100644 --- a/modules/axhal/src/percpu.rs +++ b/modules/axhal/src/percpu.rs @@ -72,6 +72,11 @@ pub fn current_task_ptr() -> *const T { } } } + #[cfg(target_arch = "arm")] + unsafe { + let _guard = kernel_guard::IrqSave::new(); + CURRENT_TASK_PTR.read_current_raw() as _ + } } /// Sets the pointer to the current task with preemption-safety. @@ -105,6 +110,11 @@ pub unsafe fn set_current_task_ptr(ptr: *const T) { cache_current_task_ptr(ptr); } } + #[cfg(target_arch = "arm")] + { + let _guard = kernel_guard::IrqSave::new(); + unsafe { CURRENT_TASK_PTR.write_current_raw(ptr as usize) } + } } #[allow(dead_code)] diff --git a/rust-toolchain.toml b/rust-toolchain.toml index c045ffc66b..1727658285 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -7,4 +7,5 @@ targets = [ "riscv64gc-unknown-none-elf", "aarch64-unknown-none-softfloat", "loongarch64-unknown-none-softfloat", + "armv7a-none-eabi", ] diff --git a/scripts/make/platform.mk b/scripts/make/platform.mk index 265c2f1721..580dbd12b0 100644 --- a/scripts/make/platform.mk +++ b/scripts/make/platform.mk @@ -29,8 +29,10 @@ ifeq ($(MYPLAT),) PLAT_PACKAGE := axplat-riscv64-qemu-virt else ifeq ($(ARCH), loongarch64) PLAT_PACKAGE := axplat-loongarch64-qemu-virt + else ifeq ($(ARCH), arm) + PLAT_PACKAGE := axplat-arm-qemu-virt else - $(error "ARCH" must be one of "x86_64", "riscv64", "aarch64" or "loongarch64") + $(error "ARCH" must be one of "x86_64", "riscv64", "aarch64", "loongarch64" or "arm") endif PLAT_CONFIG := $(strip $(call resolve_config)) # We don't need to check whether `PLAT_CONFIG` is valid here, as the `PLAT_PACKAGE` diff --git a/scripts/make/qemu.mk b/scripts/make/qemu.mk index f35663a6c6..4829145887 100644 --- a/scripts/make/qemu.mk +++ b/scripts/make/qemu.mk @@ -21,6 +21,8 @@ else ifeq ($(ARCH), aarch64) else machine := virt endif +else ifeq ($(ARCH), arm) + machine := virt,gic-version=2 else ifeq ($(ARCH), loongarch64) machine := virt override MEM := 1G @@ -44,6 +46,11 @@ qemu_args-loongarch64 := \ -machine $(machine) \ -kernel $(OUT_ELF) +qemu_args-arm := \ + -machine $(machine) \ + -cpu cortex-a15 \ + -kernel $(FINAL_IMG) + qemu_args-y := -m $(MEM) -smp $(SMP) $(qemu_args-$(ARCH)) qemu_args-$(BLK) += \ diff --git a/ulib/axlibc/include/setjmp.h b/ulib/axlibc/include/setjmp.h index 5f5ee0a076..b04857fa20 100644 --- a/ulib/axlibc/include/setjmp.h +++ b/ulib/axlibc/include/setjmp.h @@ -11,6 +11,8 @@ typedef unsigned long __jmp_buf[26]; typedef unsigned long __jmp_buf[8]; #elif defined(__loongarch__) typedef unsigned long __jmp_buf[21]; +#elif defined(__arm__) +typedef unsigned long __jmp_buf[64]; /* r4-r14, d8-d15 (VFP) */ #endif typedef struct __jmp_buf_tag { diff --git a/ulib/axlibc/include/stdint.h b/ulib/axlibc/include/stdint.h index 89d87f2458..823d423bdd 100644 --- a/ulib/axlibc/include/stdint.h +++ b/ulib/axlibc/include/stdint.h @@ -41,7 +41,7 @@ typedef int64_t intmax_t; #if __riscv_xlen == 64 || defined(__x86_64__) || defined(__aarch64__) || defined(__loongarch__) typedef int64_t intptr_t; typedef uint64_t uintptr_t; -#elif __riscv_xlen == 32 || defined(__i386__) +#elif __riscv_xlen == 32 || defined(__i386__) || defined(__arm__) typedef int32_t intptr_t; typedef uint32_t uintptr_t; #endif