diff options
| author | Frédéric Desbiens <[email protected]> | 2026-08-13 17:07:36 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-08-13 17:07:36 -0400 |
| commit | b877305d13ea2a45d40cb86416adc24938bbe154 (patch) | |
| tree | e76a9f414c2e424bccb67bd27b073e56cef7d0e8 /common_modules/module_manager/src/txm_module_manager_callback_request.c | |
| parent | c991c9e6aebc32a99667ca2941d5b839f5b2b1cd (diff) | |
Verified lazy VFP context switching on S32Z280 silicon (#609)
The FVP proved the lazy save and restore path at AR1/M5, but the board had never
run it. Doing so needed one thing the model did not: the FPU has to be turned on.
entry.S opens CPACR for CP10/CP11 and sets FPEXC.EN at EL1, guarded by __ARM_FP.
EL2 already cleared HCPTR.TCP10/TCP11, but both of the EL1 gates read 0 out of
reset, so a floating-point instruction raised an Undefined Instruction exception
before this. tx_thread_vfp_enable() does not help: it sets the per-thread software
flag that makes the context switch save and restore the registers, and never
touches the hardware. Enabling it is the BSP's job. The __ARM_FP guard is what
keeps a soft-float build assemblable, since "vmsr fpexc" is not a valid
instruction for that target at all.
demo_vfp_s32z280.c is the FVP's demo_m5.c test design over the LINFlexD console.
The design is kept deliberately, because the two halves of the VFP context path
need separate provocation: "fp check" holds eight live doubles across
tx_thread_sleep, eight being enough to force the callee-saved D8-D15 bank that a
solicited switch must preserve, while "fp busy" sits at the lowest priority and
never sleeps, so the tick interrupts it mid-computation and exercises the
interrupt half, D0-D15 plus FPSCR. Only these two threads opt in, so the test
also shows that opting in is what does the work.
s32z280_vfp.elf is gated on TX_R52_ENABLE_VFP, as demo_m5.elf is in the FVP
example, since the image is meaningless unless the library was built with a
floating-point ABI.
Also made this example's -Wl,--no-warn-rwx-segments conditional on the compiler
being GNU. #604 did that for the FVP example and this file still carried the
literal, so ld.lld failed the link with "unknown argument". With that fixed the
S32Z280 images build with Arm Toolchain for Embedded too.
Verified on S32Z280 silicon:
V2 D8-D15 bank preserved across switches PASS 50 solicited switches
iterations = 0x000140A8 82,088 interrupted rounds
corruptions = 0x00000000
V3 interrupted FP thread made progress PASS
V4 no FP corruption across interrupts PASS
filex_ptr = 0xF11EF11E
V5 VFP flag did not alias filex_ptr PASS
PASS lazy VFP context switch verified on silicon
No regression: the soft-float build is warning-free and its image contains no vmsr
at all, confirming the guard elides the block, and the existing demo still reports
100 ticks with 20 preemptions on the board. Both S32Z280 images also build with
Arm Toolchain for Embedded 22.1.0, the hard-float VFP image included. No FVP file
is touched.
Assisted-by: Claude Code (Opus 5) <[email protected]>
Diffstat (limited to 'common_modules/module_manager/src/txm_module_manager_callback_request.c')
0 files changed, 0 insertions, 0 deletions
