Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions ports/cortex_r52/gnu/example_build/s32z280_evb/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@
@/* vector, syndrome and return address before parking. Without */
@/* this a fault would be indistinguishable from a hang. */
@/* */
@/* Define TX_R52_BOOT_AT_EL1 to skip the EL2 configuration, for */
@/* targets where an earlier boot stage or a vendor EL2 monitor (for */
@/* example NXP's EL2M, or Eclipse ThreadX ZoneX) has already dropped */
@/* privilege to EL1. The kernel then enters at el1_entry in A32 */
@/* state, and the register list that becomes the monitor's */
@/* responsibility is enumerated at the #ifndef itself rather than */
@/* here, next to the code it replaces. */
@/* */
@/* The Armv8-R AEM FVP entry path has carried the same option since */
@/* it was written; this file gained it later, which is why the two */
@/* brackets are not identical in shape -- the EL2 work this board */
@/* does is considerably larger. */
@/* */
@/* CNTFRQ is read and recorded rather than written. The FVP leaves it */
@/* zero and its BSP programs a known value, but the correct frequency */
@/* for this board is not yet established, and writing a wrong one would*/
Expand Down Expand Up @@ -191,6 +204,60 @@ el1_vectors:
b el1_irq_entry /* 0x18 IRQ */
b el1_fiq_entry /* 0x1C FIQ */

#ifndef TX_R52_BOOT_AT_EL1

@/**************************************************************************/
@/* THE EL2 RESET PATH, which a guest build skips entirely. */
@/* */
@/* Everything between this #ifndef and its #else configures EL2 and then */
@/* drops to EL1. With TX_R52_BOOT_AT_EL1 defined, an earlier boot stage */
@/* or a vendor EL2 monitor has already done that, so the kernel starts */
@/* straight at el1_entry and none of it runs. */
@/* */
@/* WHAT THE MONITOR MUST THEN DO, because a guest at EL1 cannot: */
@/* */
@/* CNTFRQ writable only at the highest implemented */
@/* exception level, and it reads ZERO out of */
@/* reset on this part. A guest deriving a */
@/* tick interval from it divides by zero. */
@/* HCPTR.TCP10/TCP11 both reset SET, trapping every EL1 and EL0 */
@/* floating-point access to EL2. */
@/* HSCTLR.TE an EL2 register; a guest cannot write it. */
@/* (SCTLR.TE is EL1's and el1_entry clears it */
@/* below, so the guest still handles its own.) */
@/* ICC_HSRE.SRE until it is set, every other ICC_* and */
@/* ICH_* system register is UNDEFINED -- so an */
@/* EL1 kernel cannot acknowledge an interrupt */
@/* at all. */
@/* IMP_PERIPHPREGIONR the low-latency peripheral port enables */
@/* reset to zero and an EL1 write to this */
@/* register traps to EL2 when */
@/* HACTLR.PERIPHPREGIONR is clear. A guest */
@/* that needs the RTU peripheral window at */
@/* 0x76000000 therefore depends on the monitor */
@/* having opened it; one that does not need it */
@/* is unaffected. */
@/* IMP_ATCMREGIONR and the TCM bases and enables are per-core, and */
@/* IMP_BTCMREGIONR ENABLEEL2 is silently IGNORED when written */
@/* from EL1 -- measured on this part, on both */
@/* BTCM and CTCM: the base took and bit 0 took */
@/* while bit 1 stayed clear. A guest that */
@/* places anything in a TCM therefore needs */
@/* the monitor to program and ECC-preload it, */
@/* because ECC is enabled here and a TCM */
@/* location must be WRITTEN before it can be */
@/* read (TRM 6.2.2). */
@/* */
@/* CNTHCTL.PL1PCTEN and PL1PCEN are the interesting omission from that */
@/* list. This path opens both, because a standalone kernel owns the */
@/* physical timer. A monitor that TIME-partitions its guests must NOT */
@/* open them: a partition's physical time keeps running while it is */
@/* descheduled, so a guest reading it can observe that it was not */
@/* running. Such a monitor gives its guests the virtual timer and a */
@/* per-guest CNTVOFF instead. That is the monitor's decision to make, */
@/* not this file's, which is why this list says what a guest CANNOT do */
@/* rather than what a monitor SHOULD do. */
@/**************************************************************************/
@/**************************************************************************/
@/* _start -- reset entry. Entered in THUMB state, Hyp mode (EL2). */
@/**************************************************************************/
Expand Down Expand Up @@ -438,6 +505,36 @@ start_a32:
isb
eret

#else

@/**************************************************************************/
@/* _start, when an EL2 monitor has already dropped privilege. */
@/* */
@/* A32, not T32, and that is the one real difference from the standalone */
@/* entry above. 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. Both ZoneX and NXP's EL2M enter a */
@/* guest in A32, matching the vector tables in this file, so this entry */
@/* is A32 and needs no state switch of its own. */
@/* */
@/* SPSR.T MUST AGREE WITH THIS. If it does not, 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. */
@/**************************************************************************/

.section .text.boot, "ax"
.arm
.align 2
.global _start
.type _start, %function
_start:
b el1_entry
.size _start, . - _start

#endif

@/**************************************************************************/
@/* el1_entry -- first instruction at EL1. */
@/**************************************************************************/
Expand Down