原始版本

This commit is contained in:
冯佳
2025-06-19 21:56:46 +08:00
parent fe98e5f010
commit a4841450cf
4152 changed files with 1910684 additions and 0 deletions

View File

@ -0,0 +1,187 @@
/*
* 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__
#include <rtconfig.h>
#ifdef ARCH_USING_HW_THREAD_SELF
#define ARM64_THREAD_REG tpidr_el1
#endif /* ARCH_USING_HW_THREAD_SELF */
#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 <rttypes.h>
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];
};
void rt_hw_show_register(struct rt_hw_exp_stack *regs);
#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

View File

@ -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__ */

View File

@ -0,0 +1,45 @@
/*
* 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;
#define TRACE_SYMBOL(name)
.macro NEVER_RETURN
#ifdef RT_USING_DEBUG
b .
#endif /* RT_USING_DEBUG */
.endm
.macro GET_THREAD_SELF, dst:req
#ifdef ARCH_USING_HW_THREAD_SELF
mrs x0, tpidr_el1
#else /* !ARCH_USING_HW_THREAD_SELF */
bl rt_thread_self
#endif /* ARCH_USING_HW_THREAD_SELF */
.if \dst != x0
mov dst, x0
.endif
.endm
#endif /* __ASM_GENERIC_H__ */

View File

@ -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 <rtdef.h>
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__ */

View File

@ -0,0 +1,71 @@
/*
* 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__
#include "armv8.h"
.macro SAVE_CONTEXT_SWITCH, tmpx, tmp2x
/* Save the entire context. */
SAVE_FPU sp
stp x19, x20, [sp, #-0x10]!
stp x21, x22, [sp, #-0x10]!
stp x23, x24, [sp, #-0x10]!
stp x25, x26, [sp, #-0x10]!
stp x27, x28, [sp, #-0x10]!
mrs \tmpx, sp_el0
stp x29, \tmpx, [sp, #-0x10]!
mrs \tmpx, fpcr
mrs \tmp2x, fpsr
stp \tmpx, \tmp2x, [sp, #-0x10]!
mov \tmpx, #((3 << 6) | 0x5) /* el1h, disable interrupt */
stp x30, \tmpx, [sp, #-0x10]!
.endm
.macro SAVE_CONTEXT_SWITCH_FAST
/* Save the entire context. */
add sp, sp, #-1 * CONTEXT_FPU_SIZE
add sp, sp, #-7 * 16
mov x19, #((3 << 6) | 0x4 | 0x1) /* el1h, disable interrupt */
stp lr, x19, [sp, #-0x10]!
.endm
.macro _RESTORE_CONTEXT_SWITCH
ldp x30, x19, [sp], #0x10 /* SPSR and ELR. */
msr elr_el1, x30
msr spsr_el1, x19
/* restore NEON */
ldp x19, x20, [sp], #0x10
msr fpcr, x19
msr fpsr, x20
ldp x29, x19, [sp], #0x10
msr sp_el0, x19
ldp x27, x28, [sp], #0x10
ldp x25, x26, [sp], #0x10
ldp x23, x24, [sp], #0x10
ldp x21, x22, [sp], #0x10
ldp x19, x20, [sp], #0x10
RESTORE_FPU sp
eret
.endm
#endif /* __ARM64_INC_CONTEXT_H__ */

View File

@ -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

View File

@ -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 <rtdef.h>
#include <cpuport.h>
#include <mm_aspace.h>
#ifdef RT_USING_OFW
#include <drivers/ofw.h>
#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__ */

View File

@ -0,0 +1,21 @@
#ifndef __CPU_OPS_COMMON_H__
#define __CPU_OPS_COMMON_H__
#include <rthw.h>
#include <rtthread.h>
#include <mmu.h>
#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__ */

View File

@ -0,0 +1,72 @@
/*
* 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 <armv8.h>
#include <rtcompiler.h>
#include <rttypes.h>
#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 ARCH_USING_HW_THREAD_SELF
rt_inline struct rt_thread *rt_hw_thread_self(void)
{
struct rt_thread *thread;
__asm__ volatile ("mrs %0, " RT_STRINGIFY(ARM64_THREAD_REG) :"=r"(thread));
return thread;
}
rt_inline void rt_hw_thread_set_self(struct rt_thread *thread)
{
__asm__ volatile ("msr " RT_STRINGIFY(ARM64_THREAD_REG) ", %0"::"r"(thread));
}
#endif /* ARCH_USING_HW_THREAD_SELF */
#endif /*CPUPORT_H__*/

View File

@ -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__ */

View File

@ -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 <rthw.h>
#include <board.h>
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

View File

@ -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 <rtdef.h>
#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

View File

@ -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 <rtdef.h>
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__ */

View File

@ -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 <rtdef.h>
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

View File

@ -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 <rthw.h>
#include <board.h>
#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

View File

@ -0,0 +1,218 @@
/*
* 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 <rtthread.h>
#include <mm_aspace.h>
/* 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_ASID_SHIFT 48
#define MMU_NG_SHIFT 11 /* not global bit */
#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)
/* we dont support feat detecting for now, so 8-bit is used to fallback */
#define MMU_SUPPORTED_ASID_BITS 8
#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, nglobal) \
((0x1UL << MMU_AF_SHIFT) | (0x2UL << MMU_SHARED_SHIFT) | \
((ap) << MMU_AP_SHIFT) | ((mtype) << MMU_MA_SHIFT)) | \
((rt_ubase_t)(nglobal) << MMU_NG_SHIFT)
#define MMU_MAP_K_ROCB MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_MEM, 0)
#define MMU_MAP_K_RO MMU_MAP_CUSTOM(MMU_AP_KRUN, NORMAL_NOCACHE_MEM, 0)
#define MMU_MAP_K_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM, 0)
#define MMU_MAP_K_RW MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_NOCACHE_MEM, 0)
#define MMU_MAP_K_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUN, DEVICE_MEM, 0)
#define MMU_MAP_U_ROCB MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_MEM, 1)
#define MMU_MAP_U_RO MMU_MAP_CUSTOM(MMU_AP_KRUR, NORMAL_NOCACHE_MEM, 1)
#define MMU_MAP_U_RWCB MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_MEM, 1)
#define MMU_MAP_U_RW MMU_MAP_CUSTOM(MMU_AP_KAUA, NORMAL_NOCACHE_MEM, 1)
#define MMU_MAP_U_DEVICE MMU_MAP_CUSTOM(MMU_AP_KAUA, DEVICE_MEM, 1)
#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

View File

@ -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 <rtdef.h>
/*
* 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__ */

View File

@ -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 <rtdef.h>
#include <mm_aspace.h>
#ifdef RT_USING_OFW
#include <drivers/ofw_fdt.h>
#endif
void rt_hw_common_setup(void);
#endif /* __SETUP_H__ */

View File

@ -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__ */

View File

@ -0,0 +1,91 @@
/*
* 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 <rtthread.h>
#include <stddef.h>
#include <stdint.h>
#include "mm_aspace.h"
#include "mmu.h"
#define TLBI_ARG(addr, asid) \
({ \
rt_ubase_t arg = (rt_ubase_t)(addr) >> ARCH_PAGE_SHIFT; \
arg &= (1ull << 44) - 1; \
arg |= (rt_ubase_t)(asid) << MMU_ASID_SHIFT; \
(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)
{
#ifdef ARCH_USING_ASID
__asm__ volatile(
// ensure updates to pte completed
"dsb nshst\n"
"tlbi aside1is, %0\n"
"dsb nsh\n"
// after tlb in new context, refresh inst
"isb\n" ::"r"(TLBI_ARG(0ul, aspace->asid))
: "memory");
#else
rt_hw_tlb_invalidate_all();
#endif
}
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__ */

View File

@ -0,0 +1,128 @@
/*
* 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
* 2024-04-08 Shell Optimizing exception switch between u-space/kernel,
*/
#ifndef __ARM64_INC_VECTOR_H__
#define __ARM64_INC_VECTOR_H__
#include "asm-generic.h"
#include <rtconfig.h>
#include <asm-fpu.h>
#include <armv8.h>
.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]!
.endm
#ifdef RT_USING_SMP
#include "../mp/context_gcc.h"
#else
#include "../up/context_gcc.h"
#endif
.macro RESTORE_IRQ_CONTEXT_NO_SPEL0
ldp x2, x3, [sp], #0x10
msr elr_el1, x2
msr spsr_el1, x3
ldp x29, x30, [sp], #0x10
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
.endm
.macro EXCEPTION_SWITCH, eframex, tmpx
#ifdef RT_USING_SMART
/**
* test the spsr for execution level 0
* That is { PSTATE.[NZCV] := SPSR_EL1 & M.EL0t }
*/
ldr \tmpx, [\eframex, #CONTEXT_OFFSET_SPSR_EL1]
and \tmpx, \tmpx, 0x1f
cbz \tmpx, 1f
b 2f
1:
b arch_ret_to_user
2:
#endif /* RT_USING_SMART */
.endm
.macro SAVE_USER_CTX, eframex, tmpx
#ifdef RT_USING_SMART
mrs \tmpx, spsr_el1
and \tmpx, \tmpx, 0xf
cbz \tmpx, 1f
b 2f
1:
mov x0, \eframex
bl lwp_uthread_ctx_save
2:
#endif /* RT_USING_SMART */
.endm
.macro RESTORE_USER_CTX, eframex, tmpx
#ifdef RT_USING_SMART
ldr \tmpx, [\eframex, #CONTEXT_OFFSET_SPSR_EL1]
and \tmpx, \tmpx, 0x1f
cbz \tmpx, 1f
b 2f
1:
bl lwp_uthread_ctx_restore
2:
#endif /* RT_USING_SMART */
.endm
#endif /* __ARM64_INC_VECTOR_H__ */