From 90917cc75af9406834c14fd25140405ba6f72d6d Mon Sep 17 00:00:00 2001 From: Shell Date: Fri, 28 Jun 2024 00:23:09 +0800 Subject: [format] cleanup libcpu/aarch64 (#8950) * [dfs] fixup compiler warning Signed-off-by: Shell * [format] libcpu/arm64: separate context switching codes Signed-off-by: Shell * [format] libcpu/arm64: separate vector Signed-off-by: Shell * [format] libcpu/arm64: separate context_gcc.S Signed-off-by: Shell * [format] libcpu/arm64: moving headers to include directory Signed-off-by: Shell * style: replace tab with space --------- Signed-off-by: Shell --- .../dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c | 2 +- components/lwp/arch/aarch64/cortex-a/lwp_gcc.S | 10 +- libcpu/aarch64/common/SConscript | 9 +- libcpu/aarch64/common/armv8.h | 179 ------ libcpu/aarch64/common/asm-fpu.h | 79 --- libcpu/aarch64/common/asm-generic.h | 26 - libcpu/aarch64/common/cache.h | 39 -- libcpu/aarch64/common/cache_ops.c | 2 +- libcpu/aarch64/common/context_gcc.S | 642 --------------------- libcpu/aarch64/common/cp15.h | 65 --- libcpu/aarch64/common/cpu.c | 1 - libcpu/aarch64/common/cpu.h | 92 --- libcpu/aarch64/common/cpu_gcc.S | 269 +++++++-- libcpu/aarch64/common/cpu_ops_common.h | 21 - libcpu/aarch64/common/cpuport.h | 102 ---- libcpu/aarch64/common/entry_point.h | 13 - libcpu/aarch64/common/gic.h | 62 -- libcpu/aarch64/common/gicv3.h | 198 ------- libcpu/aarch64/common/gtimer.h | 33 -- libcpu/aarch64/common/hypercall.h | 27 - libcpu/aarch64/common/include/armv8.h | 179 ++++++ libcpu/aarch64/common/include/asm-fpu.h | 83 +++ libcpu/aarch64/common/include/asm-generic.h | 26 + libcpu/aarch64/common/include/cache.h | 39 ++ libcpu/aarch64/common/include/context_gcc.h | 77 +++ libcpu/aarch64/common/include/cp15.h | 65 +++ libcpu/aarch64/common/include/cpu.h | 92 +++ libcpu/aarch64/common/include/cpu_ops_common.h | 21 + libcpu/aarch64/common/include/cpuport.h | 102 ++++ libcpu/aarch64/common/include/entry_point.h | 13 + libcpu/aarch64/common/include/gic.h | 62 ++ libcpu/aarch64/common/include/gicv3.h | 198 +++++++ libcpu/aarch64/common/include/gtimer.h | 33 ++ libcpu/aarch64/common/include/hypercall.h | 27 + libcpu/aarch64/common/include/interrupt.h | 60 ++ libcpu/aarch64/common/include/mmu.h | 212 +++++++ libcpu/aarch64/common/include/psci.h | 151 +++++ libcpu/aarch64/common/include/setup.h | 22 + libcpu/aarch64/common/include/smccc.h | 45 ++ libcpu/aarch64/common/include/tlb.h | 80 +++ libcpu/aarch64/common/include/vector_gcc.h | 114 ++++ libcpu/aarch64/common/interrupt.h | 60 -- libcpu/aarch64/common/mmu.h | 212 ------- libcpu/aarch64/common/mp/context_gcc.S | 109 ++++ libcpu/aarch64/common/mp/context_gcc.h | 66 +++ libcpu/aarch64/common/mp/vector_gcc.S | 48 ++ libcpu/aarch64/common/psci.h | 151 ----- libcpu/aarch64/common/setup.h | 22 - libcpu/aarch64/common/smccc.h | 45 -- libcpu/aarch64/common/stack_gcc.S | 28 + libcpu/aarch64/common/startup_gcc.S | 2 +- libcpu/aarch64/common/tlb.h | 80 --- libcpu/aarch64/common/up/context_gcc.S | 97 ++++ libcpu/aarch64/common/up/context_gcc.h | 79 +++ libcpu/aarch64/common/up/vector_gcc.S | 75 +++ libcpu/aarch64/common/vector_gcc.S | 76 ++- 56 files changed, 2491 insertions(+), 2231 deletions(-) delete mode 100644 libcpu/aarch64/common/armv8.h delete mode 100644 libcpu/aarch64/common/asm-fpu.h delete mode 100644 libcpu/aarch64/common/asm-generic.h delete mode 100644 libcpu/aarch64/common/cache.h delete mode 100644 libcpu/aarch64/common/context_gcc.S delete mode 100644 libcpu/aarch64/common/cp15.h delete mode 100644 libcpu/aarch64/common/cpu.h delete mode 100644 libcpu/aarch64/common/cpu_ops_common.h delete mode 100644 libcpu/aarch64/common/cpuport.h delete mode 100644 libcpu/aarch64/common/entry_point.h delete mode 100644 libcpu/aarch64/common/gic.h delete mode 100644 libcpu/aarch64/common/gicv3.h delete mode 100644 libcpu/aarch64/common/gtimer.h delete mode 100644 libcpu/aarch64/common/hypercall.h create mode 100644 libcpu/aarch64/common/include/armv8.h create mode 100644 libcpu/aarch64/common/include/asm-fpu.h create mode 100644 libcpu/aarch64/common/include/asm-generic.h create mode 100644 libcpu/aarch64/common/include/cache.h create mode 100644 libcpu/aarch64/common/include/context_gcc.h create mode 100644 libcpu/aarch64/common/include/cp15.h create mode 100644 libcpu/aarch64/common/include/cpu.h create mode 100644 libcpu/aarch64/common/include/cpu_ops_common.h create mode 100644 libcpu/aarch64/common/include/cpuport.h create mode 100644 libcpu/aarch64/common/include/entry_point.h create mode 100644 libcpu/aarch64/common/include/gic.h create mode 100644 libcpu/aarch64/common/include/gicv3.h create mode 100644 libcpu/aarch64/common/include/gtimer.h create mode 100644 libcpu/aarch64/common/include/hypercall.h create mode 100644 libcpu/aarch64/common/include/interrupt.h create mode 100644 libcpu/aarch64/common/include/mmu.h create mode 100644 libcpu/aarch64/common/include/psci.h create mode 100644 libcpu/aarch64/common/include/setup.h create mode 100644 libcpu/aarch64/common/include/smccc.h create mode 100644 libcpu/aarch64/common/include/tlb.h create mode 100644 libcpu/aarch64/common/include/vector_gcc.h delete mode 100644 libcpu/aarch64/common/interrupt.h delete mode 100644 libcpu/aarch64/common/mmu.h create mode 100644 libcpu/aarch64/common/mp/context_gcc.S create mode 100644 libcpu/aarch64/common/mp/context_gcc.h create mode 100644 libcpu/aarch64/common/mp/vector_gcc.S delete mode 100644 libcpu/aarch64/common/psci.h delete mode 100644 libcpu/aarch64/common/setup.h delete mode 100644 libcpu/aarch64/common/smccc.h create mode 100644 libcpu/aarch64/common/stack_gcc.S delete mode 100644 libcpu/aarch64/common/tlb.h create mode 100644 libcpu/aarch64/common/up/context_gcc.S create mode 100644 libcpu/aarch64/common/up/context_gcc.h create mode 100644 libcpu/aarch64/common/up/vector_gcc.S diff --git a/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c b/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c index c87be8239b..e2cda467fe 100644 --- a/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c +++ b/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c @@ -494,7 +494,7 @@ int dfs_tmpfs_stat(struct dfs_filesystem *fs, if (d_file == NULL) return -ENOENT; - st->st_dev = (rt_device_t)dfs_filesystem_lookup(fs->path); + st->st_dev = (dev_t)dfs_filesystem_lookup(fs->path); st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH; if (d_file->type == TMPFS_TYPE_DIR) diff --git a/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S b/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S index f5a93698d9..a71ee339cb 100644 --- a/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S +++ b/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S @@ -14,11 +14,11 @@ #define __ASSEMBLY__ #endif -#include "rtconfig.h" -#include "asm-generic.h" -#include "asm-fpu.h" -#include "armv8.h" -#include "lwp_arch.h" +#include +#include +#include +#include +#include /********************* * SPSR BIT * diff --git a/libcpu/aarch64/common/SConscript b/libcpu/aarch64/common/SConscript index 1449e97e6e..2041098f14 100644 --- a/libcpu/aarch64/common/SConscript +++ b/libcpu/aarch64/common/SConscript @@ -6,7 +6,14 @@ Import('rtconfig') cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.cpp') + Glob('*.S') -CPPPATH = [cwd] +CPPPATH = [cwd, cwd + '/include'] + +if GetDepend('RT_USING_SMP'): + core_model = 'mp' +else: + core_model = 'up' + +src += Glob(core_model + '/*.S') if GetDepend('RT_USING_OFW') == False: SrcRemove(src, ['setup.c', 'cpu_psci.c', 'psci.c']) diff --git a/libcpu/aarch64/common/armv8.h b/libcpu/aarch64/common/armv8.h deleted file mode 100644 index 5f64f03090..0000000000 --- a/libcpu/aarch64/common/armv8.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2006-2020, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-09-15 Bernard first version - */ - -#ifndef __ARMV8_H__ -#define __ARMV8_H__ - -#ifdef __ASSEMBLY__ - -/********************* - * CONTEXT_OFFSET * - *********************/ - -#define CONTEXT_OFFSET_ELR_EL1 0x0 -#define CONTEXT_OFFSET_SPSR_EL1 0x8 -#define CONTEXT_OFFSET_SP_EL0 0x10 -#define CONTEXT_OFFSET_X30 0x18 -#define CONTEXT_OFFSET_FPCR 0x20 -#define CONTEXT_OFFSET_FPSR 0x28 -#define CONTEXT_OFFSET_X28 0x30 -#define CONTEXT_OFFSET_X29 0x38 -#define CONTEXT_OFFSET_X26 0x40 -#define CONTEXT_OFFSET_X27 0x48 -#define CONTEXT_OFFSET_X24 0x50 -#define CONTEXT_OFFSET_X25 0x58 -#define CONTEXT_OFFSET_X22 0x60 -#define CONTEXT_OFFSET_X23 0x68 -#define CONTEXT_OFFSET_X20 0x70 -#define CONTEXT_OFFSET_X21 0x78 -#define CONTEXT_OFFSET_X18 0x80 -#define CONTEXT_OFFSET_X19 0x88 -#define CONTEXT_OFFSET_X16 0x90 -#define CONTEXT_OFFSET_X17 0x98 -#define CONTEXT_OFFSET_X14 0xa0 -#define CONTEXT_OFFSET_X15 0xa8 -#define CONTEXT_OFFSET_X12 0xb0 -#define CONTEXT_OFFSET_X13 0xb8 -#define CONTEXT_OFFSET_X10 0xc0 -#define CONTEXT_OFFSET_X11 0xc8 -#define CONTEXT_OFFSET_X8 0xd0 -#define CONTEXT_OFFSET_X9 0xd8 -#define CONTEXT_OFFSET_X6 0xe0 -#define CONTEXT_OFFSET_X7 0xe8 -#define CONTEXT_OFFSET_X4 0xf0 -#define CONTEXT_OFFSET_X5 0xf8 -#define CONTEXT_OFFSET_X2 0x100 -#define CONTEXT_OFFSET_X3 0x108 -#define CONTEXT_OFFSET_X0 0x110 -#define CONTEXT_OFFSET_X1 0x118 - -#define CONTEXT_OFFSET_Q31 0x120 -#define CONTEXT_OFFSET_Q30 0x130 -#define CONTEXT_OFFSET_Q29 0x140 -#define CONTEXT_OFFSET_Q28 0x150 -#define CONTEXT_OFFSET_Q27 0x160 -#define CONTEXT_OFFSET_Q26 0x170 -#define CONTEXT_OFFSET_Q25 0x180 -#define CONTEXT_OFFSET_Q24 0x190 -#define CONTEXT_OFFSET_Q23 0x1a0 -#define CONTEXT_OFFSET_Q22 0x1b0 -#define CONTEXT_OFFSET_Q21 0x1c0 -#define CONTEXT_OFFSET_Q20 0x1d0 -#define CONTEXT_OFFSET_Q19 0x1e0 -#define CONTEXT_OFFSET_Q18 0x1f0 -#define CONTEXT_OFFSET_Q17 0x200 -#define CONTEXT_OFFSET_Q16 0x210 -#define CONTEXT_OFFSET_Q15 0x220 -#define CONTEXT_OFFSET_Q14 0x230 -#define CONTEXT_OFFSET_Q13 0x240 -#define CONTEXT_OFFSET_Q12 0x250 -#define CONTEXT_OFFSET_Q11 0x260 -#define CONTEXT_OFFSET_Q10 0x270 -#define CONTEXT_OFFSET_Q9 0x280 -#define CONTEXT_OFFSET_Q8 0x290 -#define CONTEXT_OFFSET_Q7 0x2a0 -#define CONTEXT_OFFSET_Q6 0x2b0 -#define CONTEXT_OFFSET_Q5 0x2c0 -#define CONTEXT_OFFSET_Q4 0x2d0 -#define CONTEXT_OFFSET_Q3 0x2e0 -#define CONTEXT_OFFSET_Q2 0x2f0 -#define CONTEXT_OFFSET_Q1 0x300 -#define CONTEXT_OFFSET_Q0 0x310 - -#define CONTEXT_FPU_SIZE (32 * 16) -#define CONTEXT_SIZE (0x120 + CONTEXT_FPU_SIZE) - -#else /* !__ASSEMBLY__ */ - -#include - -typedef struct { rt_uint64_t value[2]; } rt_uint128_t; - -/* the exception stack without VFP registers */ -struct rt_hw_exp_stack -{ - rt_uint64_t pc; - rt_uint64_t cpsr; - rt_uint64_t sp_el0; - rt_uint64_t x30; - rt_uint64_t fpcr; - rt_uint64_t fpsr; - rt_uint64_t x28; - rt_uint64_t x29; - rt_uint64_t x26; - rt_uint64_t x27; - rt_uint64_t x24; - rt_uint64_t x25; - rt_uint64_t x22; - rt_uint64_t x23; - rt_uint64_t x20; - rt_uint64_t x21; - rt_uint64_t x18; - rt_uint64_t x19; - rt_uint64_t x16; - rt_uint64_t x17; - rt_uint64_t x14; - rt_uint64_t x15; - rt_uint64_t x12; - rt_uint64_t x13; - rt_uint64_t x10; - rt_uint64_t x11; - rt_uint64_t x8; - rt_uint64_t x9; - rt_uint64_t x6; - rt_uint64_t x7; - rt_uint64_t x4; - rt_uint64_t x5; - rt_uint64_t x2; - rt_uint64_t x3; - rt_uint64_t x0; - rt_uint64_t x1; - - rt_uint128_t fpu[32]; -}; - -#define SP_ELx ((unsigned long)0x01) -#define SP_EL0 ((unsigned long)0x00) -#define PSTATE_EL1 ((unsigned long)0x04) -#define PSTATE_EL2 ((unsigned long)0x08) -#define PSTATE_EL3 ((unsigned long)0x0c) - -rt_ubase_t rt_hw_get_current_el(void); -void rt_hw_set_elx_env(void); -void rt_hw_set_current_vbar(rt_ubase_t addr); - -/* ESR:generic */ -#define ARM64_ABORT_WNR(esr) ((esr) & 0x40) -#define ARM64_ESR_EXTRACT_EC(esr) ((((esr) >> 26) & 0x3fU)) -#define ARM64_ESR_EXTRACT_FSC(esr) ((esr) & 0x3f) - -/* ESR:EC */ -#define ARM64_EC_INST_ABORT_FROM_LO_EXCEPTION (0b100000) -#define ARM64_EC_INST_ABORT_WITHOUT_A_CHANGE (0b100001) -#define ARM64_EC_DATA_ABORT_FROM_LO_EXCEPTION (0b100100) -#define ARM64_EC_DATA_ABORT_WITHOUT_A_CHANGE (0b100101) - -/* ESR:FSC */ -#define ARM64_FSC_TRANSLATION_FAULT_LEVEL_0 (0b000100) -#define ARM64_FSC_TRANSLATION_FAULT_LEVEL_1 (0b000101) -#define ARM64_FSC_TRANSLATION_FAULT_LEVEL_2 (0b000110) -#define ARM64_FSC_TRANSLATION_FAULT_LEVEL_3 (0b000111) -#define ARM64_FSC_PERMISSION_FAULT_LEVEL_0 (0b001100) -#define ARM64_FSC_PERMISSION_FAULT_LEVEL_1 (0b001101) -#define ARM64_FSC_PERMISSION_FAULT_LEVEL_2 (0b001110) -#define ARM64_FSC_PERMISSION_FAULT_LEVEL_3 (0b001111) -#define ARM64_FSC_ACCESS_FLAG_FAULT_LEVEL_0 (0b001000) -#define ARM64_FSC_ACCESS_FLAG_FAULT_LEVEL_1 (0b001001) -#define ARM64_FSC_ACCESS_FLAG_FAULT_LEVEL_2 (0b001010) -#define ARM64_FSC_ACCESS_FLAG_FAULT_LEVEL_3 (0b001011) - -#endif /* __ASSEMBLY__ */ - -#endif diff --git a/libcpu/aarch64/common/asm-fpu.h b/libcpu/aarch64/common/asm-fpu.h deleted file mode 100644 index 9729f8c1b2..0000000000 --- a/libcpu/aarch64/common/asm-fpu.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-05-18 Jesven the first version - * 2023-07-13 GuEe-GUI append Q16 ~ Q31 - */ - -.macro SAVE_FPU, reg - STR Q0, [\reg, #-0x10]! - STR Q1, [\reg, #-0x10]! - STR Q2, [\reg, #-0x10]! - STR Q3, [\reg, #-0x10]! - STR Q4, [\reg, #-0x10]! - STR Q5, [\reg, #-0x10]! - STR Q6, [\reg, #-0x10]! - STR Q7, [\reg, #-0x10]! - STR Q8, [\reg, #-0x10]! - STR Q9, [\reg, #-0x10]! - STR Q10, [\reg, #-0x10]! - STR Q11, [\reg, #-0x10]! - STR Q12, [\reg, #-0x10]! - STR Q13, [\reg, #-0x10]! - STR Q14, [\reg, #-0x10]! - STR Q15, [\reg, #-0x10]! - STR Q16, [\reg, #-0x10]! - STR Q17, [\reg, #-0x10]! - STR Q18, [\reg, #-0x10]! - STR Q19, [\reg, #-0x10]! - STR Q20, [\reg, #-0x10]! - STR Q21, [\reg, #-0x10]! - STR Q22, [\reg, #-0x10]! - STR Q23, [\reg, #-0x10]! - STR Q24, [\reg, #-0x10]! - STR Q25, [\reg, #-0x10]! - STR Q26, [\reg, #-0x10]! - STR Q27, [\reg, #-0x10]! - STR Q28, [\reg, #-0x10]! - STR Q29, [\reg, #-0x10]! - STR Q30, [\reg, #-0x10]! - STR Q31, [\reg, #-0x10]! -.endm -.macro RESTORE_FPU, reg - LDR Q31, [\reg], #0x10 - LDR Q30, [\reg], #0x10 - LDR Q29, [\reg], #0x10 - LDR Q28, [\reg], #0x10 - LDR Q27, [\reg], #0x10 - LDR Q26, [\reg], #0x10 - LDR Q25, [\reg], #0x10 - LDR Q24, [\reg], #0x10 - LDR Q23, [\reg], #0x10 - LDR Q22, [\reg], #0x10 - LDR Q21, [\reg], #0x10 - LDR Q20, [\reg], #0x10 - LDR Q19, [\reg], #0x10 - LDR Q18, [\reg], #0x10 - LDR Q17, [\reg], #0x10 - LDR Q16, [\reg], #0x10 - LDR Q15, [\reg], #0x10 - LDR Q14, [\reg], #0x10 - LDR Q13, [\reg], #0x10 - LDR Q12, [\reg], #0x10 - LDR Q11, [\reg], #0x10 - LDR Q10, [\reg], #0x10 - LDR Q9, [\reg], #0x10 - LDR Q8, [\reg], #0x10 - LDR Q7, [\reg], #0x10 - LDR Q6, [\reg], #0x10 - LDR Q5, [\reg], #0x10 - LDR Q4, [\reg], #0x10 - LDR Q3, [\reg], #0x10 - LDR Q2, [\reg], #0x10 - LDR Q1, [\reg], #0x10 - LDR Q0, [\reg], #0x10 -.endm diff --git a/libcpu/aarch64/common/asm-generic.h b/libcpu/aarch64/common/asm-generic.h deleted file mode 100644 index 9d90b37a92..0000000000 --- a/libcpu/aarch64/common/asm-generic.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2006-2023 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-03-12 WangXiaoyao the first version - */ -#ifndef __ASM_GENERIC_H__ -#define __ASM_GENERIC_H__ - -/* use to mark a start point where every task start from */ -#define START_POINT(funcname) \ - .global funcname; \ - .type funcname, %function; \ - funcname: \ - .cfi_sections .debug_frame, .eh_frame; \ - .cfi_startproc; \ - .cfi_undefined x30 - -#define START_POINT_END(name) \ - .cfi_endproc; \ - .size name, .-name; - -#endif /* __ASM_GENERIC_H__ */ diff --git a/libcpu/aarch64/common/cache.h b/libcpu/aarch64/common/cache.h deleted file mode 100644 index ef7b235d0e..0000000000 --- a/libcpu/aarch64/common/cache.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-12-18 RT-Thread the first version - */ - -#ifndef __CACHE_H__ -#define __CACHE_H__ - -#include - -void __asm_invalidate_icache_all(void); - -void rt_hw_dcache_flush_all(void); -void rt_hw_dcache_invalidate_all(void); -void rt_hw_dcache_flush_range(unsigned long start_addr, unsigned long size); -void rt_hw_cpu_dcache_clean(void *addr, unsigned long size); -void rt_hw_cpu_dcache_invalidate(void *start_addr, unsigned long size); - -static inline void rt_hw_icache_invalidate_all(void) -{ - /* wait for previous modification to complete */ - __asm__ volatile ("dsb ishst"); - - __asm__ volatile ("ic ialluis"); - /* wait for ic to retire */ - __asm__ volatile ("dsb nsh"); - /* flush instruction pipeline */ - __asm__ volatile ("isb"); -} - -void rt_hw_cpu_icache_invalidate(void *addr, rt_size_t size); -void rt_hw_cpu_dcache_clean_and_invalidate(void *addr, rt_size_t size); - -#endif /* __CACHE_H__ */ diff --git a/libcpu/aarch64/common/cache_ops.c b/libcpu/aarch64/common/cache_ops.c index 9193434599..fa0457bee8 100644 --- a/libcpu/aarch64/common/cache_ops.c +++ b/libcpu/aarch64/common/cache_ops.c @@ -5,7 +5,7 @@ * * Change Logs: * Date Author Notes - * 2019-03-29 quanzhao the first version + * 2019-03-29 quanzhao the first version */ #include #include diff --git a/libcpu/aarch64/common/context_gcc.S b/libcpu/aarch64/common/context_gcc.S deleted file mode 100644 index 0233806d96..0000000000 --- a/libcpu/aarch64/common/context_gcc.S +++ /dev/null @@ -1,642 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-05-18 Jesven the first version - * 2023-06-24 WangXiaoyao Support backtrace for user thread - * 2024-01-06 Shell Fix barrier on irq_disable/enable - * 2024-01-18 Shell fix implicit dependency of cpuid management - */ - -#ifndef __ASSEMBLY__ -#define __ASSEMBLY__ -#endif - -#include "rtconfig.h" -#include "asm-generic.h" -#include "asm-fpu.h" -#include "armv8.h" - -#ifndef RT_USING_SMP -.section .data -rt_interrupt_from_thread: .zero 8 -rt_interrupt_to_thread: .zero 8 -rt_thread_switch_interrupt_flag: .zero 8 -#endif - -.text - -/** - * #ifdef RT_USING_OFW - * void rt_hw_cpu_id_set(long cpuid) - * #else - * void rt_hw_cpu_id_set(void) - * #endif - */ -.type rt_hw_cpu_id_set, @function -rt_hw_cpu_id_set: -#ifdef ARCH_USING_GENERIC_CPUID - .globl rt_hw_cpu_id_set -#else /* !ARCH_USING_GENERIC_CPUID */ - .weak rt_hw_cpu_id_set -#endif /* ARCH_USING_GENERIC_CPUID */ - -#ifndef RT_USING_OFW - mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */ -#ifdef ARCH_ARM_CORTEX_A55 - lsr x0, x0, #8 -#endif /* ARCH_ARM_CORTEX_A55 */ - and x0, x0, #15 -#endif /* !RT_USING_OFW */ - -#ifdef ARCH_USING_HW_THREAD_SELF - msr tpidrro_el0, x0 -#else /* !ARCH_USING_HW_THREAD_SELF */ - msr tpidr_el1, x0 -#endif /* ARCH_USING_HW_THREAD_SELF */ - ret - -/* -int rt_hw_cpu_id(void) -*/ -.type rt_hw_cpu_id, @function -rt_hw_cpu_id: -#ifdef ARCH_USING_GENERIC_CPUID - .globl rt_hw_cpu_id -#else /* !ARCH_USING_GENERIC_CPUID */ - .weak rt_hw_cpu_id -#endif /* ARCH_USING_GENERIC_CPUID */ - -#if RT_CPUS_NR > 1 - #ifdef ARCH_USING_GENERIC_CPUID - mrs x0, tpidrro_el0 - #else /* !ARCH_USING_GENERIC_CPUID */ - mrs x0, tpidr_el1 - #endif /* ARCH_USING_GENERIC_CPUID */ -#else /* RT_CPUS_NR == 1 */ - mov x0, xzr -#endif - ret - -/* -void rt_hw_set_process_id(size_t id) -*/ -.global rt_hw_set_process_id -rt_hw_set_process_id: - msr CONTEXTIDR_EL1, x0 - ret - - /* - *enable gtimer - */ -.globl rt_hw_gtimer_enable -rt_hw_gtimer_enable: - MOV X0,#1 - MSR CNTP_CTL_EL0,X0 - RET - -/* - *set gtimer CNTP_TVAL_EL0 value - */ -.globl rt_hw_set_gtimer_val -rt_hw_set_gtimer_val: - MSR CNTP_TVAL_EL0,X0 - RET - -/* - *get gtimer CNTP_TVAL_EL0 value - */ -.globl rt_hw_get_gtimer_val -rt_hw_get_gtimer_val: - MRS X0,CNTP_TVAL_EL0 - RET - - -.globl rt_hw_get_cntpct_val -rt_hw_get_cntpct_val: - MRS X0, CNTPCT_EL0 - RET - -/* - *get gtimer frq value - */ -.globl rt_hw_get_gtimer_frq -rt_hw_get_gtimer_frq: - MRS X0,CNTFRQ_EL0 - RET - -START_POINT(_thread_start) - blr x19 - mov x29, #0 - blr x20 - b . /* never here */ -START_POINT_END(_thread_start) - -.macro SAVE_CONTEXT - /* Save the entire context. */ - SAVE_FPU SP - STP X0, X1, [SP, #-0x10]! - STP X2, X3, [SP, #-0x10]! - STP X4, X5, [SP, #-0x10]! - STP X6, X7, [SP, #-0x10]! - STP X8, X9, [SP, #-0x10]! - STP X10, X11, [SP, #-0x10]! - STP X12, X13, [SP, #-0x10]! - STP X14, X15, [SP, #-0x10]! - STP X16, X17, [SP, #-0x10]! - STP X18, X19, [SP, #-0x10]! - STP X20, X21, [SP, #-0x10]! - STP X22, X23, [SP, #-0x10]! - STP X24, X25, [SP, #-0x10]! - STP X26, X27, [SP, #-0x10]! - STP X28, X29, [SP, #-0x10]! - MRS X28, FPCR - MRS X29, FPSR - STP X28, X29, [SP, #-0x10]! - MRS X29, SP_EL0 - STP X29, X30, [SP, #-0x10]! - - MRS X3, SPSR_EL1 - MRS X2, ELR_EL1 - - STP X2, X3, [SP, #-0x10]! - - MOV X0, SP /* Move SP into X0 for saving. */ -.endm - -.macro SAVE_CONTEXT_FROM_EL1 - /* Save the entire context. */ - SAVE_FPU SP - STP X0, X1, [SP, #-0x10]! - STP X2, X3, [SP, #-0x10]! - STP X4, X5, [SP, #-0x10]! - STP X6, X7, [SP, #-0x10]! - STP X8, X9, [SP, #-0x10]! - STP X10, X11, [SP, #-0x10]! - STP X12, X13, [SP, #-0x10]! - STP X14, X15, [SP, #-0x10]! - STP X16, X17, [SP, #-0x10]! - STP X18, X19, [SP, #-0x10]! - STP X20, X21, [SP, #-0x10]! - STP X22, X23, [SP, #-0x10]! - STP X24, X25, [SP, #-0x10]! - STP X26, X27, [SP, #-0x10]! - STP X28, X29, [SP, #-0x10]! - MRS X28, FPCR - MRS X29, FPSR - STP X28, X29, [SP, #-0x10]! - MRS X29, SP_EL0 - STP X29, X30, [SP, #-0x10]! - - MOV X19, #((3 << 6) | 0x4 | 0x1) /* el1h, disable interrupt */ - MOV X18, X30 - - STP X18, X19, [SP, #-0x10]! -.endm - -#ifdef RT_USING_SMP -.macro RESTORE_CONTEXT - /* Set the SP to point to the stack of the task being restored. */ - MOV SP, X0 - - LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ - - TST X3, #0x1f - MSR SPSR_EL1, X3 - MSR ELR_EL1, X2 - - LDP X29, X30, [SP], #0x10 - MSR SP_EL0, X29 - LDP X28, X29, [SP], #0x10 - MSR FPCR, X28 - MSR FPSR, X29 - LDP X28, X29, [SP], #0x10 - LDP X26, X27, [SP], #0x10 - LDP X24, X25, [SP], #0x10 - LDP X22, X23, [SP], #0x10 - LDP X20, X21, [SP], #0x10 - LDP X18, X19, [SP], #0x10 - LDP X16, X17, [SP], #0x10 - LDP X14, X15, [SP], #0x10 - LDP X12, X13, [SP], #0x10 - LDP X10, X11, [SP], #0x10 - LDP X8, X9, [SP], #0x10 - LDP X6, X7, [SP], #0x10 - LDP X4, X5, [SP], #0x10 - LDP X2, X3, [SP], #0x10 - LDP X0, X1, [SP], #0x10 - RESTORE_FPU SP -#ifdef RT_USING_SMART - BEQ arch_ret_to_user -#endif - ERET -.endm -#else -.macro RESTORE_CONTEXT - /* Set the SP to point to the stack of the task being restored. */ - MOV SP, X0 -#ifdef RT_USING_SMART - BL rt_thread_self - MOV X19, X0 - BL lwp_aspace_switch - MOV X0, X19 - BL lwp_user_setting_restore -#endif - LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ - - TST X3, #0x1f - MSR SPSR_EL1, X3 - MSR ELR_EL1, X2 - - LDP X29, X30, [SP], #0x10 - MSR SP_EL0, X29 - LDP X28, X29, [SP], #0x10 - MSR FPCR, X28 - MSR FPSR, X29 - LDP X28, X29, [SP], #0x10 - LDP X26, X27, [SP], #0x10 - LDP X24, X25, [SP], #0x10 - LDP X22, X23, [SP], #0x10 - LDP X20, X21, [SP], #0x10 - LDP X18, X19, [SP], #0x10 - LDP X16, X17, [SP], #0x10 - LDP X14, X15, [SP], #0x10 - LDP X12, X13, [SP], #0x10 - LDP X10, X11, [SP], #0x10 - LDP X8, X9, [SP], #0x10 - LDP X6, X7, [SP], #0x10 - LDP X4, X5, [SP], #0x10 - LDP X2, X3, [SP], #0x10 - LDP X0, X1, [SP], #0x10 - RESTORE_FPU SP -#ifdef RT_USING_SMART - BEQ arch_ret_to_user -#endif - ERET -.endm -#endif - -.macro RESTORE_CONTEXT_WITHOUT_MMU_SWITCH - /* the SP is already ok */ - LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ - - TST X3, #0x1f - MSR SPSR_EL1, X3 - MSR ELR_EL1, X2 - - LDP X29, X30, [SP], #0x10 - MSR SP_EL0, X29 - LDP X28, X29, [SP], #0x10 - MSR FPCR, X28 - MSR FPSR, X29 - LDP X28, X29, [SP], #0x10 - LDP X26, X27, [SP], #0x10 - LDP X24, X25, [SP], #0x10 - LDP X22, X23, [SP], #0x10 - LDP X20, X21, [SP], #0x10 - LDP X18, X19, [SP], #0x10 - LDP X16, X17, [SP], #0x10 - LDP X14, X15, [SP], #0x10 - LDP X12, X13, [SP], #0x10 - LDP X10, X11, [SP], #0x10 - LDP X8, X9, [SP], #0x10 - LDP X6, X7, [SP], #0x10 - LDP X4, X5, [SP], #0x10 - LDP X2, X3, [SP], #0x10 - LDP X0, X1, [SP], #0x10 - RESTORE_FPU SP -#ifdef RT_USING_SMART - BEQ arch_ret_to_user -#endif - ERET -.endm - -.macro SAVE_USER_CTX - MRS X1, SPSR_EL1 - AND X1, X1, 0xf - CMP X1, XZR - - BNE 1f - BL lwp_uthread_ctx_save - LDP X0, X1, [SP] -1: -.endm - -.macro RESTORE_USER_CTX, ctx - LDR X1, [\ctx, #CONTEXT_OFFSET_SPSR_EL1] - AND X1, X1, 0x1f - CMP X1, XZR - - BNE 1f - BL lwp_uthread_ctx_restore -1: -.endm - -#ifdef RT_USING_SMP -#define rt_hw_interrupt_disable rt_hw_local_irq_disable -#define rt_hw_interrupt_enable rt_hw_local_irq_enable -#endif - -.text - -.global rt_hw_interrupt_is_disabled -rt_hw_interrupt_is_disabled: - MRS X0, DAIF - TST X0, #0xc0 - CSET X0, NE - RET - -/* - * rt_base_t rt_hw_interrupt_disable(); - */ -.globl rt_hw_interrupt_disable -rt_hw_interrupt_disable: - MRS X0, DAIF - AND X0, X0, #0xc0 - CMP X0, #0xc0 - /* branch if bits not both set(zero) */ - BNE 1f - RET -1: - MSR DAIFSet, #3 - DSB NSH - ISB - RET - -/* - * void rt_hw_interrupt_enable(rt_base_t level); - */ -.globl rt_hw_interrupt_enable -rt_hw_interrupt_enable: - AND X0, X0, #0xc0 - CMP X0, #0xc0 - /* branch if one of the bits not set(zero) */ - BNE 1f - RET -1: - ISB - DSB NSH - AND X0, X0, #0xc0 - MRS X1, DAIF - BIC X1, X1, #0xc0 - ORR X0, X0, X1 - MSR DAIF, X0 - RET - -.text - -#ifdef RT_USING_SMP - -/* - * void rt_hw_context_switch_to(rt_uint3 to, struct rt_thread *to_thread); - * X0 --> to (thread stack) - * X1 --> to_thread - */ - -.globl rt_hw_context_switch_to -rt_hw_context_switch_to: - LDR X0, [X0] - MOV SP, X0 - MOV X0, X1 - BL rt_cpus_lock_status_restore -#ifdef RT_USING_SMART - BL rt_thread_self - BL lwp_user_setting_restore -#endif - B rt_hw_context_switch_exit - -/* - * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to, struct rt_thread *to_thread); - * X0 --> from (from_thread stack) - * X1 --> to (to_thread stack) - * X2 --> to_thread - */ -.globl rt_hw_context_switch -rt_hw_context_switch: - SAVE_CONTEXT_FROM_EL1 - mov X3, SP - str X3, [X0] // store sp in preempted tasks TCB - ldr X0, [X1] // get new task stack pointer - mov SP, X0 - - /* backup thread self */ - mov x19, x2 - - mov x0, x19 - bl rt_cpus_lock_status_restore -#ifdef RT_USING_SMART - mov x0, x19 - bl lwp_user_setting_restore -#endif - b rt_hw_context_switch_exit - -/* - * void rt_hw_context_switch_interrupt(context, from sp, to sp, tp tcb) - * X0 :interrupt context - * X1 :addr of from_thread's sp - * X2 :addr of to_thread's sp - * X3 :to_thread's tcb - */ -.globl rt_hw_context_switch_interrupt -rt_hw_context_switch_interrupt: - STP X0, X1, [SP, #-0x10]! - STP X2, X3, [SP, #-0x10]! - STP X29, X30, [SP, #-0x10]! -#ifdef RT_USING_SMART - BL rt_thread_self - BL lwp_user_setting_save -#endif - LDP X29, X30, [SP], #0x10 - LDP X2, X3, [SP], #0x10 - LDP X0, X1, [SP], #0x10 - STR X0, [X1] - LDR X0, [X2] - MOV SP, X0 - MOV X0, X3 - MOV X19, X0 - BL rt_cpus_lock_status_restore - MOV X0, X19 -#ifdef RT_USING_SMART - BL lwp_user_setting_restore -#endif - B rt_hw_context_switch_exit - -.globl vector_fiq -vector_fiq: - B . - -START_POINT(vector_irq) - SAVE_CONTEXT - STP X0, X1, [SP, #-0x10]! /* X0 is thread sp */ - - BL rt_interrupt_enter - LDP X0, X1, [SP] -#ifdef RT_USING_SMART - SAVE_USER_CTX -#endif - BL rt_hw_trap_irq -#ifdef RT_USING_SMART - LDP X0, X1, [SP] - RESTORE_USER_CTX X0 -#endif - BL rt_interrupt_leave - - LDP X0, X1, [SP], #0x10 - BL rt_scheduler_do_irq_switch - B rt_hw_context_switch_exit -START_POINT_END(vector_irq) - -.global rt_hw_context_switch_exit -rt_hw_context_switch_exit: - CLREX - MOV X0, SP - RESTORE_CONTEXT - -#else /* !RT_USING_SMP */ - -/* - * void rt_hw_context_switch_to(rt_ubase_t to); - * X0 --> to sp - */ -.globl rt_hw_context_switch_to -rt_hw_context_switch_to: - CLREX - LDR X0, [X0] - RESTORE_CONTEXT - -/* - * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); - * X0 --> from sp - * X1 --> to sp - * X2 --> to thread - */ -.globl rt_hw_context_switch -rt_hw_context_switch: - CLREX - SAVE_CONTEXT_FROM_EL1 - - MOV X2, SP - STR X2, [X0] // store sp in preempted tasks TCB - LDR X0, [X1] // get new task stack pointer - - RESTORE_CONTEXT - -/* - * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t from_thread, rt_thread_t to_thread); - */ -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread -.globl rt_hw_context_switch_interrupt -rt_hw_context_switch_interrupt: - CLREX - LDR X6, =rt_thread_switch_interrupt_flag - LDR X7, [X6] - CMP X7, #1 - B.EQ _reswitch - LDR X4, =rt_interrupt_from_thread // set rt_interrupt_from_thread - STR X0, [X4] - MOV X7, #1 // set rt_thread_switch_interrupt_flag to 1 - STR X7, [X6] - STP X1, X30, [SP, #-0x10]! -#ifdef RT_USING_SMART - MOV X0, X2 - BL lwp_user_setting_save -#endif - LDP X1, X30, [SP], #0x10 -_reswitch: - LDR X6, =rt_interrupt_to_thread // set rt_interrupt_to_thread - STR X1, [X6] - RET - -.text - -// -- Exception handlers ---------------------------------- - - .align 8 -.globl vector_fiq -vector_fiq: - SAVE_CONTEXT - STP X0, X1, [SP, #-0x10]! - BL rt_hw_trap_fiq - LDP X0, X1, [SP], #0x10 - RESTORE_CONTEXT - -.globl rt_interrupt_enter -.globl rt_interrupt_leave -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread - - -// ------------------------------------------------------------------- - - .align 8 -.globl vector_irq -vector_irq: - SAVE_CONTEXT - STP X0, X1, [SP, #-0x10]! /* X0 is thread sp */ - - BL rt_interrupt_enter - BL rt_hw_trap_irq - BL rt_interrupt_leave - - LDP X0, X1, [SP], #0x10 - - // if rt_thread_switch_interrupt_flag set, jump to - // rt_hw_context_switch_interrupt_do and don't return - LDR X1, =rt_thread_switch_interrupt_flag - LDR X2, [X1] - CMP X2, #1 - B.NE vector_irq_exit - - MOV X2, #0 // clear flag - STR X2, [X1] - - LDR X3, =rt_interrupt_from_thread - LDR X4, [X3] - STR x0, [X4] // store sp in preempted tasks's TCB - - LDR x3, =rt_interrupt_to_thread - LDR X4, [X3] - LDR x0, [X4] // get new task's stack pointer - - RESTORE_CONTEXT - -vector_irq_exit: - MOV SP, X0 - RESTORE_CONTEXT_WITHOUT_MMU_SWITCH -#endif /* RT_USING_SMP */ - -// ------------------------------------------------- - -START_POINT(vector_exception) - SAVE_CONTEXT - STP X0, X1, [SP, #-0x10]! -#ifdef RT_USING_SMART - SAVE_USER_CTX -#endif - - BL rt_hw_trap_exception -#ifdef RT_USING_SMART - LDP X0, X1, [SP] - RESTORE_USER_CTX X0 -#endif - - LDP X0, X1, [SP], #0x10 - MOV SP, X0 - RESTORE_CONTEXT_WITHOUT_MMU_SWITCH -START_POINT_END(vector_exception) - -START_POINT(vector_serror) - SAVE_CONTEXT -#ifdef RT_USING_SMART - SAVE_USER_CTX -#endif - STP X0, X1, [SP, #-0x10]! - BL rt_hw_trap_serror - b . -START_POINT_END(vector_serror) diff --git a/libcpu/aarch64/common/cp15.h b/libcpu/aarch64/common/cp15.h deleted file mode 100644 index cb1458ceec..0000000000 --- a/libcpu/aarch64/common/cp15.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2006-2020, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-09-15 Bernard first version - */ - -#ifndef __CP15_H__ -#define __CP15_H__ - -#ifndef __STATIC_FORCEINLINE -#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline -#endif - -#define __WFI() __asm__ volatile ("wfi":::"memory") - -#define __WFE() __asm__ volatile ("wfe":::"memory") - -#define __SEV() __asm__ volatile ("sev") - -__STATIC_FORCEINLINE void __ISB(void) -{ - __asm__ volatile ("isb 0xF":::"memory"); -} - -/** - \brief Data Synchronization Barrier - \details Acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -__STATIC_FORCEINLINE void __DSB(void) -{ - __asm__ volatile ("dsb 0xF":::"memory"); -} - -/** - \brief Data Memory Barrier - \details Ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ - -__STATIC_FORCEINLINE void __DMB(void) -{ - __asm__ volatile ("dmb 0xF":::"memory"); -} - -unsigned long rt_cpu_get_smp_id(void); - -void rt_cpu_mmu_disable(void); -void rt_cpu_mmu_enable(void); -void rt_cpu_tlb_set(volatile unsigned long*); - -void rt_cpu_dcache_clean_flush(void); -void rt_cpu_icache_flush(void); - -void rt_cpu_vector_set_base(rt_ubase_t addr); -void rt_hw_mmu_init(void); -void rt_hw_vector_init(void); - -void set_timer_counter(unsigned int counter); -void set_timer_control(unsigned int control); -#endif diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c index 72ccccac24..96abbc4c20 100644 --- a/libcpu/aarch64/common/cpu.c +++ b/libcpu/aarch64/common/cpu.c @@ -20,7 +20,6 @@ #define DBG_LVL DBG_INFO #include - #ifdef RT_USING_SMP #define REPORT_ERR(retval) LOG_E("got error code %d in %s(), %s:%d", (retval), __func__, __FILE__, __LINE__) diff --git a/libcpu/aarch64/common/cpu.h b/libcpu/aarch64/common/cpu.h deleted file mode 100644 index 81a880c433..0000000000 --- a/libcpu/aarch64/common/cpu.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef __RT_HW_CPU_H__ -#define __RT_HW_CPU_H__ - -#include -#include -#include - -#ifdef RT_USING_OFW -#include -#endif - -#define ID_ERROR __INT64_MAX__ -#define MPIDR_AFFINITY_MASK 0x000000ff00ffffffUL - -struct cpu_ops_t -{ - const char *method; - int (*cpu_init)(rt_uint32_t id, void *param); - int (*cpu_boot)(rt_uint32_t id, rt_uint64_t entry); - void (*cpu_shutdown)(void); -}; -#define sysreg_32(op1, crn, crm, op2) s3_##op1 ##_##crn ##_##crm ##_##op2 -#define sysreg_64(op1, crn, crm, op2) sysreg_32(op1, crn, crm, op2) - -#define MPIDR_AFFINITY_MASK 0x000000ff00ffffffUL - -#define MPIDR_LEVEL_BITS_SHIFT 3 -#define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT) -#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) -#define MPIDR_LEVEL_SHIFT(level) (((1 << (level)) >> 1) << MPIDR_LEVEL_BITS_SHIFT) - -#define MPIDR_AFFINITY_LEVEL(mpidr, level) (((mpidr) >> MPIDR_LEVEL_SHIFT(level)) & MPIDR_LEVEL_MASK) - -/* GIC registers */ -#define ICC_IAR0_SYS sysreg_64(0, c12, c8, 0) -#define ICC_IAR1_SYS sysreg_64(0, c12, c12, 0) -#define ICC_EOIR0_SYS sysreg_64(0, c12, c8, 1) -#define ICC_EOIR1_SYS sysreg_64(0, c12, c12, 1) -#define ICC_HPPIR0_SYS sysreg_64(0, c12, c8, 2) -#define ICC_HPPIR1_SYS sysreg_64(0, c12, c12, 2) -#define ICC_BPR0_SYS sysreg_64(0, c12, c8, 3) -#define ICC_BPR1_SYS sysreg_64(0, c12, c12, 3) -#define ICC_DIR_SYS sysreg_64(0, c12, c11, 1) -#define ICC_PMR_SYS sysreg_64(0, c4, c6, 0) -#define ICC_RPR_SYS sysreg_64(0, c12, c11, 3) -#define ICC_CTLR_SYS sysreg_64(0, c12, c12, 4) -#define ICC_SRE_SYS sysreg_64(0, c12, c12, 5) -#define ICC_IGRPEN0_SYS sysreg_64(0, c12, c12, 6) -#define ICC_IGRPEN1_SYS sysreg_64(0, c12, c12, 7) -#define ICC_SGI0R_SYS sysreg_64(0, c12, c11, 7) -#define ICC_SGI1R_SYS sysreg_64(0, c12, c11, 5) -#define ICC_ASGI1R_SYS sysreg_64(0, c12, c11, 6) - -/* Arch timer registers */ -#define CNTP_CTL CNTP_CTL_EL0 /* EL1 Physical Timer */ -#define CNTHP_CTL CNTHP_CTL_EL2 /* EL2 Non-secure Physical Timer */ -#define CNTHPS_CTL CNTHPS_CTL_EL2 /* EL2 Secure Physical Timer */ -#define CNTPS_CTL CNTPS_CTL_EL1 /* EL3 Physical Timer */ -#define CNTV_CTL CNTV_CTL_EL0 /* EL1 Virtual Timer */ -#define CNTHV_CTL CNTHV_CTL_EL2 /* EL2 Non-secure Virtual Timer */ -#define CNTHVS_CTL CNTHVS_CTL_EL2 /* EL2 Secure Virtual Timer */ - -#define CNTP_CVAL CNTP_CVAL_EL0 -#define CNTHP_CVAL CNTHP_CVAL_EL2 -#define CNTHPS_CVAL CNTHPS_CVAL_EL2 -#define CNTPS_CVAL CNTPS_CVAL_EL1 -#define CNTV_CVAL CNTV_CVAL_EL0 -#define CNTHV_CVAL CNTHV_CVAL_EL2 -#define CNTHVS_CVAL CNTHVS_CVAL_EL2 - -#define CNTP_TVAL CNTP_TVAL_EL0 -#define CNTHP_TVAL CNTHP_TVAL_EL2 -#define CNTHPS_TVAL CNTHPS_TVAL_EL2 -#define CNTPS_TVAL CNTPS_TVAL_EL1 -#define CNTV_TVAL CNTV_TVAL_EL0 -#define CNTHV_TVAL CNTHV_TVAL_EL2 -#define CNTHVS_TVAL CNTHVS_TVAL_EL2 - -#define CNTPCT CNTPCT_EL0 -#define CNTVCT CNTVCT_EL0 -#define CNTFRQ CNTFRQ_EL0 -extern rt_uint64_t rt_cpu_mpidr_table[]; - -#endif /* __RT_HW_CPU_H__ */ diff --git a/libcpu/aarch64/common/cpu_gcc.S b/libcpu/aarch64/common/cpu_gcc.S index e0e6544eb9..ab15f4c241 100644 --- a/libcpu/aarch64/common/cpu_gcc.S +++ b/libcpu/aarch64/common/cpu_gcc.S @@ -4,87 +4,248 @@ * SPDX-License-Identifier: Apache-2.0 * * Date Author Notes - * 2018-10-06 ZhaoXiaowei the first version - * 2024-04-28 Shell add generic spinlock implementation + * 2018-10-06 ZhaoXiaowei the first version (cpu_gcc.S) + * 2021-05-18 Jesven the first version (context_gcc.S) + * 2024-01-06 Shell Fix barrier on irq_disable/enable + * 2024-01-18 Shell fix implicit dependency of cpuid management + * 2024-03-28 Shell Move cpu codes from context_gcc.S */ +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "rtconfig.h" +#include "asm-generic.h" +#include "asm-fpu.h" +#include "armv8.h" + +#ifdef RT_USING_SMP +#define rt_hw_interrupt_disable rt_hw_local_irq_disable +#define rt_hw_interrupt_enable rt_hw_local_irq_enable +#endif /* RT_USING_SMP */ + .text + +/** + * #ifdef RT_USING_OFW + * void rt_hw_cpu_id_set(long cpuid) + * #else + * void rt_hw_cpu_id_set(void) + * #endif + */ +.type rt_hw_cpu_id_set, @function +rt_hw_cpu_id_set: +#ifdef ARCH_USING_GENERIC_CPUID + .globl rt_hw_cpu_id_set +#else /* !ARCH_USING_GENERIC_CPUID */ + .weak rt_hw_cpu_id_set +#endif /* ARCH_USING_GENERIC_CPUID */ + +#ifndef RT_USING_OFW + mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */ +#ifdef ARCH_ARM_CORTEX_A55 + lsr x0, x0, #8 +#endif /* ARCH_ARM_CORTEX_A55 */ + and x0, x0, #15 +#endif /* !RT_USING_OFW */ + +#ifdef ARCH_USING_HW_THREAD_SELF + msr tpidrro_el0, x0 +#else /* !ARCH_USING_HW_THREAD_SELF */ + msr tpidr_el1, x0 +#endif /* ARCH_USING_HW_THREAD_SELF */ + ret + +/* +int rt_hw_cpu_id(void) +*/ +.type rt_hw_cpu_id, @function +rt_hw_cpu_id: +#ifdef ARCH_USING_GENERIC_CPUID + .globl rt_hw_cpu_id +#else /* !ARCH_USING_GENERIC_CPUID */ + .weak rt_hw_cpu_id +#endif /* ARCH_USING_GENERIC_CPUID */ + +#if RT_CPUS_NR > 1 + #ifdef ARCH_USING_GENERIC_CPUID + mrs x0, tpidrro_el0 + #else /* !ARCH_USING_GENERIC_CPUID */ + mrs x0, tpidr_el1 + #endif /* ARCH_USING_GENERIC_CPUID */ +#else /* RT_CPUS_NR == 1 */ + mov x0, xzr +#endif + ret + +/* +void rt_hw_set_process_id(size_t id) +*/ +.global rt_hw_set_process_id +rt_hw_set_process_id: + msr CONTEXTIDR_EL1, x0 + ret + +/* + *enable gtimer + */ +.globl rt_hw_gtimer_enable +rt_hw_gtimer_enable: + mov x0, #1 + msr CNTP_CTL_EL0, x0 + ret + +/* + *set gtimer CNTP_TVAL_EL0 value + */ +.globl rt_hw_set_gtimer_val +rt_hw_set_gtimer_val: + msr CNTP_TVAL_EL0, x0 + ret + +/* + *get gtimer CNTP_TVAL_EL0 value + */ +.globl rt_hw_get_gtimer_val +rt_hw_get_gtimer_val: + mrs x0, CNTP_TVAL_EL0 + ret + + +.globl rt_hw_get_cntpct_val +rt_hw_get_cntpct_val: + mrs x0, CNTPCT_EL0 + ret + +/* + *get gtimer frq value + */ +.globl rt_hw_get_gtimer_frq +rt_hw_get_gtimer_frq: + mrs x0, CNTFRQ_EL0 + ret + +.global rt_hw_interrupt_is_disabled +rt_hw_interrupt_is_disabled: + mrs x0, DAIF + tst x0, #0xc0 + cset x0, NE + ret + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mrs x0, DAIF + and x0, x0, #0xc0 + cmp x0, #0xc0 + /* branch if bits not both set(zero) */ + bne 1f + ret +1: + msr DAIFSet, #3 + dsb nsh + isb + ret + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + and x0, x0, #0xc0 + cmp x0, #0xc0 + /* branch if one of the bits not set(zero) */ + bne 1f + ret +1: + isb + dsb nsh + and x0, x0, #0xc0 + mrs x1, DAIF + bic x1, x1, #0xc0 + orr x0, x0, x1 + msr DAIF, x0 + ret + .globl rt_hw_get_current_el rt_hw_get_current_el: - MRS X0, CurrentEL - CMP X0, 0xc - B.EQ 3f - CMP X0, 0x8 - B.EQ 2f - CMP X0, 0x4 - B.EQ 1f - - LDR X0, =0 - B 0f + mrs x0, CurrentEL + cmp x0, 0xc + b.eq 3f + cmp x0, 0x8 + b.eq 2f + cmp x0, 0x4 + b.eq 1f + + ldr x0, =0 + b 0f 3: - LDR X0, =3 - B 0f + ldr x0, =3 + b 0f 2: - LDR X0, =2 - B 0f + ldr x0, =2 + b 0f 1: - LDR X0, =1 - B 0f + ldr x0, =1 + b 0f 0: - RET + ret .globl rt_hw_set_current_vbar rt_hw_set_current_vbar: - MRS X1, CurrentEL - CMP X1, 0xc - B.EQ 3f - CMP X1, 0x8 - B.EQ 2f - CMP X1, 0x4 - B.EQ 1f - B 0f + mrs x1, CurrentEL + cmp x1, 0xc + b.eq 3f + cmp x1, 0x8 + b.eq 2f + cmp x1, 0x4 + b.eq 1f + b 0f 3: - MSR VBAR_EL3,X0 - B 0f + msr VBAR_EL3,x0 + b 0f 2: - MSR VBAR_EL2,X0 - B 0f + msr VBAR_EL2,x0 + b 0f 1: - MSR VBAR_EL1,X0 - B 0f + msr VBAR_EL1,x0 + b 0f 0: - RET + ret .globl rt_hw_set_elx_env rt_hw_set_elx_env: - MRS X1, CurrentEL - CMP X1, 0xc - B.EQ 3f - CMP X1, 0x8 - B.EQ 2f - CMP X1, 0x4 - B.EQ 1f - B 0f + mrs x1, CurrentEL + cmp x1, 0xc + b.eq 3f + cmp x1, 0x8 + b.eq 2f + cmp x1, 0x4 + b.eq 1f + b 0f 3: - MRS X0, SCR_EL3 - ORR X0, X0, #0xF /* SCR_EL3.NS|IRQ|FIQ|EA */ - MSR SCR_EL3, X0 - B 0f + mrs x0, SCR_EL3 + orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */ + msr SCR_EL3, x0 + b 0f 2: - MRS X0, HCR_EL2 - ORR X0, X0, #0x38 - MSR HCR_EL2, X0 - B 0f + mrs x0, HCR_EL2 + orr x0, x0, #0x38 + msr HCR_EL2, x0 + b 0f 1: - B 0f + b 0f 0: - RET + ret .globl rt_cpu_vector_set_base rt_cpu_vector_set_base: - MSR VBAR_EL1,X0 - RET + msr VBAR_EL1, x0 + ret /** diff --git a/libcpu/aarch64/common/cpu_ops_common.h b/libcpu/aarch64/common/cpu_ops_common.h deleted file mode 100644 index 5e47584c7b..0000000000 --- a/libcpu/aarch64/common/cpu_ops_common.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __CPU_OPS_COMMON_H__ -#define __CPU_OPS_COMMON_H__ - -#include -#include -#include -#include "entry_point.h" - -static inline rt_uint64_t get_secondary_entry_pa(void) -{ - rt_uint64_t secondary_entry_pa = (rt_uint64_t)rt_kmem_v2p(_secondary_cpu_entry); - - if (!secondary_entry_pa) - { - LOG_E("Failed to translate 'secondary_entry_pa' to physical address"); - return 0; - } - return secondary_entry_pa; -} - -#endif /* __CPU_OPS_COMMON_H__ */ \ No newline at end of file diff --git a/libcpu/aarch64/common/cpuport.h b/libcpu/aarch64/common/cpuport.h deleted file mode 100644 index 217f477aaf..0000000000 --- a/libcpu/aarch64/common/cpuport.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-10-25 Shell Move ffs to cpuport, add general implementation - * by inline assembly - * 2024-01-18 Shell support rt_hw_thread_self to improve overall performance - */ - -#ifndef CPUPORT_H__ -#define CPUPORT_H__ - -#include -#include -#include - -#ifdef RT_USING_SMP - -/** - * Spinlock - */ - -typedef struct -{ - rt_uint32_t value; -} rt_hw_spinlock_t; - -#endif /* RT_USING_SMP */ - -#define rt_hw_barrier(cmd, ...) \ - __asm__ volatile (RT_STRINGIFY(cmd) " "RT_STRINGIFY(__VA_ARGS__):::"memory") - -#define rt_hw_isb() rt_hw_barrier(isb) -#define rt_hw_dmb() rt_hw_barrier(dmb, ish) -#define rt_hw_wmb() rt_hw_barrier(dmb, ishst) -#define rt_hw_rmb() rt_hw_barrier(dmb, ishld) -#define rt_hw_dsb() rt_hw_barrier(dsb, ish) - -#define rt_hw_wfi() rt_hw_barrier(wfi) -#define rt_hw_wfe() rt_hw_barrier(wfe) -#define rt_hw_sev() rt_hw_barrier(sev) - -#define rt_hw_cpu_relax() rt_hw_barrier(yield) - -#define rt_hw_sysreg_write(sysreg, val) \ - __asm__ volatile ("msr "RT_STRINGIFY(sysreg)", %0"::"r"((rt_uint64_t)(val))) - -#define rt_hw_sysreg_read(sysreg, val) \ - __asm__ volatile ("mrs %0, "RT_STRINGIFY(sysreg)"":"=r"((val))) - -void _thread_start(void); - -#ifdef RT_USING_CPU_FFS -/** - * This function finds the first bit set (beginning with the least significant bit) - * in value and return the index of that bit. - * - * Bits are numbered starting at 1 (the least significant bit). A return value of - * zero from any of these functions means that the argument was zero. - * - * @return return the index of the first bit set. If value is 0, then this function - * shall return 0. - */ -rt_inline int __rt_ffs(int value) -{ -#ifdef __GNUC__ - return __builtin_ffs(value); -#else - __asm__ volatile ( - "rbit w1, %w0\n" - "cmp %w0, 0\n" - "clz w1, w1\n" - "csinc %w0, wzr, w1, eq\n" - : "=r"(value) - : "0"(value) - ); - return value; -#endif -} - -#endif /* RT_USING_CPU_FFS */ - -#ifdef ARCH_USING_HW_THREAD_SELF -rt_inline struct rt_thread *rt_hw_thread_self(void) -{ - struct rt_thread *thread; - __asm__ volatile ("mrs %0, tpidr_el1":"=r"(thread)); - - return thread; -} - -rt_inline void rt_hw_thread_set_self(struct rt_thread *thread) -{ - __asm__ volatile ("msr tpidr_el1, %0"::"r"(thread)); -} - -#endif /* ARCH_USING_HW_THREAD_SELF */ - -#endif /*CPUPORT_H__*/ diff --git a/libcpu/aarch64/common/entry_point.h b/libcpu/aarch64/common/entry_point.h deleted file mode 100644 index fc3e6c061f..0000000000 --- a/libcpu/aarch64/common/entry_point.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef __ENTRY_POINT_H__ -#define __ENTRY_POINT_H__ - -extern void _secondary_cpu_entry(void); -#endif /* __ENTRY_POINT_H__ */ \ No newline at end of file diff --git a/libcpu/aarch64/common/gic.h b/libcpu/aarch64/common/gic.h deleted file mode 100644 index 4cdcb44028..0000000000 --- a/libcpu/aarch64/common/gic.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - */ - -#ifndef __GIC_H__ -#define __GIC_H__ - -#include -#include - -int arm_gic_get_active_irq(rt_uint64_t index); -void arm_gic_ack(rt_uint64_t index, int irq); - -void arm_gic_mask(rt_uint64_t index, int irq); -void arm_gic_umask(rt_uint64_t index, int irq); - -rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq); -void arm_gic_set_pending_irq(rt_uint64_t index, int irq); -void arm_gic_clear_pending_irq(rt_uint64_t index, int irq); - -void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config); -rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq); - -void arm_gic_clear_active(rt_uint64_t index, int irq); - -void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask); -rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq); - -void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority); -rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq); - -void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority); -rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index); - -void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point); -rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index); - -rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq); - -void arm_gic_send_sgi(rt_uint64_t index, int irq, rt_uint64_t target_list, rt_uint64_t filter_list); - -rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index); - -rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index); - -void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group); -rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq); - -int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start); -int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base); - -void arm_gic_dump_type(rt_uint64_t index); -void arm_gic_dump(rt_uint64_t index); - -#endif - diff --git a/libcpu/aarch64/common/gicv3.h b/libcpu/aarch64/common/gicv3.h deleted file mode 100644 index d449774c5f..0000000000 --- a/libcpu/aarch64/common/gicv3.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - * 2014-04-03 Grissiom many enhancements - * 2018-11-22 Jesven add rt_hw_ipi_send() - * add rt_hw_ipi_handler_install() - */ - -#ifndef __GICV3_H__ -#define __GICV3_H__ - -#include - -#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) - - -#ifndef ARM_GIC_CPU_NUM -#define ARM_GIC_CPU_NUM RT_CPUS_NR -#endif - -#define GICV3_ROUTED_TO_ALL 1UL -#define GICV3_ROUTED_TO_SPEC 0UL -#define GET_GICV3_REG(reg, out) __asm__ volatile ("mrs %0, " reg:"=r"(out)::"memory"); -#define SET_GICV3_REG(reg, in) __asm__ volatile ("msr " reg ", %0"::"r"(in):"memory"); - -/* AArch64 System register interface to GICv3 */ -#define ICC_IAR0_EL1 "S3_0_C12_C8_0" -#define ICC_IAR1_EL1 "S3_0_C12_C12_0" -#define ICC_EOIR0_EL1 "S3_0_C12_C8_1" -#define ICC_EOIR1_EL1 "S3_0_C12_C12_1" -#define ICC_HPPIR0_EL1 "S3_0_C12_C8_2" -#define ICC_HPPIR1_EL1 "S3_0_C12_C12_2" -#define ICC_BPR0_EL1 "S3_0_C12_C8_3" -#define ICC_BPR1_EL1 "S3_0_C12_C12_3" -#define ICC_DIR_EL1 "S3_0_C12_C11_1" -#define ICC_PMR_EL1 "S3_0_C4_C6_0" -#define ICC_RPR_EL1 "S3_0_C12_C11_3" -#define ICC_CTLR_EL1 "S3_0_C12_C12_4" -#define ICC_CTLR_EL3 "S3_6_C12_C12_4" -#define ICC_SRE_EL1 "S3_0_C12_C12_5" -#define ICC_SRE_EL2 "S3_4_C12_C9_5" -#define ICC_SRE_EL3 "S3_6_C12_C12_5" -#define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6" -#define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7" -#define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7" -#define ICC_SGI0R_EL1 "S3_0_C12_C11_7" -#define ICC_SGI1R_EL1 "S3_0_C12_C11_5" -#define ICC_ASGI1R_EL1 "S3_0_C12_C11_6" - -/* Macro to access the Distributor Control Register (GICD_CTLR) */ -#define GICD_CTLR_RWP (1U << 31) -#define GICD_CTLR_E1NWF (1U << 7) -#define GICD_CTLR_DS (1U << 6) -#define GICD_CTLR_ARE_NS (1U << 5) -#define GICD_CTLR_ARE_S (1U << 4) -#define GICD_CTLR_ENGRP1S (1U << 2) -#define GICD_CTLR_ENGRP1NS (1U << 1) -#define GICD_CTLR_ENGRP0 (1U << 0) - -/* Macro to access the Redistributor Control Register (GICR_CTLR) */ -#define GICR_CTLR_UWP (1U << 31) -#define GICR_CTLR_DPG1S (1U << 26) -#define GICR_CTLR_DPG1NS (1U << 25) -#define GICR_CTLR_DPG0 (1U << 24) -#define GICR_CTLR_RWP (1U << 3) -#define GICR_CTLR_IR (1U << 2) -#define GICR_CTLR_CES (1U << 1) -#define GICR_CTLR_EnableLPI (1U << 0) - -/* Macro to access the Generic Interrupt Controller Interface (GICC) */ -#define GIC_CPU_CTRL(hw_base) HWREG32((hw_base) + 0x00U) -#define GIC_CPU_PRIMASK(hw_base) HWREG32((hw_base) + 0x04U) -#define GIC_CPU_BINPOINT(hw_base) HWREG32((hw_base) + 0x08U) -#define GIC_CPU_INTACK(hw_base) HWREG32((hw_base) + 0x0cU) -#define GIC_CPU_EOI(hw_base) HWREG32((hw_base) + 0x10U) -#define GIC_CPU_RUNNINGPRI(hw_base) HWREG32((hw_base) + 0x14U) -#define GIC_CPU_HIGHPRI(hw_base) HWREG32((hw_base) + 0x18U) -#define GIC_CPU_IIDR(hw_base) HWREG32((hw_base) + 0xFCU) - -/* Macro to access the Generic Interrupt Controller Distributor (GICD) */ -#define GIC_DIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U) -#define GIC_DIST_TYPE(hw_base) HWREG32((hw_base) + 0x004U) -#define GIC_DIST_IIDR(hw_base) HWREG32((hw_base) + 0x008U) -#define GIC_DIST_IGROUP(hw_base, n) HWREG32((hw_base) + 0x080U + ((n) / 32U) * 4U) -#define GIC_DIST_ENABLE_SET(hw_base, n) HWREG32((hw_base) + 0x100U + ((n) / 32U) * 4U) -#define GIC_DIST_ENABLE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x180U + ((n) / 32U) * 4U) -#define GIC_DIST_PENDING_SET(hw_base, n) HWREG32((hw_base) + 0x200U + ((n) / 32U) * 4U) -#define GIC_DIST_PENDING_CLEAR(hw_base, n) HWREG32((hw_base) + 0x280U + ((n) / 32U) * 4U) -#define GIC_DIST_ACTIVE_SET(hw_base, n) HWREG32((hw_base) + 0x300U + ((n) / 32U) * 4U) -#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x380U + ((n) / 32U) * 4U) -#define GIC_DIST_PRI(hw_base, n) HWREG32((hw_base) + 0x400U + ((n) / 4U) * 4U) -#define GIC_DIST_TARGET(hw_base, n) HWREG32((hw_base) + 0x800U + ((n) / 4U) * 4U) -#define GIC_DIST_CONFIG(hw_base, n) HWREG32((hw_base) + 0xc00U + ((n) / 16U) * 4U) -#define GIC_DIST_SOFTINT(hw_base) HWREG32((hw_base) + 0xf00U) -#define GIC_DIST_CPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf10U + ((n) / 4U) * 4U) -#define GIC_DIST_SPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf20U + ((n) / 4U) * 4U) -#define GIC_DIST_ICPIDR2(hw_base) HWREG32((hw_base) + 0xfe8U) -#define GIC_DIST_IROUTER(hw_base, n) HWREG64((hw_base) + 0x6000U + (n) * 8U) - -/* SGI base address is at 64K offset from Redistributor base address */ -#define GIC_RSGI_OFFSET 0x10000 - -/* Macro to access the Generic Interrupt Controller Redistributor (GICR) */ -#define GIC_RDIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U) -#define GIC_RDIST_IIDR(hw_base) HWREG32((hw_base) + 0x004U) -#define GIC_RDIST_TYPER(hw_base) HWREG64((hw_base) + 0x008U) -#define GIC_RDIST_TSTATUSR(hw_base) HWREG32((hw_base) + 0x010U) -#define GIC_RDIST_WAKER(hw_base) HWREG32((hw_base) + 0x014U) -#define GIC_RDIST_SETLPIR(hw_base) HWREG32((hw_base) + 0x040U) -#define GIC_RDIST_CLRLPIR(hw_base) HWREG32((hw_base) + 0x048U) -#define GIC_RDIST_PROPBASER(hw_base) HWREG32((hw_base) + 0x070U) -#define GIC_RDIST_PENDBASER(hw_base) HWREG32((hw_base) + 0x078U) -#define GIC_RDIST_INVLPIR(hw_base) HWREG32((hw_base) + 0x0A0U) -#define GIC_RDIST_INVALLR(hw_base) HWREG32((hw_base) + 0x0B0U) -#define GIC_RDIST_SYNCR(hw_base) HWREG32((hw_base) + 0x0C0U) - -#define GIC_RDISTSGI_IGROUPR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x080U + (n) * 4U) -#define GIC_RDISTSGI_ISENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x100U) -#define GIC_RDISTSGI_ICENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x180U) -#define GIC_RDISTSGI_ISPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x200U) -#define GIC_RDISTSGI_ICPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x280U) -#define GIC_RDISTSGI_ISACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x300U) -#define GIC_RDISTSGI_ICACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x380U) -#define GIC_RDISTSGI_IPRIORITYR(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x400U + ((n) / 4U) * 4U) -#define GIC_RDISTSGI_ICFGR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC00U) -#define GIC_RDISTSGI_ICFGR1(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC04U) -#define GIC_RDISTSGI_IGRPMODR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xD00U + (n) * 4) -#define GIC_RDISTSGI_NSACR(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U) - -struct arm_gic -{ - rt_uint64_t offset; /* the first interrupt index in the vector table */ - rt_uint64_t redist_hw_base[ARM_GIC_CPU_NUM]; /* the pointer of the gic redistributor */ - rt_uint64_t dist_hw_base; /* the base address of the gic distributor */ - rt_uint64_t cpu_hw_base[ARM_GIC_CPU_NUM]; /* the base address of the gic cpu interface */ -}; - -int arm_gic_get_active_irq(rt_uint64_t index); -void arm_gic_ack(rt_uint64_t index, int irq); - -void arm_gic_mask(rt_uint64_t index, int irq); -void arm_gic_umask(rt_uint64_t index, int irq); - -rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq); -void arm_gic_set_pending_irq(rt_uint64_t index, int irq); -void arm_gic_clear_pending_irq(rt_uint64_t index, int irq); - -void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config); -rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq); - -void arm_gic_clear_active(rt_uint64_t index, int irq); - -void arm_gic_set_router_cpu(rt_uint64_t index, int irq, rt_uint64_t aff); -void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask); -rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq); - -void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority); -rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq); - -void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority); -rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index); - -void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point); -rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index); - -rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq); - -#if defined(RT_USING_SMP) || defined(RT_USING_AMP) -void arm_gic_send_affinity_sgi(rt_uint64_t index, int irq, rt_uint32_t cpu_masks[], rt_uint64_t routing_mode); -#endif - -rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index); - -rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index); - -void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group); -rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq); - -int arm_gic_redist_address_set(rt_uint64_t index, rt_uint64_t redist_addr, int cpu_id); -int arm_gic_cpu_interface_address_set(rt_uint64_t index, rt_uint64_t interface_addr, int cpu_id); - -int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start); -int arm_gic_redist_init(rt_uint64_t index, rt_uint64_t redist_base); -int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base); - -rt_uint64_t *arm_gic_get_gic_table_addr(void); -void arm_gic_dump_type(rt_uint64_t index); -void arm_gic_dump(rt_uint64_t index); - -#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) */ - -#endif - diff --git a/libcpu/aarch64/common/gtimer.h b/libcpu/aarch64/common/gtimer.h deleted file mode 100644 index 83a0d53165..0000000000 --- a/libcpu/aarch64/common/gtimer.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-20 GuEe-GUI first version - */ - -#ifndef __GTIMER_H__ -#define __GTIMER_H__ - -#include - -void rt_hw_gtimer_init(void); -void rt_hw_gtimer_local_enable(void); -void rt_hw_gtimer_local_disable(void); - -void rt_hw_gtimer_enable(); - -rt_inline void rt_hw_gtimer_disable(void) -{ - __asm__ volatile ("msr CNTP_CTL_EL0, xzr":::"memory"); -} - -void rt_hw_set_gtimer_val(rt_uint64_t value); -rt_uint64_t rt_hw_get_gtimer_val(); -rt_uint64_t rt_hw_get_cntpct_val(); -rt_uint64_t rt_hw_get_gtimer_frq(); -rt_uint64_t rt_hw_set_gtimer_frq(rt_uint64_t value); - -#endif /* __GTIMER_H__ */ diff --git a/libcpu/aarch64/common/hypercall.h b/libcpu/aarch64/common/hypercall.h deleted file mode 100644 index e9599d7f78..0000000000 --- a/libcpu/aarch64/common/hypercall.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2006-2020, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-02-24 GuEe-GUI first version - */ - -#ifndef __HYPERCALL_H__ -#define __HYPERCALL_H__ - -#include - -rt_inline rt_uint32_t rt_hw_hypercall(rt_uint32_t w0, rt_uint64_t x1, rt_uint64_t x2, - rt_uint64_t x3, rt_uint64_t x4, rt_uint64_t x5, rt_uint64_t x6, rt_uint32_t w7) -{ - register rt_uint64_t ret __asm__ ("x0"); - __asm__ volatile ("hvc #0"); - - return (rt_uint32_t)ret; -} - -rt_err_t rt_hv_stage2_map(unsigned long paddr, unsigned long size); - -#endif diff --git a/libcpu/aarch64/common/include/armv8.h b/libcpu/aarch64/common/include/armv8.h new file mode 100644 index 0000000000..5f64f03090 --- /dev/null +++ b/libcpu/aarch64/common/include/armv8.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + */ + +#ifndef __ARMV8_H__ +#define __ARMV8_H__ + +#ifdef __ASSEMBLY__ + +/********************* + * CONTEXT_OFFSET * + *********************/ + +#define CONTEXT_OFFSET_ELR_EL1 0x0 +#define CONTEXT_OFFSET_SPSR_EL1 0x8 +#define CONTEXT_OFFSET_SP_EL0 0x10 +#define CONTEXT_OFFSET_X30 0x18 +#define CONTEXT_OFFSET_FPCR 0x20 +#define CONTEXT_OFFSET_FPSR 0x28 +#define CONTEXT_OFFSET_X28 0x30 +#define CONTEXT_OFFSET_X29 0x38 +#define CONTEXT_OFFSET_X26 0x40 +#define CONTEXT_OFFSET_X27 0x48 +#define CONTEXT_OFFSET_X24 0x50 +#define CONTEXT_OFFSET_X25 0x58 +#define CONTEXT_OFFSET_X22 0x60 +#define CONTEXT_OFFSET_X23 0x68 +#define CONTEXT_OFFSET_X20 0x70 +#define CONTEXT_OFFSET_X21 0x78 +#define CONTEXT_OFFSET_X18 0x80 +#define CONTEXT_OFFSET_X19 0x88 +#define CONTEXT_OFFSET_X16 0x90 +#define CONTEXT_OFFSET_X17 0x98 +#define CONTEXT_OFFSET_X14 0xa0 +#define CONTEXT_OFFSET_X15 0xa8 +#define CONTEXT_OFFSET_X12 0xb0 +#define CONTEXT_OFFSET_X13 0xb8 +#define CONTEXT_OFFSET_X10 0xc0 +#define CONTEXT_OFFSET_X11 0xc8 +#define CONTEXT_OFFSET_X8 0xd0 +#define CONTEXT_OFFSET_X9 0xd8 +#define CONTEXT_OFFSET_X6 0xe0 +#define CONTEXT_OFFSET_X7 0xe8 +#define CONTEXT_OFFSET_X4 0xf0 +#define CONTEXT_OFFSET_X5 0xf8 +#define CONTEXT_OFFSET_X2 0x100 +#define CONTEXT_OFFSET_X3 0x108 +#define CONTEXT_OFFSET_X0 0x110 +#define CONTEXT_OFFSET_X1 0x118 + +#define CONTEXT_OFFSET_Q31 0x120 +#define CONTEXT_OFFSET_Q30 0x130 +#define CONTEXT_OFFSET_Q29 0x140 +#define CONTEXT_OFFSET_Q28 0x150 +#define CONTEXT_OFFSET_Q27 0x160 +#define CONTEXT_OFFSET_Q26 0x170 +#define CONTEXT_OFFSET_Q25 0x180 +#define CONTEXT_OFFSET_Q24 0x190 +#define CONTEXT_OFFSET_Q23 0x1a0 +#define CONTEXT_OFFSET_Q22 0x1b0 +#define CONTEXT_OFFSET_Q21 0x1c0 +#define CONTEXT_OFFSET_Q20 0x1d0 +#define CONTEXT_OFFSET_Q19 0x1e0 +#define CONTEXT_OFFSET_Q18 0x1f0 +#define CONTEXT_OFFSET_Q17 0x200 +#define CONTEXT_OFFSET_Q16 0x210 +#define CONTEXT_OFFSET_Q15 0x220 +#define CONTEXT_OFFSET_Q14 0x230 +#define CONTEXT_OFFSET_Q13 0x240 +#define CONTEXT_OFFSET_Q12 0x250 +#define CONTEXT_OFFSET_Q11 0x260 +#define CONTEXT_OFFSET_Q10 0x270 +#define CONTEXT_OFFSET_Q9 0x280 +#define CONTEXT_OFFSET_Q8 0x290 +#define CONTEXT_OFFSET_Q7 0x2a0 +#define CONTEXT_OFFSET_Q6 0x2b0 +#define CONTEXT_OFFSET_Q5 0x2c0 +#define CONTEXT_OFFSET_Q4 0x2d0 +#define CONTEXT_OFFSET_Q3 0x2e0 +#define CONTEXT_OFFSET_Q2 0x2f0 +#define CONTEXT_OFFSET_Q1 0x300 +#define CONTEXT_OFFSET_Q0 0x310 + +#define CONTEXT_FPU_SIZE (32 * 16) +#define CONTEXT_SIZE (0x120 + CONTEXT_FPU_SIZE) + +#else /* !__ASSEMBLY__ */ + +#include + +typedef struct { rt_uint64_t value[2]; } rt_uint128_t; + +/* the exception stack without VFP registers */ +struct rt_hw_exp_stack +{ + rt_uint64_t pc; + rt_uint64_t cpsr; + rt_uint64_t sp_el0; + rt_uint64_t x30; + rt_uint64_t fpcr; + rt_uint64_t fpsr; + rt_uint64_t x28; + rt_uint64_t x29; + rt_uint64_t x26; + rt_uint64_t x27; + rt_uint64_t x24; + rt_uint64_t x25; + rt_uint64_t x22; + rt_uint64_t x23; + rt_uint64_t x20; + rt_uint64_t x21; + rt_uint64_t x18; + rt_uint64_t x19; + rt_uint64_t x16; + rt_uint64_t x17; + rt_uint64_t x14; + rt_uint64_t x15; + rt_uint64_t x12; + rt_uint64_t x13; + rt_uint64_t x10; + rt_uint64_t x11; + rt_uint64_t x8; + rt_uint64_t x9; + rt_uint64_t x6; + rt_uint64_t x7; + rt_uint64_t x4; + rt_uint64_t x5; + rt_uint64_t x2; + rt_uint64_t x3; + rt_uint64_t x0; + rt_uint64_t x1; + + rt_uint128_t fpu[32]; +}; + +#define SP_ELx ((unsigned long)0x01) +#define SP_EL0 ((unsigned long)0x00) +#define PSTATE_EL1 ((unsigned long)0x04) +#define PSTATE_EL2 ((unsigned long)0x08) +#define PSTATE_EL3 ((unsigned long)0x0c) + +rt_ubase_t rt_hw_get_current_el(void); +void rt_hw_set_elx_env(void); +void rt_hw_set_current_vbar(rt_ubase_t addr); + +/* ESR:generic */ +#define ARM64_ABORT_WNR(esr) ((esr) & 0x40) +#define ARM64_ESR_EXTRACT_EC(esr) ((((esr) >> 26) & 0x3fU)) +#define ARM64_ESR_EXTRACT_FSC(esr) ((esr) & 0x3f) + +/* ESR:EC */ +#define ARM64_EC_INST_ABORT_FROM_LO_EXCEPTION (0b100000) +#define ARM64_EC_INST_ABORT_WITHOUT_A_CHANGE (0b100001) +#define ARM64_EC_DATA_ABORT_FROM_LO_EXCEPTION (0b100100) +#define ARM64_EC_DATA_ABORT_WITHOUT_A_CHANGE (0b100101) + +/* ESR:FSC */ +#define ARM64_FSC_TRANSLATION_FAULT_LEVEL_0 (0b000100) +#define ARM64_FSC_TRANSLATION_FAULT_LEVEL_1 (0b000101) +#define ARM64_FSC_TRANSLATION_FAULT_LEVEL_2 (0b000110) +#define ARM64_FSC_TRANSLATION_FAULT_LEVEL_3 (0b000111) +#define ARM64_FSC_PERMISSION_FAULT_LEVEL_0 (0b001100) +#define ARM64_FSC_PERMISSION_FAULT_LEVEL_1 (0b001101) +#define ARM64_FSC_PERMISSION_FAULT_LEVEL_2 (0b001110) +#define ARM64_FSC_PERMISSION_FAULT_LEVEL_3 (0b001111) +#define ARM64_FSC_ACCESS_FLAG_FAULT_LEVEL_0 (0b001000) +#define ARM64_FSC_ACCESS_FLAG_FAULT_LEVEL_1 (0b001001) +#define ARM64_FSC_ACCESS_FLAG_FAULT_LEVEL_2 (0b001010) +#define ARM64_FSC_ACCESS_FLAG_FAULT_LEVEL_3 (0b001011) + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/libcpu/aarch64/common/include/asm-fpu.h b/libcpu/aarch64/common/include/asm-fpu.h new file mode 100644 index 0000000000..956a2030bf --- /dev/null +++ b/libcpu/aarch64/common/include/asm-fpu.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-18 Jesven the first version + * 2023-07-13 GuEe-GUI append Q16 ~ Q31 + */ +#ifndef __ARM64_ASM_FPU_H__ +#define __ARM64_ASM_FPU_H__ + +.macro SAVE_FPU, reg + str q0, [\reg, #-0x10]! + str q1, [\reg, #-0x10]! + str q2, [\reg, #-0x10]! + str q3, [\reg, #-0x10]! + str q4, [\reg, #-0x10]! + str q5, [\reg, #-0x10]! + str q6, [\reg, #-0x10]! + str q7, [\reg, #-0x10]! + str q8, [\reg, #-0x10]! + str q9, [\reg, #-0x10]! + str q10, [\reg, #-0x10]! + str q11, [\reg, #-0x10]! + str q12, [\reg, #-0x10]! + str q13, [\reg, #-0x10]! + str q14, [\reg, #-0x10]! + str q15, [\reg, #-0x10]! + str q16, [\reg, #-0x10]! + str q17, [\reg, #-0x10]! + str q18, [\reg, #-0x10]! + str q19, [\reg, #-0x10]! + str q20, [\reg, #-0x10]! + str q21, [\reg, #-0x10]! + str q22, [\reg, #-0x10]! + str q23, [\reg, #-0x10]! + str q24, [\reg, #-0x10]! + str q25, [\reg, #-0x10]! + str q26, [\reg, #-0x10]! + str q27, [\reg, #-0x10]! + str q28, [\reg, #-0x10]! + str q29, [\reg, #-0x10]! + str q30, [\reg, #-0x10]! + str q31, [\reg, #-0x10]! +.endm +.macro RESTORE_FPU, reg + ldr q31, [\reg], #0x10 + ldr q30, [\reg], #0x10 + ldr q29, [\reg], #0x10 + ldr q28, [\reg], #0x10 + ldr q27, [\reg], #0x10 + ldr q26, [\reg], #0x10 + ldr q25, [\reg], #0x10 + ldr q24, [\reg], #0x10 + ldr q23, [\reg], #0x10 + ldr q22, [\reg], #0x10 + ldr q21, [\reg], #0x10 + ldr q20, [\reg], #0x10 + ldr q19, [\reg], #0x10 + ldr q18, [\reg], #0x10 + ldr q17, [\reg], #0x10 + ldr q16, [\reg], #0x10 + ldr q15, [\reg], #0x10 + ldr q14, [\reg], #0x10 + ldr q13, [\reg], #0x10 + ldr q12, [\reg], #0x10 + ldr q11, [\reg], #0x10 + ldr q10, [\reg], #0x10 + ldr q9, [\reg], #0x10 + ldr q8, [\reg], #0x10 + ldr q7, [\reg], #0x10 + ldr q6, [\reg], #0x10 + ldr q5, [\reg], #0x10 + ldr q4, [\reg], #0x10 + ldr q3, [\reg], #0x10 + ldr q2, [\reg], #0x10 + ldr q1, [\reg], #0x10 + ldr q0, [\reg], #0x10 +.endm + +#endif /* __ARM64_ASM_FPU_H__ */ diff --git a/libcpu/aarch64/common/include/asm-generic.h b/libcpu/aarch64/common/include/asm-generic.h new file mode 100644 index 0000000000..b6b5d48dcb --- /dev/null +++ b/libcpu/aarch64/common/include/asm-generic.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2006-2023 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-03-12 WangXiaoyao the first version + */ +#ifndef __ASM_GENERIC_H__ +#define __ASM_GENERIC_H__ + +/* use to mark a start point where every task start from */ +#define START_POINT(funcname) \ + .global funcname; \ + .type funcname, %function; \ + funcname: \ + .cfi_sections .debug_frame, .eh_frame; \ + .cfi_startproc; \ + .cfi_undefined x30 + +#define START_POINT_END(name) \ + .cfi_endproc; \ + .size name, .-name; + +#endif /* __ASM_GENERIC_H__ */ diff --git a/libcpu/aarch64/common/include/cache.h b/libcpu/aarch64/common/include/cache.h new file mode 100644 index 0000000000..ef7b235d0e --- /dev/null +++ b/libcpu/aarch64/common/include/cache.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-12-18 RT-Thread the first version + */ + +#ifndef __CACHE_H__ +#define __CACHE_H__ + +#include + +void __asm_invalidate_icache_all(void); + +void rt_hw_dcache_flush_all(void); +void rt_hw_dcache_invalidate_all(void); +void rt_hw_dcache_flush_range(unsigned long start_addr, unsigned long size); +void rt_hw_cpu_dcache_clean(void *addr, unsigned long size); +void rt_hw_cpu_dcache_invalidate(void *start_addr, unsigned long size); + +static inline void rt_hw_icache_invalidate_all(void) +{ + /* wait for previous modification to complete */ + __asm__ volatile ("dsb ishst"); + + __asm__ volatile ("ic ialluis"); + /* wait for ic to retire */ + __asm__ volatile ("dsb nsh"); + /* flush instruction pipeline */ + __asm__ volatile ("isb"); +} + +void rt_hw_cpu_icache_invalidate(void *addr, rt_size_t size); +void rt_hw_cpu_dcache_clean_and_invalidate(void *addr, rt_size_t size); + +#endif /* __CACHE_H__ */ diff --git a/libcpu/aarch64/common/include/context_gcc.h b/libcpu/aarch64/common/include/context_gcc.h new file mode 100644 index 0000000000..cf9f53786b --- /dev/null +++ b/libcpu/aarch64/common/include/context_gcc.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-03-28 Shell Move vector handling codes from context_gcc.S + */ +#ifndef __ARM64_INC_CONTEXT_H__ +#define __ARM64_INC_CONTEXT_H__ + +.macro SAVE_CONTEXT_SWITCH + /* Save the entire context. */ + SAVE_FPU sp + stp x0, x1, [sp, #-0x10]! + stp x2, x3, [sp, #-0x10]! + stp x4, x5, [sp, #-0x10]! + stp x6, x7, [sp, #-0x10]! + stp x8, x9, [sp, #-0x10]! + stp x10, x11, [sp, #-0x10]! + stp x12, x13, [sp, #-0x10]! + stp x14, x15, [sp, #-0x10]! + stp x16, x17, [sp, #-0x10]! + stp x18, x19, [sp, #-0x10]! + stp x20, x21, [sp, #-0x10]! + stp x22, x23, [sp, #-0x10]! + stp x24, x25, [sp, #-0x10]! + stp x26, x27, [sp, #-0x10]! + stp x28, x29, [sp, #-0x10]! + mrs x28, fpcr + mrs x29, fpsr + stp x28, x29, [sp, #-0x10]! + mrs x29, sp_el0 + stp x29, x30, [sp, #-0x10]! + + mov x19, #((3 << 6) | 0x4 | 0x1) /* el1h, disable interrupt */ + mov x18, x30 + + stp x18, x19, [sp, #-0x10]! +.endm + +.macro _RESTORE_CONTEXT_SWITCH + ldp x2, x3, [sp], #0x10 /* SPSR and ELR. */ + + tst x3, #0x1f + msr spsr_el1, x3 + msr elr_el1, x2 + + ldp x29, x30, [sp], #0x10 + msr sp_el0, x29 + ldp x28, x29, [sp], #0x10 + msr fpcr, x28 + msr fpsr, x29 + ldp x28, x29, [sp], #0x10 + ldp x26, x27, [sp], #0x10 + ldp x24, x25, [sp], #0x10 + ldp x22, x23, [sp], #0x10 + ldp x20, x21, [sp], #0x10 + ldp x18, x19, [sp], #0x10 + ldp x16, x17, [sp], #0x10 + ldp x14, x15, [sp], #0x10 + ldp x12, x13, [sp], #0x10 + ldp x10, x11, [sp], #0x10 + ldp x8, x9, [sp], #0x10 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp +#ifdef RT_USING_SMART + beq arch_ret_to_user +#endif + eret +.endm + +#endif /* __ARM64_INC_CONTEXT_H__ */ diff --git a/libcpu/aarch64/common/include/cp15.h b/libcpu/aarch64/common/include/cp15.h new file mode 100644 index 0000000000..cb1458ceec --- /dev/null +++ b/libcpu/aarch64/common/include/cp15.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + */ + +#ifndef __CP15_H__ +#define __CP15_H__ + +#ifndef __STATIC_FORCEINLINE +#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif + +#define __WFI() __asm__ volatile ("wfi":::"memory") + +#define __WFE() __asm__ volatile ("wfe":::"memory") + +#define __SEV() __asm__ volatile ("sev") + +__STATIC_FORCEINLINE void __ISB(void) +{ + __asm__ volatile ("isb 0xF":::"memory"); +} + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __asm__ volatile ("dsb 0xF":::"memory"); +} + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ + +__STATIC_FORCEINLINE void __DMB(void) +{ + __asm__ volatile ("dmb 0xF":::"memory"); +} + +unsigned long rt_cpu_get_smp_id(void); + +void rt_cpu_mmu_disable(void); +void rt_cpu_mmu_enable(void); +void rt_cpu_tlb_set(volatile unsigned long*); + +void rt_cpu_dcache_clean_flush(void); +void rt_cpu_icache_flush(void); + +void rt_cpu_vector_set_base(rt_ubase_t addr); +void rt_hw_mmu_init(void); +void rt_hw_vector_init(void); + +void set_timer_counter(unsigned int counter); +void set_timer_control(unsigned int control); +#endif diff --git a/libcpu/aarch64/common/include/cpu.h b/libcpu/aarch64/common/include/cpu.h new file mode 100644 index 0000000000..81a880c433 --- /dev/null +++ b/libcpu/aarch64/common/include/cpu.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#ifndef __RT_HW_CPU_H__ +#define __RT_HW_CPU_H__ + +#include +#include +#include + +#ifdef RT_USING_OFW +#include +#endif + +#define ID_ERROR __INT64_MAX__ +#define MPIDR_AFFINITY_MASK 0x000000ff00ffffffUL + +struct cpu_ops_t +{ + const char *method; + int (*cpu_init)(rt_uint32_t id, void *param); + int (*cpu_boot)(rt_uint32_t id, rt_uint64_t entry); + void (*cpu_shutdown)(void); +}; +#define sysreg_32(op1, crn, crm, op2) s3_##op1 ##_##crn ##_##crm ##_##op2 +#define sysreg_64(op1, crn, crm, op2) sysreg_32(op1, crn, crm, op2) + +#define MPIDR_AFFINITY_MASK 0x000000ff00ffffffUL + +#define MPIDR_LEVEL_BITS_SHIFT 3 +#define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT) +#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) +#define MPIDR_LEVEL_SHIFT(level) (((1 << (level)) >> 1) << MPIDR_LEVEL_BITS_SHIFT) + +#define MPIDR_AFFINITY_LEVEL(mpidr, level) (((mpidr) >> MPIDR_LEVEL_SHIFT(level)) & MPIDR_LEVEL_MASK) + +/* GIC registers */ +#define ICC_IAR0_SYS sysreg_64(0, c12, c8, 0) +#define ICC_IAR1_SYS sysreg_64(0, c12, c12, 0) +#define ICC_EOIR0_SYS sysreg_64(0, c12, c8, 1) +#define ICC_EOIR1_SYS sysreg_64(0, c12, c12, 1) +#define ICC_HPPIR0_SYS sysreg_64(0, c12, c8, 2) +#define ICC_HPPIR1_SYS sysreg_64(0, c12, c12, 2) +#define ICC_BPR0_SYS sysreg_64(0, c12, c8, 3) +#define ICC_BPR1_SYS sysreg_64(0, c12, c12, 3) +#define ICC_DIR_SYS sysreg_64(0, c12, c11, 1) +#define ICC_PMR_SYS sysreg_64(0, c4, c6, 0) +#define ICC_RPR_SYS sysreg_64(0, c12, c11, 3) +#define ICC_CTLR_SYS sysreg_64(0, c12, c12, 4) +#define ICC_SRE_SYS sysreg_64(0, c12, c12, 5) +#define ICC_IGRPEN0_SYS sysreg_64(0, c12, c12, 6) +#define ICC_IGRPEN1_SYS sysreg_64(0, c12, c12, 7) +#define ICC_SGI0R_SYS sysreg_64(0, c12, c11, 7) +#define ICC_SGI1R_SYS sysreg_64(0, c12, c11, 5) +#define ICC_ASGI1R_SYS sysreg_64(0, c12, c11, 6) + +/* Arch timer registers */ +#define CNTP_CTL CNTP_CTL_EL0 /* EL1 Physical Timer */ +#define CNTHP_CTL CNTHP_CTL_EL2 /* EL2 Non-secure Physical Timer */ +#define CNTHPS_CTL CNTHPS_CTL_EL2 /* EL2 Secure Physical Timer */ +#define CNTPS_CTL CNTPS_CTL_EL1 /* EL3 Physical Timer */ +#define CNTV_CTL CNTV_CTL_EL0 /* EL1 Virtual Timer */ +#define CNTHV_CTL CNTHV_CTL_EL2 /* EL2 Non-secure Virtual Timer */ +#define CNTHVS_CTL CNTHVS_CTL_EL2 /* EL2 Secure Virtual Timer */ + +#define CNTP_CVAL CNTP_CVAL_EL0 +#define CNTHP_CVAL CNTHP_CVAL_EL2 +#define CNTHPS_CVAL CNTHPS_CVAL_EL2 +#define CNTPS_CVAL CNTPS_CVAL_EL1 +#define CNTV_CVAL CNTV_CVAL_EL0 +#define CNTHV_CVAL CNTHV_CVAL_EL2 +#define CNTHVS_CVAL CNTHVS_CVAL_EL2 + +#define CNTP_TVAL CNTP_TVAL_EL0 +#define CNTHP_TVAL CNTHP_TVAL_EL2 +#define CNTHPS_TVAL CNTHPS_TVAL_EL2 +#define CNTPS_TVAL CNTPS_TVAL_EL1 +#define CNTV_TVAL CNTV_TVAL_EL0 +#define CNTHV_TVAL CNTHV_TVAL_EL2 +#define CNTHVS_TVAL CNTHVS_TVAL_EL2 + +#define CNTPCT CNTPCT_EL0 +#define CNTVCT CNTVCT_EL0 +#define CNTFRQ CNTFRQ_EL0 +extern rt_uint64_t rt_cpu_mpidr_table[]; + +#endif /* __RT_HW_CPU_H__ */ diff --git a/libcpu/aarch64/common/include/cpu_ops_common.h b/libcpu/aarch64/common/include/cpu_ops_common.h new file mode 100644 index 0000000000..5e47584c7b --- /dev/null +++ b/libcpu/aarch64/common/include/cpu_ops_common.h @@ -0,0 +1,21 @@ +#ifndef __CPU_OPS_COMMON_H__ +#define __CPU_OPS_COMMON_H__ + +#include +#include +#include +#include "entry_point.h" + +static inline rt_uint64_t get_secondary_entry_pa(void) +{ + rt_uint64_t secondary_entry_pa = (rt_uint64_t)rt_kmem_v2p(_secondary_cpu_entry); + + if (!secondary_entry_pa) + { + LOG_E("Failed to translate 'secondary_entry_pa' to physical address"); + return 0; + } + return secondary_entry_pa; +} + +#endif /* __CPU_OPS_COMMON_H__ */ \ No newline at end of file diff --git a/libcpu/aarch64/common/include/cpuport.h b/libcpu/aarch64/common/include/cpuport.h new file mode 100644 index 0000000000..217f477aaf --- /dev/null +++ b/libcpu/aarch64/common/include/cpuport.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-10-25 Shell Move ffs to cpuport, add general implementation + * by inline assembly + * 2024-01-18 Shell support rt_hw_thread_self to improve overall performance + */ + +#ifndef CPUPORT_H__ +#define CPUPORT_H__ + +#include +#include +#include + +#ifdef RT_USING_SMP + +/** + * Spinlock + */ + +typedef struct +{ + rt_uint32_t value; +} rt_hw_spinlock_t; + +#endif /* RT_USING_SMP */ + +#define rt_hw_barrier(cmd, ...) \ + __asm__ volatile (RT_STRINGIFY(cmd) " "RT_STRINGIFY(__VA_ARGS__):::"memory") + +#define rt_hw_isb() rt_hw_barrier(isb) +#define rt_hw_dmb() rt_hw_barrier(dmb, ish) +#define rt_hw_wmb() rt_hw_barrier(dmb, ishst) +#define rt_hw_rmb() rt_hw_barrier(dmb, ishld) +#define rt_hw_dsb() rt_hw_barrier(dsb, ish) + +#define rt_hw_wfi() rt_hw_barrier(wfi) +#define rt_hw_wfe() rt_hw_barrier(wfe) +#define rt_hw_sev() rt_hw_barrier(sev) + +#define rt_hw_cpu_relax() rt_hw_barrier(yield) + +#define rt_hw_sysreg_write(sysreg, val) \ + __asm__ volatile ("msr "RT_STRINGIFY(sysreg)", %0"::"r"((rt_uint64_t)(val))) + +#define rt_hw_sysreg_read(sysreg, val) \ + __asm__ volatile ("mrs %0, "RT_STRINGIFY(sysreg)"":"=r"((val))) + +void _thread_start(void); + +#ifdef RT_USING_CPU_FFS +/** + * This function finds the first bit set (beginning with the least significant bit) + * in value and return the index of that bit. + * + * Bits are numbered starting at 1 (the least significant bit). A return value of + * zero from any of these functions means that the argument was zero. + * + * @return return the index of the first bit set. If value is 0, then this function + * shall return 0. + */ +rt_inline int __rt_ffs(int value) +{ +#ifdef __GNUC__ + return __builtin_ffs(value); +#else + __asm__ volatile ( + "rbit w1, %w0\n" + "cmp %w0, 0\n" + "clz w1, w1\n" + "csinc %w0, wzr, w1, eq\n" + : "=r"(value) + : "0"(value) + ); + return value; +#endif +} + +#endif /* RT_USING_CPU_FFS */ + +#ifdef ARCH_USING_HW_THREAD_SELF +rt_inline struct rt_thread *rt_hw_thread_self(void) +{ + struct rt_thread *thread; + __asm__ volatile ("mrs %0, tpidr_el1":"=r"(thread)); + + return thread; +} + +rt_inline void rt_hw_thread_set_self(struct rt_thread *thread) +{ + __asm__ volatile ("msr tpidr_el1, %0"::"r"(thread)); +} + +#endif /* ARCH_USING_HW_THREAD_SELF */ + +#endif /*CPUPORT_H__*/ diff --git a/libcpu/aarch64/common/include/entry_point.h b/libcpu/aarch64/common/include/entry_point.h new file mode 100644 index 0000000000..fc3e6c061f --- /dev/null +++ b/libcpu/aarch64/common/include/entry_point.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#ifndef __ENTRY_POINT_H__ +#define __ENTRY_POINT_H__ + +extern void _secondary_cpu_entry(void); +#endif /* __ENTRY_POINT_H__ */ \ No newline at end of file diff --git a/libcpu/aarch64/common/include/gic.h b/libcpu/aarch64/common/include/gic.h new file mode 100644 index 0000000000..4cdcb44028 --- /dev/null +++ b/libcpu/aarch64/common/include/gic.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + */ + +#ifndef __GIC_H__ +#define __GIC_H__ + +#include +#include + +int arm_gic_get_active_irq(rt_uint64_t index); +void arm_gic_ack(rt_uint64_t index, int irq); + +void arm_gic_mask(rt_uint64_t index, int irq); +void arm_gic_umask(rt_uint64_t index, int irq); + +rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq); +void arm_gic_set_pending_irq(rt_uint64_t index, int irq); +void arm_gic_clear_pending_irq(rt_uint64_t index, int irq); + +void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config); +rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq); + +void arm_gic_clear_active(rt_uint64_t index, int irq); + +void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask); +rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq); + +void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority); +rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq); + +void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority); +rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index); + +void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point); +rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index); + +rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq); + +void arm_gic_send_sgi(rt_uint64_t index, int irq, rt_uint64_t target_list, rt_uint64_t filter_list); + +rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index); + +rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index); + +void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group); +rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq); + +int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start); +int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base); + +void arm_gic_dump_type(rt_uint64_t index); +void arm_gic_dump(rt_uint64_t index); + +#endif + diff --git a/libcpu/aarch64/common/include/gicv3.h b/libcpu/aarch64/common/include/gicv3.h new file mode 100644 index 0000000000..d449774c5f --- /dev/null +++ b/libcpu/aarch64/common/include/gicv3.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + * 2014-04-03 Grissiom many enhancements + * 2018-11-22 Jesven add rt_hw_ipi_send() + * add rt_hw_ipi_handler_install() + */ + +#ifndef __GICV3_H__ +#define __GICV3_H__ + +#include + +#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) + + +#ifndef ARM_GIC_CPU_NUM +#define ARM_GIC_CPU_NUM RT_CPUS_NR +#endif + +#define GICV3_ROUTED_TO_ALL 1UL +#define GICV3_ROUTED_TO_SPEC 0UL +#define GET_GICV3_REG(reg, out) __asm__ volatile ("mrs %0, " reg:"=r"(out)::"memory"); +#define SET_GICV3_REG(reg, in) __asm__ volatile ("msr " reg ", %0"::"r"(in):"memory"); + +/* AArch64 System register interface to GICv3 */ +#define ICC_IAR0_EL1 "S3_0_C12_C8_0" +#define ICC_IAR1_EL1 "S3_0_C12_C12_0" +#define ICC_EOIR0_EL1 "S3_0_C12_C8_1" +#define ICC_EOIR1_EL1 "S3_0_C12_C12_1" +#define ICC_HPPIR0_EL1 "S3_0_C12_C8_2" +#define ICC_HPPIR1_EL1 "S3_0_C12_C12_2" +#define ICC_BPR0_EL1 "S3_0_C12_C8_3" +#define ICC_BPR1_EL1 "S3_0_C12_C12_3" +#define ICC_DIR_EL1 "S3_0_C12_C11_1" +#define ICC_PMR_EL1 "S3_0_C4_C6_0" +#define ICC_RPR_EL1 "S3_0_C12_C11_3" +#define ICC_CTLR_EL1 "S3_0_C12_C12_4" +#define ICC_CTLR_EL3 "S3_6_C12_C12_4" +#define ICC_SRE_EL1 "S3_0_C12_C12_5" +#define ICC_SRE_EL2 "S3_4_C12_C9_5" +#define ICC_SRE_EL3 "S3_6_C12_C12_5" +#define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6" +#define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7" +#define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7" +#define ICC_SGI0R_EL1 "S3_0_C12_C11_7" +#define ICC_SGI1R_EL1 "S3_0_C12_C11_5" +#define ICC_ASGI1R_EL1 "S3_0_C12_C11_6" + +/* Macro to access the Distributor Control Register (GICD_CTLR) */ +#define GICD_CTLR_RWP (1U << 31) +#define GICD_CTLR_E1NWF (1U << 7) +#define GICD_CTLR_DS (1U << 6) +#define GICD_CTLR_ARE_NS (1U << 5) +#define GICD_CTLR_ARE_S (1U << 4) +#define GICD_CTLR_ENGRP1S (1U << 2) +#define GICD_CTLR_ENGRP1NS (1U << 1) +#define GICD_CTLR_ENGRP0 (1U << 0) + +/* Macro to access the Redistributor Control Register (GICR_CTLR) */ +#define GICR_CTLR_UWP (1U << 31) +#define GICR_CTLR_DPG1S (1U << 26) +#define GICR_CTLR_DPG1NS (1U << 25) +#define GICR_CTLR_DPG0 (1U << 24) +#define GICR_CTLR_RWP (1U << 3) +#define GICR_CTLR_IR (1U << 2) +#define GICR_CTLR_CES (1U << 1) +#define GICR_CTLR_EnableLPI (1U << 0) + +/* Macro to access the Generic Interrupt Controller Interface (GICC) */ +#define GIC_CPU_CTRL(hw_base) HWREG32((hw_base) + 0x00U) +#define GIC_CPU_PRIMASK(hw_base) HWREG32((hw_base) + 0x04U) +#define GIC_CPU_BINPOINT(hw_base) HWREG32((hw_base) + 0x08U) +#define GIC_CPU_INTACK(hw_base) HWREG32((hw_base) + 0x0cU) +#define GIC_CPU_EOI(hw_base) HWREG32((hw_base) + 0x10U) +#define GIC_CPU_RUNNINGPRI(hw_base) HWREG32((hw_base) + 0x14U) +#define GIC_CPU_HIGHPRI(hw_base) HWREG32((hw_base) + 0x18U) +#define GIC_CPU_IIDR(hw_base) HWREG32((hw_base) + 0xFCU) + +/* Macro to access the Generic Interrupt Controller Distributor (GICD) */ +#define GIC_DIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U) +#define GIC_DIST_TYPE(hw_base) HWREG32((hw_base) + 0x004U) +#define GIC_DIST_IIDR(hw_base) HWREG32((hw_base) + 0x008U) +#define GIC_DIST_IGROUP(hw_base, n) HWREG32((hw_base) + 0x080U + ((n) / 32U) * 4U) +#define GIC_DIST_ENABLE_SET(hw_base, n) HWREG32((hw_base) + 0x100U + ((n) / 32U) * 4U) +#define GIC_DIST_ENABLE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x180U + ((n) / 32U) * 4U) +#define GIC_DIST_PENDING_SET(hw_base, n) HWREG32((hw_base) + 0x200U + ((n) / 32U) * 4U) +#define GIC_DIST_PENDING_CLEAR(hw_base, n) HWREG32((hw_base) + 0x280U + ((n) / 32U) * 4U) +#define GIC_DIST_ACTIVE_SET(hw_base, n) HWREG32((hw_base) + 0x300U + ((n) / 32U) * 4U) +#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x380U + ((n) / 32U) * 4U) +#define GIC_DIST_PRI(hw_base, n) HWREG32((hw_base) + 0x400U + ((n) / 4U) * 4U) +#define GIC_DIST_TARGET(hw_base, n) HWREG32((hw_base) + 0x800U + ((n) / 4U) * 4U) +#define GIC_DIST_CONFIG(hw_base, n) HWREG32((hw_base) + 0xc00U + ((n) / 16U) * 4U) +#define GIC_DIST_SOFTINT(hw_base) HWREG32((hw_base) + 0xf00U) +#define GIC_DIST_CPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf10U + ((n) / 4U) * 4U) +#define GIC_DIST_SPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf20U + ((n) / 4U) * 4U) +#define GIC_DIST_ICPIDR2(hw_base) HWREG32((hw_base) + 0xfe8U) +#define GIC_DIST_IROUTER(hw_base, n) HWREG64((hw_base) + 0x6000U + (n) * 8U) + +/* SGI base address is at 64K offset from Redistributor base address */ +#define GIC_RSGI_OFFSET 0x10000 + +/* Macro to access the Generic Interrupt Controller Redistributor (GICR) */ +#define GIC_RDIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U) +#define GIC_RDIST_IIDR(hw_base) HWREG32((hw_base) + 0x004U) +#define GIC_RDIST_TYPER(hw_base) HWREG64((hw_base) + 0x008U) +#define GIC_RDIST_TSTATUSR(hw_base) HWREG32((hw_base) + 0x010U) +#define GIC_RDIST_WAKER(hw_base) HWREG32((hw_base) + 0x014U) +#define GIC_RDIST_SETLPIR(hw_base) HWREG32((hw_base) + 0x040U) +#define GIC_RDIST_CLRLPIR(hw_base) HWREG32((hw_base) + 0x048U) +#define GIC_RDIST_PROPBASER(hw_base) HWREG32((hw_base) + 0x070U) +#define GIC_RDIST_PENDBASER(hw_base) HWREG32((hw_base) + 0x078U) +#define GIC_RDIST_INVLPIR(hw_base) HWREG32((hw_base) + 0x0A0U) +#define GIC_RDIST_INVALLR(hw_base) HWREG32((hw_base) + 0x0B0U) +#define GIC_RDIST_SYNCR(hw_base) HWREG32((hw_base) + 0x0C0U) + +#define GIC_RDISTSGI_IGROUPR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x080U + (n) * 4U) +#define GIC_RDISTSGI_ISENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x100U) +#define GIC_RDISTSGI_ICENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x180U) +#define GIC_RDISTSGI_ISPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x200U) +#define GIC_RDISTSGI_ICPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x280U) +#define GIC_RDISTSGI_ISACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x300U) +#define GIC_RDISTSGI_ICACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x380U) +#define GIC_RDISTSGI_IPRIORITYR(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x400U + ((n) / 4U) * 4U) +#define GIC_RDISTSGI_ICFGR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC00U) +#define GIC_RDISTSGI_ICFGR1(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC04U) +#define GIC_RDISTSGI_IGRPMODR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xD00U + (n) * 4) +#define GIC_RDISTSGI_NSACR(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U) + +struct arm_gic +{ + rt_uint64_t offset; /* the first interrupt index in the vector table */ + rt_uint64_t redist_hw_base[ARM_GIC_CPU_NUM]; /* the pointer of the gic redistributor */ + rt_uint64_t dist_hw_base; /* the base address of the gic distributor */ + rt_uint64_t cpu_hw_base[ARM_GIC_CPU_NUM]; /* the base address of the gic cpu interface */ +}; + +int arm_gic_get_active_irq(rt_uint64_t index); +void arm_gic_ack(rt_uint64_t index, int irq); + +void arm_gic_mask(rt_uint64_t index, int irq); +void arm_gic_umask(rt_uint64_t index, int irq); + +rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq); +void arm_gic_set_pending_irq(rt_uint64_t index, int irq); +void arm_gic_clear_pending_irq(rt_uint64_t index, int irq); + +void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config); +rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq); + +void arm_gic_clear_active(rt_uint64_t index, int irq); + +void arm_gic_set_router_cpu(rt_uint64_t index, int irq, rt_uint64_t aff); +void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask); +rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq); + +void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority); +rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq); + +void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority); +rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index); + +void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point); +rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index); + +rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq); + +#if defined(RT_USING_SMP) || defined(RT_USING_AMP) +void arm_gic_send_affinity_sgi(rt_uint64_t index, int irq, rt_uint32_t cpu_masks[], rt_uint64_t routing_mode); +#endif + +rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index); + +rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index); + +void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group); +rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq); + +int arm_gic_redist_address_set(rt_uint64_t index, rt_uint64_t redist_addr, int cpu_id); +int arm_gic_cpu_interface_address_set(rt_uint64_t index, rt_uint64_t interface_addr, int cpu_id); + +int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start); +int arm_gic_redist_init(rt_uint64_t index, rt_uint64_t redist_base); +int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base); + +rt_uint64_t *arm_gic_get_gic_table_addr(void); +void arm_gic_dump_type(rt_uint64_t index); +void arm_gic_dump(rt_uint64_t index); + +#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) */ + +#endif + diff --git a/libcpu/aarch64/common/include/gtimer.h b/libcpu/aarch64/common/include/gtimer.h new file mode 100644 index 0000000000..83a0d53165 --- /dev/null +++ b/libcpu/aarch64/common/include/gtimer.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-12-20 GuEe-GUI first version + */ + +#ifndef __GTIMER_H__ +#define __GTIMER_H__ + +#include + +void rt_hw_gtimer_init(void); +void rt_hw_gtimer_local_enable(void); +void rt_hw_gtimer_local_disable(void); + +void rt_hw_gtimer_enable(); + +rt_inline void rt_hw_gtimer_disable(void) +{ + __asm__ volatile ("msr CNTP_CTL_EL0, xzr":::"memory"); +} + +void rt_hw_set_gtimer_val(rt_uint64_t value); +rt_uint64_t rt_hw_get_gtimer_val(); +rt_uint64_t rt_hw_get_cntpct_val(); +rt_uint64_t rt_hw_get_gtimer_frq(); +rt_uint64_t rt_hw_set_gtimer_frq(rt_uint64_t value); + +#endif /* __GTIMER_H__ */ diff --git a/libcpu/aarch64/common/include/hypercall.h b/libcpu/aarch64/common/include/hypercall.h new file mode 100644 index 0000000000..e9599d7f78 --- /dev/null +++ b/libcpu/aarch64/common/include/hypercall.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-02-24 GuEe-GUI first version + */ + +#ifndef __HYPERCALL_H__ +#define __HYPERCALL_H__ + +#include + +rt_inline rt_uint32_t rt_hw_hypercall(rt_uint32_t w0, rt_uint64_t x1, rt_uint64_t x2, + rt_uint64_t x3, rt_uint64_t x4, rt_uint64_t x5, rt_uint64_t x6, rt_uint32_t w7) +{ + register rt_uint64_t ret __asm__ ("x0"); + __asm__ volatile ("hvc #0"); + + return (rt_uint32_t)ret; +} + +rt_err_t rt_hv_stage2_map(unsigned long paddr, unsigned long size); + +#endif diff --git a/libcpu/aarch64/common/include/interrupt.h b/libcpu/aarch64/common/include/interrupt.h new file mode 100644 index 0000000000..d90b8a9e87 --- /dev/null +++ b/libcpu/aarch64/common/include/interrupt.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-06 Bernard first version + */ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#include +#include + +#define INT_IRQ 0x00 +#define INT_FIQ 0x01 + +#define IRQ_MODE_TRIG_LEVEL (0x00) /* Trigger: level triggered interrupt */ +#define IRQ_MODE_TRIG_EDGE (0x01) /* Trigger: edge triggered interrupt */ +#define IRQ_MODE_MASK (0x01) + +void rt_hw_vector_init(void); + +void rt_hw_interrupt_init(void); +void rt_hw_interrupt_mask(int vector); +void rt_hw_interrupt_umask(int vector); + +int rt_hw_interrupt_get_irq(void); +void rt_hw_interrupt_ack(int vector); + +void rt_hw_interrupt_set_target_cpus(int vector, unsigned long cpu_mask); +unsigned int rt_hw_interrupt_get_target_cpus(int vector); + +void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode); +unsigned int rt_hw_interrupt_get_triger_mode(int vector); + +void rt_hw_interrupt_set_pending(int vector); +unsigned int rt_hw_interrupt_get_pending(int vector); +void rt_hw_interrupt_clear_pending(int vector); + +void rt_hw_interrupt_set_priority(int vector, unsigned int priority); +unsigned int rt_hw_interrupt_get_priority(int vector); + +void rt_hw_interrupt_set_priority_mask(unsigned int priority); +unsigned int rt_hw_interrupt_get_priority_mask(void); + +int rt_hw_interrupt_set_prior_group_bits(unsigned int bits); +unsigned int rt_hw_interrupt_get_prior_group_bits(void); + +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name); + +#if defined(RT_USING_SMP) || defined(RT_USING_AMP) +void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler); +#endif + +#endif + diff --git a/libcpu/aarch64/common/include/mmu.h b/libcpu/aarch64/common/include/mmu.h new file mode 100644 index 0000000000..e2599d2d30 --- /dev/null +++ b/libcpu/aarch64/common/include/mmu.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-12 RT-Thread the first version + * 2023-08-15 Shell Support more mapping attribution + */ +#ifndef __MMU_H_ +#define __MMU_H_ + +#ifndef __ASSEMBLY__ + +#include +#include + +/* normal memory wra mapping type */ +#define NORMAL_MEM 0 +/* normal nocache memory mapping type */ +#define NORMAL_NOCACHE_MEM 1 +/* device mapping type */ +#define DEVICE_MEM 2 + +struct mem_desc +{ + unsigned long vaddr_start; + unsigned long vaddr_end; + unsigned long paddr_start; + unsigned long attr; + struct rt_varea varea; +}; + +#endif /* !__ASSEMBLY__ */ + +#define RT_HW_MMU_PROT_READ 1 +#define RT_HW_MMU_PROT_WRITE 2 +#define RT_HW_MMU_PROT_EXECUTE 4 +#define RT_HW_MMU_PROT_KERNEL 8 +#define RT_HW_MMU_PROT_USER 16 +#define RT_HW_MMU_PROT_CACHE 32 + +#define MMU_AF_SHIFT 10 +#define MMU_SHARED_SHIFT 8 +#define MMU_AP_SHIFT 6 +#define MMU_MA_SHIFT 2 +#define MMU_AP_MASK (0x3 << MMU_AP_SHIFT) + +#define MMU_AP_KAUN 0UL /* kernel r/w, user none */ +#define MMU_AP_KAUA 1UL /* kernel r/w, user r/w */ +#define MMU_AP_KRUN 2UL /* kernel r, user none */ +#define MMU_AP_KRUR 3UL /* kernel r, user r */ +#define MMU_ATTR_AF (1ul << MMU_AF_SHIFT) /* the access flag */ +#define MMU_ATTR_DBM (1ul << 51) /* the dirty bit modifier */ + +#define MMU_MAP_CUSTOM(ap, mtype) \ + ((0x1UL << MMU_AF_SHIFT) | (0x2UL << MMU_SHARED_SHIFT) | \ + ((ap) << MMU_AP_SHIFT) | ((mtype) << MMU_MA_SHIFT)) +#define MMU_MAP_K_ROCB MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_MEM) +#define MMU_MAP_K_RO MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_NOCACHE_MEM) +#define MMU_MAP_K_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM) +#define MMU_MAP_K_RW MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_NOCACHE_MEM) +#define MMU_MAP_K_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUN, DEVICE_MEM) +#define MMU_MAP_U_ROCB MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_MEM) +#define MMU_MAP_U_RO MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_NOCACHE_MEM) +#define MMU_MAP_U_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_MEM) +#define MMU_MAP_U_RW MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_NOCACHE_MEM) +#define MMU_MAP_U_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUA, DEVICE_MEM) +#define MMU_MAP_TRACE(attr) ((attr) & ~(MMU_ATTR_AF | MMU_ATTR_DBM)) + +#define ARCH_SECTION_SHIFT 21 +#define ARCH_SECTION_SIZE (1 << ARCH_SECTION_SHIFT) +#define ARCH_SECTION_MASK (ARCH_SECTION_SIZE - 1) +#define ARCH_PAGE_SHIFT 12 +#define ARCH_PAGE_SIZE (1 << ARCH_PAGE_SHIFT) +#define ARCH_PAGE_MASK (ARCH_PAGE_SIZE - 1) +#define ARCH_PAGE_TBL_SHIFT 12 +#define ARCH_PAGE_TBL_SIZE (1 << ARCH_PAGE_TBL_SHIFT) +#define ARCH_PAGE_TBL_MASK (ARCH_PAGE_TBL_SIZE - 1) + +#define ARCH_VADDR_WIDTH 48 +#define ARCH_ADDRESS_WIDTH_BITS 64 + +#define MMU_MAP_ERROR_VANOTALIGN -1 +#define MMU_MAP_ERROR_PANOTALIGN -2 +#define MMU_MAP_ERROR_NOPAGE -3 +#define MMU_MAP_ERROR_CONFLICT -4 + +#define ARCH_MAP_FAILED ((void *)0x1ffffffffffff) + +#define ARCH_EARLY_MAP_SIZE (0x40000000) +/* this is big enough for even 16TB first-time mapping */ +#define ARCH_PAGE_INIT_THRESHOLD (0x10000000) + +#ifndef __ASSEMBLY__ + +struct rt_aspace; + +void rt_hw_mmu_ktbl_set(unsigned long tbl); +void rt_hw_mem_setup_early(unsigned long *tbl0, unsigned long *tbl1, + unsigned long size, unsigned long pv_off); +void rt_hw_mmu_setup(struct rt_aspace *aspace, struct mem_desc *mdesc, + int desc_nr); + +int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, size_t size, size_t *vtable, size_t pv_off); +void *rt_hw_mmu_map(struct rt_aspace *aspace, void *v_addr, void *p_addr, + size_t size, size_t attr); +void rt_hw_mmu_unmap(struct rt_aspace *aspace, void *v_addr, size_t size); +void rt_hw_aspace_switch(struct rt_aspace *aspace); +void *rt_hw_mmu_v2p(struct rt_aspace *aspace, void *vaddr); +void rt_hw_mmu_kernel_map_init(struct rt_aspace *aspace, rt_size_t vaddr_start, + rt_size_t size); +void *rt_hw_mmu_pgtbl_create(void); +void rt_hw_mmu_pgtbl_delete(void *pgtbl); +void *rt_hw_mmu_tbl_get(void); + +static inline void *rt_hw_mmu_kernel_v2p(void *v_addr) +{ + rt_ubase_t par; + void *paddr; + __asm__ volatile("at s1e1w, %0"::"r"(v_addr):"memory"); + __asm__ volatile("mrs %0, par_el1":"=r"(par)::"memory"); + + if (par & 0x1) + { + paddr = ARCH_MAP_FAILED; + } + else + { + #define MMU_ADDRESS_MASK 0x0000fffffffff000UL + par &= MMU_ADDRESS_MASK; + par |= (rt_ubase_t)v_addr & ARCH_PAGE_MASK; + paddr = (void *)par; + } + + return paddr; +} +/** + * @brief Add permission from attribution + * + * @param attr architecture specified mmu attribution + * @param prot protect that will be added + * @return size_t returned attribution + */ +rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, rt_base_t prot) +{ + switch (prot) + { + /* remove write permission for user */ + case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER: + attr = (attr & ~MMU_AP_MASK) | (MMU_AP_KAUA << MMU_AP_SHIFT); + break; + default: + RT_ASSERT(0); + } + return attr; +} + +/** + * @brief Remove permission from attribution + * + * @param attr architecture specified mmu attribution + * @param prot protect that will be removed + * @return size_t returned attribution + */ +rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, rt_base_t prot) +{ + switch (prot) + { + /* remove write permission for user */ + case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER: + if (attr & 0x40) + attr |= 0x80; + break; + default: + RT_ASSERT(0); + } + return attr; +} + +/** + * @brief Test permission from attribution + * + * @param attr architecture specified mmu attribution + * @param prot protect that will be test + * @return rt_bool_t RT_TRUE if the prot is allowed, otherwise RT_FALSE + */ +rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, rt_base_t prot) +{ + rt_bool_t rc; + switch (prot) + { + /* test write permission for user */ + case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER: + if ((attr & MMU_AP_MASK) == (MMU_AP_KAUA << MMU_AP_SHIFT)) + rc = RT_TRUE; + else + rc = RT_FALSE; + break; + default: + RT_ASSERT(0); + } + return rc; +} + +int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size, + enum rt_mmu_cntl cmd); + +#endif /* !__ASSEMBLY__ */ + +#endif diff --git a/libcpu/aarch64/common/include/psci.h b/libcpu/aarch64/common/include/psci.h new file mode 100644 index 0000000000..5557d9192b --- /dev/null +++ b/libcpu/aarch64/common/include/psci.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-09-09 GuEe-GUI The first version + */ + +#ifndef __PSCI_H__ +#define __PSCI_H__ + +#include + +/* + * Non-Confidential PSCI 1.0 release (30 January 2015), and errata fix for PSCI 0.2, unsupport PSCI 0.1 + */ + +/* PSCI 0.2 interface */ +#define PSCI_0_2_FN_BASE 0x84000000 +#define PSCI_0_2_FN(n) (PSCI_0_2_FN_BASE + (n)) +#define PSCI_0_2_FN_END 0x8400001F + +#define PSCI_0_2_FN64_BASE 0xC4000000 +#define PSCI_0_2_FN64(n) (PSCI_0_2_FN64_BASE + (n)) +#define PSCI_0_2_FN64_END 0xC400001F + +#define PSCI_0_2_FN_PSCI_VERSION PSCI_0_2_FN(0) +#define PSCI_0_2_FN_CPU_SUSPEND PSCI_0_2_FN(1) +#define PSCI_0_2_FN_CPU_OFF PSCI_0_2_FN(2) +#define PSCI_0_2_FN_CPU_ON PSCI_0_2_FN(3) +#define PSCI_0_2_FN_AFFINITY_INFO PSCI_0_2_FN(4) +#define PSCI_0_2_FN_MIGRATE PSCI_0_2_FN(5) +#define PSCI_0_2_FN_MIGRATE_INFO_TYPE PSCI_0_2_FN(6) +#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU PSCI_0_2_FN(7) +#define PSCI_0_2_FN_SYSTEM_OFF PSCI_0_2_FN(8) +#define PSCI_0_2_FN_SYSTEM_RESET PSCI_0_2_FN(9) + +#define PSCI_0_2_FN64_CPU_SUSPEND PSCI_0_2_FN64(1) +#define PSCI_0_2_FN64_CPU_ON PSCI_0_2_FN64(3) +#define PSCI_0_2_FN64_AFFINITY_INFO PSCI_0_2_FN64(4) +#define PSCI_0_2_FN64_MIGRATE PSCI_0_2_FN64(5) +#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7) + +/* PSCI 1.0 interface */ +#define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10) +#define PSCI_1_0_FN_CPU_FREEZE PSCI_0_2_FN(11) +#define PSCI_1_0_FN_CPU_DEFAULT_SUSPEND PSCI_0_2_FN(12) +#define PSCI_1_0_FN_NODE_HW_STATE PSCI_0_2_FN(13) +#define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14) +#define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15) +#define PSCI_1_0_FN_STAT_RESIDENCY PSCI_0_2_FN(16) +#define PSCI_1_0_FN_STAT_COUNT PSCI_0_2_FN(17) +#define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) + +#define PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND PSCI_0_2_FN64(12) +#define PSCI_1_0_FN64_NODE_HW_STATE PSCI_0_2_FN64(13) +#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) +#define PSCI_1_0_FN64_STAT_RESIDENCY PSCI_0_2_FN64(16) +#define PSCI_1_0_FN64_STAT_COUNT PSCI_0_2_FN64(17) +#define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) + +/* PSCI version decoding (independent of PSCI version) */ +#define PSCI_VERSION_MAJOR_SHIFT 16 +#define PSCI_VERSION_MINOR_MASK ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1) +#define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK +#define PSCI_VERSION_MAJOR(version) (((version) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) +#define PSCI_VERSION_MINOR(version) ((version) & PSCI_VERSION_MINOR_MASK) +#define PSCI_VERSION(major, min) ((((major) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \ + ((min) & PSCI_VERSION_MINOR_MASK)) + +/* PSCI affinity level state returned by AFFINITY_INFO */ +#define PSCI_AFFINITY_LEVEL_ON 0 +#define PSCI_AFFINITY_LEVEL_OFF 1 +#define PSCI_AFFINITY_LEVEL_ON_PENDING 2 + +/* + * PSCI power state + * power_level: + * Level 0: cores + * Level 1: clusters + * Level 2: system + * state_type: + * value 0: standby or retention state + * value 1: powerdown state(entry and context_id is valid) + * state_id: + * StateID + */ +#define PSCI_POWER_STATE_LEVEL_CORES 0 +#define PSCI_POWER_STATE_LEVEL_CLUSTERS 1 +#define PSCI_POWER_STATE_LEVEL_SYSTEM 2 + +#define PSCI_POWER_STATE_TYPE_STANDBY 0 +#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1 + +#define PSCI_POWER_LEVEL_SHIFT 24 +#define PSCI_POWER_STATE_TYPE_SHIFT 16 +#define PSCI_POWER_STATE_ID_SHIFT 0 +#define PSCI_POWER_STATE(power_level, state_type, state_id) \ +( \ + ((power_level) << PSCI_POWER_LEVEL_SHIFT) | \ + ((state_type) << PSCI_POWER_STATE_TYPE_SHIFT) | \ + ((state_id) << PSCI_POWER_STATE_ID_SHIFT) \ +) +#define PSCI_POWER_LEVEL_VAL(state) (((state) >> PSCI_POWER_LEVEL_SHIFT) & 0x3) +#define PSCI_POWER_STATE_TYPE_VAL(state) (((state) >> PSCI_POWER_STATE_TYPE_SHIFT) & 0x1) +#define PSCI_POWER_STATE_ID_VAL(state) (((state) >> PSCI_POWER_STATE_ID_SHIFT) & 0xffff) + +/* + * For system, cluster, core + * 0: run + * 1: standby(only core) + * 2: retention + * 3: powerdown + */ +#define PSCI_POWER_STATE_ID_RUN 0 +#define PSCI_POWER_STATE_ID_STANDBY 1 +#define PSCI_POWER_STATE_ID_RETENTION 2 +#define PSCI_POWER_STATE_ID_POWERDOWN 3 + +#define PSCI_POWER_STATE_ID(state_id_power_level, system, cluster, core) \ +( \ + ((state_id_power_level) << 12) | \ + ((system) << 8) | \ + ((cluster) << 4) | \ + (core) \ +) + +#define PSCI_RET_SUCCESS 0 +#define PSCI_RET_NOT_SUPPORTED (-1) +#define PSCI_RET_INVALID_PARAMETERS (-2) +#define PSCI_RET_DENIED (-3) +#define PSCI_RET_ALREADY_ON (-4) +#define PSCI_RET_ON_PENDING (-5) +#define PSCI_RET_INTERNAL_FAILURE (-6) +#define PSCI_RET_NOT_PRESENT (-7) +#define PSCI_RET_DISABLED (-8) +#define PSCI_RET_INVALID_ADDRESS (-9) + +void psci_system_off(void); +void psci_system_reboot(void); +rt_uint32_t rt_psci_get_version(void); +rt_uint32_t rt_psci_cpu_on(int cpuid, rt_ubase_t entry_point); +rt_uint32_t rt_psci_cpu_off(rt_uint32_t state); +rt_uint32_t rt_psci_cpu_suspend(rt_uint32_t power_state, rt_ubase_t entry_point); +rt_uint32_t rt_psci_migrate(int cpuid); +rt_uint32_t rt_psci_get_affinity_info(rt_ubase_t target_affinity, rt_ubase_t lowest_affinity_level); +rt_uint32_t rt_psci_migrate_info_type(void); + +#endif /* __PSCI_H__ */ diff --git a/libcpu/aarch64/common/include/setup.h b/libcpu/aarch64/common/include/setup.h new file mode 100644 index 0000000000..f571dba8f0 --- /dev/null +++ b/libcpu/aarch64/common/include/setup.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-02-21 GuEe-GUI first version + */ + +#ifndef __SETUP_H__ +#define __SETUP_H__ + +#include +#include +#ifdef RT_USING_OFW +#include +#endif + +void rt_hw_common_setup(void); + +#endif /* __SETUP_H__ */ diff --git a/libcpu/aarch64/common/include/smccc.h b/libcpu/aarch64/common/include/smccc.h new file mode 100644 index 0000000000..3b2283ac50 --- /dev/null +++ b/libcpu/aarch64/common/include/smccc.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ +#ifndef __SMCCC_H__ +#define __SMCCC_H__ + +/** + * result from SMC/HVC call + * ARM DEN0028E chapter 5, + */ +typedef struct arm_smccc_res_t +{ + unsigned long a0; + // reserved for ARM SMC and HVC Fast Call services + unsigned long a1; + unsigned long a2; + unsigned long a3; +} arm_smccc_res_t; + +/** + * quirk is a structure contains vendor specified information, + * it just a placeholder currently + */ +struct arm_smccc_quirk_t +{ +}; + +/* smccc version 0.2 */ + +void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + unsigned long a6, unsigned long a7, struct arm_smccc_res_t *res, + struct arm_smccc_quirk_t *quirk); + +void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + unsigned long a6, unsigned long a7, struct arm_smccc_res_t *res, + struct arm_smccc_quirk_t *quirk); + +#endif /* __SMCCC_H__ */ diff --git a/libcpu/aarch64/common/include/tlb.h b/libcpu/aarch64/common/include/tlb.h new file mode 100644 index 0000000000..d5267b32a2 --- /dev/null +++ b/libcpu/aarch64/common/include/tlb.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-28 WangXiaoyao the first version + */ +#ifndef __TLB_H__ +#define __TLB_H__ + +#include +#include +#include +#include "mm_aspace.h" +#include "mmu.h" + +#define TLBI_ARG(addr, asid) \ + ({ \ + uintptr_t arg = (uintptr_t)(addr) >> 12; \ + arg &= (1ull << 44) - 1; \ + arg |= (uintptr_t)(asid) << 48; \ + (void *)arg; \ + }) + +static inline void rt_hw_tlb_invalidate_all(void) +{ + __asm__ volatile( + // ensure updates to pte completed + "dsb ishst\n" + "tlbi vmalle1is\n" + "dsb ish\n" + // after tlb in new context, refresh inst + "isb\n" :: + : "memory"); +} + +static inline void rt_hw_tlb_invalidate_all_local(void) +{ + __asm__ volatile( + // ensure updates to pte completed + "dsb nshst\n" + "tlbi vmalle1is\n" + "dsb nsh\n" + // after tlb in new context, refresh inst + "isb\n" :: + : "memory"); +} + +static inline void rt_hw_tlb_invalidate_aspace(rt_aspace_t aspace) +{ + rt_hw_tlb_invalidate_all(); +} + +static inline void rt_hw_tlb_invalidate_page(rt_aspace_t aspace, void *start) +{ + start = TLBI_ARG(start, 0); + __asm__ volatile( + "dsb ishst\n" + "tlbi vaae1is, %0\n" + "dsb ish\n" + "isb\n" ::"r"(start) + : "memory"); +} + +static inline void rt_hw_tlb_invalidate_range(rt_aspace_t aspace, void *start, + size_t size, size_t stride) +{ + if (size <= ARCH_PAGE_SIZE) + { + rt_hw_tlb_invalidate_page(aspace, start); + } + else + { + rt_hw_tlb_invalidate_aspace(aspace); + } +} + +#endif /* __TLB_H__ */ diff --git a/libcpu/aarch64/common/include/vector_gcc.h b/libcpu/aarch64/common/include/vector_gcc.h new file mode 100644 index 0000000000..8fa5c04aec --- /dev/null +++ b/libcpu/aarch64/common/include/vector_gcc.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-03-28 Shell Move vector handling codes from context_gcc.S + */ + +#ifndef __ARM64_INC_VECTOR_H__ +#define __ARM64_INC_VECTOR_H__ + +#include "asm-generic.h" + +#include +#include +#include + +.macro SAVE_IRQ_CONTEXT + /* Save the entire context. */ + SAVE_FPU sp + stp x0, x1, [sp, #-0x10]! + stp x2, x3, [sp, #-0x10]! + stp x4, x5, [sp, #-0x10]! + stp x6, x7, [sp, #-0x10]! + stp x8, x9, [sp, #-0x10]! + stp x10, x11, [sp, #-0x10]! + stp x12, x13, [sp, #-0x10]! + stp x14, x15, [sp, #-0x10]! + stp x16, x17, [sp, #-0x10]! + stp x18, x19, [sp, #-0x10]! + stp x20, x21, [sp, #-0x10]! + stp x22, x23, [sp, #-0x10]! + stp x24, x25, [sp, #-0x10]! + stp x26, x27, [sp, #-0x10]! + stp x28, x29, [sp, #-0x10]! + mrs x28, fpcr + mrs x29, fpsr + stp x28, x29, [sp, #-0x10]! + mrs x29, sp_el0 + stp x29, x30, [sp, #-0x10]! + + mrs x3, spsr_el1 + mrs x2, elr_el1 + + stp x2, x3, [sp, #-0x10]! + + mov x0, sp /* Move SP into X0 for saving. */ +.endm + +#ifdef RT_USING_SMP +#include "../mp/context_gcc.h" +#else +#include "../up/context_gcc.h" +#endif + +.macro RESTORE_IRQ_CONTEXT_WITHOUT_MMU_SWITCH + /* the SP is already ok */ + ldp x2, x3, [sp], #0x10 /* SPSR and ELR. */ + + tst x3, #0x1f + msr spsr_el1, x3 + msr elr_el1, x2 + + ldp x29, x30, [sp], #0x10 + msr sp_el0, x29 + ldp x28, x29, [sp], #0x10 + msr fpcr, x28 + msr fpsr, x29 + ldp x28, x29, [sp], #0x10 + ldp x26, x27, [sp], #0x10 + ldp x24, x25, [sp], #0x10 + ldp x22, x23, [sp], #0x10 + ldp x20, x21, [sp], #0x10 + ldp x18, x19, [sp], #0x10 + ldp x16, x17, [sp], #0x10 + ldp x14, x15, [sp], #0x10 + ldp x12, x13, [sp], #0x10 + ldp x10, x11, [sp], #0x10 + ldp x8, x9, [sp], #0x10 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp +#ifdef RT_USING_SMART + beq arch_ret_to_user +#endif + eret +.endm + +.macro SAVE_USER_CTX + mrs x1, spsr_el1 + and x1, x1, 0xf + cmp x1, xzr + + bne 1f + bl lwp_uthread_ctx_save + ldp x0, x1, [sp] +1: +.endm + +.macro RESTORE_USER_CTX, ctx + ldr x1, [\ctx, #CONTEXT_OFFSET_SPSR_EL1] + and x1, x1, 0x1f + cmp x1, xzr + + bne 1f + bl lwp_uthread_ctx_restore +1: +.endm + +#endif /* __ARM64_INC_VECTOR_H__ */ diff --git a/libcpu/aarch64/common/interrupt.h b/libcpu/aarch64/common/interrupt.h deleted file mode 100644 index d90b8a9e87..0000000000 --- a/libcpu/aarch64/common/interrupt.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-06 Bernard first version - */ - -#ifndef __INTERRUPT_H__ -#define __INTERRUPT_H__ - -#include -#include - -#define INT_IRQ 0x00 -#define INT_FIQ 0x01 - -#define IRQ_MODE_TRIG_LEVEL (0x00) /* Trigger: level triggered interrupt */ -#define IRQ_MODE_TRIG_EDGE (0x01) /* Trigger: edge triggered interrupt */ -#define IRQ_MODE_MASK (0x01) - -void rt_hw_vector_init(void); - -void rt_hw_interrupt_init(void); -void rt_hw_interrupt_mask(int vector); -void rt_hw_interrupt_umask(int vector); - -int rt_hw_interrupt_get_irq(void); -void rt_hw_interrupt_ack(int vector); - -void rt_hw_interrupt_set_target_cpus(int vector, unsigned long cpu_mask); -unsigned int rt_hw_interrupt_get_target_cpus(int vector); - -void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode); -unsigned int rt_hw_interrupt_get_triger_mode(int vector); - -void rt_hw_interrupt_set_pending(int vector); -unsigned int rt_hw_interrupt_get_pending(int vector); -void rt_hw_interrupt_clear_pending(int vector); - -void rt_hw_interrupt_set_priority(int vector, unsigned int priority); -unsigned int rt_hw_interrupt_get_priority(int vector); - -void rt_hw_interrupt_set_priority_mask(unsigned int priority); -unsigned int rt_hw_interrupt_get_priority_mask(void); - -int rt_hw_interrupt_set_prior_group_bits(unsigned int bits); -unsigned int rt_hw_interrupt_get_prior_group_bits(void); - -rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, - void *param, const char *name); - -#if defined(RT_USING_SMP) || defined(RT_USING_AMP) -void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler); -#endif - -#endif - diff --git a/libcpu/aarch64/common/mmu.h b/libcpu/aarch64/common/mmu.h deleted file mode 100644 index e2599d2d30..0000000000 --- a/libcpu/aarch64/common/mmu.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-05-12 RT-Thread the first version - * 2023-08-15 Shell Support more mapping attribution - */ -#ifndef __MMU_H_ -#define __MMU_H_ - -#ifndef __ASSEMBLY__ - -#include -#include - -/* normal memory wra mapping type */ -#define NORMAL_MEM 0 -/* normal nocache memory mapping type */ -#define NORMAL_NOCACHE_MEM 1 -/* device mapping type */ -#define DEVICE_MEM 2 - -struct mem_desc -{ - unsigned long vaddr_start; - unsigned long vaddr_end; - unsigned long paddr_start; - unsigned long attr; - struct rt_varea varea; -}; - -#endif /* !__ASSEMBLY__ */ - -#define RT_HW_MMU_PROT_READ 1 -#define RT_HW_MMU_PROT_WRITE 2 -#define RT_HW_MMU_PROT_EXECUTE 4 -#define RT_HW_MMU_PROT_KERNEL 8 -#define RT_HW_MMU_PROT_USER 16 -#define RT_HW_MMU_PROT_CACHE 32 - -#define MMU_AF_SHIFT 10 -#define MMU_SHARED_SHIFT 8 -#define MMU_AP_SHIFT 6 -#define MMU_MA_SHIFT 2 -#define MMU_AP_MASK (0x3 << MMU_AP_SHIFT) - -#define MMU_AP_KAUN 0UL /* kernel r/w, user none */ -#define MMU_AP_KAUA 1UL /* kernel r/w, user r/w */ -#define MMU_AP_KRUN 2UL /* kernel r, user none */ -#define MMU_AP_KRUR 3UL /* kernel r, user r */ -#define MMU_ATTR_AF (1ul << MMU_AF_SHIFT) /* the access flag */ -#define MMU_ATTR_DBM (1ul << 51) /* the dirty bit modifier */ - -#define MMU_MAP_CUSTOM(ap, mtype) \ - ((0x1UL << MMU_AF_SHIFT) | (0x2UL << MMU_SHARED_SHIFT) | \ - ((ap) << MMU_AP_SHIFT) | ((mtype) << MMU_MA_SHIFT)) -#define MMU_MAP_K_ROCB MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_MEM) -#define MMU_MAP_K_RO MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_NOCACHE_MEM) -#define MMU_MAP_K_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM) -#define MMU_MAP_K_RW MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_NOCACHE_MEM) -#define MMU_MAP_K_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUN, DEVICE_MEM) -#define MMU_MAP_U_ROCB MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_MEM) -#define MMU_MAP_U_RO MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_NOCACHE_MEM) -#define MMU_MAP_U_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_MEM) -#define MMU_MAP_U_RW MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_NOCACHE_MEM) -#define MMU_MAP_U_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUA, DEVICE_MEM) -#define MMU_MAP_TRACE(attr) ((attr) & ~(MMU_ATTR_AF | MMU_ATTR_DBM)) - -#define ARCH_SECTION_SHIFT 21 -#define ARCH_SECTION_SIZE (1 << ARCH_SECTION_SHIFT) -#define ARCH_SECTION_MASK (ARCH_SECTION_SIZE - 1) -#define ARCH_PAGE_SHIFT 12 -#define ARCH_PAGE_SIZE (1 << ARCH_PAGE_SHIFT) -#define ARCH_PAGE_MASK (ARCH_PAGE_SIZE - 1) -#define ARCH_PAGE_TBL_SHIFT 12 -#define ARCH_PAGE_TBL_SIZE (1 << ARCH_PAGE_TBL_SHIFT) -#define ARCH_PAGE_TBL_MASK (ARCH_PAGE_TBL_SIZE - 1) - -#define ARCH_VADDR_WIDTH 48 -#define ARCH_ADDRESS_WIDTH_BITS 64 - -#define MMU_MAP_ERROR_VANOTALIGN -1 -#define MMU_MAP_ERROR_PANOTALIGN -2 -#define MMU_MAP_ERROR_NOPAGE -3 -#define MMU_MAP_ERROR_CONFLICT -4 - -#define ARCH_MAP_FAILED ((void *)0x1ffffffffffff) - -#define ARCH_EARLY_MAP_SIZE (0x40000000) -/* this is big enough for even 16TB first-time mapping */ -#define ARCH_PAGE_INIT_THRESHOLD (0x10000000) - -#ifndef __ASSEMBLY__ - -struct rt_aspace; - -void rt_hw_mmu_ktbl_set(unsigned long tbl); -void rt_hw_mem_setup_early(unsigned long *tbl0, unsigned long *tbl1, - unsigned long size, unsigned long pv_off); -void rt_hw_mmu_setup(struct rt_aspace *aspace, struct mem_desc *mdesc, - int desc_nr); - -int rt_hw_mmu_map_init(rt_aspace_t aspace, void *v_address, size_t size, size_t *vtable, size_t pv_off); -void *rt_hw_mmu_map(struct rt_aspace *aspace, void *v_addr, void *p_addr, - size_t size, size_t attr); -void rt_hw_mmu_unmap(struct rt_aspace *aspace, void *v_addr, size_t size); -void rt_hw_aspace_switch(struct rt_aspace *aspace); -void *rt_hw_mmu_v2p(struct rt_aspace *aspace, void *vaddr); -void rt_hw_mmu_kernel_map_init(struct rt_aspace *aspace, rt_size_t vaddr_start, - rt_size_t size); -void *rt_hw_mmu_pgtbl_create(void); -void rt_hw_mmu_pgtbl_delete(void *pgtbl); -void *rt_hw_mmu_tbl_get(void); - -static inline void *rt_hw_mmu_kernel_v2p(void *v_addr) -{ - rt_ubase_t par; - void *paddr; - __asm__ volatile("at s1e1w, %0"::"r"(v_addr):"memory"); - __asm__ volatile("mrs %0, par_el1":"=r"(par)::"memory"); - - if (par & 0x1) - { - paddr = ARCH_MAP_FAILED; - } - else - { - #define MMU_ADDRESS_MASK 0x0000fffffffff000UL - par &= MMU_ADDRESS_MASK; - par |= (rt_ubase_t)v_addr & ARCH_PAGE_MASK; - paddr = (void *)par; - } - - return paddr; -} -/** - * @brief Add permission from attribution - * - * @param attr architecture specified mmu attribution - * @param prot protect that will be added - * @return size_t returned attribution - */ -rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, rt_base_t prot) -{ - switch (prot) - { - /* remove write permission for user */ - case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER: - attr = (attr & ~MMU_AP_MASK) | (MMU_AP_KAUA << MMU_AP_SHIFT); - break; - default: - RT_ASSERT(0); - } - return attr; -} - -/** - * @brief Remove permission from attribution - * - * @param attr architecture specified mmu attribution - * @param prot protect that will be removed - * @return size_t returned attribution - */ -rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, rt_base_t prot) -{ - switch (prot) - { - /* remove write permission for user */ - case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER: - if (attr & 0x40) - attr |= 0x80; - break; - default: - RT_ASSERT(0); - } - return attr; -} - -/** - * @brief Test permission from attribution - * - * @param attr architecture specified mmu attribution - * @param prot protect that will be test - * @return rt_bool_t RT_TRUE if the prot is allowed, otherwise RT_FALSE - */ -rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, rt_base_t prot) -{ - rt_bool_t rc; - switch (prot) - { - /* test write permission for user */ - case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER: - if ((attr & MMU_AP_MASK) == (MMU_AP_KAUA << MMU_AP_SHIFT)) - rc = RT_TRUE; - else - rc = RT_FALSE; - break; - default: - RT_ASSERT(0); - } - return rc; -} - -int rt_hw_mmu_control(struct rt_aspace *aspace, void *vaddr, size_t size, - enum rt_mmu_cntl cmd); - -#endif /* !__ASSEMBLY__ */ - -#endif diff --git a/libcpu/aarch64/common/mp/context_gcc.S b/libcpu/aarch64/common/mp/context_gcc.S new file mode 100644 index 0000000000..9b91d1d3d0 --- /dev/null +++ b/libcpu/aarch64/common/mp/context_gcc.S @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-18 Jesven the first version + * 2023-06-24 Shell Support backtrace for user thread + * 2024-01-06 Shell Fix barrier on irq_disable/enable + * 2024-03-28 Shell Move vector handling codes from context_gcc.S + */ + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "context_gcc.h" +#include "../include/vector_gcc.h" + +#include +#include +#include +#include + +.section .text + +.globl rt_hw_context_switch_to + +/* + * void rt_hw_context_switch_to(rt_uint3 to, struct rt_thread *to_thread); + * X0 --> to (thread stack) + * X1 --> to_thread + */ +rt_hw_context_switch_to: + ldr x0, [x0] + mov sp, x0 + mov x0, x1 + bl rt_cpus_lock_status_restore +#ifdef RT_USING_SMART + bl rt_thread_self + bl lwp_user_setting_restore +#endif + b rt_hw_context_switch_exit + +.globl rt_hw_context_switch + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 +to, struct rt_thread *to_thread); + * X0 --> from (from_thread stack) + * X1 --> to (to_thread stack) + * X2 --> to_thread + */ +rt_hw_context_switch: + SAVE_CONTEXT_SWITCH + mov x3, sp + str x3, [x0] // store sp in preempted tasks TCB + ldr x0, [x1] // get new task stack pointer + mov sp, x0 + + /* backup thread self */ + mov x19, x2 + + mov x0, x19 + bl rt_cpus_lock_status_restore +#ifdef RT_USING_SMART + mov x0, x19 + bl lwp_user_setting_restore +#endif + b rt_hw_context_switch_exit + +.globl rt_hw_context_switch_interrupt + +/* + * void rt_hw_context_switch_interrupt(context, from sp, to sp, tp tcb) + * X0 :interrupt context + * X1 :addr of from_thread's sp + * X2 :addr of to_thread's sp + * X3 :to_thread's tcb + */ +rt_hw_context_switch_interrupt: + stp x0, x1, [sp, #-0x10]! + stp x2, x3, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! +#ifdef RT_USING_SMART + bl rt_thread_self + bl lwp_user_setting_save +#endif + ldp x29, x30, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + str x0, [x1] + ldr x0, [x2] + mov sp, x0 + mov x0, x3 + mov x19, x0 + bl rt_cpus_lock_status_restore + mov x0, x19 +#ifdef RT_USING_SMART + bl lwp_user_setting_restore +#endif + b rt_hw_context_switch_exit + +.global rt_hw_context_switch_exit +rt_hw_context_switch_exit: + clrex + mov x0, sp + RESTORE_CONTEXT_SWITCH diff --git a/libcpu/aarch64/common/mp/context_gcc.h b/libcpu/aarch64/common/mp/context_gcc.h new file mode 100644 index 0000000000..2a1e7fe92b --- /dev/null +++ b/libcpu/aarch64/common/mp/context_gcc.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-03-25 Shell Trimming unecessary ops and + * improve the performance of ctx switch + */ + +#ifndef __ARM64_CONTEXT_H__ +#define __ARM64_CONTEXT_H__ + +#include "../include/context_gcc.h" + +#include +#include +#include +#include + +.macro RESTORE_CONTEXT_SWITCH + /* Set the SP to point to the stack of the task being restored. */ + mov sp, x0 + + _RESTORE_CONTEXT_SWITCH +.endm + +.macro RESTORE_IRQ_CONTEXT + /* Set the SP to point to the stack of the task being restored. */ + mov sp, x0 + + ldp x2, x3, [sp], #0x10 /* SPSR and ELR. */ + + tst x3, #0x1f + msr spsr_el1, x3 + msr elr_el1, x2 + + ldp x29, x30, [sp], #0x10 + msr sp_el0, x29 + ldp x28, x29, [sp], #0x10 + msr fpcr, x28 + msr fpsr, x29 + ldp x28, x29, [sp], #0x10 + ldp x26, x27, [sp], #0x10 + ldp x24, x25, [sp], #0x10 + ldp x22, x23, [sp], #0x10 + ldp x20, x21, [sp], #0x10 + ldp x18, x19, [sp], #0x10 + ldp x16, x17, [sp], #0x10 + ldp x14, x15, [sp], #0x10 + ldp x12, x13, [sp], #0x10 + ldp x10, x11, [sp], #0x10 + ldp x8, x9, [sp], #0x10 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp +#ifdef RT_USING_SMART + beq arch_ret_to_user +#endif + eret +.endm + +#endif /* __ARM64_CONTEXT_H__ */ diff --git a/libcpu/aarch64/common/mp/vector_gcc.S b/libcpu/aarch64/common/mp/vector_gcc.S new file mode 100644 index 0000000000..67b4bc5fe8 --- /dev/null +++ b/libcpu/aarch64/common/mp/vector_gcc.S @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-03-28 Shell Move vector handling codes from context_gcc.S + */ + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "../include/vector_gcc.h" +#include "context_gcc.h" + +.globl vector_fiq +vector_fiq: + b . + +START_POINT(vector_irq) + SAVE_IRQ_CONTEXT + stp x0, x1, [sp, #-0x10]! /* X0 is thread sp */ + + bl rt_interrupt_enter + ldp x0, x1, [sp] + +#ifdef RT_USING_SMART + SAVE_USER_CTX +#endif /* RT_USING_SMART */ + + bl rt_hw_trap_irq + +#ifdef RT_USING_SMART + ldp x0, x1, [sp] + RESTORE_USER_CTX x0 +#endif /* RT_USING_SMART */ + + bl rt_interrupt_leave + + ldp x0, x1, [sp], #0x10 + bl rt_scheduler_do_irq_switch + + mov x0, sp + RESTORE_IRQ_CONTEXT + +START_POINT_END(vector_irq) diff --git a/libcpu/aarch64/common/psci.h b/libcpu/aarch64/common/psci.h deleted file mode 100644 index 5557d9192b..0000000000 --- a/libcpu/aarch64/common/psci.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-09-09 GuEe-GUI The first version - */ - -#ifndef __PSCI_H__ -#define __PSCI_H__ - -#include - -/* - * Non-Confidential PSCI 1.0 release (30 January 2015), and errata fix for PSCI 0.2, unsupport PSCI 0.1 - */ - -/* PSCI 0.2 interface */ -#define PSCI_0_2_FN_BASE 0x84000000 -#define PSCI_0_2_FN(n) (PSCI_0_2_FN_BASE + (n)) -#define PSCI_0_2_FN_END 0x8400001F - -#define PSCI_0_2_FN64_BASE 0xC4000000 -#define PSCI_0_2_FN64(n) (PSCI_0_2_FN64_BASE + (n)) -#define PSCI_0_2_FN64_END 0xC400001F - -#define PSCI_0_2_FN_PSCI_VERSION PSCI_0_2_FN(0) -#define PSCI_0_2_FN_CPU_SUSPEND PSCI_0_2_FN(1) -#define PSCI_0_2_FN_CPU_OFF PSCI_0_2_FN(2) -#define PSCI_0_2_FN_CPU_ON PSCI_0_2_FN(3) -#define PSCI_0_2_FN_AFFINITY_INFO PSCI_0_2_FN(4) -#define PSCI_0_2_FN_MIGRATE PSCI_0_2_FN(5) -#define PSCI_0_2_FN_MIGRATE_INFO_TYPE PSCI_0_2_FN(6) -#define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU PSCI_0_2_FN(7) -#define PSCI_0_2_FN_SYSTEM_OFF PSCI_0_2_FN(8) -#define PSCI_0_2_FN_SYSTEM_RESET PSCI_0_2_FN(9) - -#define PSCI_0_2_FN64_CPU_SUSPEND PSCI_0_2_FN64(1) -#define PSCI_0_2_FN64_CPU_ON PSCI_0_2_FN64(3) -#define PSCI_0_2_FN64_AFFINITY_INFO PSCI_0_2_FN64(4) -#define PSCI_0_2_FN64_MIGRATE PSCI_0_2_FN64(5) -#define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7) - -/* PSCI 1.0 interface */ -#define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10) -#define PSCI_1_0_FN_CPU_FREEZE PSCI_0_2_FN(11) -#define PSCI_1_0_FN_CPU_DEFAULT_SUSPEND PSCI_0_2_FN(12) -#define PSCI_1_0_FN_NODE_HW_STATE PSCI_0_2_FN(13) -#define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14) -#define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15) -#define PSCI_1_0_FN_STAT_RESIDENCY PSCI_0_2_FN(16) -#define PSCI_1_0_FN_STAT_COUNT PSCI_0_2_FN(17) -#define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) - -#define PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND PSCI_0_2_FN64(12) -#define PSCI_1_0_FN64_NODE_HW_STATE PSCI_0_2_FN64(13) -#define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) -#define PSCI_1_0_FN64_STAT_RESIDENCY PSCI_0_2_FN64(16) -#define PSCI_1_0_FN64_STAT_COUNT PSCI_0_2_FN64(17) -#define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) - -/* PSCI version decoding (independent of PSCI version) */ -#define PSCI_VERSION_MAJOR_SHIFT 16 -#define PSCI_VERSION_MINOR_MASK ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1) -#define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK -#define PSCI_VERSION_MAJOR(version) (((version) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) -#define PSCI_VERSION_MINOR(version) ((version) & PSCI_VERSION_MINOR_MASK) -#define PSCI_VERSION(major, min) ((((major) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \ - ((min) & PSCI_VERSION_MINOR_MASK)) - -/* PSCI affinity level state returned by AFFINITY_INFO */ -#define PSCI_AFFINITY_LEVEL_ON 0 -#define PSCI_AFFINITY_LEVEL_OFF 1 -#define PSCI_AFFINITY_LEVEL_ON_PENDING 2 - -/* - * PSCI power state - * power_level: - * Level 0: cores - * Level 1: clusters - * Level 2: system - * state_type: - * value 0: standby or retention state - * value 1: powerdown state(entry and context_id is valid) - * state_id: - * StateID - */ -#define PSCI_POWER_STATE_LEVEL_CORES 0 -#define PSCI_POWER_STATE_LEVEL_CLUSTERS 1 -#define PSCI_POWER_STATE_LEVEL_SYSTEM 2 - -#define PSCI_POWER_STATE_TYPE_STANDBY 0 -#define PSCI_POWER_STATE_TYPE_POWER_DOWN 1 - -#define PSCI_POWER_LEVEL_SHIFT 24 -#define PSCI_POWER_STATE_TYPE_SHIFT 16 -#define PSCI_POWER_STATE_ID_SHIFT 0 -#define PSCI_POWER_STATE(power_level, state_type, state_id) \ -( \ - ((power_level) << PSCI_POWER_LEVEL_SHIFT) | \ - ((state_type) << PSCI_POWER_STATE_TYPE_SHIFT) | \ - ((state_id) << PSCI_POWER_STATE_ID_SHIFT) \ -) -#define PSCI_POWER_LEVEL_VAL(state) (((state) >> PSCI_POWER_LEVEL_SHIFT) & 0x3) -#define PSCI_POWER_STATE_TYPE_VAL(state) (((state) >> PSCI_POWER_STATE_TYPE_SHIFT) & 0x1) -#define PSCI_POWER_STATE_ID_VAL(state) (((state) >> PSCI_POWER_STATE_ID_SHIFT) & 0xffff) - -/* - * For system, cluster, core - * 0: run - * 1: standby(only core) - * 2: retention - * 3: powerdown - */ -#define PSCI_POWER_STATE_ID_RUN 0 -#define PSCI_POWER_STATE_ID_STANDBY 1 -#define PSCI_POWER_STATE_ID_RETENTION 2 -#define PSCI_POWER_STATE_ID_POWERDOWN 3 - -#define PSCI_POWER_STATE_ID(state_id_power_level, system, cluster, core) \ -( \ - ((state_id_power_level) << 12) | \ - ((system) << 8) | \ - ((cluster) << 4) | \ - (core) \ -) - -#define PSCI_RET_SUCCESS 0 -#define PSCI_RET_NOT_SUPPORTED (-1) -#define PSCI_RET_INVALID_PARAMETERS (-2) -#define PSCI_RET_DENIED (-3) -#define PSCI_RET_ALREADY_ON (-4) -#define PSCI_RET_ON_PENDING (-5) -#define PSCI_RET_INTERNAL_FAILURE (-6) -#define PSCI_RET_NOT_PRESENT (-7) -#define PSCI_RET_DISABLED (-8) -#define PSCI_RET_INVALID_ADDRESS (-9) - -void psci_system_off(void); -void psci_system_reboot(void); -rt_uint32_t rt_psci_get_version(void); -rt_uint32_t rt_psci_cpu_on(int cpuid, rt_ubase_t entry_point); -rt_uint32_t rt_psci_cpu_off(rt_uint32_t state); -rt_uint32_t rt_psci_cpu_suspend(rt_uint32_t power_state, rt_ubase_t entry_point); -rt_uint32_t rt_psci_migrate(int cpuid); -rt_uint32_t rt_psci_get_affinity_info(rt_ubase_t target_affinity, rt_ubase_t lowest_affinity_level); -rt_uint32_t rt_psci_migrate_info_type(void); - -#endif /* __PSCI_H__ */ diff --git a/libcpu/aarch64/common/setup.h b/libcpu/aarch64/common/setup.h deleted file mode 100644 index f571dba8f0..0000000000 --- a/libcpu/aarch64/common/setup.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-21 GuEe-GUI first version - */ - -#ifndef __SETUP_H__ -#define __SETUP_H__ - -#include -#include -#ifdef RT_USING_OFW -#include -#endif - -void rt_hw_common_setup(void); - -#endif /* __SETUP_H__ */ diff --git a/libcpu/aarch64/common/smccc.h b/libcpu/aarch64/common/smccc.h deleted file mode 100644 index 3b2283ac50..0000000000 --- a/libcpu/aarch64/common/smccc.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2006-2019, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef __SMCCC_H__ -#define __SMCCC_H__ - -/** - * result from SMC/HVC call - * ARM DEN0028E chapter 5, - */ -typedef struct arm_smccc_res_t -{ - unsigned long a0; - // reserved for ARM SMC and HVC Fast Call services - unsigned long a1; - unsigned long a2; - unsigned long a3; -} arm_smccc_res_t; - -/** - * quirk is a structure contains vendor specified information, - * it just a placeholder currently - */ -struct arm_smccc_quirk_t -{ -}; - -/* smccc version 0.2 */ - -void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, - unsigned long a3, unsigned long a4, unsigned long a5, - unsigned long a6, unsigned long a7, struct arm_smccc_res_t *res, - struct arm_smccc_quirk_t *quirk); - -void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, - unsigned long a3, unsigned long a4, unsigned long a5, - unsigned long a6, unsigned long a7, struct arm_smccc_res_t *res, - struct arm_smccc_quirk_t *quirk); - -#endif /* __SMCCC_H__ */ diff --git a/libcpu/aarch64/common/stack_gcc.S b/libcpu/aarch64/common/stack_gcc.S new file mode 100644 index 0000000000..26016882b8 --- /dev/null +++ b/libcpu/aarch64/common/stack_gcc.S @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-18 Jesven the first version + * 2023-06-24 Shell Support debug frame for user thread + */ + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "rtconfig.h" +#include "asm-generic.h" +#include "asm-fpu.h" +#include "armv8.h" + +.section .text + +START_POINT(_thread_start) + blr x19 + mov x29, #0 + blr x20 + b . /* never here */ +START_POINT_END(_thread_start) diff --git a/libcpu/aarch64/common/startup_gcc.S b/libcpu/aarch64/common/startup_gcc.S index 9674b57d57..8325436ca5 100644 --- a/libcpu/aarch64/common/startup_gcc.S +++ b/libcpu/aarch64/common/startup_gcc.S @@ -7,7 +7,7 @@ * Date Author Notes */ - .global Reset_Handler + .global Reset_Handler .section ".start", "ax" Reset_Handler: nop diff --git a/libcpu/aarch64/common/tlb.h b/libcpu/aarch64/common/tlb.h deleted file mode 100644 index d5267b32a2..0000000000 --- a/libcpu/aarch64/common/tlb.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-28 WangXiaoyao the first version - */ -#ifndef __TLB_H__ -#define __TLB_H__ - -#include -#include -#include -#include "mm_aspace.h" -#include "mmu.h" - -#define TLBI_ARG(addr, asid) \ - ({ \ - uintptr_t arg = (uintptr_t)(addr) >> 12; \ - arg &= (1ull << 44) - 1; \ - arg |= (uintptr_t)(asid) << 48; \ - (void *)arg; \ - }) - -static inline void rt_hw_tlb_invalidate_all(void) -{ - __asm__ volatile( - // ensure updates to pte completed - "dsb ishst\n" - "tlbi vmalle1is\n" - "dsb ish\n" - // after tlb in new context, refresh inst - "isb\n" :: - : "memory"); -} - -static inline void rt_hw_tlb_invalidate_all_local(void) -{ - __asm__ volatile( - // ensure updates to pte completed - "dsb nshst\n" - "tlbi vmalle1is\n" - "dsb nsh\n" - // after tlb in new context, refresh inst - "isb\n" :: - : "memory"); -} - -static inline void rt_hw_tlb_invalidate_aspace(rt_aspace_t aspace) -{ - rt_hw_tlb_invalidate_all(); -} - -static inline void rt_hw_tlb_invalidate_page(rt_aspace_t aspace, void *start) -{ - start = TLBI_ARG(start, 0); - __asm__ volatile( - "dsb ishst\n" - "tlbi vaae1is, %0\n" - "dsb ish\n" - "isb\n" ::"r"(start) - : "memory"); -} - -static inline void rt_hw_tlb_invalidate_range(rt_aspace_t aspace, void *start, - size_t size, size_t stride) -{ - if (size <= ARCH_PAGE_SIZE) - { - rt_hw_tlb_invalidate_page(aspace, start); - } - else - { - rt_hw_tlb_invalidate_aspace(aspace); - } -} - -#endif /* __TLB_H__ */ diff --git a/libcpu/aarch64/common/up/context_gcc.S b/libcpu/aarch64/common/up/context_gcc.S new file mode 100644 index 0000000000..c22658af36 --- /dev/null +++ b/libcpu/aarch64/common/up/context_gcc.S @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-18 Jesven the first version + * 2023-06-24 Shell Support backtrace for user thread + * 2024-01-06 Shell Fix barrier on irq_disable/enable + * 2024-03-28 Shell Move vector handling codes from context_gcc.S + */ + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "context_gcc.h" +#include "../include/vector_gcc.h" + +#include +#include +#include +#include + +/** + * Context switch status + */ +.section .bss +rt_interrupt_from_thread: + .quad 0 +rt_interrupt_to_thread: + .quad 0 +rt_thread_switch_interrupt_flag: + .quad 0 + +.section .text + +/* + * void rt_hw_context_switch_to(rt_ubase_t to); + * X0 --> to sp + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + clrex + ldr x0, [x0] + RESTORE_CONTEXT_SWITCH + +/* + * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); + * X0 --> from sp + * X1 --> to sp + * X2 --> to thread + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + clrex + SAVE_CONTEXT_SWITCH + + mov x2, sp + str x2, [x0] // store sp in preempted tasks TCB + ldr x0, [x1] // get new task stack pointer + + RESTORE_CONTEXT_SWITCH + +/* + * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t from_thread, rt_thread_t to_thread); + */ +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + clrex + ldr x6, =rt_thread_switch_interrupt_flag + ldr x7, [x6] + cmp x7, #1 + b.eq _reswitch + + /* set rt_interrupt_from_thread */ + ldr x4, =rt_interrupt_from_thread + str x0, [x4] + + /* set rt_thread_switch_interrupt_flag to 1 */ + mov x7, #1 + str x7, [x6] + + stp x1, x30, [sp, #-0x10]! +#ifdef RT_USING_SMART + mov x0, x2 + bl lwp_user_setting_save +#endif + ldp x1, x30, [sp], #0x10 +_reswitch: + ldr x6, =rt_interrupt_to_thread // set rt_interrupt_to_thread + str x1, [x6] + ret diff --git a/libcpu/aarch64/common/up/context_gcc.h b/libcpu/aarch64/common/up/context_gcc.h new file mode 100644 index 0000000000..266d3f6f31 --- /dev/null +++ b/libcpu/aarch64/common/up/context_gcc.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-03-25 Shell Trimming unecessary ops and + * improve the performance of ctx switch + */ + +#ifndef __ARM64_CONTEXT_H__ +#define __ARM64_CONTEXT_H__ + +#include "../include/context_gcc.h" + +#include +#include +#include +#include + +.macro RESTORE_CONTEXT_SWITCH + /* Set the SP to point to the stack of the task being restored. */ + mov sp, x0 + +#ifdef RT_USING_SMART + bl rt_thread_self + mov x19, x0 + bl lwp_aspace_switch + mov x0, x19 + bl lwp_user_setting_restore +#endif /* RT_USING_SMART */ + _RESTORE_CONTEXT_SWITCH +.endm + +.macro RESTORE_IRQ_CONTEXT + /* Set the SP to point to the stack of the task being restored. */ + MOV SP, X0 +#ifdef RT_USING_SMART + BL rt_thread_self + MOV X19, X0 + BL lwp_aspace_switch + MOV X0, X19 + BL lwp_user_setting_restore +#endif + LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ + + TST X3, #0x1f + MSR SPSR_EL1, X3 + MSR ELR_EL1, X2 + + LDP X29, X30, [SP], #0x10 + MSR SP_EL0, X29 + LDP X28, X29, [SP], #0x10 + MSR FPCR, X28 + MSR FPSR, X29 + LDP X28, X29, [SP], #0x10 + LDP X26, X27, [SP], #0x10 + LDP X24, X25, [SP], #0x10 + LDP X22, X23, [SP], #0x10 + LDP X20, X21, [SP], #0x10 + LDP X18, X19, [SP], #0x10 + LDP X16, X17, [SP], #0x10 + LDP X14, X15, [SP], #0x10 + LDP X12, X13, [SP], #0x10 + LDP X10, X11, [SP], #0x10 + LDP X8, X9, [SP], #0x10 + LDP X6, X7, [SP], #0x10 + LDP X4, X5, [SP], #0x10 + LDP X2, X3, [SP], #0x10 + LDP X0, X1, [SP], #0x10 + RESTORE_FPU SP +#ifdef RT_USING_SMART + BEQ arch_ret_to_user +#endif + ERET +.endm + +#endif /* __ARM64_CONTEXT_H__ */ diff --git a/libcpu/aarch64/common/up/vector_gcc.S b/libcpu/aarch64/common/up/vector_gcc.S new file mode 100644 index 0000000000..0bc509f9bc --- /dev/null +++ b/libcpu/aarch64/common/up/vector_gcc.S @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2024-03-28 Shell Move vector handling codes from context_gcc.S + */ + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include "../include/vector_gcc.h" +#include "context_gcc.h" + +#include +#include +#include +#include + +.section .text + + .align 8 + .globl vector_fiq +vector_fiq: + SAVE_IRQ_CONTEXT + stp x0, x1, [sp, #-0x10]! + bl rt_hw_trap_fiq + ldp x0, x1, [sp], #0x10 + RESTORE_IRQ_CONTEXT + +.globl rt_interrupt_enter +.globl rt_interrupt_leave +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread + + .align 8 + .globl vector_irq +vector_irq: + SAVE_IRQ_CONTEXT + stp x0, x1, [sp, #-0x10]! /* X0 is thread sp */ + + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave + + ldp x0, x1, [sp], #0x10 + + /** + * if rt_thread_switch_interrupt_flag set, jump to + * rt_hw_context_switch_interrupt_do and don't return + */ + ldr x1, =rt_thread_switch_interrupt_flag + ldr x2, [x1] + cmp x2, #1 + b.ne vector_irq_exit + + mov x2, #0 // clear flag + str x2, [x1] + + ldr x3, =rt_interrupt_from_thread + ldr x4, [x3] + str x0, [x4] // store sp in preempted tasks's tcb + + ldr x3, =rt_interrupt_to_thread + ldr x4, [x3] + ldr x0, [x4] // get new task's stack pointer + + RESTORE_IRQ_CONTEXT + +vector_irq_exit: + RESTORE_IRQ_CONTEXT_WITHOUT_MMU_SWITCH diff --git a/libcpu/aarch64/common/vector_gcc.S b/libcpu/aarch64/common/vector_gcc.S index d765fdd89c..6475e19a01 100644 --- a/libcpu/aarch64/common/vector_gcc.S +++ b/libcpu/aarch64/common/vector_gcc.S @@ -3,12 +3,19 @@ * * SPDX-License-Identifier: Apache-2.0 * + * Change Logs: * Date Author Notes - * 2018-10-06 ZhaoXiaowei the first version + * 2018-10-06 ZhaoXiaowei the first version + * 2024-03-28 Shell Move vector handling codes from context_gcc.S */ - -.text +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif + +#include + +.text .globl system_vectors .globl vector_exception .globl vector_irq @@ -21,40 +28,71 @@ system_vectors: /* Exception from CurrentEL (EL1) with SP_EL0 (SPSEL=1) */ .org (VBAR + 0x00 + 0) - B vector_serror /* Synchronous */ + b vector_serror /* Synchronous */ .org (VBAR + 0x80 + 0) - B vector_serror /* IRQ/vIRQ */ + b vector_serror /* IRQ/vIRQ */ .org (VBAR + 0x100 + 0) - B vector_serror /* FIQ/vFIQ */ + b vector_serror /* FIQ/vFIQ */ .org (VBAR + 0x180 + 0) - B vector_serror /* Error/vError */ + b vector_serror /* Error/vError */ /* Exception from CurrentEL (EL1) with SP_ELn */ .org (VBAR + 0x200 + 0) - B vector_exception /* Synchronous */ + b vector_exception /* Synchronous */ .org (VBAR + 0x280 + 0) - B vector_irq /* IRQ/vIRQ */ + b vector_irq /* IRQ/vIRQ */ .org (VBAR + 0x300 + 0) - B vector_fiq /* FIQ/vFIQ */ + b vector_fiq /* FIQ/vFIQ */ .org (VBAR + 0x380 + 0) - B vector_serror + b vector_serror /* Exception from lower EL, aarch64 */ .org (VBAR + 0x400 + 0) - B vector_exception + b vector_exception .org (VBAR + 0x480 + 0) - B vector_irq + b vector_irq .org (VBAR + 0x500 + 0) - B vector_fiq + b vector_fiq .org (VBAR + 0x580 + 0) - B vector_serror + b vector_serror /* Exception from lower EL, aarch32 */ .org (VBAR + 0x600 + 0) - B vector_serror + b vector_serror .org (VBAR + 0x680 + 0) - B vector_serror + b vector_serror .org (VBAR + 0x700 + 0) - B vector_serror + b vector_serror .org (VBAR + 0x780 + 0) - B vector_serror + b vector_serror + +#include "include/vector_gcc.h" + +START_POINT(vector_exception) + SAVE_IRQ_CONTEXT + stp x0, x1, [sp, #-0x10]! +#ifdef RT_USING_SMART + SAVE_USER_CTX +#endif + + bl rt_hw_trap_exception +#ifdef RT_USING_SMART + ldp x0, x1, [sp] + RESTORE_USER_CTX x0 +#endif + + ldp x0, x1, [sp], #0x10 + RESTORE_IRQ_CONTEXT_WITHOUT_MMU_SWITCH +START_POINT_END(vector_exception) + +START_POINT(vector_serror) + SAVE_IRQ_CONTEXT + +#ifdef RT_USING_SMART + SAVE_USER_CTX +#endif + + stp x0, x1, [sp, #-0x10]! + bl rt_hw_trap_serror + b . +START_POINT_END(vector_serror) -- cgit v1.3.1