From d18a43e0f062c5702e090d90e8fc938022d3788d Mon Sep 17 00:00:00 2001 From: Richard Elberger Date: Wed, 24 Jun 2026 09:09:30 -0400 Subject: [PATCH] armv9: optimize portASM.S barriers, ISB merge, IRQ register save MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove redundant memory barriers that the ARM architecture guarantees are unnecessary, merge ISB instructions, and eliminate an unneeded callee-saved register save in the IRQ handler. Changes: - Remove DSB SY after MSR DAIFSET in FreeRTOS_IRQ_Handler (ARM ARM §D1.7.1: DAIF change effective immediately) - Remove DSB SY + ISB SY before ERET on both IRQ exit paths (ARM ARM §D1.10.2: ERET is a context synchronization event) - Merge PAC key restore ISB with ICC_PMR_EL1 ISB — single ISB now synchronizes both sets of system register writes - Remove X19 from IRQ volatile save/restore (AAPCS64 §6.1.1: X19 is callee-saved, preserved across BL vApplicationIRQHandler) - Add configARMV9_PAC_KEYS option (4/2/1) to control how many PAC key pairs are saved per context switch (default: all 4) - Update DSB SY comment after ICC_PMR_EL1 to reference GIC spec IHI 0069H §12.1.6 justification for keeping it Validated: FVP demo passes (SVE ctx, PAC ctx, emboss filter). --- portable/GCC/ARM_AARCH64_ARMV9/port.c | 2 +- portable/GCC/ARM_AARCH64_ARMV9/portASM.S | 36 +++++++++++++++--------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/portable/GCC/ARM_AARCH64_ARMV9/port.c b/portable/GCC/ARM_AARCH64_ARMV9/port.c index a68f4b6d9..3acf21a63 100644 --- a/portable/GCC/ARM_AARCH64_ARMV9/port.c +++ b/portable/GCC/ARM_AARCH64_ARMV9/port.c @@ -699,4 +699,4 @@ void vPortTaskSetVL( uint32_t ulVL ) __asm volatile( "MSR S3_0_C1_C2_0, %0\n ISB\n" :: "r"( (uint64_t)ulVL ) ); } -#endif /* configARMV9_TASK_VL */ \ No newline at end of file +#endif /* configARMV9_TASK_VL */ diff --git a/portable/GCC/ARM_AARCH64_ARMV9/portASM.S b/portable/GCC/ARM_AARCH64_ARMV9/portASM.S index 79713ae55..52b43a150 100644 --- a/portable/GCC/ARM_AARCH64_ARMV9/portASM.S +++ b/portable/GCC/ARM_AARCH64_ARMV9/portASM.S @@ -179,19 +179,26 @@ 1: #if ( configARMV9_PAC == 1 ) - /* Save PAC keys (4 key pairs = 8 registers = 64 bytes) */ + /* Save PAC keys. configARMV9_PAC_KEYS controls how many key pairs: + * 4 = all (APIA+APIB+APDA+APDB), 2 = APIA+APDA, 1 = APIA only. */ MRS X9, APIAKeyLo_EL1 MRS X10, APIAKeyHi_EL1 STP X9, X10, [SP, #-0x10]! +#if ( !defined( configARMV9_PAC_KEYS ) || configARMV9_PAC_KEYS >= 4 ) MRS X9, APIBKeyLo_EL1 MRS X10, APIBKeyHi_EL1 STP X9, X10, [SP, #-0x10]! +#endif +#if ( !defined( configARMV9_PAC_KEYS ) || configARMV9_PAC_KEYS >= 2 ) MRS X9, APDAKeyLo_EL1 MRS X10, APDAKeyHi_EL1 STP X9, X10, [SP, #-0x10]! +#endif +#if ( !defined( configARMV9_PAC_KEYS ) || configARMV9_PAC_KEYS >= 4 ) MRS X9, APDBKeyLo_EL1 MRS X10, APDBKeyHi_EL1 STP X9, X10, [SP, #-0x10]! +#endif #endif /* configARMV9_PAC */ /* Store the critical nesting count and FPU context indicator. */ @@ -223,20 +230,26 @@ LDP X2, X3, [SP], #0x10 /* Critical nesting and FPU context. */ #if ( configARMV9_PAC == 1 ) - /* Restore PAC keys (reverse order of save) */ + /* Restore PAC keys (reverse order of save). */ +#if ( !defined( configARMV9_PAC_KEYS ) || configARMV9_PAC_KEYS >= 4 ) LDP X9, X10, [SP], #0x10 MSR APDBKeyLo_EL1, X9 MSR APDBKeyHi_EL1, X10 +#endif +#if ( !defined( configARMV9_PAC_KEYS ) || configARMV9_PAC_KEYS >= 2 ) LDP X9, X10, [SP], #0x10 MSR APDAKeyLo_EL1, X9 MSR APDAKeyHi_EL1, X10 +#endif +#if ( !defined( configARMV9_PAC_KEYS ) || configARMV9_PAC_KEYS >= 4 ) LDP X9, X10, [SP], #0x10 MSR APIBKeyLo_EL1, X9 MSR APIBKeyHi_EL1, X10 +#endif LDP X9, X10, [SP], #0x10 MSR APIAKeyLo_EL1, X9 MSR APIAKeyHi_EL1, X10 - ISB + /* ISB deferred: merged with ISB after ICC_PMR_EL1 write below. */ #endif /* configARMV9_PAC */ /* Set the PMR register to be correct for the current critical nesting @@ -249,8 +262,8 @@ LDR X1, [X6] /* X1 holds the mask value. */ 1: MSR s3_0_c4_c6_0, X1 /* Write the mask value to ICCPMR. s3_0_c4_c6_0 is ICC_PMR_EL1. */ - DSB SY /* _RB_Barriers probably not required here. */ - ISB SY + DSB SY /* Required when ICC_CTLR_EL1.PMHE==1 (GIC IHI 0069H §12.1.6). */ + ISB SY /* Synchronizes both PAC key and PMR writes. */ STR X3, [X0] /* Restore the task's critical nesting count. */ /* Restore the FPU context indicator. */ @@ -465,7 +478,7 @@ FreeRTOS_IRQ_Handler: STP X12, X13, [SP, #-0x10]! STP X14, X15, [SP, #-0x10]! STP X16, X17, [SP, #-0x10]! - STP X18, X19, [SP, #-0x10]! + STP X18, XZR, [SP, #-0x10]! /* X19 is callee-saved; preserved by BL vApplicationIRQHandler. */ STP X29, X30, [SP, #-0x10]! /* Save the SPSR and ELR. */ @@ -499,7 +512,6 @@ FreeRTOS_IRQ_Handler: /* Disable interrupts. */ MSR DAIFSET, #2 - DSB SY ISB SY /* Restore the interrupt ID value. */ @@ -535,11 +547,10 @@ FreeRTOS_IRQ_Handler: MSR SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */ MSR ELR_EL3, X4 #endif - DSB SY - ISB SY + /* DSB+ISB removed: portSAVE_CONTEXT follows, then ERET in portRESTORE_CONTEXT. */ LDP X29, X30, [SP], #0x10 - LDP X18, X19, [SP], #0x10 + LDP X18, XZR, [SP], #0x10 LDP X16, X17, [SP], #0x10 LDP X14, X15, [SP], #0x10 LDP X12, X13, [SP], #0x10 @@ -565,11 +576,10 @@ Exit_IRQ_No_Context_Switch: MSR SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */ MSR ELR_EL3, X4 #endif - DSB SY - ISB SY + /* DSB+ISB removed: ERET is a context synchronization event (ARM ARM §D1.10.2). */ LDP X29, X30, [SP], #0x10 - LDP X18, X19, [SP], #0x10 + LDP X18, XZR, [SP], #0x10 LDP X16, X17, [SP], #0x10 LDP X14, X15, [SP], #0x10 LDP X12, X13, [SP], #0x10