ARM64-A Porting Guide
6 minute read
Overview
XWOS source code already includes most of the ARM64-Cortex-A architecture code:
- Architecture Description Layer (ADL)
- ARMv8a:
XWOS/xwcd/soc/arm/v8a
- ARMv8a:
- CPU Description Layer (CDL)
- m0:
XWOS/xwcd/soc/arm/v8a/a72 - m0p:
XWOS/xwcd/soc/arm/v8a/a76a55
- m0:
- SoC Description Layer (SDL)
- UNISOC A7870:
XWOS/xwcd/soc/arm/v8a/a76a55/a7870 - Raspberry Pi 4B SoC:
XWOS/xwcd/soc/arm/v8a/a72/bcm2711
- UNISOC A7870:
For a new SoC chip, you only need to add an SoC folder in the CPU folder, which includes:
- Initialization:
soc_init.handsoc_init.c - Interrupts:
xwosimpl_irq.handxwosimpl_irq.c- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
XWOS/xwos/ospl/irq.h.
- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
- Scheduler:
xwosimpl_skd.handxwosimpl_skd.c- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
XWOS/xwos/ospl/skd.h.
- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
- Tick Timer:
xwosimpl_syshwt.handxwosimpl_syshwt.c- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
XWOS/xwos/ospl/syshwt.h.
- Must provide implementations for functions declared in the XWOS Kernel Porting Layer (XWOSPL)
.lds: Linker script
Type Definitions
The XWOS Kernel Porting Layer (XWOSPL) XWOS/xwos/ospl/type.h requires the SoC to provide definitions of standard types:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_type.h
Compiler Macro Definitions
The XWOS Porting Implementation Layer is located at:
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
Lock-Free Queue Implementation
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_lfq.h
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_lfq.c
Spinlock
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_spinlock.h
Architecture Instructions
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_isa.h
Bit Operations
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v8a/xwosimpl_arch_xwbop.c
8-bit Atomic Operations
The XWOS Kernel Porting Layer (XWOSPL) XWOS/xwos/ospl/xwaop8.h requires the SoC to provide single-byte atomic operation implementations at the assembly instruction level:
XWOS/xwcd/soc/arm/v8a/xwaop/s8.c
XWOS/xwcd/soc/arm/v8a/xwaop/u8.c
16-bit Atomic Operations
The XWOS Kernel Porting Layer (XWOSPL) XWOS/xwos/ospl/xwaop16.h requires the SoC to provide double-byte atomic operation implementations at the assembly instruction level:
XWOS/xwcd/soc/arm/v8a/xwaop/s16.c
XWOS/xwcd/soc/arm/v8a/xwaop/u16.c
32-bit Atomic Operations
The XWOS Kernel Porting Layer (XWOSPL) XWOS/xwos/ospl/xwaop32.h requires the SoC to provide 4-byte atomic operation implementations at the assembly instruction level:
XWOS/xwcd/soc/arm/v8a/xwaop/s32.c
XWOS/xwcd/soc/arm/v8a/xwaop/u32.c
64-bit Atomic Operations
The XWOS Kernel Porting Layer (XWOSPL) XWOS/xwos/ospl/xwaop64.h requires the SoC to provide 8-byte atomic operation implementations at the assembly instruction level:
XWOS/xwcd/soc/arm/v8a/xwaop/s64.c
XWOS/xwcd/soc/arm/v8a/xwaop/u64.c
System Initialization
-
SPSelset to1: Different EL levels use different SP registers -
SCTLR_EL1.EE = 0: Select little-endian format -
SCTLR_EL1.SA = 1: Enable stack alignment check -
SCTLR_EL1.A = 0: Disable alignment check, as alignment checks often cause sync exceptions -
SCTLR_EL1.C = 1: Enable data cache -
SCTLR_EL1.I = 1: Enable instruction cache -
SCTLR_EL2.EE = 0: Select little-endian format -
SCTLR_EL2.SA = 1: Enable stack alignment check -
SCTLR_EL2.A = 0: Disable alignment check, as alignment checks often cause sync exceptions -
SCTLR_EL2.C = 1: Enable data cache -
SCTLR_EL2.I = 1: Enable instruction cache -
CPACR_EL1.FPEN = 0b11: Enable floating-point unit -
Virtualization is temporarily not enabled
HCR_EL2.VM = 0
HCR_EL2.TGE = 0
Interrupts
The XWOS Porting Implementation Layer is located at:
XWOS/xwcd/soc/arm/v8a/[CPU]/[SoC]/xwosimpl_irq.h
XWOS/xwcd/soc/arm/v8a/[CPU]/[SoC]/xwosimpl_irq.c
- Exceptions are not handled in EL3
SCR_EL3.FIQ = 0
SCR_EL3.IRQ = 0
HCR_EL3.EA = 0
HCR_EL3.HCE = 1: Enable HVC instruction
-
Disable traps in
CPTR_EL3 -
Disable traps in
CPTR_EL2 -
Handle interrupts in EL2
HCR_EL2.AMO = 1
HCR_EL2.IMO = 1
HCR_EL2.FMO = 1
Scheduler
The XWOS Kernel Porting Layer (XWOSPL) XWOS/xwos/ospl/skd.h requires the SoC to provide implementations for scheduler context switching and other operations:
XWOS/xwcd/soc/arm/v8a/[CPU]/[SoC]/xwosimpl_skd.h
XWOS/xwcd/soc/arm/v8a/[CPU]/[SoC]/xwosimpl_skd.c
The specific implementation methods for SoCs based on the ARM-V8A architecture are essentially the same. Therefore, they can be uniformly implemented as:
XWOS/xwcd/soc/arm/v8a/arch_skd.h
XWOS/xwcd/soc/arm/v8a/arch_skd.c
The XWOS kernel runs at EL2, using sp_el2
Thread
Threads run at EL2T, the kernel runs at EL2H.
Stack
- According to AAPCS64 requirements, a 16-byte aligned full descending stack is used,
therefore in the configuration file
cfg/xwos.h:XWMMCFG_FD_STACKis configured as1XWMMCFG_ALIGNMENTis configured as16U
Stack Layout
+------------+-----------------------------+
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) |
--------------------------------------------
- Note: According to the official manual, the x18 register should be caller-saved,
but the Linux kernel uses this register as the ShadowCallStack pointer (when configuration
CONFIG_SHADOW_CALL_STACKisy), in which case x18 should be callee-saved. - XWOS follows Linux’s convention, so x18 is also callee-saved.
- The compilation option
-ffixed-x18needs to be added.
Note: The current version of XWOS has not yet implemented saving and restoring of floating-point context. It plans to be implemented based on Lazy Save and Restore technology:
- SIMD registers (q0~q31)
- ARMv8.2-A introduced SVE, q0
q31 extended to z0z31, variable-length registers, up to 2048 bits- ARMv9-A introduced SVE2, adding 16 predicate registers (P0-P15)
- ARMv9-A introduced SME, adding the ZA register, up to 64KiB
Tick Timer
The XWOS Kernel Porting Layer (XWOSPL) XWOS/xwos/ospl/syshwt.h requires the SoC to provide an implementation of the tick timer:
xwcd/soc/arm/v8a/[CPU]/[SoC]/xwosimpl_soc_syshwt.h
xwcd/soc/arm/v8a/[CPU]/[SoC]/xwosimpl_soc_syshwt.c
XWOS runs at EL2, using cnthp:
xwcd/soc/arm/v8a/arch_timer.h
xwcd/soc/arm/v8a/arch_timer.c