ARM64-A移植说明

概述

XWOS的源码中,已包含了大部分ARM64-Cortex-A架构的代码:

  • 架构描述层(ADL)
    • ARMv8a: XWOS/xwcd/soc/arm/v8a
  • CPU描述层(CDL)
    • m0: XWOS/xwcd/soc/arm/v8a/a72
    • m0p: XWOS/xwcd/soc/arm/v8a/a76a55
  • SOC描述层(SDL)
    • UNISOC A7870: XWOS/xwcd/soc/arm/v8a/a76a55/a7870
    • 树莓派4B SOC: XWOS/xwcd/soc/arm/v8a/a72/bcm2711

新的SOC芯片,只需在CPU文件夹中增加SOC文件夹,其中包括:

  • 初始化: soc_init.hsoc_init.c
  • 中断: xwosimpl_irq.hxwosimpl_irq.c
    • 其中需要给出XWOS内核移植层(XWOSPL) XWOS/xwos/ospl/irq.h 中声明的函数的实现。
  • 调度器: xwosimpl_skd.hxwosimpl_skd.c
    • 其中需要给出XWOS内核移植层(XWOSPL) XWOS/xwos/ospl/skd.h 中声明的函数的实现。
  • 滴答定时器: xwosimpl_syshwt.hxwosimpl_syshwt.c
    • 其中需要给出XWOS内核移植层(XWOSPL) XWOS/xwos/ospl/syshwt.h 中声明的函数的实现。
  • .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.h
    • XWMMCFG_FD_STACK 配置为 1
    • XWMMCFG_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_STACKy 时), 此时x18应该为 callee-saved 的。
  • XWOS和Linux保持一致,因此x18也为 callee-saved
  • 需要增加编译选项 -ffixed-x18

注意 目前版本的XWOS,还未实现浮点上下文的保存与恢复,计划基于Lazy Save and Restore技术实现:

  • SIMD的寄存器(q0~q31)
  • ARMv8.2-A推出SVE,q0q31扩展为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