ARM64-A移植说明
4 分钟阅读
概述
XWOS的源码中,已包含了大部分ARM64-Cortex-A架构的代码:
- 架构描述层(ADL)
- ARMv8a:
XWOS/xwcd/soc/arm/v8a
- ARMv8a:
- CPU描述层(CDL)
- m0:
XWOS/xwcd/soc/arm/v8a/a72 - m0p:
XWOS/xwcd/soc/arm/v8a/a76a55
- m0:
- SOC描述层(SDL)
- UNISOC A7870:
XWOS/xwcd/soc/arm/v8a/a76a55/a7870 - 树莓派4B SOC:
XWOS/xwcd/soc/arm/v8a/a72/bcm2711
- UNISOC A7870:
新的SOC芯片,只需在CPU文件夹中增加SOC文件夹,其中包括:
- 初始化:
soc_init.h与soc_init.c - 中断:
xwosimpl_irq.h与xwosimpl_irq.c- 其中需要给出XWOS内核移植层(XWOSPL)
XWOS/xwos/ospl/irq.h中声明的函数的实现。
- 其中需要给出XWOS内核移植层(XWOSPL)
- 调度器:
xwosimpl_skd.h与xwosimpl_skd.c- 其中需要给出XWOS内核移植层(XWOSPL)
XWOS/xwos/ospl/skd.h中声明的函数的实现。
- 其中需要给出XWOS内核移植层(XWOSPL)
- 滴答定时器:
xwosimpl_syshwt.h与xwosimpl_syshwt.c- 其中需要给出XWOS内核移植层(XWOSPL)
XWOS/xwos/ospl/syshwt.h中声明的函数的实现。
- 其中需要给出XWOS内核移植层(XWOSPL)
.lds:链接脚本
类型的定义
XWOS内核移植层(XWOSPL) XWOS/xwos/ospl/type.h 要求SOC给出标准类型的定义:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_type.h
编译器的宏定义
XWOS移植实现层位于:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_compiler.h
- gcc:
XWOS/xwcd/soc/arm/v8a/compiler/gcc.h - llvm:
XWOS/xwcd/soc/arm/v8a/compiler/llvm.h
无锁队列的实现
XWOS移植实现层位于:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_lfq.h
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_lfq.c
自旋锁
XWOS移植实现层位于:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_spinlock.h
架构指令
XWOS移植实现层位于:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_isa.h
位操作
XWOS移植实现层位于:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_xwbop.c
8位原子操作
XWOS内核移植层(XWOSPL) XWOS/xwos/ospl/xwaop8.h 要求SOC在汇编指令层面给出单字节原子操作的实现:
XWOS/xwcd/soc/arm/v8a/xwaop/s8.c
XWOS/xwcd/soc/arm/v8a/xwaop/u8.c
16位原子操作
XWOS内核移植层(XWOSPL) XWOS/xwos/ospl/xwaop16.h 要求SOC在汇编指令层面给出双字节原子操作的实现:
XWOS/xwcd/soc/arm/v8a/xwaop/s16.c
XWOS/xwcd/soc/arm/v8a/xwaop/u16.c
32位原子操作
XWOS内核移植层(XWOSPL) XWOS/xwos/ospl/xwaop32.h 要求SOC在汇编指令层面给出4字节原子操作的实现:
XWOS/xwcd/soc/arm/v8a/xwaop/s32.c
XWOS/xwcd/soc/arm/v8a/xwaop/u32.c
64位原子操作
XWOS内核移植层(XWOSPL) XWOS/xwos/ospl/xwaop64.h 要求SOC在汇编指令层面给出8字节原子操作的实现:
XWOS/xwcd/soc/arm/v8a/xwaop/s64.c
XWOS/xwcd/soc/arm/v8a/xwaop/u64.c
系统初始化
-
SPSel设置为1,不同EL等级使用不同的SP寄存器 -
SCTLR_EL1.EE = 0:选择小端格式 -
SCTLR_EL1.SA = 1:开启stack对齐检测 -
SCTLR_EL1.A = 0:关闭对齐检测,对齐检测经常导致进sync异常 -
SCTLR_EL1.C = 1:开启数据缓存 -
SCTLR_EL1.I = 1:开启指令缓存 -
SCTLR_EL2.EE = 0:选择小端格式 -
SCTLR_EL2.SA = 1:开启stack对齐检测 -
SCTLR_EL2.A = 0:关闭对齐检测,对齐检测经常导致进sync异常 -
SCTLR_EL2.C = 1:开启数据缓存 -
SCTLR_EL2.I = 1:开启指令缓存 -
CPACR_EL1.FPEN = 0b11:开启浮点单元 -
暂时不启用虚拟化
HCR_EL2.VM = 0
HCR_EL2.TGE = 0
中断
XWOS移植实现层位于:
XWOS/xwcd/soc/arm/v8a/[CPU]/[SOC]/xwosimpl_irq.h
XWOS/xwcd/soc/arm/v8a/[CPU]/[SOC]/xwosimpl_irq.c
- 不在EL3响应异常
SCR_EL3.FIQ = 0
SCR_EL3.IRQ = 0
HCR_EL3.EA = 0
HCR_EL3.HCE = 1 开启 HVC 指令
-
CPTR_EL3中关闭trap -
CPTR_EL2中关闭trap -
在EL2中处理中断
HCR_EL2.AMO = 1
HCR_EL2.IMO = 1
HCR_EL2.FMO = 1
调度器
XWOS内核移植层(XWOSPL) XWOS/xwos/ospl/skd.h 要求SOC提供调度器切换上下文等操作的实现:
XWOS/xwcd/soc/arm/v8a/[CPU]/[SOC]/xwosimpl_skd.h
XWOS/xwcd/soc/arm/v8a/[CPU]/[SOC]/xwosimpl_skd.c
基于ARM-V8A架构的Soc的具体实现方法基本相同。因此又可以统一实现为:
XWOS/xwcd/soc/arm/v8a/arch_skd.h
XWOS/xwcd/soc/arm/v8a/arch_skd.c
XWOS内核运行在EL2,使用sp_el2
线程
线程运行在 EL2T ,内核运行在 EL2H 。
栈
- 按照AAPCS64的要求,使用 16字节对齐 的 满递减 栈,
因此配置文件
cfg/xwos.hXWMMCFG_FD_STACK配置为1XWMMCFG_ALIGNMENT配置为16U
栈结构
+------------+-----------------------------+
sp+0x31c | reserved | |
sp+0x318 | reserved | |
sp+0x314 | FPCR | |
sp+0x310 | FPSR | volatile (caller-saved) |
+------------+-----------------------------+
sp+0x300 | q31 | volatile (caller-saved) |
sp+0x2F0 | q30 | volatile (caller-saved) |
sp+0x2E0 | q29 | volatile (caller-saved) |
sp+0x2D0 | q28 | volatile (caller-saved) |
sp+0x2C0 | q27 | volatile (caller-saved) |
sp+0x2B0 | q26 | volatile (caller-saved) |
sp+0x2A0 | q25 | volatile (caller-saved) |
sp+0x290 | q24 | volatile (caller-saved) |
sp+0x280 | q23 | volatile (caller-saved) |
sp+0x270 | q22 | volatile (caller-saved) |
sp+0x260 | q21 | volatile (caller-saved) |
sp+0x250 | q20 | volatile (caller-saved) |
sp+0x240 | q19 | volatile (caller-saved) |
sp+0x230 | q18 | volatile (caller-saved) |
sp+0x220 | q17 | volatile (caller-saved) |
sp+0x210 | q16 | volatile (caller-saved) |
+------------+-----------------------------+
sp+0x200 | q15 | non-volatile (callee-saved) |
sp+0x1F0 | q14 | non-volatile (callee-saved) |
sp+0x1E0 | q13 | non-volatile (callee-saved) |
sp+0x1D0 | q12 | non-volatile (callee-saved) |
sp+0x1C0 | q11 | non-volatile (callee-saved) |
sp+0x1B0 | q10 | non-volatile (callee-saved) |
sp+0x1A0 | q9 | non-volatile (callee-saved) |
sp+0x190 | q8 | non-volatile (callee-saved) |
+------------+-----------------------------+
sp+0x180 | q7 | volatile (caller-saved) |
sp+0x170 | q6 | volatile (caller-saved) |
sp+0x160 | q5 | volatile (caller-saved) |
sp+0x150 | q4 | volatile (caller-saved) |
sp+0x140 | q3 | volatile (caller-saved) |
sp+0x130 | q2 | volatile (caller-saved) |
sp+0x120 | q1 | volatile (caller-saved) |
sp+0x110 | q0 | volatile (caller-saved) |
+------------+-----------------------------+
sp+0x108 | spsr | volatile (caller-saved) |
sp+0x100 | pc(elr) | volatile (caller-saved) |
sp+0xF8 | sp | volatile (caller-saved) |
sp+0xF0 | lr | volatile (caller-saved) |
---------+------------+-----------------------------+
sp+0xE8 | x29 | non-volatile (callee-saved) |
sp+0xE0 | x28 | non-volatile (callee-saved) |
sp+0xD8 | x27 | non-volatile (callee-saved) |
sp+0xD0 | x26 | non-volatile (callee-saved) |
sp+0xC8 | x25 | non-volatile (callee-saved) |
sp+0xC0 | x24 | non-volatile (callee-saved) |
sp+0xB8 | x23 | non-volatile (callee-saved) |
sp+0xB0 | x22 | non-volatile (callee-saved) |
sp+0xA8 | x21 | non-volatile (callee-saved) |
sp+0xA0 | x20 | non-volatile (callee-saved) |
sp+0x98 | x19 | non-volatile (callee-saved) |
sp+0x90 | x18 | non-volatile (callee-saved) |
---------+------------+-----------------------------+
sp+0x88 | x17 | volatile (caller-saved) |
sp+0x80 | x16 | volatile (caller-saved) |
sp+0x78 | x15 | volatile (caller-saved) |
sp+0x70 | x14 | volatile (caller-saved) |
sp+0x68 | x13 | volatile (caller-saved) |
sp+0x60 | x12 | volatile (caller-saved) |
sp+0x58 | x11 | volatile (caller-saved) |
sp+0x50 | x10 | volatile (caller-saved) |
sp+0x48 | x9 | volatile (caller-saved) |
sp+0x40 | x8 | volatile (caller-saved) |
sp+0x38 | x7 | volatile (caller-saved) |
sp+0x30 | x6 | volatile (caller-saved) |
sp+0x28 | x5 | volatile (caller-saved) |
sp+0x20 | x4 | volatile (caller-saved) |
sp+0x18 | x3 | volatile (caller-saved) |
sp+0x10 | x2 | volatile (caller-saved) |
sp+0x08 | x1 | volatile (caller-saved) |
sp+0x00 | x0 | volatile (caller-saved) |
--------------------------------------------
- 说明:x18寄存器按照官方手册描述,应该为 caller-saved ,
但Linux内核将此寄存器用作 ShadowCallStack 的指针(配置
CONFIG_SHADOW_CALL_STACK为y时), 此时x18应该为 callee-saved 的。 - XWOS和Linux保持一致,因此x18也为 callee-saved 。
- 需要增加编译选项
-ffixed-x18。
注意 目前版本的XWOS,还未实现浮点上下文的保存与恢复,计划基于Lazy Save and Restore技术实现:
- SIMD的寄存器(q0~q31)
- ARMv8.2-A推出SVE,q0
q31扩展为z0z31,寄存器变长,最长2048位- ARMv9-A推出SVE2,又多出16个谓词寄存器(P0-P15)
- ARMv9-A推出SME,又多出ZA寄存器,最大可达64KiB
滴答定时器
XWOS内核移植层(XWOSPL) XWOS/xwos/ospl/syshwt.h 要求SOC给出滴答定时器的实现:
xwcd/soc/arm/v8a/[CPU]/[SOC]/xwosimpl_soc_syshwt.h
xwcd/soc/arm/v8a/[CPU]/[SOC]/xwosimpl_soc_syshwt.c
XWOS运行在EL2,使用cnthp:
xwcd/soc/arm/v8a/arch_timer.h
xwcd/soc/arm/v8a/arch_timer.c