diff options
| author | Frédéric Desbiens <[email protected]> | 2026-09-02 19:08:24 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-09-02 19:08:24 -0400 |
| commit | 13c8c768c73b9ce10c9605f6df8b02080440f953 (patch) | |
| tree | ac2023d2ccb609e2827b4f39dfb12925033cbc6e /common_modules/module_lib/src/txm_module_application_request.c | |
| parent | 8c681c188ee748c777185e229024255c054a49d9 (diff) | |
Added the boot-at-EL1 option to the S32Z280 entry path (#690)
The Armv8-R AEM FVP entry path has carried TX_R52_BOOT_AT_EL1 since it
was written, for the case its own comment describes: "an earlier boot
stage or a vendor EL2 monitor has already dropped privilege to EL1".
This board's entry path did not, so a kernel could not be built as a
guest on it at all -- and it is the board where that matters most,
because it is the one with silicon behind it.
The bracket is the whole change. Everything from the Thumb reset
trampoline to the ERET goes inside #ifndef TX_R52_BOOT_AT_EL1, and the
#else supplies a one-instruction A32 _start that branches to el1_entry.
A32 AND NOT T32, which is the one real difference from the standalone
entry. The core resets in Thumb state here because the RTU boot
instruction NXP plants is a T32 branch, but a guest is not reached by
reset: it is reached by the monitor's ERET, and the monitor chooses the
state through SPSR.T. Get the two out of agreement and the guest dies
on its first instruction with an undefined-instruction exception, which
looks exactly like a bad entry address and sends the reader to the
loader instead of to the ERET.
WHAT THE MONITOR INHERITS is enumerated at the #ifndef, next to the code
it replaces rather than in a document, because that is where somebody
adding a third board will be looking. This board's EL2 block is
considerably larger than the model's, and each item on the list is
something a guest at EL1 provably cannot do rather than something it
merely does not: CNTFRQ is writable only at the highest implemented
exception level and reads zero out of reset; HCPTR.TCP10/TCP11 reset
set, trapping every EL1 floating-point access; HSCTLR.TE is an EL2
register (SCTLR.TE is EL1's, and el1_entry still clears it below);
ICC_HSRE.SRE makes every other ICC_* and ICH_* register exist at all;
the low-latency peripheral port enables reset to zero and an EL1 write
to that register traps to EL2; and the TCM enables are per-core with
ENABLEEL2 SILENTLY IGNORED from EL1 -- measured on both BTCM and CTCM,
the base took and bit 0 took while bit 1 stayed clear.
CNTHCTL.PL1PCTEN and PL1PCEN are the deliberate omission from that list,
and the note says why. This path opens both, because a standalone
kernel owns the physical timer. A monitor that TIME-partitions its
guests must not: a partition's physical time keeps running while it is
descheduled, so a guest reading it can observe that it was not running.
That is the monitor's decision rather than this file's, which is why the
list says what a guest cannot do rather than what a monitor should.
Verified both ways. The three standalone images build and link
unchanged, and a kernel built with the option boots at EL1 on a
S32Z280-594EVB under an EL2 monitor, runs two threads through a queue
and a semaphore, and reports back -- with no other change to the kernel
or to its port.
Assisted-by: Claude Code (Opus 5) <[email protected]>
Diffstat (limited to 'common_modules/module_lib/src/txm_module_application_request.c')
0 files changed, 0 insertions, 0 deletions
