diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/board.h b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/board.h index d5e50b809..07e0fa77e 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/board.h +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/board.h @@ -34,7 +34,8 @@ /* header the definitions have external linkage and no visible */ /* declaration, which MISRA C:2012 Rule 8.4 prohibits and which */ /* -Wmissing-prototypes reports. Declaring them in one place also */ -/* means a signature change cannot silently disagree with the assembly.*/ +/* means a signature change cannot silently disagree with the */ +/* assembly. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/cache.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/cache.c index 6632096ad..30406a059 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/cache.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/cache.c @@ -25,17 +25,17 @@ /* */ /* DESCRIPTION */ /* */ -/* Cache maintenance for a loader that copies code. See cache.h for */ +/* Cache maintenance for a loader that copies code. See cache.h for */ /* why only these three functions exist. */ /* */ /* MISRA C:2012 deviations (justified) */ /* */ -/* Directive 4.3 -- cache maintenance and CTR are reachable only */ -/* through CP15; every access is encapsulated in a one-line accessor */ +/* Directive 4.3 -- cache maintenance and CTR are reachable only */ +/* through CP15; every access is encapsulated in a one-line accessor */ /* below and nowhere else in this file. */ -/* Rule 11.6 (conversion between a pointer and an integer) -- a cache */ -/* maintenance operation takes a virtual address as a register value, */ -/* so the conversion is what the instruction requires. */ +/* Rule 11.6 (conversion between a pointer and an integer) -- a cache */ +/* maintenance operation takes a virtual address as a register */ +/* value, so the conversion is what the instruction requires. */ /* */ /**************************************************************************/ @@ -51,7 +51,8 @@ /**************************************************************************/ -/* CP15 accessors. The only assembly in this file (MISRA C:2012 Dir 4.3).*/ +/* CP15 accessors. The only assembly in this file (MISRA C:2012 Dir */ +/* 4.3). */ /**************************************************************************/ static unsigned long read_ctr(void) @@ -96,13 +97,13 @@ unsigned long cache_dcache_line_bytes(void) /**************************************************************************/ /* cache_clean_range */ /* */ -/* Clean by virtual address over [start, start + length). */ +/* Clean by virtual address over [start, start + length). */ /* */ -/* The start is rounded DOWN to a line boundary and the walk continues */ -/* past the end until the last line containing a requested byte has been */ -/* cleaned. Rounding the start up instead would leave the first partial */ -/* line dirty, which is the whole failure this exists to prevent and is */ -/* invisible whenever the caller happens to be line aligned. */ +/* The start is rounded DOWN to a line boundary and the walk continues */ +/* past the end until the last line containing a requested byte has been */ +/* cleaned. Rounding the start up instead would leave the first partial */ +/* line dirty, which is the whole failure this exists to prevent and is */ +/* invisible whenever the caller happens to be line aligned. */ /**************************************************************************/ void cache_clean_range(const void *start_address, unsigned long length) diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/cache.h b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/cache.h index 0ed8dcfc0..419236687 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/cache.h +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/cache.h @@ -25,27 +25,28 @@ /* */ /* DESCRIPTION */ /* */ -/* The cache maintenance a loader owes the instruction side, and */ +/* The cache maintenance a loader owes the instruction side, and */ /* nothing else. */ /* */ -/* The S32Z280 board support carries a full cache driver -- enable, */ -/* disable, geometry, set/way sweeps -- because silicon bring-up needed */ -/* to ask the hardware what it had. None of that is needed here: the */ -/* caches are turned on once in mpu_init and never turned off, and the */ -/* model's geometry is not in question. What IS needed is the pair of */ -/* operations that make copied code executable, so that is all this is. */ +/* The S32Z280 board support carries a full cache driver -- enable, */ +/* disable, geometry, set/way sweeps -- because silicon bring-up */ +/* needed to ask the hardware what it had. None of that is needed */ +/* here: the caches are turned on once in mpu_init and never turned */ +/* off, and the model's geometry is not in question. What IS needed */ +/* is the pair of operations that make copied code executable, so that */ +/* is all this is. */ /* */ -/* Why it is needed at all: the module area is Normal write-back memory, */ -/* so a byte copy of module code leaves the bytes in dirty data-cache */ -/* lines while the instruction side -- which is not coherent with the */ -/* data cache on this core -- fetches whatever main memory still holds. */ -/* Cleaning by address range and then invalidating the instruction cache */ -/* is what closes that gap. */ +/* Why it is needed at all: the module area is Normal write-back */ +/* memory, so a byte copy of module code leaves the bytes in dirty */ +/* data-cache lines while the instruction side -- which is not */ +/* coherent with the data cache on this core -- fetches whatever main */ +/* memory still holds. Cleaning by address range and then invalidating */ +/* the instruction cache is what closes that gap. */ /* */ -/* By range rather than by set/way, deliberately. A set/way sweep needs */ -/* the cache geometry and touches every line in the machine; the loader */ -/* knows exactly which bytes it wrote, so the range form is both tighter */ -/* and shorter to get right. */ +/* By range rather than by set/way, deliberately. A set/way sweep */ +/* needs the cache geometry and touches every line in the machine; the */ +/* loader knows exactly which bytes it wrote, so the range form is */ +/* both tighter and shorter to get right. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/console.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/console.c index 2f75f605b..ab78f4929 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/console.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/console.c @@ -32,9 +32,9 @@ /* */ /* MISRA C:2012 deviations (justified) */ /* */ -/* Directive 4.3 (assembly language shall be encapsulated and isolated)*/ -/* -- observed rather than violated: the single asm statement lives */ -/* in semihost_call() and nowhere else in the port. */ +/* Directive 4.3 (assembly language shall be encapsulated and */ +/* isolated) -- observed rather than violated: the single asm */ +/* statement lives in semihost_call() and nowhere else in the port. */ /* Rule 1.1 / 1.2 (language extensions) */ /* -- register-asm bindings and inline assembly are unavoidable to */ /* invoke a semihosting trap; no standard C construct expresses it. */ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_clz.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_clz.c index a156f4ec7..9f5489274 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_clz.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_clz.c @@ -56,7 +56,7 @@ /* hide. */ /* 5. The m == 0 divergence is PINNED, not fixed. CLZ(0) is 32, so */ /* this implementation yields 31 - 32 while the portable loop */ -/* yields 0. Every one of the twelve call sites in common/src */ +/* yields 0. Every one of the twelve call sites in common/src */ /* reaches the macro only on a map already tested against zero, */ /* so the difference is unreachable -- and a test that records */ /* it is how it stays a decision instead of becoming a surprise. */ @@ -153,8 +153,8 @@ static ULONG next_pattern(ULONG state) /* */ /* Runs one map through the macro twice, once landing in a UINT and once */ /* in a ULONG, and compares both against the reference. The macro */ -/* CONSUMES its first argument -- both implementations rewrite the map */ -/* in place -- so each call gets its own copy, which is also the trap a */ +/* CONSUMES its first argument -- both implementations rewrite the map */ +/* in place -- so each call gets its own copy, which is also the trap a */ /* caller reusing the variable afterwards would fall into. */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_fiq.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_fiq.c index b28990359..836ebae50 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_fiq.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_fiq.c @@ -25,35 +25,35 @@ /* */ /* DESCRIPTION */ /* */ -/* Nested FIQ handling: _tx_thread_fiq_nesting_start and */ -/* _tx_thread_fiq_nesting_end, the last pair in this port that nothing */ +/* Nested FIQ handling: _tx_thread_fiq_nesting_start and */ +/* _tx_thread_fiq_nesting_end, the last pair in this port that nothing */ /* had ever called. */ /* */ -/* FIQ needs more of the GIC than IRQ does. With a single security */ -/* state the controller delivers Group 0 as FIQ and Group 1 as IRQ, so */ -/* an interrupt only arrives as an FIQ if it has been moved into Group */ -/* 0, the distributor and CPU interface both have Group 0 enabled, and */ -/* it is acknowledged through the Group 0 registers. Group 1's */ -/* acknowledge returns the spurious INTID for a Group 0 interrupt and */ -/* leaves it pending, which presents as a storm rather than an error. */ +/* FIQ needs more of the GIC than IRQ does. With a single security */ +/* state the controller delivers Group 0 as FIQ and Group 1 as IRQ, so */ +/* an interrupt only arrives as an FIQ if it has been moved into Group */ +/* 0, the distributor and CPU interface both have Group 0 enabled, and */ +/* it is acknowledged through the Group 0 registers. Group 1's */ +/* acknowledge returns the spurious INTID for a Group 0 interrupt and */ +/* leaves it pending, which presents as a storm rather than an error. */ /* */ -/* FIQ nesting means an FIQ taken while an FIQ handler is running, so */ -/* one source cannot demonstrate it. Two Group 0 SGIs are used, the */ -/* second at a numerically lower priority so it can preempt the first, */ -/* and the first's handler raises it. */ +/* FIQ nesting means an FIQ taken while an FIQ handler is running, so */ +/* one source cannot demonstrate it. Two Group 0 SGIs are used, the */ +/* second at a numerically lower priority so it can preempt the first, */ +/* and the first's handler raises it. */ /* */ /* WHAT EACH CHECK IS FOR */ /* */ -/* F1 an FIQ arrives at all. Separate on purpose: it covers the whole */ -/* Group 0 chain -- IGRPEN0, the ICC_SGI0R encoding, IAR0 and */ -/* EOIR0, the EL1 FIQ vector, and F being unmasked. If F1 fails */ -/* the fault is in one of those and not in the nesting routines. */ -/* F2 an FIQ arrived while another FIQ handler was active, depth 2. */ -/* F3 the depth returned to zero, so the pairing unwound. */ -/* F4 the IRQ path is undisturbed: the tick still advances. */ -/* F5 threads still run, so FIQ context save and restore survived */ +/* F1 an FIQ arrives at all. Separate on purpose: it covers the */ +/* whole Group 0 chain -- IGRPEN0, the ICC_SGI0R encoding, IAR0 */ +/* and EOIR0, the EL1 FIQ vector, and F being unmasked. If F1 */ +/* fails the fault is in one of those and not in the nesting */ +/* routines. F2 an FIQ arrived while another FIQ handler was active, */ +/* depth 2. F3 the depth returned to zero, so the pairing unwound. */ +/* F4 the IRQ path is undisturbed: the tick still advances. */ +/* F5 threads still run, so FIQ context save and restore survived */ /* being re-entered. */ -/* F6 no unexpected Group 0 INTID arrived. */ +/* F6 no unexpected Group 0 INTID arrived. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m2.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m2.c index e6b7da2cf..a5f6243ce 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m2.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m2.c @@ -35,7 +35,8 @@ /* The threads record their execution order in a trace buffer, and the */ /* expected alternating sequence is asserted at the end. Counting */ /* iterations alone would not prove a context switch happened: if */ -/* switching were broken, one thread could run to completion by itself.*/ +/* switching were broken, one thread could run to completion by */ +/* itself. */ /* */ /* Only tx_thread_relinquish is used. tx_thread_sleep would hang */ /* without a tick, which AR1/M3 adds. */ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m3.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m3.c index 96beac48a..f07e06321 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m3.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m3.c @@ -36,13 +36,13 @@ /* 2. counter is enabled -> the control frame was started */ /* 3. CNTPCT advances -> the counter really runs */ /* 4. interrupts arrive -> GICv3 + PPI + vector wiring work */ -/* 5. tx_time_get advances -> _tx_timer_interrupt drives the tick*/ -/* 6. tx_thread_sleep returns -> timer-driven thread resumption */ -/* 7. a lower-priority thread ran while we slept -> preemption and */ -/* context save/restore across an interrupt */ +/* 5. tx_time_get advances -> _tx_timer_interrupt drives the */ +/* tick 6. tx_thread_sleep returns -> timer-driven thread */ +/* resumption 7. a lower-priority thread ran while we slept -> */ +/* preemption and context save/restore across an interrupt */ /* */ -/* The timer PPI INTID is reported, not assumed: the whole PPI range is*/ -/* enabled and whichever INTID the model drives is recorded. */ +/* The timer PPI INTID is reported, not assumed: the whole PPI range */ +/* is enabled and whichever INTID the model drives is recorded. */ /* */ /**************************************************************************/ @@ -81,7 +81,8 @@ static UINT report(const char *label_ptr, UINT passed) /**************************************************************************/ -/* thread_busy_entry -- lowest priority; only runs when nothing else can.*/ +/* thread_busy_entry -- lowest priority; only runs when nothing else */ +/* can. */ /**************************************************************************/ static void thread_busy_entry(ULONG thread_input) diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m5.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m5.c index 783bed06a..c3c78e492 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m5.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_m5.c @@ -29,10 +29,10 @@ /* */ /* Two paths must be covered, and they use different register sets: */ /* */ -/* solicited tx_thread_system_return saves D8-D15 and FPSCR, because*/ -/* the callee-saved half is all a voluntary switch can */ -/* lose. Exercised by the checking thread, which keeps */ -/* eight doubles live across tx_thread_sleep. */ +/* solicited tx_thread_system_return saves D8-D15 and FPSCR, */ +/* because the callee-saved half is all a voluntary */ +/* switch can lose. Exercised by the checking thread, */ +/* which keeps eight doubles live across tx_thread_sleep. */ /* interrupt tx_thread_context_restore restores D0-D15 and FPSCR, */ /* because an asynchronous interrupt can land anywhere. */ /* Exercised by a lower-priority thread doing continuous */ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_mpu.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_mpu.c index c96afc087..7b1365e36 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_mpu.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_mpu.c @@ -27,13 +27,14 @@ /* */ /* AR1 milestone M5: PMSAv8-R protection and caches. */ /* */ -/* The important check here is enforcement, not configuration. Reading*/ -/* SCTLR back only proves a bit was set; it says nothing about whether */ -/* the region table actually describes memory correctly. So the test */ -/* provokes a real permission fault by writing to the read-only code */ -/* region and requires the abort to arrive, then confirms a legal write*/ -/* to the data region still succeeds. A region set that permitted */ -/* everything would pass the first kind of check and fail this one. */ +/* The important check here is enforcement, not configuration. */ +/* Reading SCTLR back only proves a bit was set; it says nothing about */ +/* whether the region table actually describes memory correctly. So */ +/* the test provokes a real permission fault by writing to the */ +/* read-only code region and requires the abort to arrive, then */ +/* confirms a legal write to the data region still succeeds. A region */ +/* set that permitted everything would pass the first kind of check */ +/* and fail this one. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_nesting.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_nesting.c index 0e204d061..a724a71d5 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_nesting.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_nesting.c @@ -28,39 +28,39 @@ /* Nested IRQ handling: _tx_thread_irq_nesting_start and */ /* _tx_thread_irq_nesting_end. */ /* */ -/* Those two routines have shipped in this port since it was written */ -/* and nothing had ever called them. They were compiled into every */ -/* build, never entered by any image, on the model or on silicon. */ +/* Those two routines have shipped in this port since it was written */ +/* and nothing had ever called them. They were compiled into every */ +/* build, never entered by any image, on the model or on silicon. */ /* This is the image that enters them. */ /* */ /* HOW NESTING IS PROVOKED */ /* */ -/* Two interrupt sources are needed and one must outrank the other. */ -/* The generic timer PPI is already there; the second is an SGI, which */ -/* a core can raise on itself, given a numerically lower priority so */ +/* Two interrupt sources are needed and one must outrank the other. */ +/* The generic timer PPI is already there; the second is an SGI, which */ +/* a core can raise on itself, given a numerically lower priority so */ /* the GIC lets it preempt. */ /* */ -/* Inside the timer handler, after nesting_start has left IRQ mode for */ -/* System mode and re-enabled IRQ, board_irq_handler raises the SGI and */ -/* spins briefly. The SGI outranks the timer, so it is delivered */ -/* immediately and re-enters el1_irq_entry while the timer handler is */ -/* still on the stack. That is nesting, and the depth counter sees 2. */ +/* Inside the timer handler, after nesting_start has left IRQ mode for */ +/* System mode and re-enabled IRQ, board_irq_handler raises the SGI */ +/* and spins briefly. The SGI outranks the timer, so it is delivered */ +/* immediately and re-enters el1_irq_entry while the timer handler is */ +/* still on the stack. That is nesting, and the depth counter sees 2. */ /* */ -/* The spin is bounded. Without TX_ENABLE_IRQ_NESTING the SGI can */ -/* never arrive, and a test that hangs in that configuration would be */ +/* The spin is bounded. Without TX_ENABLE_IRQ_NESTING the SGI can */ +/* never arrive, and a test that hangs in that configuration would be */ /* worse than one that fails. */ /* */ /* WHAT EACH CHECK IS FOR */ /* */ -/* N1 the SGI arrives at all. This is separate on purpose: it tests */ -/* the ICC_SGI1R encoding, which does not transcribe from the */ -/* AArch64 alias, so if N1 fails the fault is in gicv3_send_sgi and */ -/* not in the nesting routines. */ -/* N2 the SGI arrived while another handler was active, depth 2. */ -/* N3 depth returned to zero, so the pairing unwound. */ -/* N4 the tick still advances afterwards, so nesting did not damage */ +/* N1 the SGI arrives at all. This is separate on purpose: it tests */ +/* the ICC_SGI1R encoding, which does not transcribe from the */ +/* AArch64 alias, so if N1 fails the fault is in gicv3_send_sgi */ +/* and not in the nesting routines. */ +/* N2 the SGI arrived while another handler was active, depth 2. */ +/* N3 depth returned to zero, so the pairing unwound. */ +/* N4 the tick still advances afterwards, so nesting did not damage */ /* the timer path. */ -/* N5 threads still run and preempt, so the context save and restore */ +/* N5 threads still run and preempt, so the context save and restore */ /* survived being re-entered. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_verify.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_verify.c index a22c7e135..f51691a86 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_verify.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/demo_verify.c @@ -31,11 +31,11 @@ /* */ /* Where M3 proved the tick and a single preemption, this exercises */ /* the demo's full object set -- queue, semaphore, mutex, event flags, */ -/* byte pool and block pool -- across eight threads at five priorities.*/ -/* Each of the ten demo counters is required to have advanced: a */ -/* stalled thread (a lost wakeup, a mishandled priority inversion) */ -/* shows up as a counter still at zero rather than as a plausible- */ -/* looking run. */ +/* byte pool and block pool -- across eight threads at five */ +/* priorities. Each of the ten demo counters is required to have */ +/* advanced: a stalled thread (a lost wakeup, a mishandled priority */ +/* inversion) shows up as a counter still at zero rather than as a */ +/* plausible- looking run. */ /* */ /* The verification thread runs at priority 0 so it can always preempt */ /* the demo, and spends nearly all its life suspended. */ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/entry.S b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/entry.S index 77d813361..e1dff629a 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/entry.S +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/entry.S @@ -468,9 +468,9 @@ el2_hyp_trap_unhandled: FAULT_REPORT msg_el2_hyp /**************************************************************************/ -/* Unhandled exceptions. Each records a distinct code in r12 so a halted*/ -/* model or a later fault dump (AR1/M5) can identify the cause. Real */ -/* handlers arrive with the interrupt work in M3. */ +/* Unhandled exceptions. Each records a distinct code in r12 so a */ +/* halted model or a later fault dump (AR1/M5) can identify the cause. */ +/* Real handlers arrive with the interrupt work in M3. */ /**************************************************************************/ /* Unhandled exceptions. Real handlers arrive with the interrupt work in diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/gicv3.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/gicv3.c index 4771625df..d6cd61fad 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/gicv3.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/gicv3.c @@ -31,10 +31,11 @@ /* parameters rather than assumed: */ /* */ /* has-two-security-states=0 single security state, so GICD_CTLR.DS */ -/* reads 1 and the Group 1 enable is bit 1*/ -/* ARE-fixed-to-one=1 affinity routing cannot be turned off */ -/* priority-bits=5 only the top 5 priority bits exist, so */ -/* priorities must be multiples of 8 */ +/* reads 1 and the Group 1 enable is bit */ +/* 1 ARE-fixed-to-one=1 affinity routing cannot be turned */ +/* off priority-bits=5 only the top 5 priority bits */ +/* exist, so priorities must be multiples */ +/* of 8 */ /* */ /* MISRA C:2012 deviations (justified) */ /* */ @@ -225,9 +226,9 @@ void gicv3_enable_ppi(unsigned int intid, unsigned int priority) /**************************************************************************/ /* gicv3_enable_sgi */ /* */ -/* An SGI lives in the same redistributor frame as a PPI, so this is */ -/* gicv3_enable_ppi without the ICFGR step: INTIDs 0-15 have no */ -/* configurable edge/level, they are always edge-triggered. */ +/* An SGI lives in the same redistributor frame as a PPI, so this is */ +/* gicv3_enable_ppi without the ICFGR step: INTIDs 0-15 have no */ +/* configurable edge/level, they are always edge-triggered. */ /**************************************************************************/ void gicv3_enable_sgi(unsigned int intid, unsigned int priority) @@ -251,15 +252,15 @@ void gicv3_enable_sgi(unsigned int intid, unsigned int priority) /**************************************************************************/ /* gicv3_send_sgi */ /* */ -/* ICC_SGI1R is 64-bit, so in AArch32 it is an MCRR rather than an MCR. */ -/* Fields: INTID in [27:24], TargetList in [15:0], Aff1/2/3 and IRM zero */ -/* for this single-core configuration, so TargetList = 1 selects core 0. */ +/* ICC_SGI1R is 64-bit, so in AArch32 it is an MCRR rather than an MCR. */ +/* Fields: INTID in [27:24], TargetList in [15:0], Aff1/2/3 and IRM zero */ +/* for this single-core configuration, so TargetList = 1 selects core 0. */ /* */ -/* The AArch64 name for this register is S3_0_C12_C11_5, which the */ -/* Cortex-A72 example uses, but that encoding does not transcribe to the */ -/* AArch32 64-bit CP15 space. The CRm here was confirmed by observing */ -/* that the SGI is actually delivered and acknowledged with the expected */ -/* INTID rather than by reading it off the A-profile alias. */ +/* The AArch64 name for this register is S3_0_C12_C11_5, which the */ +/* Cortex-A72 example uses, but that encoding does not transcribe to the */ +/* AArch32 64-bit CP15 space. The CRm here was confirmed by observing */ +/* that the SGI is actually delivered and acknowledged with the expected */ +/* INTID rather than by reading it off the A-profile alias. */ /**************************************************************************/ void gicv3_send_sgi(unsigned int intid) @@ -273,11 +274,11 @@ void gicv3_send_sgi(unsigned int intid) /**************************************************************************/ -/* gicv3_enable_sgi_group0 */ +/* gicv3_enable_sgi_group0 */ /* */ -/* As gicv3_enable_sgi, but leaves the interrupt in Group 0 so it arrives */ -/* as an FIQ. The group is chosen by clearing the GICR_IGROUPR0 bit; the */ -/* Group 1 version sets it. */ +/* As gicv3_enable_sgi, but leaves the interrupt in Group 0 so it */ +/* arrives as an FIQ. The group is chosen by clearing the GICR_IGROUPR0 */ +/* bit; the Group 1 version sets it. */ /**************************************************************************/ void gicv3_enable_sgi_group0(unsigned int intid, unsigned int priority) @@ -299,11 +300,12 @@ void gicv3_enable_sgi_group0(unsigned int intid, unsigned int priority) /**************************************************************************/ -/* gicv3_send_sgi_group0 */ +/* gicv3_send_sgi_group0 */ /* */ -/* ICC_SGI0R rather than ICC_SGI1R: the two differ only in opc1, 2 against */ -/* 0, and each raises the SGI into its own group. Raising a Group 0 */ -/* interrupt through the Group 1 register does not deliver it as an FIQ. */ +/* ICC_SGI0R rather than ICC_SGI1R: the two differ only in opc1, 2 */ +/* against 0, and each raises the SGI into its own group. Raising a */ +/* Group 0 interrupt through the Group 1 register does not deliver it as */ +/* an FIQ. */ /**************************************************************************/ void gicv3_send_sgi_group0(unsigned int intid) @@ -317,11 +319,12 @@ void gicv3_send_sgi_group0(unsigned int intid) /**************************************************************************/ -/* gicv3_acknowledge_group0 / gicv3_end_of_interrupt_group0 */ +/* gicv3_acknowledge_group0 / gicv3_end_of_interrupt_group0 */ /* */ -/* Group 0 has its own pair at c12, c8, where Group 1 uses c12, c12. */ -/* Acknowledging a Group 0 interrupt through IAR1 returns the spurious */ -/* INTID and leaves the interrupt pending, which presents as an FIQ storm. */ +/* Group 0 has its own pair at c12, c8, where Group 1 uses c12, c12. */ +/* Acknowledging a Group 0 interrupt through IAR1 returns the spurious */ +/* INTID and leaves the interrupt pending, which presents as an FIQ */ +/* storm. */ /**************************************************************************/ unsigned long gicv3_acknowledge_group0(void) diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/irq_dispatch.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/irq_dispatch.c index f244c3d7b..a53cd65bf 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/irq_dispatch.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/irq_dispatch.c @@ -114,10 +114,10 @@ void board_init(void) /**************************************************************************/ /**************************************************************************/ -/* board_irq_service -- service an already-acknowledged INTID. */ +/* board_irq_service -- service an already-acknowledged INTID. */ /* */ -/* Split out so the nesting path in entry.S can acknowledge in IRQ mode */ -/* before nesting starts. Does not acknowledge and does not EOI. */ +/* Split out so the nesting path in entry.S can acknowledge in IRQ mode */ +/* before nesting starts. Does not acknowledge and does not EOI. */ /**************************************************************************/ void board_irq_service(unsigned long intid) @@ -199,12 +199,12 @@ void board_irq_service(unsigned long intid) /**************************************************************************/ -/* board_irq_handler -- the non-nesting entry point. */ +/* board_irq_handler -- the non-nesting entry point. */ /* */ -/* Acknowledges, services and ends the interrupt, all in IRQ mode with */ -/* interrupts masked. entry.S calls this when the image was built without */ -/* TX_ENABLE_IRQ_NESTING, so the behaviour of every existing image is */ -/* exactly what it was. */ +/* Acknowledges, services and ends the interrupt, all in IRQ mode with */ +/* interrupts masked. entry.S calls this when the image was built */ +/* without TX_ENABLE_IRQ_NESTING, so the behaviour of every existing */ +/* image is exactly what it was. */ /**************************************************************************/ void board_irq_handler(void) @@ -222,11 +222,11 @@ void board_irq_handler(void) #ifdef TX_ENABLE_FIQ_SUPPORT /**************************************************************************/ -/* board_fiq_service -- service an already-acknowledged Group 0 INTID. */ +/* board_fiq_service -- service an already-acknowledged Group 0 INTID. */ /* */ -/* The FIQ counterpart of board_irq_service, and split for the same */ -/* reason: the acknowledge has to happen before nesting starts. Does not */ -/* acknowledge and does not EOI. */ +/* The FIQ counterpart of board_irq_service, and split for the same */ +/* reason: the acknowledge has to happen before nesting starts. Does */ +/* not acknowledge and does not EOI. */ /**************************************************************************/ void board_fiq_service(unsigned long intid) @@ -289,7 +289,7 @@ void board_fiq_service(unsigned long intid) /**************************************************************************/ -/* board_fiq_handler -- the non-nesting FIQ entry point. */ +/* board_fiq_handler -- the non-nesting FIQ entry point. */ /**************************************************************************/ void board_fiq_handler(void) diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/mpu.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/mpu.c index 4fad2f7eb..0f7f8a444 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/mpu.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/mpu.c @@ -29,10 +29,11 @@ /* */ /* Register model (AArch32): a region is selected through PRSELR and */ /* then described by PRBAR (base, shareability, access permission, */ -/* execute-never) and PRLAR (inclusive limit, attribute index, enable).*/ -/* Both addresses have a 64-byte granule, so the low six bits of each */ -/* register hold attributes rather than address. Memory types come */ -/* from MAIR through the attribute index, not from the region itself. */ +/* execute-never) and PRLAR (inclusive limit, attribute index, */ +/* enable). Both addresses have a 64-byte granule, so the low six bits */ +/* of each register hold attributes rather than address. Memory types */ +/* come from MAIR through the attribute index, not from the region */ +/* itself. */ /* */ /* Caches are invalidated before being enabled. On this model they */ /* come out of reset invalid, but silicon does not guarantee that, and */ @@ -40,9 +41,9 @@ /* */ /* MISRA C:2012 deviations (justified) */ /* */ -/* Directive 4.3 -- the MPU, MAIR, SCTLR and cache maintenance are only*/ -/* reachable through CP15; every access is encapsulated in a one-line*/ -/* accessor below. */ +/* Directive 4.3 -- the MPU, MAIR, SCTLR and cache maintenance are */ +/* only reachable through CP15; every access is encapsulated in a */ +/* one-line accessor below. */ /* */ /**************************************************************************/ @@ -302,20 +303,21 @@ static void program_region(unsigned int index, const MPU_REGION *region_ptr) /* A window over the module area, for the manager to load through. */ /* */ /* No region in the table above covers the module area, which is what */ -/* stops every thread from reaching a module's memory -- but the manager */ +/* stops every thread from reaching a module's memory -- but the manager */ /* has to read the preamble and write the module's data to load it at */ /* all. Without this the load faults on its first read of the image. */ /* */ /* Not opened and closed around the load. It is left enabled here and */ -/* the SCHEDULER owns it from then on: it turns this region on for every */ -/* thread that owns no module and off for every thread that does, which */ -/* is what keeps it and a module's own regions -- which cover the same */ -/* memory -- from ever being enabled together. PMSAv8-R has no region */ -/* priority, so an access hitting more than one enabled region takes a */ -/* translation fault (TRM 8.1), and mutual exclusion by ownership is the */ -/* only form of it that does not depend on remembering to bracket a call. */ +/* the SCHEDULER owns it from then on: it turns this region on for every */ +/* thread that owns no module and off for every thread that does, which */ +/* is what keeps it and a module's own regions -- which cover the same */ +/* memory -- from ever being enabled together. PMSAv8-R has no region */ +/* priority, so an access hitting more than one enabled region takes a */ +/* translation fault (TRM 8.1), and mutual exclusion by ownership is the */ +/* only form of it that does not depend on remembering to bracket a */ +/* call. */ /* */ -/* EL1 read/write with no EL0 access, and execute-never: the manager can */ +/* EL1 read/write with no EL0 access, and execute-never: the manager can */ /* load through it, and a module cannot use it to reach anything. */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/timer.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/timer.c index eac0b3dc1..f90b6b460 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/timer.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/timer.c @@ -46,7 +46,8 @@ /* MISRA C:2012 deviations (justified) */ /* */ /* Directive 4.3 -- the generic timer is only reachable through CP15 */ -/* registers; every such access is encapsulated in an accessor below.*/ +/* registers; every such access is encapsulated in an accessor */ +/* below. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/tx_initialize_low_level.S b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/tx_initialize_low_level.S index c8d3f1883..48a2dd8c3 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/tx_initialize_low_level.S +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/tx_initialize_low_level.S @@ -60,12 +60,12 @@ /* here and no run-time stack-overlap check to perform -- the linker */ /* guarantees the regions do not overlap. */ /* */ -/* When built with TX_R52_USE_THREADX_IRQ, board_init() brings up GICv3*/ -/* and the generic timer tick here. That is safe this early because */ -/* interrupts stay masked until _tx_thread_schedule enables them, so no*/ -/* tick can be delivered before the kernel is ready to take one. */ -/* Without that symbol (the M2 cooperative demo) no tick is created, */ -/* which keeps M2 free of any interrupt dependency. */ +/* When built with TX_R52_USE_THREADX_IRQ, board_init() brings up */ +/* GICv3 and the generic timer tick here. That is safe this early */ +/* because interrupts stay masked until _tx_thread_schedule enables */ +/* them, so no tick can be delivered before the kernel is ready to */ +/* take one. Without that symbol (the M2 cooperative demo) no tick is */ +/* created, which keeps M2 free of any interrupt dependency. */ /* */ /* CALLED BY */ /* */ diff --git a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/uart_pl011.c b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/uart_pl011.c index b4c78127d..0c17be313 100644 --- a/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/uart_pl011.c +++ b/ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/uart_pl011.c @@ -30,9 +30,9 @@ /* */ /* Semihosting remains the default because it needs no peripheral at */ /* all, which keeps early bring-up independent of the memory map. The */ -/* UART matters because it is what real silicon will use: exercising it*/ -/* here means the S32Z280 console differs only in its base address and */ -/* clocking, not in structure. */ +/* UART matters because it is what real silicon will use: exercising */ +/* it here means the S32Z280 console differs only in its base address */ +/* and clocking, not in structure. */ /* */ /* The model leaves UART0 disabled at reset */ /* (bp.pl011_uart0.uart_enable=0), so the control register must be */ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/bsp_boot.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/bsp_boot.c index 13ea498b4..8dc04fb56 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/bsp_boot.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/bsp_boot.c @@ -28,12 +28,12 @@ /* First-boot verification for the NXP S32Z280-594EVB. Records what */ /* the core reports about itself into a structure a debugger reads. */ /* */ -/* There is no console on this board yet: LIN9 reaches the host through*/ -/* the daughtercard USB-UART, but its baud rate depends on clock */ -/* configuration that is not yet established, and a console that prints*/ -/* at the wrong rate produces garbage indistinguishable from a crash. */ -/* So this milestone reports through memory instead, which cannot be */ -/* mis-configured. The console arrives in the next step. */ +/* There is no console on this board yet: LIN9 reaches the host */ +/* through the daughtercard USB-UART, but its baud rate depends on */ +/* clock configuration that is not yet established, and a console that */ +/* prints at the wrong rate produces garbage indistinguishable from a */ +/* crash. So this milestone reports through memory instead, which */ +/* cannot be mis-configured. The console arrives in the next step. */ /* */ /* Only EL1-accessible registers are read here. EL2-only ones */ /* (HMPUIR, CNTFRQ) are captured by entry.S before the drop to EL1, */ @@ -153,12 +153,13 @@ static void report(const char *name, unsigned int value) /**************************************************************************/ -/* bsp_done -- breakpoint target, reached once the structure is complete.*/ +/* bsp_done -- breakpoint target, reached once the structure is */ +/* complete. */ /* */ -/* Deliberately not static and deliberately not inlined: it exists purely*/ -/* so a debugger can break on a symbol. An optimising build would remove*/ -/* an empty static function, and then the script would have nothing to */ -/* attach to. */ +/* Deliberately not static and deliberately not inlined: it exists */ +/* purely so a debugger can break on a symbol. An optimising build */ +/* would remove an empty static function, and then the script would have */ +/* nothing to attach to. */ /**************************************************************************/ /* Clear CPSR.I so the GIC can deliver to this core. Interrupts stay masked diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/cache.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/cache.c index a7b0d6a19..f9acd2df7 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/cache.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/cache.c @@ -27,12 +27,12 @@ /* */ /* Cache maintenance and enable for the S32Z280-594EVB. */ /* */ -/* The FVP example enables SCTLR.C and SCTLR.I but only invalidates the*/ -/* instruction cache, with a note that a data-cache set/way sweep */ +/* The FVP example enables SCTLR.C and SCTLR.I but only invalidates */ +/* the instruction cache, with a note that a data-cache set/way sweep */ /* belongs with silicon bring-up "where it can be verified against the */ /* real cache geometry". This is that: the sweep here reads CLIDR and */ -/* CCSIDR and walks every set and way the hardware reports, rather than*/ -/* assuming a size. */ +/* CCSIDR and walks every set and way the hardware reports, rather */ +/* than assuming a size. */ /* */ /* The sweep matters more here than on a model. This image is written */ /* into SRAM by a debugger with the caches off, so nothing has been */ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_fiq_s32z280.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_fiq_s32z280.c index ad359704b..4a6d056cb 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_fiq_s32z280.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_fiq_s32z280.c @@ -25,39 +25,39 @@ /* */ /* DESCRIPTION */ /* */ -/* Nested FIQ handling: _tx_thread_fiq_nesting_start and */ -/* _tx_thread_fiq_nesting_end, the last pair in this port that nothing */ +/* Nested FIQ handling: _tx_thread_fiq_nesting_start and */ +/* _tx_thread_fiq_nesting_end, the last pair in this port that nothing */ /* had ever called. */ /* */ -/* The FVP established that the Group 0 chain works and what breaks it. */ -/* What it cannot show is whether a real GIC-600 routes Group 0 to FIQ */ -/* the same way, which is the point of running this here. */ +/* The FVP established that the Group 0 chain works and what breaks */ +/* it. What it cannot show is whether a real GIC-600 routes Group 0 to */ +/* FIQ the same way, which is the point of running this here. */ /* */ -/* FIQ needs more of the GIC than IRQ does. With a single security */ -/* state the controller delivers Group 0 as FIQ and Group 1 as IRQ, so */ -/* an interrupt only arrives as an FIQ if it has been moved into Group */ -/* 0, the distributor and CPU interface both have Group 0 enabled, and */ -/* it is acknowledged through the Group 0 registers. Group 1's */ -/* acknowledge returns the spurious INTID for a Group 0 interrupt and */ -/* leaves it pending, which presents as a storm rather than an error. */ +/* FIQ needs more of the GIC than IRQ does. With a single security */ +/* state the controller delivers Group 0 as FIQ and Group 1 as IRQ, so */ +/* an interrupt only arrives as an FIQ if it has been moved into Group */ +/* 0, the distributor and CPU interface both have Group 0 enabled, and */ +/* it is acknowledged through the Group 0 registers. Group 1's */ +/* acknowledge returns the spurious INTID for a Group 0 interrupt and */ +/* leaves it pending, which presents as a storm rather than an error. */ /* */ -/* FIQ nesting means an FIQ taken while an FIQ handler is running, so */ -/* one source cannot demonstrate it. Two Group 0 SGIs are used, the */ -/* second at a numerically lower priority so it can preempt the first, */ -/* and the first's handler raises it. */ +/* FIQ nesting means an FIQ taken while an FIQ handler is running, so */ +/* one source cannot demonstrate it. Two Group 0 SGIs are used, the */ +/* second at a numerically lower priority so it can preempt the first, */ +/* and the first's handler raises it. */ /* */ /* WHAT EACH CHECK IS FOR */ /* */ -/* F1 an FIQ arrives at all. Separate on purpose: it covers the whole */ -/* Group 0 chain -- IGRPEN0, the ICC_SGI0R encoding, IAR0 and */ -/* EOIR0, the EL1 FIQ vector, and F being unmasked. If F1 fails */ -/* the fault is in one of those and not in the nesting routines. */ -/* F2 an FIQ arrived while another FIQ handler was active, depth 2. */ -/* F3 the depth returned to zero, so the pairing unwound. */ -/* F4 the IRQ path is undisturbed: the tick still advances. */ -/* F5 threads still run, so FIQ context save and restore survived */ +/* F1 an FIQ arrives at all. Separate on purpose: it covers the */ +/* whole Group 0 chain -- IGRPEN0, the ICC_SGI0R encoding, IAR0 */ +/* and EOIR0, the EL1 FIQ vector, and F being unmasked. If F1 */ +/* fails the fault is in one of those and not in the nesting */ +/* routines. F2 an FIQ arrived while another FIQ handler was active, */ +/* depth 2. F3 the depth returned to zero, so the pairing unwound. */ +/* F4 the IRQ path is undisturbed: the tick still advances. */ +/* F5 threads still run, so FIQ context save and restore survived */ /* being re-entered. */ -/* F6 no unexpected Group 0 INTID arrived. */ +/* F6 no unexpected Group 0 INTID arrived. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_nesting_s32z280.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_nesting_s32z280.c index ca2a67754..330eaac83 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_nesting_s32z280.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_nesting_s32z280.c @@ -27,26 +27,26 @@ /* */ /* Nested IRQ handling on S32Z280 silicon. */ /* */ -/* The FVP established that the nesting routines work and, more */ -/* usefully, what breaks them: the interrupt has to be acknowledged */ -/* before nesting starts, or the still-pending level-asserted timer is */ -/* retaken the moment IRQ is enabled and recurses until the stacks are */ -/* gone. entry.S here has the same ordering for the same reason. */ +/* The FVP established that the nesting routines work and, more */ +/* usefully, what breaks them: the interrupt has to be acknowledged */ +/* before nesting starts, or the still-pending level-asserted timer is */ +/* retaken the moment IRQ is enabled and recurses until the stacks are */ +/* gone. entry.S here has the same ordering for the same reason. */ /* */ -/* What the model could not answer is whether a real GIC-600 agrees. */ -/* Two things differ from a model and both are visible here: */ +/* What the model could not answer is whether a real GIC-600 agrees. */ +/* Two things differ from a model and both are visible here: */ /* */ -/* P1 how many priority bits the GIC implements. Equal priorities */ -/* do not preempt, and it is the low bits that vanish, so if the */ -/* timer and the SGI collapse to the same value after truncation */ -/* nesting cannot happen at all. board_init discovers the count */ -/* by write and readback rather than assuming the model's five, */ -/* and this demo reports it. */ +/* P1 how many priority bits the GIC implements. Equal priorities */ +/* do not preempt, and it is the low bits that vanish, so if the */ +/* timer and the SGI collapse to the same value after truncation */ +/* nesting cannot happen at all. board_init discovers the count */ +/* by write and readback rather than assuming the model's five, */ +/* and this demo reports it. */ /* */ -/* P2 whether an SGI raised on real silicon is delivered at all. */ -/* ICC_SGI1R is a 64-bit AArch32 CP15 register and its encoding */ -/* does not transcribe from the AArch64 alias, so N1 tests SGI */ -/* delivery on its own before nesting is involved. */ +/* P2 whether an SGI raised on real silicon is delivered at all. */ +/* ICC_SGI1R is a 64-bit AArch32 CP15 register and its encoding */ +/* does not transcribe from the AArch64 alias, so N1 tests SGI */ +/* delivery on its own before nesting is involved. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_s32z280.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_s32z280.c index 9f09d8d3d..a72b29a3e 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_s32z280.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_s32z280.c @@ -41,9 +41,9 @@ /* preempt -- the sleeper resumed while the spinner was runnable, */ /* which is preemption rather than cooperative handoff */ /* */ -/* Counting alone would not distinguish these: a demo that only checked*/ -/* that both threads ran would pass with a broken tick if the threads */ -/* happened to yield to each other. */ +/* Counting alone would not distinguish these: a demo that only */ +/* checked that both threads ran would pass with a broken tick if the */ +/* threads happened to yield to each other. */ /* */ /**************************************************************************/ @@ -110,23 +110,24 @@ static void report(const char *name, unsigned long value) /* Context-switch cost, stack in BTCM against stack in DRAM0. */ /* */ /* Two pairs of equal-priority threads hand control back and forth with */ -/* tx_thread_relinquish, and the measuring thread of each pair times the */ -/* round trip. One pair has both stacks in BTCM, the other in DRAM0. */ +/* tx_thread_relinquish, and the measuring thread of each pair times the */ +/* round trip. One pair has both stacks in BTCM, the other in DRAM0. */ /* */ -/* A round trip is two context switches plus the partner's loop, and the */ -/* partner's code is the same for both pairs, so the difference between */ -/* the pairs is the memory holding the stacks and nothing else. */ +/* A round trip is two context switches plus the partner's loop, and the */ +/* partner's code is the same for both pairs, so the difference between */ +/* the pairs is the memory holding the stacks and nothing else. */ /* */ -/* Both pairs run in one image from one copy of the measuring code, which */ -/* is what makes this comparison safe. The alignment trap that invalid- */ -/* ated earlier work here bites when two builds with different layouts */ -/* are compared; a code shift moves both pairs equally and cancels. */ +/* Both pairs run in one image from one copy of the measuring code, */ +/* which is what makes this comparison safe. The alignment trap that */ +/* invalid- ated earlier work here bites when two builds with different */ +/* layouts are compared; a code shift moves both pairs equally and */ +/* cancels. */ /* */ -/* Cycles, from the PMU counter: CNTPCT at 8 MHz cannot resolve a context */ -/* switch. Priorities 2 and 3 put the BTCM pair first and keep both */ -/* above judge and spinner. The sleeper at priority 1 still preempts */ -/* occasionally, which can land in max; min and mean are the robust */ -/* figures and all three are reported. */ +/* Cycles, from the PMU counter: CNTPCT at 8 MHz cannot resolve a */ +/* context switch. Priorities 2 and 3 put the BTCM pair first and keep */ +/* both above judge and spinner. The sleeper at priority 1 still */ +/* preempts occasionally, which can land in max; min and mean are the */ +/* robust figures and all three are reported. */ /**************************************************************************/ static void demo_dec(unsigned long value) @@ -263,27 +264,27 @@ static void ctx_partner_entry(ULONG which) /**************************************************************************/ /* Stack-heavy work, stack in BTCM against stack in DRAM0. */ /* */ -/* #635 measured context switches and found BTCM worth about 7.4%, with */ -/* no determinism advantage, and said why: a switch saves sixteen */ -/* registers, roughly one cache line, so the stack's cache state has */ -/* almost nothing to contribute. It also said the interesting case was */ -/* work with a large stack working set, that it had not been measured, and */ -/* that it should not be assumed. This measures it. */ +/* #635 measured context switches and found BTCM worth about 7.4%, with */ +/* no determinism advantage, and said why: a switch saves sixteen */ +/* registers, roughly one cache line, so the stack's cache state has */ +/* almost nothing to contribute. It also said the interesting case was */ +/* work with a large stack working set, that it had not been measured, */ +/* and that it should not be assumed. This measures it. */ /* */ -/* deep_touch recurses, writing a frame on the way down and reading it on */ -/* the way up, so the stack working set is the whole descent rather than */ -/* one frame. The cache is cleaned and invalidated before each sample, so */ -/* the descent starts cold: a stack in DRAM0 must fill a line per frame, */ -/* while a stack in BTCM has no cache in the path to miss. */ +/* deep_touch recurses, writing a frame on the way down and reading it */ +/* on the way up, so the stack working set is the whole descent rather */ +/* than one frame. The cache is cleaned and invalidated before each */ +/* sample, so the descent starts cold: a stack in DRAM0 must fill a line */ +/* per frame, while a stack in BTCM has no cache in the path to miss. */ /* */ -/* No partner threads and no relinquish here. The measurement is entirely */ -/* within one thread, which removes the confound that made the context */ -/* switch figure hard to read -- there, the timed region included the */ -/* partner's execution. */ +/* No partner threads and no relinquish here. The measurement is */ +/* entirely within one thread, which removes the confound that made the */ +/* context switch figure hard to read -- there, the timed region */ +/* included the partner's execution. */ /* */ -/* Samples are kept and post-processed rather than filtered against a */ -/* fixed threshold, because the cost of this workload was not known in */ -/* advance and a guessed threshold discarded every sample once already. */ +/* Samples are kept and post-processed rather than filtered against a */ +/* fixed threshold, because the cost of this workload was not known in */ +/* advance and a guessed threshold discarded every sample once already. */ /**************************************************************************/ #define DEEP_SAMPLES 64U @@ -442,20 +443,20 @@ static void deep_entry(ULONG which) /**************************************************************************/ /* Per-thread memory protection, demonstrated rather than asserted. */ /* */ -/* Two threads each own a 4 KB window at the top of DRAM2, carved out of */ -/* the broad data region in mpu.c so that nothing else grants access to */ -/* them. Each thread writes its own window, which must succeed, and then */ -/* reaches for the other thread's, which must fault. */ +/* Two threads each own a 4 KB window at the top of DRAM2, carved out of */ +/* the broad data region in mpu.c so that nothing else grants access to */ +/* them. Each thread writes its own window, which must succeed, and */ +/* then reaches for the other thread's, which must fault. */ /* */ -/* The second half is the part that matters. A test that only shows a */ -/* thread reaching its own memory proves nothing about isolation: it */ +/* The second half is the part that matters. A test that only shows a */ +/* thread reaching its own memory proves nothing about isolation: it */ /* would pass just as well with no protection at all. */ /* */ -/* The fault is made survivable the same way the boot probes do it -- */ -/* fault_expected tells the data abort handler to record the violation */ -/* and resume at the instruction after the faulting access, rather than */ -/* treating it as fatal. That works in thread context because the */ -/* handler returns to where it came from rather than to a fixed recovery */ +/* The fault is made survivable the same way the boot probes do it -- */ +/* fault_expected tells the data abort handler to record the violation */ +/* and resume at the instruction after the faulting access, rather than */ +/* treating it as fatal. That works in thread context because the */ +/* handler returns to where it came from rather than to a fixed recovery */ /* point. */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_vfp_s32z280.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_vfp_s32z280.c index 456ad3190..192f51fa7 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_vfp_s32z280.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/demo_vfp_s32z280.c @@ -59,7 +59,7 @@ /* software flag and never touches the hardware. Without that, the */ /* first D-register access after a switch takes an Undefined */ /* Instruction exception -- which on this board was invisible until */ -/* SCTLR.TE was cleared. */ +/* SCTLR.TE was cleared. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/entry.S b/ports/cortex_r52/gnu/example_build/s32z280_evb/entry.S index 6601b25ec..b265c405a 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/entry.S +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/entry.S @@ -46,9 +46,9 @@ @/* 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 */ +@/* 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 */ +@/* 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 */ @@ -61,8 +61,8 @@ @/* */ @/* 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*/ -@/* silently mis-scale every tick interval derived from it. */ +@/* for this board is not yet established, and writing a wrong one */ +@/* would silently mis-scale every tick interval derived from it. */ @/* */ @/**************************************************************************/ @@ -232,41 +232,41 @@ el1_vectors: @/* 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 */ +@/* 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 */ +@/* 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). */ +@/* 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. */ +@/* 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). */ @@ -520,18 +520,18 @@ start_a32: @/**************************************************************************/ @/* _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. */ +@/* 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. */ +@/* 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" diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/gicv3.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/gicv3.c index 1bca8dded..76b24683c 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/gicv3.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/gicv3.c @@ -31,10 +31,11 @@ /* parameters rather than assumed: */ /* */ /* has-two-security-states=0 single security state, so GICD_CTLR.DS */ -/* reads 1 and the Group 1 enable is bit 1*/ -/* ARE-fixed-to-one=1 affinity routing cannot be turned off */ -/* priority-bits=5 only the top 5 priority bits exist, so */ -/* priorities must be multiples of 8 */ +/* reads 1 and the Group 1 enable is bit */ +/* 1 ARE-fixed-to-one=1 affinity routing cannot be turned */ +/* off priority-bits=5 only the top 5 priority bits */ +/* exist, so priorities must be multiples */ +/* of 8 */ /* */ /* MISRA C:2012 deviations (justified) */ /* */ @@ -225,9 +226,9 @@ void gicv3_enable_ppi(unsigned int intid, unsigned int priority) /**************************************************************************/ /* gicv3_enable_sgi */ /* */ -/* An SGI lives in the same redistributor frame as a PPI, so this is */ -/* gicv3_enable_ppi without the ICFGR step: INTIDs 0-15 have no */ -/* configurable edge/level, they are always edge-triggered. */ +/* An SGI lives in the same redistributor frame as a PPI, so this is */ +/* gicv3_enable_ppi without the ICFGR step: INTIDs 0-15 have no */ +/* configurable edge/level, they are always edge-triggered. */ /**************************************************************************/ void gicv3_enable_sgi(unsigned int intid, unsigned int priority) @@ -251,15 +252,15 @@ void gicv3_enable_sgi(unsigned int intid, unsigned int priority) /**************************************************************************/ /* gicv3_send_sgi */ /* */ -/* ICC_SGI1R is 64-bit, so in AArch32 it is an MCRR rather than an MCR. */ -/* Fields: INTID in [27:24], TargetList in [15:0], Aff1/2/3 and IRM zero */ -/* for this single-core configuration, so TargetList = 1 selects core 0. */ +/* ICC_SGI1R is 64-bit, so in AArch32 it is an MCRR rather than an MCR. */ +/* Fields: INTID in [27:24], TargetList in [15:0], Aff1/2/3 and IRM zero */ +/* for this single-core configuration, so TargetList = 1 selects core 0. */ /* */ -/* The AArch64 name for this register is S3_0_C12_C11_5, which the */ -/* Cortex-A72 example uses, but that encoding does not transcribe to the */ -/* AArch32 64-bit CP15 space. The CRm here was confirmed by observing */ -/* that the SGI is actually delivered and acknowledged with the expected */ -/* INTID rather than by reading it off the A-profile alias. */ +/* The AArch64 name for this register is S3_0_C12_C11_5, which the */ +/* Cortex-A72 example uses, but that encoding does not transcribe to the */ +/* AArch32 64-bit CP15 space. The CRm here was confirmed by observing */ +/* that the SGI is actually delivered and acknowledged with the expected */ +/* INTID rather than by reading it off the A-profile alias. */ /**************************************************************************/ void gicv3_send_sgi(unsigned int intid) @@ -273,19 +274,19 @@ void gicv3_send_sgi(unsigned int intid) /**************************************************************************/ -/* gicv3_priority_bits */ +/* gicv3_priority_bits */ /* */ -/* How many priority bits this GIC actually implements, discovered rather */ -/* than assumed: write 0xFF to a priority byte and see which bits stick. */ -/* The unimplemented bits are the low ones and they read as zero. */ +/* How many priority bits this GIC actually implements, discovered */ +/* rather than assumed: write 0xFF to a priority byte and see which bits */ +/* stick. The unimplemented bits are the low ones and they read as zero. */ /* */ -/* This matters for nesting. Two interrupts only preempt one another if */ -/* their priorities differ AFTER truncation, so a test that picks values */ -/* 0x20 apart on a GIC keeping four bits is testing nothing. The FVP */ -/* keeps five; real silicon need not agree. */ +/* This matters for nesting. Two interrupts only preempt one another if */ +/* their priorities differ AFTER truncation, so a test that picks values */ +/* 0x20 apart on a GIC keeping four bits is testing nothing. The FVP */ +/* keeps five; real silicon need not agree. */ /* */ -/* Called before the SGI is configured, and it leaves the byte at zero, so */ -/* the caller must set the priority it wants afterwards. */ +/* Called before the SGI is configured, and it leaves the byte at zero, */ +/* so the caller must set the priority it wants afterwards. */ /**************************************************************************/ unsigned int gicv3_priority_bits(unsigned int scratch_intid) @@ -322,11 +323,11 @@ unsigned int gicv3_priority_bits(unsigned int scratch_intid) /**************************************************************************/ -/* gicv3_enable_sgi_group0 */ +/* gicv3_enable_sgi_group0 */ /* */ -/* As gicv3_enable_sgi, but leaves the interrupt in Group 0 so it arrives */ -/* as an FIQ. The group is chosen by clearing the GICR_IGROUPR0 bit; the */ -/* Group 1 version sets it. */ +/* As gicv3_enable_sgi, but leaves the interrupt in Group 0 so it */ +/* arrives as an FIQ. The group is chosen by clearing the GICR_IGROUPR0 */ +/* bit; the Group 1 version sets it. */ /**************************************************************************/ void gicv3_enable_sgi_group0(unsigned int intid, unsigned int priority) @@ -348,11 +349,12 @@ void gicv3_enable_sgi_group0(unsigned int intid, unsigned int priority) /**************************************************************************/ -/* gicv3_send_sgi_group0 */ +/* gicv3_send_sgi_group0 */ /* */ -/* ICC_SGI0R rather than ICC_SGI1R: the two differ only in opc1, 2 against */ -/* 0, and each raises the SGI into its own group. Raising a Group 0 */ -/* interrupt through the Group 1 register does not deliver it as an FIQ. */ +/* ICC_SGI0R rather than ICC_SGI1R: the two differ only in opc1, 2 */ +/* against 0, and each raises the SGI into its own group. Raising a */ +/* Group 0 interrupt through the Group 1 register does not deliver it as */ +/* an FIQ. */ /**************************************************************************/ void gicv3_send_sgi_group0(unsigned int intid) @@ -366,11 +368,12 @@ void gicv3_send_sgi_group0(unsigned int intid) /**************************************************************************/ -/* gicv3_acknowledge_group0 / gicv3_end_of_interrupt_group0 */ +/* gicv3_acknowledge_group0 / gicv3_end_of_interrupt_group0 */ /* */ -/* Group 0 has its own pair at c12, c8, where Group 1 uses c12, c12. */ -/* Acknowledging a Group 0 interrupt through IAR1 returns the spurious */ -/* INTID and leaves the interrupt pending, which presents as an FIQ storm. */ +/* Group 0 has its own pair at c12, c8, where Group 1 uses c12, c12. */ +/* Acknowledging a Group 0 interrupt through IAR1 returns the spurious */ +/* INTID and leaves the interrupt pending, which presents as an FIQ */ +/* storm. */ /**************************************************************************/ unsigned long gicv3_acknowledge_group0(void) diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/irq_dispatch.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/irq_dispatch.c index 92fbe97b4..edacec509 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/irq_dispatch.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/irq_dispatch.c @@ -32,10 +32,10 @@ /* so a failure here is a board or GIC problem and not a kernel one. */ /* It counts ticks instead, which is what makes the interrupt visible. */ /* */ -/* Every count is volatile and read by the debugger as well as printed.*/ -/* An interrupt that never arrives and an interrupt that arrives and is*/ -/* mishandled look identical from the console alone, and the separate */ -/* spurious and unexpected counters distinguish them. */ +/* Every count is volatile and read by the debugger as well as */ +/* printed. An interrupt that never arrives and an interrupt that */ +/* arrives and is mishandled look identical from the console alone, */ +/* and the separate spurious and unexpected counters distinguish them. */ /* */ /**************************************************************************/ @@ -158,28 +158,29 @@ void board_init(void) /**************************************************************************/ -/* board_irq_service -- service an already-acknowledged INTID. */ +/* board_irq_service -- service an already-acknowledged INTID. */ /* */ -/* Split out so the nesting path in entry.S can acknowledge in IRQ mode */ -/* before nesting starts. Does not acknowledge and does not EOI. */ +/* Split out so the nesting path in entry.S can acknowledge in IRQ mode */ +/* before nesting starts. Does not acknowledge and does not EOI. */ /**************************************************************************/ /**************************************************************************/ /* Handler execution time, and where the handler's instructions live. */ /* */ -/* TX_R52_ATCM_ISR places the service routine in ATCM. ATCM runs at full */ -/* core speed with one wait state; .text lives in RTU code RAM, which runs */ -/* at half the core frequency (S32Z2 RM 6.3.6). ATCM also has no cache to */ -/* miss, which is the property that matters for a determinism argument. */ +/* TX_R52_ATCM_ISR places the service routine in ATCM. ATCM runs at */ +/* full core speed with one wait state; .text lives in RTU code RAM, */ +/* which runs at half the core frequency (S32Z2 RM 6.3.6). ATCM also */ +/* has no cache to miss, which is the property that matters for a */ +/* determinism argument. */ /* */ -/* Measured in cycles from the PMU counter, not CNTPCT: at 8 MHz CNTPCT */ -/* cannot resolve a handler body, let alone the variation in one. */ +/* Measured in cycles from the PMU counter, not CNTPCT: at 8 MHz CNTPCT */ +/* cannot resolve a handler body, let alone the variation in one. */ /* */ -/* The timing wrapper below stays in .text in both configurations, so its */ -/* own cost appears in every sample and cancels when the two are compared. */ -/* Only the body moves. What matters in the result is the spread: a warm */ -/* instruction cache can match ATCM on the mean and cannot match it on the */ -/* worst case. */ +/* The timing wrapper below stays in .text in both configurations, so */ +/* its own cost appears in every sample and cancels when the two are */ +/* compared. Only the body moves. What matters in the result is the */ +/* spread: a warm instruction cache can match ATCM on the mean and */ +/* cannot match it on the worst case. */ /**************************************************************************/ #define BOARD_LATENCY_SAMPLES 64U @@ -356,11 +357,11 @@ void board_irq_service(unsigned long intid) /**************************************************************************/ -/* board_irq_handler -- the non-nesting entry point. */ +/* board_irq_handler -- the non-nesting entry point. */ /* */ -/* Acknowledges, services and ends the interrupt in IRQ mode with */ -/* interrupts masked, which is what every image built without */ -/* TX_ENABLE_IRQ_NESTING did before this split. */ +/* Acknowledges, services and ends the interrupt in IRQ mode with */ +/* interrupts masked, which is what every image built without */ +/* TX_ENABLE_IRQ_NESTING did before this split. */ /**************************************************************************/ void board_irq_handler(void) @@ -378,11 +379,11 @@ void board_irq_handler(void) #ifdef TX_ENABLE_FIQ_SUPPORT /**************************************************************************/ -/* board_fiq_service -- service an already-acknowledged Group 0 INTID. */ +/* board_fiq_service -- service an already-acknowledged Group 0 INTID. */ /* */ -/* The FIQ counterpart of board_irq_service, and split for the same */ -/* reason: the acknowledge has to happen before nesting starts. Does not */ -/* acknowledge and does not EOI. */ +/* The FIQ counterpart of board_irq_service, and split for the same */ +/* reason: the acknowledge has to happen before nesting starts. Does */ +/* not acknowledge and does not EOI. */ /**************************************************************************/ void board_fiq_service(unsigned long intid) @@ -445,7 +446,7 @@ void board_fiq_service(unsigned long intid) /**************************************************************************/ -/* board_fiq_handler -- the non-nesting FIQ entry point. */ +/* board_fiq_handler -- the non-nesting FIQ entry point. */ /**************************************************************************/ void board_fiq_handler(void) diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/mpu.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/mpu.c index c8277fc47..01a3cc72b 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/mpu.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/mpu.c @@ -29,10 +29,11 @@ /* */ /* Register model (AArch32): a region is selected through PRSELR and */ /* then described by PRBAR (base, shareability, access permission, */ -/* execute-never) and PRLAR (inclusive limit, attribute index, enable).*/ -/* Both addresses have a 64-byte granule, so the low six bits of each */ -/* register hold attributes rather than address. Memory types come */ -/* from MAIR through the attribute index, not from the region itself. */ +/* execute-never) and PRLAR (inclusive limit, attribute index, */ +/* enable). Both addresses have a 64-byte granule, so the low six bits */ +/* of each register hold attributes rather than address. Memory types */ +/* come from MAIR through the attribute index, not from the region */ +/* itself. */ /* */ /* Caches are invalidated before being enabled. On this model they */ /* come out of reset invalid, but silicon does not guarantee that, and */ @@ -40,9 +41,9 @@ /* */ /* MISRA C:2012 deviations (justified) */ /* */ -/* Directive 4.3 -- the MPU, MAIR, SCTLR and cache maintenance are only*/ -/* reachable through CP15; every access is encapsulated in a one-line*/ -/* accessor below. */ +/* Directive 4.3 -- the MPU, MAIR, SCTLR and cache maintenance are */ +/* only reachable through CP15; every access is encapsulated in a */ +/* one-line accessor below. */ /* */ /**************************************************************************/ @@ -467,7 +468,7 @@ static void program_region(unsigned int index, const MPU_REGION *region_ptr) /* the preamble and write the module's data to load it at all. Without */ /* this the load faulted on its first read of the image, and because a */ /* privileged data abort ends in a handler that only spins, that looked */ -/* exactly like the load hanging. */ +/* exactly like the load hanging. */ /* */ /* Opened around the load and closed straight after, rather than left in */ /* place, because PMSAv8-R has no region priority: if this region were */ @@ -475,7 +476,7 @@ static void program_region(unsigned int index, const MPU_REGION *region_ptr) /* own regions, and an access hitting both takes a translation fault */ /* (TRM 8.1). */ /* Closing it before any module thread starts is what keeps the two from */ -/* ever being enabled together. */ +/* ever being enabled together. */ /* */ /* Region 16, above both the kernel's 0-7 and the eight the manager */ /* hands to a module, so neither the scheduler's per-thread region load */ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/tcm.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/tcm.c index 081dc4140..aa36cbe04 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/tcm.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/tcm.c @@ -29,11 +29,12 @@ /* the register layouts and where they come from; nothing here is */ /* inferred from a neighbouring register's shape. */ /* */ -/* Reading only. Programming a base address and setting the enables */ -/* comes after these values have been seen and agree with both the */ -/* Cortex-R52 TRM and the S32Z2 reference manual, because a disagreement*/ -/* would mean one of the two documents does not describe this part and */ -/* guessing which would be the whole PRBAR mistake again. */ +/* Reading only. Programming a base address and setting the enables */ +/* comes after these values have been seen and agree with both the */ +/* Cortex-R52 TRM and the S32Z2 reference manual, because a */ +/* disagreement would mean one of the two documents does not describe */ +/* this part and guessing which would be the whole PRBAR mistake */ +/* again. */ /* */ /* MISRA C:2012 deviations (justified) */ /* */ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/tcm.h b/ports/cortex_r52/gnu/example_build/s32z280_evb/tcm.h index b80f226d3..e13a37231 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/tcm.h +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/tcm.h @@ -36,20 +36,20 @@ /* at MRC/MCR p15, 0, , c9, c1, {0,1,2} and are laid out: */ /* */ /* [31:13] BASEADDRESS bits [31:13] of the TCM base address */ -/* [12:9] RES0 */ -/* [8] WAITSTATES wait states for TCM accesses */ -/* [7] RES0 */ -/* [6:2] SIZE size indicator, read-only in effect */ -/* [1] ENABLEEL2 enable at EL2 */ -/* [0] ENABLEEL10 enable at EL1 and EL0 */ -/* */ -/* ⚠ BASEADDRESS is [31:13], not [31:12]. IMP_PERIPHPREGIONR uses */ -/* [31:12] and inferring the same here would be wrong by one bit -- */ +/* [12:9] RES0 */ +/* [8] WAITSTATES wait states for TCM accesses */ +/* [7] RES0 */ +/* [6:2] SIZE size indicator, read-only in effect */ +/* [1] ENABLEEL2 enable at EL2 */ +/* [0] ENABLEEL10 enable at EL1 and EL0 */ +/* */ +/* ⚠ BASEADDRESS is [31:13], not [31:12]. IMP_PERIPHPREGIONR uses */ +/* [31:12] and inferring the same here would be wrong by one bit -- */ /* the same class of mistake that made PRBAR silently drop XN. The */ -/* base is therefore 8KB-aligned, not 4KB. */ +/* base is therefore 8KB-aligned, not 4KB. */ /* */ -/* SIZE encodings: 0 none, 4 8KB, 5 16KB, 6 32KB, 7 64KB, 8 128KB, */ -/* 9 256KB, 10 512KB, 11 1MB. */ +/* SIZE encodings: 0 none, 4 8KB, 5 16KB, 6 32KB, 7 64KB, 8 128KB, */ +/* 9 256KB, 10 512KB, 11 1MB. */ /* */ /* "At reset all bits are 0 apart from SIZE and WAITSTATES", unless */ /* CFGTCMBOOTx is high, which resets the ATCM enables to 1. So a */ @@ -60,7 +60,7 @@ /* IMP_MEMPROTCTLR is at p15, 1, , c9, c1, 2 (TRM 3.3.76, table */ /* 3-114): RAMPROTIMP [4] says whether RAM protection exists at all, */ /* RAMPROTEN [0] whether it is on, and RAMPROTEN is ignored when */ -/* RAMPROTIMP is 0. */ +/* RAMPROTIMP is 0. */ /* */ /* S32Z2 reference manual: TCMA 64KB with 1 wait state, TCMB 16KB with */ /* 0, TCMC 16KB with 1, per core. Those give expected SIZE values of */ @@ -78,7 +78,7 @@ /* The preload widths are not uniform: BTCM and CTCM take STR, STRD */ /* or STM at 32-bit alignment, but ATCM needs STRD or STM at 64-bit */ /* alignment. A C loop storing 32-bit words would leave ATCM's check */ -/* bits invalid. */ +/* bits invalid. */ /* */ /**************************************************************************/ @@ -117,21 +117,21 @@ unsigned int tcm_ecc_enabled(void); /**************************************************************************/ /* ENABLING */ /* */ -/* Constraints, all from Cortex-R52 TRM r1p3 section 6.2 and 3.3.94: */ +/* Constraints, all from Cortex-R52 TRM r1p3 section 6.2 and 3.3.94: */ /* */ -/* - The base address must be SIZE-ALIGNED, not merely 8KB-aligned as */ +/* - The base address must be SIZE-ALIGNED, not merely 8KB-aligned as */ /* the BASEADDRESS field's width alone would suggest. */ -/* - A disabled TCM's base address is UNKNOWN, not zero, so every bank */ -/* must be programmed explicitly rather than adjusted from what it */ +/* - A disabled TCM's base address is UNKNOWN, not zero, so every bank */ +/* must be programmed explicitly rather than adjusted from what it */ /* appears to hold. */ -/* - "Before using the TCM you must program MPU regions to cover the */ -/* TCM regions to give access." An enabled TCM with no MPU region */ +/* - "Before using the TCM you must program MPU regions to cover the */ +/* TCM regions to give access." An enabled TCM with no MPU region */ /* still faults once the MPU is on. */ -/* - An enabled TCM always behaves as Non-cacheable Non-shareable */ -/* Normal memory whatever the MPU says; the MPU supplies only the */ -/* permissions. So the MPU region's attribute index is irrelevant */ +/* - An enabled TCM always behaves as Non-cacheable Non-shareable */ +/* Normal memory whatever the MPU says; the MPU supplies only the */ +/* permissions. So the MPU region's attribute index is irrelevant */ /* here and its AP and XN bits are not. */ -/* - With ECC on, every location must be written before it is read. */ +/* - With ECC on, every location must be written before it is read. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/thread_mpu.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/thread_mpu.c index 5681754f9..d53c45ab7 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/thread_mpu.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/thread_mpu.c @@ -26,7 +26,7 @@ /* DESCRIPTION */ /* */ /* Per-thread memory protection. See thread_mpu.h for what this is */ -/* and is not. */ +/* and is not. */ /* */ /* MISRA C:2012 deviations (justified) */ /* */ @@ -159,22 +159,22 @@ unsigned long thread_mpu_grant(TX_THREAD *thread_ptr, unsigned int window) /**************************************************************************/ /* Activation. */ /* */ -/* Called explicitly by a thread rather than from the scheduler, and that */ -/* is a deliberate limitation of this step rather than the intended */ -/* design. */ +/* Called explicitly by a thread rather than from the scheduler, and */ +/* that is a deliberate limitation of this step rather than the intended */ +/* design. */ /* */ -/* The port's scheduler does call _tx_execution_thread_enter under */ -/* TX_ENABLE_EXECUTION_CHANGE_NOTIFY, which would make this automatic on */ -/* every switch. That macro is read by the port assembly compiled into */ -/* the shared threadx library, so enabling it would oblige all nine */ -/* example targets in this port -- including the FVP ones -- to supply */ -/* the four execution hooks. A ThreadX module port carries its own */ -/* copies of the port assembly for exactly this reason, and that is where */ -/* the switch belongs. */ +/* The port's scheduler does call _tx_execution_thread_enter under */ +/* TX_ENABLE_EXECUTION_CHANGE_NOTIFY, which would make this automatic on */ +/* every switch. That macro is read by the port assembly compiled into */ +/* the shared threadx library, so enabling it would oblige all nine */ +/* example targets in this port -- including the FVP ones -- to supply */ +/* the four execution hooks. A ThreadX module port carries its own */ +/* copies of the port assembly for exactly this reason, and that is */ +/* where the switch belongs. */ /* */ -/* What this step establishes without that machinery: that a PMSAv8-R */ -/* region can be reprogrammed per thread on this part, what it costs, and */ -/* that a violation faults. Those are the questions worth answering */ +/* What this step establishes without that machinery: that a PMSAv8-R */ +/* region can be reprogrammed per thread on this part, what it costs, */ +/* and that a violation faults. Those are the questions worth answering */ /* before writing a module manager on top of them. */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/thread_mpu.h b/ports/cortex_r52/gnu/example_build/s32z280_evb/thread_mpu.h index cba6226e5..a8b47d635 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/thread_mpu.h +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/thread_mpu.h @@ -27,21 +27,21 @@ /* */ /* Per-thread memory protection for the NXP S32Z280-594EVB. */ /* */ -/* One MPU region is reprogrammed on every thread entry to grant the */ -/* incoming thread access to its own window and nothing else. A thread */ -/* with no window registered runs with that region disabled, so it */ -/* reaches none of them. */ +/* One MPU region is reprogrammed on every thread entry to grant the */ +/* incoming thread access to its own window and nothing else. A */ +/* thread with no window registered runs with that region disabled, so */ +/* it reaches none of them. */ /* */ -/* This is a step towards a ThreadX module port for this core, not a */ -/* substitute for one. It demonstrates that PMSAv8-R regions can be */ -/* switched per thread on this part, at a measured cost, and that a */ -/* violation faults -- which are the questions worth answering before */ -/* building a module manager on top of them. There is no user mode, no */ -/* syscall boundary and no loader here. */ +/* This is a step towards a ThreadX module port for this core, not a */ +/* substitute for one. It demonstrates that PMSAv8-R regions can be */ +/* switched per thread on this part, at a measured cost, and that a */ +/* violation faults -- which are the questions worth answering before */ +/* building a module manager on top of them. There is no user mode, */ +/* no syscall boundary and no loader here. */ /* */ -/* The hook is _tx_execution_thread_enter, which the port's scheduler */ -/* already calls under TX_ENABLE_EXECUTION_CHANGE_NOTIFY, after the */ -/* stack pointer has been switched. No port assembly is modified. */ +/* The hook is _tx_execution_thread_enter, which the port's scheduler */ +/* already calls under TX_ENABLE_EXECUTION_CHANGE_NOTIFY, after the */ +/* stack pointer has been switched. No port assembly is modified. */ /* */ /**************************************************************************/ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/timer.c b/ports/cortex_r52/gnu/example_build/s32z280_evb/timer.c index 9fc5c0a17..582a92dea 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/timer.c +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/timer.c @@ -36,10 +36,10 @@ /* */ /* The rate itself is measured rather than computed. The RTU divides */ /* a cluster clock by RTU.GPR CFG_CNTDV to generate the timer's */ -/* clock-enable, so deriving it needs the divider AND the cluster clock*/ -/* AND the PLL configuration feeding it -- three places to be wrong. */ -/* Sampling CNTPCT against host wall-clock time needs none of them and */ -/* is checkable against the clock tree afterwards. */ +/* clock-enable, so deriving it needs the divider AND the cluster */ +/* clock AND the PLL configuration feeding it -- three places to be */ +/* wrong. Sampling CNTPCT against host wall-clock time needs none of */ +/* them and is checkable against the clock tree afterwards. */ /* */ /* MISRA C:2012 deviations (justified) */ /* */ @@ -151,10 +151,11 @@ void timer_stop(void) /**************************************************************************/ /* PMU cycle counter. */ /* */ -/* PMCR.E gates all counters including the dedicated cycle counter, and */ -/* PMCNTENSET bit 31 enables that counter specifically. Both are needed. */ -/* PMCR.D is left clear so the counter advances every cycle rather than */ -/* every 64th, which is the resolution these measurements want. */ +/* PMCR.E gates all counters including the dedicated cycle counter, and */ +/* PMCNTENSET bit 31 enables that counter specifically. Both are */ +/* needed. PMCR.D is left clear so the counter advances every cycle */ +/* rather than every 64th, which is the resolution these measurements */ +/* want. */ /**************************************************************************/ #define PMCR_E (1UL << 0) /* enable all counters */ diff --git a/ports/cortex_r52/gnu/example_build/s32z280_evb/tx_initialize_low_level.S b/ports/cortex_r52/gnu/example_build/s32z280_evb/tx_initialize_low_level.S index 097eeafed..a93a951c5 100644 --- a/ports/cortex_r52/gnu/example_build/s32z280_evb/tx_initialize_low_level.S +++ b/ports/cortex_r52/gnu/example_build/s32z280_evb/tx_initialize_low_level.S @@ -62,11 +62,11 @@ /* */ /* When built with TX_R52_USE_THREADX_IRQ, board_init() brings up the */ /* MPU, GICv3 and the generic timer tick here. The MPU comes first on */ -/* this board: the GIC region has to be mapped Device nGnRnE before any*/ -/* GIC register can be touched at all. */ +/* this board: the GIC region has to be mapped Device nGnRnE before */ +/* any GIC register can be touched at all. */ /* and the generic timer tick here. That is safe this early because */ -/* interrupts stay masked until _tx_thread_schedule enables them, so no*/ -/* tick can be delivered before the kernel is ready to take one. */ +/* interrupts stay masked until _tx_thread_schedule enables them, so */ +/* no tick can be delivered before the kernel is ready to take one. */ /* Without that symbol (the M2 cooperative demo) no tick is created, */ /* which keeps M2 free of any interrupt dependency. */ /* */ diff --git a/ports/cortex_r52/gnu/src/tx_port_offset_check.c b/ports/cortex_r52/gnu/src/tx_port_offset_check.c index 5e853fca6..2bb58fa2a 100644 --- a/ports/cortex_r52/gnu/src/tx_port_offset_check.c +++ b/ports/cortex_r52/gnu/src/tx_port_offset_check.c @@ -52,8 +52,8 @@ /* */ /* A negative array dimension is used rather than _Static_assert */ /* because this project targets C99, where _Static_assert does not */ -/* exist. If an assertion below fails, the compiler reports a negative*/ -/* or zero-sized array for the named typedef. */ +/* exist. If an assertion below fails, the compiler reports a */ +/* negative or zero-sized array for the named typedef. */ /* */ /**************************************************************************/ diff --git a/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/module_blob.S b/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/module_blob.S index b3c2d44df..f58dade56 100644 --- a/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/module_blob.S +++ b/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/module_blob.S @@ -25,23 +25,23 @@ @/* */ @/* DESCRIPTION */ @/* */ -@/* Carries the demonstration module into the manager image as data. */ +@/* Carries the demonstration module into the manager image as data. */ @/* */ -@/* The module is built as its own link unit and objcopied to a raw */ -@/* binary, which is included here verbatim. It has to be a separate */ -@/* link: the module library defines shims named after the ThreadX API */ -@/* entry points the kernel also defines, and in one link the shims win */ -@/* -- objects beat archive members -- so the manager's own service calls */ -@/* end up trapping into the module. */ +@/* The module is built as its own link unit and objcopied to a raw */ +@/* binary, which is included here verbatim. It has to be a separate */ +@/* link: the module library defines shims named after the ThreadX API */ +@/* entry points the kernel also defines, and in one link the shims win */ +@/* -- objects beat archive members -- so the manager's own service */ +@/* calls end up trapping into the module. */ @/* */ -@/* Included as bytes rather than linked as objects, so the module's */ -@/* symbols never enter the manager's link at all. Nothing here is */ -@/* called: the manager finds the preamble at the start of the image and */ -@/* reaches everything else through that. */ +@/* Included as bytes rather than linked as objects, so the module's */ +@/* symbols never enter the manager's link at all. Nothing here is */ +@/* called: the manager finds the preamble at the start of the image */ +@/* and reaches everything else through that. */ @/* */ -@/* A separate copy from the S32Z280 one, and identical to it: the two */ -@/* module examples are deliberately independent builds, and each names */ -@/* its own raw image through its own assembler include path. */ +@/* A separate copy from the S32Z280 one, and identical to it: the two */ +@/* module examples are deliberately independent builds, and each names */ +@/* its own raw image through its own assembler include path. */ @/* */ @/**************************************************************************/ diff --git a/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module.c b/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module.c index e2fd2508f..a18c04d8b 100644 --- a/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module.c +++ b/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module.c @@ -25,58 +25,59 @@ /* */ /* DESCRIPTION */ /* */ -/* A module that exercises the protection boundary rather than */ -/* demonstrating features, for the Armv8-R AEM FVP. */ +/* A module that exercises the protection boundary rather than */ +/* demonstrating features, for the Armv8-R AEM FVP. */ /* */ -/* The S32Z280 copy of this file is the same module for the same port; */ -/* what differs is the two addresses at the bottom and the board named */ -/* here, so `diff` is the tool for telling whether the two have drifted. */ +/* The S32Z280 copy of this file is the same module for the same port; */ +/* what differs is the two addresses at the bottom and the board named */ +/* here, so `diff` is the tool for telling whether the two have */ +/* drifted. */ /* */ -/* Four steps: */ +/* Four steps: */ /* */ /* 1. Writes and reads its own data, which must succeed. */ -/* 2. Makes a kernel call, which must succeed -- proving a module in */ -/* User mode can reach the kernel through the supervisor call */ +/* 2. Makes a kernel call, which must succeed -- proving a module in */ +/* User mode can reach the kernel through the supervisor call */ /* boundary and come back. */ -/* 3. Violates its protection in one of three ways the manager */ +/* 3. Violates its protection in one of three ways the manager */ /* selects, which must fault. */ /* 4. Never reaches step 4, because step 3 terminates it. */ /* */ -/* THE THREE VIOLATIONS. Two of them are the two aborts the hardware */ -/* distinguishes: reading the kernel's data is a DATA abort reported */ -/* through DFSR and DFAR, branching out of the code region is a */ -/* PREFETCH abort reported through IFSR and IFAR. The third writes a */ -/* granule of the SHARED area that the manager deliberately did not */ -/* grant, after writing and reading back every granule it did -- so it */ -/* is the shared-region machinery under test rather than the kernel's */ -/* own memory, and a grant that covered one granule too many is what it */ -/* is looking for. */ +/* THE THREE VIOLATIONS. Two of them are the two aborts the hardware */ +/* distinguishes: reading the kernel's data is a DATA abort reported */ +/* through DFSR and DFAR, branching out of the code region is a */ +/* PREFETCH abort reported through IFSR and IFAR. The third writes a */ +/* granule of the SHARED area that the manager deliberately did not */ +/* grant, after writing and reading back every granule it did -- so it */ +/* is the shared-region machinery under test rather than the kernel's */ +/* own memory, and a grant that covered one granule too many is what */ +/* it is looking for. */ /* */ -/* Steps 1 and 2 passing without step 3 faulting would mean the module */ -/* is running unprotected, which is the failure this example exists to */ -/* detect. A module that only ever touched its own memory would pass */ +/* Steps 1 and 2 passing without step 3 faulting would mean the module */ +/* is running unprotected, which is the failure this example exists to */ +/* detect. A module that only ever touched its own memory would pass */ /* identically with the MPU switched off. */ /* */ -/* HOW PROGRESS GETS OUT. A module cannot print: the console belongs */ -/* to the board support package, outside every region a module owns, so */ -/* reaching it would fault as surely as step 3 does. So progress is */ -/* recorded twice -- in the module's own data, and in the first granule */ -/* of the shared area the manager granted it. */ +/* HOW PROGRESS GETS OUT. A module cannot print: the console belongs */ +/* to the board support package, outside every region a module owns, */ +/* so reaching it would fault as surely as step 3 does. So progress */ +/* is recorded twice -- in the module's own data, and in the first */ +/* granule of the shared area the manager granted it. */ /* */ -/* Which of the two can be read depends on the board. On silicon a GDB */ -/* harness reads the module's own copy out of the data area the manager */ -/* allocated for it; the FVP has no such seam -- it exposes an Iris */ -/* server and no GDB stub -- so there only the shared copy is readable */ -/* and everything the run reports has to be reported by the image */ -/* itself. Both writes are kept on both boards deliberately: if the */ -/* shared write were the only one, a module that could not reach its own */ -/* data would still report progress. */ +/* Which of the two can be read depends on the board. On silicon a */ +/* GDB harness reads the module's own copy out of the data area the */ +/* manager allocated for it; the FVP has no such seam -- it exposes an */ +/* Iris server and no GDB stub -- so there only the shared copy is */ +/* readable and everything the run reports has to be reported by the */ +/* image itself. Both writes are kept on both boards deliberately: if */ +/* the shared write were the only one, a module that could not reach */ +/* its own data would still report progress. */ /* */ -/* The shared address is a literal on this side. The module has no */ -/* loader to tell it anything and the manager deliberately knows no */ -/* symbol of the module, so the two agree by convention -- and the */ -/* manager checks that they do, against the linker's own symbol, rather */ -/* than trusting them to. */ +/* The shared address is a literal on this side. The module has no */ +/* loader to tell it anything and the manager deliberately knows no */ +/* symbol of the module, so the two agree by convention -- and the */ +/* manager checks that they do, against the linker's own symbol, */ +/* rather than trusting them to. */ /* */ /**************************************************************************/ diff --git a/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module_manager.c b/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module_manager.c index 365dfecf9..79818fa2c 100644 --- a/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module_manager.c +++ b/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module_manager.c @@ -25,90 +25,93 @@ /* */ /* DESCRIPTION */ /* */ -/* Loads the sample module four times, lets it misbehave every time, */ -/* and reports what the hardware did about it -- on the Armv8-R AEM */ -/* FVP, with no debugger and no person in the loop. */ +/* Loads the sample module four times, lets it misbehave every time, */ +/* and reports what the hardware did about it -- on the Armv8-R AEM */ +/* FVP, with no debugger and no person in the loop. */ /* */ -/* This is the S32Z280 module demonstration turned into a regression. */ -/* The silicon version is judged by a human reading a console and by a */ -/* GDB harness that reads the module's memory between passes; neither */ -/* exists here. The model offers an Iris server and no GDB stub, so */ -/* the image has to judge itself and say so in one line the runner can */ -/* match. Everything below that differs from the silicon sample */ -/* differs for that reason. */ +/* This is the S32Z280 module demonstration turned into a regression. */ +/* The silicon version is judged by a human reading a console and by a */ +/* GDB harness that reads the module's memory between passes; neither */ +/* exists here. The model offers an Iris server and no GDB stub, so */ +/* the image has to judge itself and say so in one line the runner can */ +/* match. Everything below that differs from the silicon sample */ +/* differs for that reason. */ /* */ -/* THE RESULT THIS EXAMPLE EXISTS TO PRODUCE IS THE FAULT. A module */ -/* that starts and runs proves the loader works; a module that is */ -/* stopped by the memory protection unit when it reaches outside its */ -/* own memory proves the port works. So the fault notification is not */ -/* an error path here, it is the expected outcome, and its absence is */ +/* THE RESULT THIS EXAMPLE EXISTS TO PRODUCE IS THE FAULT. A module */ +/* that starts and runs proves the loader works; a module that is */ +/* stopped by the memory protection unit when it reaches outside its */ +/* own memory proves the port works. So the fault notification is not */ +/* an error path here, it is the expected outcome, and its absence is */ /* the failure. */ /* */ -/* TWO PASSES, because one proves nothing about relocation. The module */ -/* is position independent: it is linked against nominal addresses it */ -/* never runs at, and _gcc_setup rewrites its global offset table to */ -/* wherever the manager actually put it. A single run at the linked */ -/* address would exercise a rebase whose input and output are the same */ -/* number, and would look identical if the rebase did nothing at all. */ +/* TWO PASSES, because one proves nothing about relocation. The */ +/* module is position independent: it is linked against nominal */ +/* addresses it never runs at, and _gcc_setup rewrites its global */ +/* offset table to wherever the manager actually put it. A single run */ +/* at the linked address would exercise a rebase whose input and */ +/* output are the same number, and would look identical if the rebase */ +/* did nothing at all. */ /* */ -/* So pass 1 loads the blob where the linker placed it and pass 2 loads */ -/* a byte-for-byte copy of it from the staging area, with pass 1 still */ -/* holding its pool memory so that pass 2's data lands somewhere else */ -/* too. Both bases therefore differ between the passes, which is what */ -/* makes the comparison at the end mean something. */ +/* So pass 1 loads the blob where the linker placed it and pass 2 */ +/* loads a byte-for-byte copy of it from the staging area, with pass 1 */ +/* still holding its pool memory so that pass 2's data lands somewhere */ +/* else too. Both bases therefore differ between the passes, which is */ +/* what makes the comparison at the end mean something. */ /* */ -/* THEN A THIRD PASS, which faults the other way. The two passes above */ -/* make the module read an address it does not own: a data abort, */ -/* reported through DFSR and DFAR. A module can equally leave its code */ -/* region, which is a prefetch abort reported through IFSR and IFAR and */ -/* arrives at the handler by a different vector. Both halves of the */ -/* port's fault path are therefore exercised, and neither is inferred */ -/* from the other. The third pass also runs after the first two have */ -/* been unloaded, which is the other half of what this file shows: a */ -/* module fault must leave the manager able to load and run the next */ -/* module. */ +/* THEN A THIRD PASS, which faults the other way. The two passes */ +/* above make the module read an address it does not own: a data */ +/* abort, reported through DFSR and DFAR. A module can equally leave */ +/* its code region, which is a prefetch abort reported through IFSR */ +/* and IFAR and arrives at the handler by a different vector. Both */ +/* halves of the port's fault path are therefore exercised, and */ +/* neither is inferred from the other. The third pass also runs after */ +/* the first two have been unloaded, which is the other half of what */ +/* this file shows: a module fault must leave the manager able to load */ +/* and run the next module. */ /* */ -/* AND WHAT THE MODULE ACHIEVED IS READ BACK, not inferred. The manager */ -/* grants each pass a shared MPU region over one granule at a fixed */ -/* address and the module records its progress there. That is what */ -/* replaces the GDB harness, and it is what lets this file fail on the */ -/* two flags that matter -- SURVIVED_STEAL and SURVIVED_JUMP -- by name */ -/* rather than only on the absence of a fault. The two are the same */ -/* event seen from both ends, and a regression that showed one without */ -/* the other would be worth knowing about. */ +/* AND WHAT THE MODULE ACHIEVED IS READ BACK, not inferred. The */ +/* manager grants each pass a shared MPU region over one granule at a */ +/* fixed address and the module records its progress there. That is */ +/* what replaces the GDB harness, and it is what lets this file fail */ +/* on the two flags that matter -- SURVIVED_STEAL and SURVIVED_JUMP -- */ +/* by name rather than only on the absence of a fault. The two are */ +/* the same event seen from both ends, and a regression that showed */ +/* one without the other would be worth knowing about. */ /* */ -/* AND A FOURTH PASS FOR THE SHARED REGIONS. The three above are each */ -/* granted one shared region -- the status granule -- which exercises */ -/* the first of the five shared entries the port provides and says */ -/* nothing about the other four. The fourth pass is granted all five, */ -/* one 64-byte granule each, and is NOT granted the granule that sits */ -/* between two of them. It writes every granule it was given, reads */ -/* every one of them back, and then writes the gap, which must fault. */ +/* AND A FOURTH PASS FOR THE SHARED REGIONS. The three above are each */ +/* granted one shared region -- the status granule -- which exercises */ +/* the first of the five shared entries the port provides and says */ +/* nothing about the other four. The fourth pass is granted all five, */ +/* one 64-byte granule each, and is NOT granted the granule that sits */ +/* between two of them. It writes every granule it was given, reads */ +/* every one of them back, and then writes the gap, which must fault. */ /* */ -/* That shape is chosen against a specific defect. A limit register */ -/* masked the wrong way, or a base off by one granule, extends a region */ -/* past what was asked for -- and with the gap sandwiched between two */ -/* granted granules it is reachable from either side if that happens. */ -/* The readback matters as much as the write: a region programmed with */ -/* the wrong base accepts a store and puts it elsewhere, so five marks */ -/* read out of five granules is what says five distinct extents were */ -/* programmed rather than one of them five times. */ +/* That shape is chosen against a specific defect. A limit register */ +/* masked the wrong way, or a base off by one granule, extends a */ +/* region past what was asked for -- and with the gap sandwiched */ +/* between two granted granules it is reachable from either side if */ +/* that happens. The readback matters as much as the write: a region */ +/* programmed with the wrong base accepts a store and puts it */ +/* elsewhere, so five marks read out of five granules is what says */ +/* five distinct extents were programmed rather than one of them five */ +/* times. */ /* */ -/* The same pass probes the two ways the manager refuses a grant, which */ -/* nothing had ever called: an unaligned address must come back */ -/* TXM_MODULE_ALIGNMENT_ERROR, and one grant past the entry count must */ -/* come back TX_NO_MEMORY. Both are checked by name. The order is not */ -/* free -- the entry-count check runs before the alignment check, so the */ -/* unaligned probe has to happen while entries remain. */ +/* The same pass probes the two ways the manager refuses a grant, */ +/* which nothing had ever called: an unaligned address must come back */ +/* TXM_MODULE_ALIGNMENT_ERROR, and one grant past the entry count must */ +/* come back TX_NO_MEMORY. Both are checked by name. The order is */ +/* not free -- the entry-count check runs before the alignment check, */ +/* so the unaligned probe has to happen while entries remain. */ /* */ -/* WHAT A GREEN RUN HERE DOES NOT PROVE. The model reports 32 EL1 MPU */ -/* regions. The Cortex-R52 TRM gives MPUIR.DREGION as 16, 20 or 24, so */ -/* 32 is not an architecturally permitted value for this core and the */ -/* model is the generic AEMv8-R rather than an R52. It is strictly more */ -/* permissive than every real part: this port needs seventeen regions, */ -/* which the S32Z280's twenty supply and a legal 16-region R52 does not, */ -/* and no result from this image can tell you that. The count is */ -/* reported below so the log says what it was rather than implying it. */ +/* WHAT A GREEN RUN HERE DOES NOT PROVE. The model reports 32 EL1 MPU */ +/* regions. The Cortex-R52 TRM gives MPUIR.DREGION as 16, 20 or 24, */ +/* so 32 is not an architecturally permitted value for this core and */ +/* the model is the generic AEMv8-R rather than an R52. It is */ +/* strictly more permissive than every real part: this port needs */ +/* seventeen regions, which the S32Z280's twenty supply and a legal */ +/* 16-region R52 does not, and no result from this image can tell you */ +/* that. The count is reported below so the log says what it was */ +/* rather than implying it. */ /* */ /**************************************************************************/ @@ -393,16 +396,16 @@ static unsigned char report_stack[2048] __attribute__((aligned(8))); /**************************************************************************/ /* Fault notification. */ /* */ -/* Called by the module manager after it has terminated the offending */ -/* thread. Records rather than prints: this runs in Abort mode on the */ -/* Abort stack, which is a kilobyte and already carries the terminate */ -/* underneath this frame. A callback that printed would work here and */ +/* Called by the module manager after it has terminated the offending */ +/* thread. Records rather than prints: this runs in Abort mode on the */ +/* Abort stack, which is a kilobyte and already carries the terminate */ +/* underneath this frame. A callback that printed would work here and */ /* would still be the wrong shape to copy. */ /* */ -/* Its two arguments are the point of the hook, so they are recorded and */ -/* checked rather than discarded: an application is being told WHICH */ -/* thread and WHICH module faulted, and a callback that fires with the */ -/* wrong pair is no more use than one that never fires. */ +/* Its two arguments are the point of the hook, so they are recorded and */ +/* checked rather than discarded: an application is being told WHICH */ +/* thread and WHICH module faulted, and a callback that fires with the */ +/* wrong pair is no more use than one that never fires. */ /**************************************************************************/ static void module_fault_notify(TX_THREAD *thread_ptr, TXM_MODULE_INSTANCE *module_instance) @@ -422,15 +425,15 @@ static void put_field(const char *label, unsigned long value) /**************************************************************************/ -/* The shared status word, reached through the manager's load window. */ +/* The shared status word, reached through the manager's load window. */ /* */ -/* No kernel region covers the module area; region 16 does, and the */ -/* scheduler enables it for every thread that owns no module. This */ -/* thread owns none, so the window is open on it and these two functions */ -/* need no bracketing of their own -- which is the whole reason the */ -/* window is owned by the scheduler rather than by whoever calls. */ +/* No kernel region covers the module area; region 16 does, and the */ +/* scheduler enables it for every thread that owns no module. This */ +/* thread owns none, so the window is open on it and these two functions */ +/* need no bracketing of their own -- which is the whole reason the */ +/* window is owned by the scheduler rather than by whoever calls. */ /* */ -/* MISRA C:2012 Rule 11.6 is deliberately violated: the address is an */ +/* MISRA C:2012 Rule 11.6 is deliberately violated: the address is an */ /* agreement between two separately linked images. */ /**************************************************************************/ @@ -460,9 +463,9 @@ static ULONG module_status_read(void) /**************************************************************************/ /* A byte copy, written out rather than called for. */ /* */ -/* The manager links -nostartfiles and nothing else in this image reaches */ -/* for a C library, so calling memcpy would pull one in for a single */ -/* copy. The blob is under two kilobytes and this runs once. */ +/* The manager links -nostartfiles and nothing else in this image */ +/* reaches for a C library, so calling memcpy would pull one in for a */ +/* single copy. The blob is under two kilobytes and this runs once. */ /**************************************************************************/ static void copy_bytes(unsigned char *destination, const unsigned char *source, @@ -478,21 +481,22 @@ static void copy_bytes(unsigned char *destination, const unsigned char *source, /**************************************************************************/ -/* The shared grants a pass gets, and the two ways a grant is refused. */ +/* The shared grants a pass gets, and the two ways a grant is refused. */ /* */ -/* Every pass is granted the first granule, which is the progress word it */ -/* reports through. The shared pass is granted one granule per shared */ -/* entry the port provides, skipping the gap, because a single grant only */ -/* ever exercises the first of the five and this port has never run the */ -/* other four. */ +/* Every pass is granted the first granule, which is the progress word */ +/* it reports through. The shared pass is granted one granule per */ +/* shared entry the port provides, skipping the gap, because a single */ +/* grant only ever exercises the first of the five and this port has */ +/* never run the other four. */ /* */ -/* It also probes the two ways a grant is refused, which can only be done */ -/* on a LOADED instance. ORDER MATTERS: the manager checks the entry */ -/* count BEFORE it checks alignment, so the unaligned probe has to happen */ -/* while entries remain -- after five grants it would come back */ -/* TX_NO_MEMORY and say nothing about alignment at all. */ +/* It also probes the two ways a grant is refused, which can only be */ +/* done on a LOADED instance. ORDER MATTERS: the manager checks the */ +/* entry count BEFORE it checks alignment, so the unaligned probe has to */ +/* happen while entries remain -- after five grants it would come back */ +/* TX_NO_MEMORY and say nothing about alignment at all. */ /* */ -/* Returns the first grant status that was not TX_SUCCESS, or TX_SUCCESS. */ +/* Returns the first grant status that was not TX_SUCCESS, or */ +/* TX_SUCCESS. */ /**************************************************************************/ static UINT grant_shared_regions(TXM_MODULE_INSTANCE *instance, PASS_RESULT *result) @@ -576,24 +580,24 @@ static UINT grant_shared_regions(TXM_MODULE_INSTANCE *instance, PASS_RESULT *res /**************************************************************************/ -/* The size guards on a shared grant. */ +/* The size guards on a shared grant. */ /* */ -/* A grant of no bytes and a grant whose inclusive end wraps past the top */ -/* of the address space both used to compute a limit BELOW the base, */ -/* program it, return TX_SUCCESS and spend one of the five entries on a */ -/* region the hardware cannot honour. Both must now be refused as */ -/* TX_SIZE_ERROR, and -- the half that a status code alone does not say -- */ -/* must leave the entry count exactly where they found it, because an */ -/* entry spent on a refused grant is one the caller can never get back. */ +/* A grant of no bytes and a grant whose inclusive end wraps past the */ +/* top of the address space both used to compute a limit BELOW the base, */ +/* program it, return TX_SUCCESS and spend one of the five entries on a */ +/* region the hardware cannot honour. Both must now be refused as */ +/* TX_SIZE_ERROR, and -- the half that a status code alone does not say */ +/* -- must leave the entry count exactly where they found it, because an */ +/* entry spent on a refused grant is one the caller can never get back. */ /* */ -/* The third probe is the one that must SUCCEED: a grant ending exactly */ -/* at 0xFFFFFFFF is legal, and a guard that refused it would be a new bug */ -/* in place of the old one. It is checked last so that the count it does */ -/* move is unambiguous. */ +/* The third probe is the one that must SUCCEED: a grant ending exactly */ +/* at 0xFFFFFFFF is legal, and a guard that refused it would be a new */ +/* bug in place of the old one. It is checked last so that the count it */ +/* does move is unambiguous. */ /* */ -/* Loaded here and unloaded below without ever being started, so nothing */ -/* these probes accept is programmed into an MPU region. See the comment */ -/* on MODULE_TOP_GRANULE_ADDRESS for why that matters. */ +/* Loaded here and unloaded below without ever being started, so nothing */ +/* these probes accept is programmed into an MPU region. See the */ +/* comment on MODULE_TOP_GRANULE_ADDRESS for why that matters. */ /**************************************************************************/ static void run_guard_probes(VOID *location) @@ -657,12 +661,13 @@ static void run_guard_probes(VOID *location) /**************************************************************************/ -/* One pass: load the blob from a given address, grant it the shared */ -/* granules it is entitled to, start it, wait for the fault it is written */ -/* to provoke, and stop it. */ +/* One pass: load the blob from a given address, grant it the shared */ +/* granules it is entitled to, start it, wait for the fault it is */ +/* written to provoke, and stop it. */ /* */ -/* The module is left loaded. Its data allocation is what moves the next */ -/* pass's data base, and releasing it here would defeat half the test. */ +/* The module is left loaded. Its data allocation is what moves the */ +/* next pass's data base, and releasing it here would defeat half the */ +/* test. */ /**************************************************************************/ /* name is CHAR * and not const CHAR *, because txm_module_manager_in_place_load diff --git a/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module_properties.c b/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module_properties.c index a24934098..ec5a1f0c2 100644 --- a/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module_properties.c +++ b/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/sample_threadx_module_properties.c @@ -25,105 +25,107 @@ /* */ /* DESCRIPTION */ /* */ -/* Walks the module property combinations this port accepts and */ -/* refuses, and checks each one against the documented contract, on */ -/* the Armv8-R AEM FVP with no debugger and no person in the loop. */ +/* Walks the module property combinations this port accepts and */ +/* refuses, and checks each one against the documented contract, on */ +/* the Armv8-R AEM FVP with no debugger and no person in the loop. */ /* */ -/* WHY THIS IS A SEPARATE IMAGE from fvp_module.elf. That one loads */ -/* one property word -- 0x02000003, the only combination any example */ -/* in the tree ships -- and asks what the hardware does about a module */ -/* that misbehaves. This one asks what the LOADER does about a module */ -/* whose property word is something else, which is a question about a */ -/* module that never runs at all in four of the six cases below. The */ -/* two have different subjects and different verdicts, and the only */ -/* thing they share is the module blob. */ +/* WHY THIS IS A SEPARATE IMAGE from fvp_module.elf. That one loads */ +/* one property word -- 0x02000003, the only combination any example */ +/* in the tree ships -- and asks what the hardware does about a module */ +/* that misbehaves. This one asks what the LOADER does about a module */ +/* whose property word is something else, which is a question about a */ +/* module that never runs at all in four of the six cases below. The */ +/* two have different subjects and different verdicts, and the only */ +/* thing they share is the module blob. */ /* */ -/* WHAT THE CONTRACT IS. TXM_MODULE_MANAGER_REQUIRED_OPTIONS in */ -/* txm_module_port.h requires TXM_MODULE_USER_MODE and */ -/* TXM_MODULE_MEMORY_PROTECTION together, which every other module port */ -/* in the tree leaves at zero. The reason is PMSAv8-R and not policy: */ -/* the port programs a module's region table only when both bits are */ -/* set, the scheduler closes the kernel's window over module memory */ -/* before it dispatches a module thread, and per the Cortex-R52 TRM */ -/* section 8.2.1 there is no background region to fall back on -- EL0 */ -/* accesses are faulted whenever the MPU is enabled, and EL1 needs */ -/* SCTLR.BR, which neither board support package sets. So a module */ -/* that asks for user mode without protection is not an unprotected */ -/* module. It is a module with no mapping, and it aborts on the fetch */ -/* of its own first instruction. */ +/* WHAT THE CONTRACT IS. TXM_MODULE_MANAGER_REQUIRED_OPTIONS in */ +/* txm_module_port.h requires TXM_MODULE_USER_MODE and */ +/* TXM_MODULE_MEMORY_PROTECTION together, which every other module */ +/* port in the tree leaves at zero. The reason is PMSAv8-R and not */ +/* policy: the port programs a module's region table only when both */ +/* bits are set, the scheduler closes the kernel's window over module */ +/* memory before it dispatches a module thread, and per the Cortex-R52 */ +/* TRM section 8.2.1 there is no background region to fall back on -- */ +/* EL0 accesses are faulted whenever the MPU is enabled, and EL1 needs */ +/* SCTLR.BR, which neither board support package sets. So a module */ +/* that asks for user mode without protection is not an unprotected */ +/* module. It is a module with no mapping, and it aborts on the fetch */ +/* of its own first instruction. */ /* */ -/* TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS is supported and optional, */ -/* and both halves of that are checked below rather than asserted. */ +/* TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS is supported and optional, */ +/* and both halves of that are checked below rather than asserted. */ /* */ -/* ONE BLOB, SIX PROPERTY WORDS. The property word is a field of the */ -/* preamble, and the preamble is the first thing in the module image, so */ -/* a case is set up by copying the blob into the staging area and */ -/* writing one word of the copy. Nothing else about the module changes */ -/* between cases, which is what makes the six verdicts comparable: the */ -/* only variable is the word under test. Six separately built module */ -/* images would each also carry their own code, and a difference in */ -/* outcome could then be blamed on any of it. */ +/* ONE BLOB, SIX PROPERTY WORDS. The property word is a field of the */ +/* preamble, and the preamble is the first thing in the module image, */ +/* so a case is set up by copying the blob into the staging area and */ +/* writing one word of the copy. Nothing else about the module */ +/* changes between cases, which is what makes the six verdicts */ +/* comparable: the only variable is the word under test. Six */ +/* separately built module images would each also carry their own */ +/* code, and a difference in outcome could then be blamed on any of */ +/* it. */ /* */ -/* THE FOUR REFUSALS ARE CHECKED BY NAME, not by "it did not run". A */ -/* load that failed with TX_NO_MEMORY, or one that succeeded and then */ -/* faulted in the module's first instruction, would both leave the */ -/* module not running. The whole point of the contract is that the */ -/* refusal arrives from txm_module_manager_in_place_load as */ -/* TXM_MODULE_INVALID_PROPERTIES, at the moment the property word can */ -/* still be corrected, so that status is what is compared. */ +/* THE FOUR REFUSALS ARE CHECKED BY NAME, not by "it did not run". A */ +/* load that failed with TX_NO_MEMORY, or one that succeeded and then */ +/* faulted in the module's first instruction, would both leave the */ +/* module not running. The whole point of the contract is that the */ +/* refusal arrives from txm_module_manager_in_place_load as */ +/* TXM_MODULE_INVALID_PROPERTIES, at the moment the property word can */ +/* still be corrected, so that status is what is compared. */ /* */ -/* A REFUSAL MUST ALSO COST NOTHING. Each case gets its own instance */ -/* out of .bss, and a refused case's instance is checked to be */ -/* untouched and the manager's loaded count to be unmoved. The port */ -/* would still be wrong if it rejected the module and left half an */ -/* instance behind, and the four refusals run before the two loads for */ -/* the same reason: what follows them proves the manager is still able */ -/* to load. */ +/* A REFUSAL MUST ALSO COST NOTHING. Each case gets its own instance */ +/* out of .bss, and a refused case's instance is checked to be */ +/* untouched and the manager's loaded count to be unmoved. The port */ +/* would still be wrong if it rejected the module and left half an */ +/* instance behind, and the four refusals run before the two loads for */ +/* the same reason: what follows them proves the manager is still able */ +/* to load. */ /* */ -/* THE TWO ACCEPTED CASES ARE RUN, not merely loaded. A load that */ -/* returns TX_SUCCESS says nothing about whether the region table it */ -/* programmed describes anything, which is exactly the defect this file */ -/* exists for. So both accepted cases start the module and wait for the */ -/* abort it is written to provoke, and the abort is attributed to the */ -/* case by thread pointer and checked for its address, its mode and its */ -/* offset into the module's own code. */ +/* THE TWO ACCEPTED CASES ARE RUN, not merely loaded. A load that */ +/* returns TX_SUCCESS says nothing about whether the region table it */ +/* programmed describes anything, which is exactly the defect this */ +/* file exists for. So both accepted cases start the module and wait */ +/* for the abort it is written to provoke, and the abort is attributed */ +/* to the case by thread pointer and checked for its address, its mode */ +/* and its offset into the module's own code. */ /* */ -/* The two differ in what they are granted, which is the optional half */ -/* of the contract: */ +/* The two differ in what they are granted, which is the optional half */ +/* of the contract: */ /* */ -/* 0x03, user mode and protection. Granted NOTHING. It reports */ -/* through no shared granule, so what is read back is the abort: the */ -/* module wrote its own data, then reached the status word it was */ -/* never granted, and faulted there. A module that did not ask for */ -/* shared access and was given none cannot reach the shared area, and */ -/* the fault address says so. */ +/* 0x03, user mode and protection. Granted NOTHING. It reports */ +/* through no shared granule, so what is read back is the abort: the */ +/* module wrote its own data, then reached the status word it was */ +/* never granted, and faulted there. A module that did not ask for */ +/* shared access and was given none cannot reach the shared area, */ +/* and the fault address says so. */ /* */ -/* 0x07, and the status granule granted. The module reports its */ -/* progress through that granule, gets as far as a kernel call, and */ -/* faults where fvp_module.elf's first pass does -- on the kernel's */ -/* data. So the shared grant is what is under test here, and the */ -/* progress word is the evidence that it worked. */ +/* 0x07, and the status granule granted. The module reports its */ +/* progress through that granule, gets as far as a kernel call, and */ +/* faults where fvp_module.elf's first pass does -- on the kernel's */ +/* data. So the shared grant is what is under test here, and the */ +/* progress word is the evidence that it worked. */ /* */ -/* WHAT A GREEN RUN HERE DOES NOT PROVE. Two things, and both are */ -/* limits of the contract rather than gaps in the checking. */ -/* */ -/* The port does not gate txm_module_manager_external_memory_enable on */ -/* TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS, and neither does any other */ -/* module port; a manager that granted a region to the 0x03 module would */ -/* be obliged. That is why the 0x03 case above is granted nothing rather */ -/* than granted something and expected to be refused: this file checks */ -/* the contract the port states, and the port does not state that one. */ -/* */ -/* And nothing here exercises the property-flag test in */ -/* tx_thread_schedule.S, which decides the same question a second time */ -/* for a thread being dispatched. It cannot: the loader refuses every */ -/* combination that would reach the scheduler with an unprogrammed region */ -/* table, so the assembly's test is unreachable by construction while */ -/* TXM_MODULE_MANAGER_REQUIRED_OPTIONS stands. That redundancy is the */ -/* point of it -- the scheduler stops depending on a loader invariant it */ -/* cannot see -- but it does mean the test is covered by the offset */ -/* assertion in txm_module_manager_offset_check.c and by reading it, and */ -/* not by any run of this image. */ +/* WHAT A GREEN RUN HERE DOES NOT PROVE. Two things, and both are */ +/* limits of the contract rather than gaps in the checking. */ +/* */ +/* The port does not gate txm_module_manager_external_memory_enable on */ +/* TXM_MODULE_SHARED_EXTERNAL_MEMORY_ACCESS, and neither does any */ +/* other module port; a manager that granted a region to the 0x03 */ +/* module would be obliged. That is why the 0x03 case above is */ +/* granted nothing rather than granted something and expected to be */ +/* refused: this file checks the contract the port states, and the */ +/* port does not state that one. */ +/* */ +/* And nothing here exercises the property-flag test in */ +/* tx_thread_schedule.S, which decides the same question a second time */ +/* for a thread being dispatched. It cannot: the loader refuses every */ +/* combination that would reach the scheduler with an unprogrammed */ +/* region table, so the assembly's test is unreachable by construction */ +/* while TXM_MODULE_MANAGER_REQUIRED_OPTIONS stands. That redundancy */ +/* is the point of it -- the scheduler stops depending on a loader */ +/* invariant it cannot see -- but it does mean the test is covered by */ +/* the offset assertion in txm_module_manager_offset_check.c and by */ +/* reading it, and not by any run of this image. */ /* */ /**************************************************************************/ @@ -249,8 +251,8 @@ static unsigned char module_object_pool[MODULE_OBJECT_POOL_SIZE] /**************************************************************************/ /* The cases. */ /* */ -/* Every low-byte combination the port has an opinion about, and the */ -/* opinion. The compiler field is ORed in when the word is written, so */ +/* Every low-byte combination the port has an opinion about, and the */ +/* opinion. The compiler field is ORed in when the word is written, so */ /* the option bits stay legible here. */ /**************************************************************************/ @@ -384,8 +386,8 @@ static unsigned char report_stack[2048] __attribute__((aligned(8))); /**************************************************************************/ /* Fault notification. */ /* */ -/* Records rather than prints: this runs in Abort mode on the Abort */ -/* stack, which is a kilobyte and already carries the terminate */ +/* Records rather than prints: this runs in Abort mode on the Abort */ +/* stack, which is a kilobyte and already carries the terminate */ /* underneath this frame. */ /**************************************************************************/ @@ -406,13 +408,13 @@ static void put_field(const char *label, unsigned long value) /**************************************************************************/ -/* The shared status granule, reached through the manager's load window. */ +/* The shared status granule, reached through the manager's load window. */ /* */ -/* No kernel region covers the module area; region 16 does, and the */ -/* scheduler enables it for every thread that owns no module. This */ +/* No kernel region covers the module area; region 16 does, and the */ +/* scheduler enables it for every thread that owns no module. This */ /* thread owns none, so the window is open on it. */ /* */ -/* MISRA C:2012 Rule 11.6 is deliberately violated: the address is an */ +/* MISRA C:2012 Rule 11.6 is deliberately violated: the address is an */ /* agreement between two separately linked images. */ /**************************************************************************/ @@ -438,10 +440,10 @@ static ULONG module_status_read(void) /**************************************************************************/ -/* A byte copy, written out rather than called for. The manager links */ -/* -nostartfiles and nothing else in this image reaches for a C library, */ -/* so calling memcpy would pull one in for a copy of under two kilobytes */ -/* that happens six times. */ +/* A byte copy, written out rather than called for. The manager links */ +/* -nostartfiles and nothing else in this image reaches for a C library, */ +/* so calling memcpy would pull one in for a copy of under two kilobytes */ +/* that happens six times. */ /**************************************************************************/ static void copy_bytes(unsigned char *destination, const unsigned char *source, @@ -457,20 +459,21 @@ static void copy_bytes(unsigned char *destination, const unsigned char *source, /**************************************************************************/ -/* Build one case in the staging area: the blob, with one word replaced. */ +/* Build one case in the staging area: the blob, with one word replaced. */ /* */ -/* Copied afresh for every case rather than patched in place, so that a */ -/* case cannot inherit anything from the one before it -- including the */ -/* previous property word, which is the single variable under test. */ +/* Copied afresh for every case rather than patched in place, so that a */ +/* case cannot inherit anything from the one before it -- including the */ +/* previous property word, which is the single variable under test. */ /* */ -/* The cache maintenance is not a precaution the passing run justifies. */ -/* These are data writes to memory that is about to be fetched as */ -/* instructions, and the module area is mapped Normal write-back, so the */ -/* copied bytes may sit in dirty D-cache lines while the instruction side */ -/* -- which is not coherent with the D cache on this core -- fetches what */ -/* main memory still holds. A cold I cache over a never-executed address */ -/* happens to work, and keeps happening to work until the staging area is */ -/* reused, which is exactly what this file does six times. */ +/* The cache maintenance is not a precaution the passing run justifies. */ +/* These are data writes to memory that is about to be fetched as */ +/* instructions, and the module area is mapped Normal write-back, so the */ +/* copied bytes may sit in dirty D-cache lines while the instruction */ +/* side -- which is not coherent with the D cache on this core -- */ +/* fetches what main memory still holds. A cold I cache over a */ +/* never-executed address happens to work, and keeps happening to work */ +/* until the staging area is reused, which is exactly what this file */ +/* does six times. */ /**************************************************************************/ static ULONG stage_module(ULONG options) @@ -508,8 +511,8 @@ static ULONG stage_module(ULONG options) /**************************************************************************/ -/* One case: stage it, load it, and -- if the contract says it loads -- */ -/* start it and wait for the abort it is written to provoke. */ +/* One case: stage it, load it, and -- if the contract says it loads -- */ +/* start it and wait for the abort it is written to provoke. */ /**************************************************************************/ static void run_one_case(UINT index) diff --git a/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/txm_module_preamble.S b/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/txm_module_preamble.S index 19bd89318..8427516df 100644 --- a/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/txm_module_preamble.S +++ b/ports_module/cortex_r52/gnu/example_build/fvp_baser_aemv8r/txm_module_preamble.S @@ -25,19 +25,19 @@ @/* */ @/* DESCRIPTION */ @/* */ -@/* The header the module manager reads before it will load a module. */ +@/* The header the module manager reads before it will load a module. */ @/* */ -@/* It must be the first thing in the module image, which is what the */ -@/* linker script arranges, and every entry point in it is an offset */ -@/* from the start of the preamble rather than an address. A module is */ -@/* position independent: the manager decides where it lands, so the */ -@/* module cannot know its own addresses at link time. */ +@/* It must be the first thing in the module image, which is what the */ +@/* linker script arranges, and every entry point in it is an offset */ +@/* from the start of the preamble rather than an address. A module is */ +@/* position independent: the manager decides where it lands, so the */ +@/* module cannot know its own addresses at link time. */ @/* */ -@/* Code and data sizes come from the linker script rather than being */ -@/* written in by hand. The Cortex-R4 preamble carries literal numbers */ -@/* for them, which is a standing invitation to grow a module past its */ -@/* declared size and have the manager map less memory than it uses -- */ -@/* a fault in a module that did nothing wrong, whose cause is a */ +@/* Code and data sizes come from the linker script rather than being */ +@/* written in by hand. The Cortex-R4 preamble carries literal numbers */ +@/* for them, which is a standing invitation to grow a module past its */ +@/* declared size and have the manager map less memory than it uses -- */ +@/* a fault in a module that did nothing wrong, whose cause is a */ @/* constant in a file nobody thought to change. */ @/* */ @/**************************************************************************/ @@ -105,8 +105,7 @@ __txm_module_preamble: @ dereference goes through a register the stack build had zeroed. On silicon @ that read faulted at 0x1C, which is offset 0x1C from a null r3. @ -@ Every other GNU module port writes these the same way; cortex_m33's -@ preamble, which this port was seeded from, spells it "symbol - . - 0". +@ Every other GNU module port writes these the same way. .word _txm_module_thread_shell_entry - . .word demo_module_start - . diff --git a/ports_module/cortex_r52/gnu/example_build/s32z280_evb/module_blob.S b/ports_module/cortex_r52/gnu/example_build/s32z280_evb/module_blob.S index bd4045422..93b7bc2e1 100644 --- a/ports_module/cortex_r52/gnu/example_build/s32z280_evb/module_blob.S +++ b/ports_module/cortex_r52/gnu/example_build/s32z280_evb/module_blob.S @@ -25,19 +25,19 @@ @/* */ @/* DESCRIPTION */ @/* */ -@/* Carries the demonstration module into the manager image as data. */ +@/* Carries the demonstration module into the manager image as data. */ @/* */ -@/* The module is built as its own link unit and objcopied to a raw */ -@/* binary, which is included here verbatim. It has to be a separate */ -@/* link: the module library defines shims named after the ThreadX API */ -@/* entry points the kernel also defines, and in one link the shims win */ -@/* -- objects beat archive members -- so the manager's own service calls */ -@/* end up trapping into the module. */ +@/* The module is built as its own link unit and objcopied to a raw */ +@/* binary, which is included here verbatim. It has to be a separate */ +@/* link: the module library defines shims named after the ThreadX API */ +@/* entry points the kernel also defines, and in one link the shims win */ +@/* -- objects beat archive members -- so the manager's own service */ +@/* calls end up trapping into the module. */ @/* */ -@/* Included as bytes rather than linked as objects, so the module's */ -@/* symbols never enter the manager's link at all. Nothing here is */ -@/* called: the manager finds the preamble at the start of the image and */ -@/* reaches everything else through that. */ +@/* Included as bytes rather than linked as objects, so the module's */ +@/* symbols never enter the manager's link at all. Nothing here is */ +@/* called: the manager finds the preamble at the start of the image */ +@/* and reaches everything else through that. */ @/* */ @/**************************************************************************/ diff --git a/ports_module/cortex_r52/gnu/example_build/s32z280_evb/sample_threadx_module.c b/ports_module/cortex_r52/gnu/example_build/s32z280_evb/sample_threadx_module.c index dbf0c8a82..96aade83d 100644 --- a/ports_module/cortex_r52/gnu/example_build/s32z280_evb/sample_threadx_module.c +++ b/ports_module/cortex_r52/gnu/example_build/s32z280_evb/sample_threadx_module.c @@ -25,58 +25,59 @@ /* */ /* DESCRIPTION */ /* */ -/* A module that exercises the protection boundary rather than */ -/* demonstrating features, for the NXP S32Z280-594EVB. */ +/* A module that exercises the protection boundary rather than */ +/* demonstrating features, for the NXP S32Z280-594EVB. */ /* */ -/* The FVP copy of this file is the same module for the same port; what */ -/* differs is the two addresses at the bottom and the board named here, */ -/* so `diff` is the tool for telling whether the two have drifted. */ +/* The FVP copy of this file is the same module for the same port; */ +/* what differs is the two addresses at the bottom and the board named */ +/* here, so `diff` is the tool for telling whether the two have */ +/* drifted. */ /* */ -/* Four steps: */ +/* Four steps: */ /* */ /* 1. Writes and reads its own data, which must succeed. */ -/* 2. Makes a kernel call, which must succeed -- proving a module in */ -/* User mode can reach the kernel through the supervisor call */ +/* 2. Makes a kernel call, which must succeed -- proving a module in */ +/* User mode can reach the kernel through the supervisor call */ /* boundary and come back. */ -/* 3. Violates its protection in one of three ways the manager */ +/* 3. Violates its protection in one of three ways the manager */ /* selects, which must fault. */ /* 4. Never reaches step 4, because step 3 terminates it. */ /* */ -/* THE THREE VIOLATIONS. Two of them are the two aborts the hardware */ -/* distinguishes: reading the kernel's data is a DATA abort reported */ -/* through DFSR and DFAR, branching out of the code region is a */ -/* PREFETCH abort reported through IFSR and IFAR. The third writes a */ -/* granule of the SHARED area that the manager deliberately did not */ -/* grant, after writing and reading back every granule it did -- so it */ -/* is the shared-region machinery under test rather than the kernel's */ -/* own memory, and a grant that covered one granule too many is what it */ -/* is looking for. */ +/* THE THREE VIOLATIONS. Two of them are the two aborts the hardware */ +/* distinguishes: reading the kernel's data is a DATA abort reported */ +/* through DFSR and DFAR, branching out of the code region is a */ +/* PREFETCH abort reported through IFSR and IFAR. The third writes a */ +/* granule of the SHARED area that the manager deliberately did not */ +/* grant, after writing and reading back every granule it did -- so it */ +/* is the shared-region machinery under test rather than the kernel's */ +/* own memory, and a grant that covered one granule too many is what */ +/* it is looking for. */ /* */ -/* Steps 1 and 2 passing without step 3 faulting would mean the module */ -/* is running unprotected, which is the failure this example exists to */ -/* detect. A module that only ever touched its own memory would pass */ +/* Steps 1 and 2 passing without step 3 faulting would mean the module */ +/* is running unprotected, which is the failure this example exists to */ +/* detect. A module that only ever touched its own memory would pass */ /* identically with the MPU switched off. */ /* */ -/* HOW PROGRESS GETS OUT. A module cannot print: the console belongs */ -/* to the board support package, outside every region a module owns, so */ -/* reaching it would fault as surely as step 3 does. So progress is */ -/* recorded twice -- in the module's own data, and in the first granule */ -/* of the shared area the manager granted it. */ +/* HOW PROGRESS GETS OUT. A module cannot print: the console belongs */ +/* to the board support package, outside every region a module owns, */ +/* so reaching it would fault as surely as step 3 does. So progress */ +/* is recorded twice -- in the module's own data, and in the first */ +/* granule of the shared area the manager granted it. */ /* */ -/* Which of the two can be read depends on the board. On silicon a GDB */ -/* harness reads the module's own copy out of the data area the manager */ -/* allocated for it; the FVP has no such seam -- it exposes an Iris */ -/* server and no GDB stub -- so there only the shared copy is readable */ -/* and everything the run reports has to be reported by the image */ -/* itself. Both writes are kept on both boards deliberately: if the */ -/* shared write were the only one, a module that could not reach its own */ -/* data would still report progress. */ +/* Which of the two can be read depends on the board. On silicon a */ +/* GDB harness reads the module's own copy out of the data area the */ +/* manager allocated for it; the FVP has no such seam -- it exposes an */ +/* Iris server and no GDB stub -- so there only the shared copy is */ +/* readable and everything the run reports has to be reported by the */ +/* image itself. Both writes are kept on both boards deliberately: if */ +/* the shared write were the only one, a module that could not reach */ +/* its own data would still report progress. */ /* */ -/* The shared address is a literal on this side. The module has no */ -/* loader to tell it anything and the manager deliberately knows no */ -/* symbol of the module, so the two agree by convention -- and the */ -/* manager checks that they do, against the linker's own symbol, rather */ -/* than trusting them to. */ +/* The shared address is a literal on this side. The module has no */ +/* loader to tell it anything and the manager deliberately knows no */ +/* symbol of the module, so the two agree by convention -- and the */ +/* manager checks that they do, against the linker's own symbol, */ +/* rather than trusting them to. */ /* */ /**************************************************************************/ diff --git a/ports_module/cortex_r52/gnu/example_build/s32z280_evb/sample_threadx_module_manager.c b/ports_module/cortex_r52/gnu/example_build/s32z280_evb/sample_threadx_module_manager.c index 7b7d822e4..c0da91bf8 100644 --- a/ports_module/cortex_r52/gnu/example_build/s32z280_evb/sample_threadx_module_manager.c +++ b/ports_module/cortex_r52/gnu/example_build/s32z280_evb/sample_threadx_module_manager.c @@ -25,108 +25,113 @@ /* */ /* DESCRIPTION */ /* */ -/* Loads the sample module four times, lets it misbehave every time, */ -/* and reports what the hardware did about it. */ +/* Loads the sample module four times, lets it misbehave every time, */ +/* and reports what the hardware did about it. */ /* */ -/* The result this example exists to produce is the fault. A module */ -/* that starts and runs proves the loader works; a module that is */ -/* stopped by the memory protection unit when it reaches outside its */ -/* own memory proves the port works. So the fault notification is not */ -/* an error path here, it is the expected outcome, and its absence is */ +/* The result this example exists to produce is the fault. A module */ +/* that starts and runs proves the loader works; a module that is */ +/* stopped by the memory protection unit when it reaches outside its */ +/* own memory proves the port works. So the fault notification is not */ +/* an error path here, it is the expected outcome, and its absence is */ /* the failure. */ /* */ -/* TWO passes, because one proves nothing about relocation. The module */ -/* is position independent: it is linked against nominal addresses it */ -/* never runs at, and _gcc_setup rewrites its global offset table to */ -/* wherever the manager actually put it. A single run at the linked */ -/* address would exercise a rebase whose input and output are the same */ -/* number, and would look identical if the rebase did nothing at all. */ +/* TWO passes, because one proves nothing about relocation. The */ +/* module is position independent: it is linked against nominal */ +/* addresses it never runs at, and _gcc_setup rewrites its global */ +/* offset table to wherever the manager actually put it. A single run */ +/* at the linked address would exercise a rebase whose input and */ +/* output are the same number, and would look identical if the rebase */ +/* did nothing at all. */ /* */ -/* So pass 1 loads the blob where the linker placed it and pass 2 loads */ -/* a byte-for-byte copy of it from the staging area, with pass 1 still */ -/* holding its pool memory so that pass 2's data lands somewhere else */ -/* too. Both the code base and the data base therefore differ between */ -/* the passes, which is what makes the comparison at the end mean */ -/* something: */ +/* So pass 1 loads the blob where the linker placed it and pass 2 */ +/* loads a byte-for-byte copy of it from the staging area, with pass 1 */ +/* still holding its pool memory so that pass 2's data lands somewhere */ +/* else too. Both the code base and the data base therefore differ */ +/* between the passes, which is what makes the comparison at the end */ +/* mean something: */ /* */ -/* * the same instruction faults in both passes -- equal offsets from */ -/* each pass's own code base, at two different absolute addresses. */ -/* The module ran relocated. */ -/* * DFAR is the forbidden address in both passes. The module got */ -/* that value by reading one of its own initialised globals through */ -/* the rebased GOT, so this single register proves the GOT was */ -/* rewritten and .data was copied. */ +/* * the same instruction faults in both passes -- equal offsets */ +/* from each pass's own code base, at two different absolute */ +/* addresses. The module ran relocated. */ +/* * DFAR is the forbidden address in both passes. The module got */ +/* that value by reading one of its own initialised globals */ +/* through the rebased GOT, so this single register proves the GOT */ +/* was rewritten and .data was copied. */ /* * SPSR says User mode in both passes. The boundary held. */ /* */ -/* All of which is checked on the console, with no help from a debugger */ -/* and without the manager needing to know one symbol of the module. */ +/* All of which is checked on the console, with no help from a */ +/* debugger and without the manager needing to know one symbol of the */ +/* module. */ /* */ -/* THEN A THIRD PASS, which faults the other way. The two passes above */ -/* make the module read an address it does not own: a data abort, */ -/* reported through DFSR and DFAR. A module can equally leave its code */ -/* region, which is a prefetch abort reported through IFSR and IFAR and */ -/* arrives at the handler by a different vector. Both halves of the */ -/* port's fault path are therefore exercised, and neither is inferred */ -/* from the other. */ +/* THEN A THIRD PASS, which faults the other way. The two passes */ +/* above make the module read an address it does not own: a data */ +/* abort, reported through DFSR and DFAR. A module can equally leave */ +/* its code region, which is a prefetch abort reported through IFSR */ +/* and IFAR and arrives at the handler by a different vector. Both */ +/* halves of the port's fault path are therefore exercised, and */ +/* neither is inferred from the other. */ /* */ -/* Which violation a pass commits is chosen here, not in the module: the */ -/* manager writes the application-defined module ID in the instance */ -/* after loading it, and the manager passes that word to the module's */ -/* start thread. So one blob covers both cases and the manager needs no */ -/* symbol of the module to select between them. */ +/* Which violation a pass commits is chosen here, not in the module: */ +/* the manager writes the application-defined module ID in the */ +/* instance after loading it, and the manager passes that word to the */ +/* module's start thread. So one blob covers both cases and the */ +/* manager needs no symbol of the module to select between them. */ /* */ -/* The third pass runs after the first two have been unloaded, which is */ -/* the other half of what this file demonstrates: a module fault must */ -/* leave the manager able to load and run the next module. A fault that */ -/* kills the manager is not isolation, and a fault that leaves the MPU */ -/* in a state where the next load misbehaves is not either. */ +/* The third pass runs after the first two have been unloaded, which */ +/* is the other half of what this file demonstrates: a module fault */ +/* must leave the manager able to load and run the next module. A */ +/* fault that kills the manager is not isolation, and a fault that */ +/* leaves the MPU in a state where the next load misbehaves is not */ +/* either. */ /* */ -/* AND THE NOTIFICATION IS CHECKED, not merely printed. The manager */ -/* registers a fault-notify callback, and every pass must see it run */ -/* exactly once with the faulting thread and the right module instance. */ -/* That path used to be dead on this port -- the shared fault handler */ -/* terminates the thread before calling the hook, which only returns if */ -/* the port's abort vector tells the kernel it is inside an exception, */ -/* and this port's did not. It does now, so the hook is a result rather */ -/* than a known defect. */ +/* AND THE NOTIFICATION IS CHECKED, not merely printed. The manager */ +/* registers a fault-notify callback, and every pass must see it run */ +/* exactly once with the faulting thread and the right module */ +/* instance. That path used to be dead on this port -- the shared */ +/* fault handler terminates the thread before calling the hook, which */ +/* only returns if the port's abort vector tells the kernel it is */ +/* inside an exception, and this port's did not. It does now, so the */ +/* hook is a result rather than a known defect. */ /* */ -/* AND A FOURTH PASS FOR THE SHARED REGIONS. The three above are each */ -/* granted one shared region -- the status granule they report their */ -/* progress through -- which exercises the first of the five shared */ -/* entries the port provides and says nothing about the other four. */ -/* The fourth pass is granted all five, one 64-byte granule each, and */ -/* is NOT granted the granule that sits between two of them. It writes */ -/* every granule it was given, reads every one of them back, and then */ -/* writes the gap, which must fault. */ +/* AND A FOURTH PASS FOR THE SHARED REGIONS. The three above are each */ +/* granted one shared region -- the status granule they report their */ +/* progress through -- which exercises the first of the five shared */ +/* entries the port provides and says nothing about the other four. */ +/* The fourth pass is granted all five, one 64-byte granule each, and */ +/* is NOT granted the granule that sits between two of them. It */ +/* writes every granule it was given, reads every one of them back, */ +/* and then writes the gap, which must fault. */ /* */ -/* That shape is chosen against a specific defect. A limit register */ -/* masked the wrong way, or a base off by one granule, extends a region */ -/* past what was asked for -- and with the gap sandwiched between two */ -/* granted granules it is reachable from either side if that happens. */ -/* The readback matters as much as the write: a region programmed with */ -/* the wrong base accepts a store and puts it elsewhere, so five marks */ -/* read out of five granules is what says five distinct extents were */ -/* programmed rather than one of them five times. */ +/* That shape is chosen against a specific defect. A limit register */ +/* masked the wrong way, or a base off by one granule, extends a */ +/* region past what was asked for -- and with the gap sandwiched */ +/* between two granted granules it is reachable from either side if */ +/* that happens. The readback matters as much as the write: a region */ +/* programmed with the wrong base accepts a store and puts it */ +/* elsewhere, so five marks read out of five granules is what says */ +/* five distinct extents were programmed rather than one of them five */ +/* times. */ /* */ -/* The same pass probes the two ways the manager refuses a grant, which */ -/* nothing had ever called: an unaligned address must come back */ -/* TXM_MODULE_ALIGNMENT_ERROR, and one grant past the entry count must */ -/* come back TX_NO_MEMORY. Both are checked by name. The order is not */ -/* free -- the entry-count check runs before the alignment check, so the */ -/* unaligned probe has to happen while entries remain. */ +/* The same pass probes the two ways the manager refuses a grant, */ +/* which nothing had ever called: an unaligned address must come back */ +/* TXM_MODULE_ALIGNMENT_ERROR, and one grant past the entry count must */ +/* come back TX_NO_MEMORY. Both are checked by name. The order is */ +/* not free -- the entry-count check runs before the alignment check, */ +/* so the unaligned probe has to happen while entries remain. */ /* */ -/* A SECOND READING OF THE PROGRESS WORD comes with those granules. The */ -/* module records what it managed twice: in its own data, which the GDB */ -/* harness reads, and in the first shared granule, which this file now */ -/* reads on the target. The two are independent readings of the same */ -/* event, so the console judges progress without a debugger and the */ -/* harness still cross-checks it against the module's own copy. */ +/* A SECOND READING OF THE PROGRESS WORD comes with those granules. */ +/* The module records what it managed twice: in its own data, which */ +/* the GDB harness reads, and in the first shared granule, which this */ +/* file now reads on the target. The two are independent readings of */ +/* the same event, so the console judges progress without a debugger */ +/* and the harness still cross-checks it against the module's own */ +/* copy. */ /* */ -/* What the module image is and where it comes from: it is linked into */ -/* this application as a separate section and loaded in place, so */ +/* What the module image is and where it comes from: it is linked into */ +/* this application as a separate section and loaded in place, so */ /* nothing is copied and no filesystem or download path is needed. */ -/* The manager still maps it with its own MPU regions, which is what */ -/* matters -- loading in place changes where the code lives, not */ +/* The manager still maps it with its own MPU regions, which is what */ +/* matters -- loading in place changes where the code lives, not */ /* whether it is protected. */ /* */ /**************************************************************************/ @@ -427,18 +432,18 @@ void pass_done(void); /**************************************************************************/ /* Fault notification. */ /* */ -/* Called by the module manager after it has terminated the offending */ -/* thread. Records rather than prints, for two reasons: this runs in the */ -/* fault path, where the console is a polled driver that spins waiting */ -/* for a transmit to complete -- and it runs in Abort mode on the Abort */ -/* stack, which is a kilobyte on this board and already carries the */ -/* terminate underneath this frame. A callback that printed would work */ -/* and would still be the wrong shape to copy. */ +/* Called by the module manager after it has terminated the offending */ +/* thread. Records rather than prints, for two reasons: this runs in */ +/* the fault path, where the console is a polled driver that spins */ +/* waiting for a transmit to complete -- and it runs in Abort mode on */ +/* the Abort stack, which is a kilobyte on this board and already */ +/* carries the terminate underneath this frame. A callback that printed */ +/* would work and would still be the wrong shape to copy. */ /* */ -/* Its two arguments are the point of the hook, so they are recorded and */ -/* checked rather than discarded: an application is being told WHICH */ -/* thread and WHICH module faulted, and a callback that fires with the */ -/* wrong pair is no more use than one that never fires. */ +/* Its two arguments are the point of the hook, so they are recorded and */ +/* checked rather than discarded: an application is being told WHICH */ +/* thread and WHICH module faulted, and a callback that fires with the */ +/* wrong pair is no more use than one that never fires. */ /**************************************************************************/ static void module_fault_notify(TX_THREAD *thread_ptr, TXM_MODULE_INSTANCE *module_instance) @@ -472,8 +477,8 @@ static void put_field(const char *label, unsigned long value) /**************************************************************************/ /* A byte copy, written out rather than called for. */ /* */ -/* The manager links -nostdlib, and reaching for memcpy would pull in a */ -/* libc whose presence this example does not otherwise depend on. The */ +/* The manager links -nostdlib, and reaching for memcpy would pull in a */ +/* libc whose presence this example does not otherwise depend on. The */ /* blob is under two kilobytes and this runs once. */ /**************************************************************************/ @@ -490,13 +495,13 @@ static void copy_bytes(unsigned char *destination, const unsigned char *source, /**************************************************************************/ -/* The shared granules, reached through the manager's load window. */ +/* The shared granules, reached through the manager's load window. */ /* */ -/* No kernel region covers the module area; region 16 does, and the */ -/* scheduler enables it for every thread that owns no module. This */ -/* thread owns none, so the window is open on it and these functions */ -/* need no bracketing of their own -- which is the whole reason the */ -/* window is owned by the scheduler rather than by whoever calls. */ +/* No kernel region covers the module area; region 16 does, and the */ +/* scheduler enables it for every thread that owns no module. This */ +/* thread owns none, so the window is open on it and these functions */ +/* need no bracketing of their own -- which is the whole reason the */ +/* window is owned by the scheduler rather than by whoever calls. */ /**************************************************************************/ static void module_status_clear(void) @@ -523,21 +528,22 @@ static ULONG module_status_read(void) /**************************************************************************/ -/* The shared grants a pass gets, and the two ways a grant is refused. */ +/* The shared grants a pass gets, and the two ways a grant is refused. */ /* */ -/* Every pass is granted the first granule, which is the progress word it */ -/* reports through. The shared pass is granted one granule per shared */ -/* entry the port provides, skipping the gap, because a single grant only */ -/* ever exercises the first of the five and this port had never run the */ -/* other four. */ +/* Every pass is granted the first granule, which is the progress word */ +/* it reports through. The shared pass is granted one granule per */ +/* shared entry the port provides, skipping the gap, because a single */ +/* grant only ever exercises the first of the five and this port had */ +/* never run the other four. */ /* */ -/* It also probes the two ways a grant is refused, which can only be done */ -/* on a LOADED instance. ORDER MATTERS: the manager checks the entry */ -/* count BEFORE it checks alignment, so the unaligned probe has to happen */ -/* while entries remain -- after five grants it would come back */ -/* TX_NO_MEMORY and say nothing about alignment at all. */ +/* It also probes the two ways a grant is refused, which can only be */ +/* done on a LOADED instance. ORDER MATTERS: the manager checks the */ +/* entry count BEFORE it checks alignment, so the unaligned probe has to */ +/* happen while entries remain -- after five grants it would come back */ +/* TX_NO_MEMORY and say nothing about alignment at all. */ /* */ -/* Returns the first grant status that was not TX_SUCCESS, or TX_SUCCESS. */ +/* Returns the first grant status that was not TX_SUCCESS, or */ +/* TX_SUCCESS. */ /**************************************************************************/ static UINT grant_shared_regions(TXM_MODULE_INSTANCE *instance, PASS_RESULT *result) @@ -621,28 +627,29 @@ static UINT grant_shared_regions(TXM_MODULE_INSTANCE *instance, PASS_RESULT *res /**************************************************************************/ -/* The size guards on a shared grant. */ +/* The size guards on a shared grant. */ /* */ -/* A grant of no bytes and a grant whose inclusive end wraps past the top */ -/* of the address space both used to compute a limit BELOW the base, */ -/* program it, return TX_SUCCESS and spend one of the five entries on a */ -/* region the hardware cannot honour. Both must now be refused as */ -/* TX_SIZE_ERROR, and -- the half that a status code alone does not say -- */ -/* must leave the entry count exactly where they found it, because an */ -/* entry spent on a refused grant is one the caller can never get back. */ +/* A grant of no bytes and a grant whose inclusive end wraps past the */ +/* top of the address space both used to compute a limit BELOW the base, */ +/* program it, return TX_SUCCESS and spend one of the five entries on a */ +/* region the hardware cannot honour. Both must now be refused as */ +/* TX_SIZE_ERROR, and -- the half that a status code alone does not say */ +/* -- must leave the entry count exactly where they found it, because an */ +/* entry spent on a refused grant is one the caller can never get back. */ /* */ -/* The third probe is the one that must SUCCEED: a grant ending exactly */ -/* at 0xFFFFFFFF is legal, and a guard that refused it would be a new bug */ -/* in place of the old one. It is checked last so that the count it does */ -/* move is unambiguous. */ +/* The third probe is the one that must SUCCEED: a grant ending exactly */ +/* at 0xFFFFFFFF is legal, and a guard that refused it would be a new */ +/* bug in place of the old one. It is checked last so that the count it */ +/* does move is unambiguous. */ /* */ -/* Loaded here and unloaded below without ever being started, so nothing */ -/* these probes accept is programmed into an MPU region. See the comment */ -/* on MODULE_TOP_GRANULE_ADDRESS for why that matters on this part. */ +/* Loaded here and unloaded below without ever being started, so nothing */ +/* these probes accept is programmed into an MPU region. See the */ +/* comment on MODULE_TOP_GRANULE_ADDRESS for why that matters on this */ +/* part. */ /* */ -/* Nothing here needs the debugger: every value it produces is a manager */ -/* return code or a field of the manager's own instance, so the console */ -/* carries the whole result and there is no pass_done() for it. */ +/* Nothing here needs the debugger: every value it produces is a manager */ +/* return code or a field of the manager's own instance, so the console */ +/* carries the whole result and there is no pass_done() for it. */ /**************************************************************************/ static void run_guard_probes(VOID *location) @@ -705,13 +712,13 @@ static void run_guard_probes(VOID *location) /**************************************************************************/ -/* One pass: load the blob from a given address, grant it the shared */ -/* granules it is entitled to, start it, wait for the fault it is written */ -/* to provoke, and stop it. */ +/* One pass: load the blob from a given address, grant it the shared */ +/* granules it is entitled to, start it, wait for the fault it is */ +/* written to provoke, and stop it. */ /* */ -/* The module is left loaded. Its data allocation is what moves the next */ -/* pass's data base, and releasing it here would defeat half the test. */ -/* Unloading happens after both passes have run. */ +/* The module is left loaded. Its data allocation is what moves the */ +/* next pass's data base, and releasing it here would defeat half the */ +/* test. Unloading happens after both passes have run. */ /**************************************************************************/ /* name is CHAR * and not const CHAR *, because txm_module_manager_in_place_load @@ -989,8 +996,8 @@ static void report_one_pass(const PASS_RESULT *result) /**************************************************************************/ -/* The shared-region verdict. Returns the number of failures it found, */ -/* and zero for any pass that does not exercise the shared regions. */ +/* The shared-region verdict. Returns the number of failures it found, */ +/* and zero for any pass that does not exercise the shared regions. */ /**************************************************************************/ static UINT judge_shared_regions(const PASS_RESULT *result) @@ -1080,13 +1087,13 @@ static UINT judge_shared_regions(const PASS_RESULT *result) /**************************************************************************/ /* Where the debugger stops. */ /* */ -/* A symbol and not a line number in the report loop. The harness used */ -/* to break on sample_threadx_module_manager.c:259, and every edit to */ -/* this file moved that line -- after which the run stops somewhere */ -/* arbitrary and reports whatever memory happens to hold, which looks */ -/* like a result rather than a mistake. This does not move. */ +/* A symbol and not a line number in the report loop. The harness used */ +/* to break on sample_threadx_module_manager.c:259, and every edit to */ +/* this file moved that line -- after which the run stops somewhere */ +/* arbitrary and reports whatever memory happens to hold, which looks */ +/* like a result rather than a mistake. This does not move. */ /* */ -/* Not static, and noinline, so it survives to the symbol table with an */ +/* Not static, and noinline, so it survives to the symbol table with an */ /* address a breakpoint can be set on. */ /**************************************************************************/ @@ -1099,20 +1106,20 @@ __attribute__((noinline)) void manager_done(void) /**************************************************************************/ /* Where the debugger stops after each pass. */ /* */ -/* A module's data is read back by the harness, not by the manager: the */ -/* manager deliberately knows no symbol of the module, so it cannot find */ -/* module_progress, while a debugger can compute its offset from the */ -/* module's ELF and add it to the data base this pass recorded. */ +/* A module's data is read back by the harness, not by the manager: the */ +/* manager deliberately knows no symbol of the module, so it cannot find */ +/* module_progress, while a debugger can compute its offset from the */ +/* module's ELF and add it to the data base this pass recorded. */ /* */ -/* But it has to read it WHILE THIS PASS STILL HOLDS THAT MEMORY. The */ -/* byte pool reuses a freed block, so once a later pass has loaded, an */ -/* earlier pass's data base points at the later pass's data -- and reading */ -/* every pass at the end of the run reports the last writer's progress for */ -/* all of them. That is not a hypothetical: pass 3 loads after passes 1 */ -/* and 2 are unloaded and lands exactly where pass 1 was. */ +/* But it has to read it WHILE THIS PASS STILL HOLDS THAT MEMORY. The */ +/* byte pool reuses a freed block, so once a later pass has loaded, an */ +/* earlier pass's data base points at the later pass's data -- and */ +/* reading every pass at the end of the run reports the last writer's */ +/* progress for all of them. That is not a hypothetical: pass 3 loads */ +/* after passes 1 and 2 are unloaded and lands exactly where pass 1 was. */ /* */ -/* So this exists to be broken on, once per pass, after the pass has */ -/* faulted and been stopped and before anything is unloaded. */ +/* So this exists to be broken on, once per pass, after the pass has */ +/* faulted and been stopped and before anything is unloaded. */ /**************************************************************************/ __attribute__((noinline)) void pass_done(void) @@ -1678,9 +1685,9 @@ static void manager_entry(ULONG input) /**************************************************************************/ /* Board entry. */ /* */ -/* entry.S calls this once the core is at EL1 with the MPU and caches */ -/* configured. Same shape as the other examples on this board: bring the */ -/* console up, say so, and enter the kernel. */ +/* entry.S calls this once the core is at EL1 with the MPU and caches */ +/* configured. Same shape as the other examples on this board: bring */ +/* the console up, say so, and enter the kernel. */ /**************************************************************************/ void bsp_main(void) diff --git a/ports_module/cortex_r52/gnu/example_build/s32z280_evb/txm_module_preamble.S b/ports_module/cortex_r52/gnu/example_build/s32z280_evb/txm_module_preamble.S index 19bd89318..8427516df 100644 --- a/ports_module/cortex_r52/gnu/example_build/s32z280_evb/txm_module_preamble.S +++ b/ports_module/cortex_r52/gnu/example_build/s32z280_evb/txm_module_preamble.S @@ -25,19 +25,19 @@ @/* */ @/* DESCRIPTION */ @/* */ -@/* The header the module manager reads before it will load a module. */ +@/* The header the module manager reads before it will load a module. */ @/* */ -@/* It must be the first thing in the module image, which is what the */ -@/* linker script arranges, and every entry point in it is an offset */ -@/* from the start of the preamble rather than an address. A module is */ -@/* position independent: the manager decides where it lands, so the */ -@/* module cannot know its own addresses at link time. */ +@/* It must be the first thing in the module image, which is what the */ +@/* linker script arranges, and every entry point in it is an offset */ +@/* from the start of the preamble rather than an address. A module is */ +@/* position independent: the manager decides where it lands, so the */ +@/* module cannot know its own addresses at link time. */ @/* */ -@/* Code and data sizes come from the linker script rather than being */ -@/* written in by hand. The Cortex-R4 preamble carries literal numbers */ -@/* for them, which is a standing invitation to grow a module past its */ -@/* declared size and have the manager map less memory than it uses -- */ -@/* a fault in a module that did nothing wrong, whose cause is a */ +@/* Code and data sizes come from the linker script rather than being */ +@/* written in by hand. The Cortex-R4 preamble carries literal numbers */ +@/* for them, which is a standing invitation to grow a module past its */ +@/* declared size and have the manager map less memory than it uses -- */ +@/* a fault in a module that did nothing wrong, whose cause is a */ @/* constant in a file nobody thought to change. */ @/* */ @/**************************************************************************/ @@ -105,8 +105,7 @@ __txm_module_preamble: @ dereference goes through a register the stack build had zeroed. On silicon @ that read faulted at 0x1C, which is offset 0x1C from a null r3. @ -@ Every other GNU module port writes these the same way; cortex_m33's -@ preamble, which this port was seeded from, spells it "symbol - . - 0". +@ Every other GNU module port writes these the same way. .word _txm_module_thread_shell_entry - . .word demo_module_start - . diff --git a/ports_module/cortex_r52/gnu/module_lib/src/txm_module_gcc_setup.S b/ports_module/cortex_r52/gnu/module_lib/src/txm_module_gcc_setup.S index 8d2b64d1f..7930a6d66 100644 --- a/ports_module/cortex_r52/gnu/module_lib/src/txm_module_gcc_setup.S +++ b/ports_module/cortex_r52/gnu/module_lib/src/txm_module_gcc_setup.S @@ -25,55 +25,55 @@ @/* */ @/* DESCRIPTION */ @/* */ -@/* Where a position-independent module fixes up its own data */ +@/* Where a position-independent module fixes up its own data */ @/* references, before it has run a line of its own code. */ @/* */ -@/* The module's shell entry calls this once, on the start thread only, */ -@/* passing the address the module's code was actually loaded at. Three */ -@/* things happen here, and the module cannot touch a single global */ -@/* until all three have: */ +@/* The module's shell entry calls this once, on the start thread only, */ +@/* passing the address the module's code was actually loaded at. */ +@/* Three things happen here, and the module cannot touch a single */ +@/* global until all three have: */ @/* */ -@/* 1. The global offset table is copied out of the image into the */ -@/* module's own data, and every entry in it is rewritten from the */ -@/* nominal address the linker chose to the address the manager */ +@/* 1. The global offset table is copied out of the image into the */ +@/* module's own data, and every entry in it is rewritten from the */ +@/* nominal address the linker chose to the address the manager */ @/* decided on. */ -@/* 2. .data is copied out of the image into the module's own data. */ +@/* 2. .data is copied out of the image into the module's own data. */ @/* 3. .bss is zeroed. */ @/* */ -@/* Why any of this is needed: the module is built -fpic with */ -@/* -msingle-pic-base, so a reference to a global compiles to */ -@/* LDR rX, [r9, #offset] -- a load of a GOT entry, at a fixed offset */ -@/* from whatever r9 holds. The manager seeds r9 with the module's data */ -@/* base when it builds the thread's stack frame, so the offsets land in */ -@/* the right place; but the entries there are zero until this function */ -@/* writes them, because the manager memsets the data area and nothing */ -@/* else populates it. */ -@/* */ -@/* And .data has to be copied for the same reason. The manager does */ -@/* not copy it: _txm_module_manager_internal_load allocates a data area */ -@/* from its byte pool and zeroes it, so the module's linked .data -- */ -@/* wherever it sits -- is outside every region the module owns. A */ -@/* module reading an initialised global before this ran would fault, or */ -@/* read a zero, depending on where it looked. */ -@/* */ -@/* This function may not use a global itself, which is the constraint */ -@/* that shapes it: it is what makes the GOT usable, so it cannot use */ -@/* the GOT. Every address it needs comes from a literal pool load of a */ -@/* linker-supplied nominal address, rebased by hand. That is also why */ -@/* it is assembly and not C. */ +@/* Why any of this is needed: the module is built -fpic with */ +@/* -msingle-pic-base, so a reference to a global compiles to */ +@/* LDR rX, [r9, #offset] -- a load of a GOT entry, at a fixed offset */ +@/* from whatever r9 holds. The manager seeds r9 with the module's */ +@/* data base when it builds the thread's stack frame, so the offsets */ +@/* land in the right place; but the entries there are zero until this */ +@/* function writes them, because the manager memsets the data area and */ +@/* nothing else populates it. */ +@/* */ +@/* And .data has to be copied for the same reason. The manager does */ +@/* not copy it: _txm_module_manager_internal_load allocates a data */ +@/* area from its byte pool and zeroes it, so the module's linked .data */ +@/* -- wherever it sits -- is outside every region the module owns. A */ +@/* module reading an initialised global before this ran would fault, */ +@/* or read a zero, depending on where it looked. */ +@/* */ +@/* This function may not use a global itself, which is the constraint */ +@/* that shapes it: it is what makes the GOT usable, so it cannot use */ +@/* the GOT. Every address it needs comes from a literal pool load of */ +@/* a linker-supplied nominal address, rebased by hand. That is also */ +@/* why it is assembly and not C. */ @/* */ @/* INPUT */ @/* */ -@/* r0 Address the module's code was actually loaded at */ -@/* r9 Address of the module's data area, already seeded by */ -@/* _txm_module_manager_thread_stack_build. Also the base the */ -@/* compiler measures every GOT offset from, so the GOT must go */ +@/* r0 Address the module's code was actually loaded at */ +@/* r9 Address of the module's data area, already seeded by */ +@/* _txm_module_manager_thread_stack_build. Also the base the */ +@/* compiler measures every GOT offset from, so the GOT must go */ @/* at exactly this address and nowhere else. */ @/* */ @/* OUTPUT */ @/* */ -@/* None. r9 is unchanged, and must be: it is the module's PIC base for */ -@/* the rest of the thread's life. */ +@/* None. r9 is unchanged, and must be: it is the module's PIC base */ +@/* for the rest of the thread's life. */ @/* */ @/* CALLED BY */ @/* */ diff --git a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_external_memory_enable.c b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_external_memory_enable.c index f60f1ad74..91a807cbf 100644 --- a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_external_memory_enable.c +++ b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_external_memory_enable.c @@ -46,8 +46,8 @@ /* This function creates an entry in the MPU table for a shared */ /* memory space. The start_address must be aligned to the PMSAv8-R */ /* protection granule, which is 64 bytes on Cortex-R52 -- the comment */ -/* inherited from the Armv8-M port says 32, and TXM_MODULE_MPU_ALIGNMENT*/ -/* below is what is actually enforced. */ +/* inherited from the Armv8-M port says 32, and */ +/* TXM_MODULE_MPU_ALIGNMENT below is what is actually enforced. */ /* */ /* The length must describe at least one byte and must not run off the */ /* top of the address space; either is TX_SIZE_ERROR. It need not be a */ diff --git a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_fault_capture.S b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_fault_capture.S index 48090ff33..b0ce9fba3 100644 --- a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_fault_capture.S +++ b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_fault_capture.S @@ -25,54 +25,54 @@ @/* */ @/* DESCRIPTION */ @/* */ -@/* Records why a memory protection fault happened, then hands over to */ +@/* Records why a memory protection fault happened, then hands over to */ @/* the C handler which terminates the offending thread. */ @/* */ -@/* A board's abort vectors branch here. Two entry points, because this */ -@/* core reports the two kinds of violation in different registers: a */ -@/* module writing outside its data region raises a data abort and */ -@/* reports through DFSR and DFAR, while a module branching outside its */ -@/* code region raises a prefetch abort and reports through IFSR and */ -@/* IFAR. Both are recorded either way, so a reader of the fault info */ -@/* can tell which pair is meaningful, and both entry points converge. */ +@/* A board's abort vectors branch here. Two entry points, because */ +@/* this core reports the two kinds of violation in different */ +@/* registers: a module writing outside its data region raises a data */ +@/* abort and reports through DFSR and DFAR, while a module branching */ +@/* outside its code region raises a prefetch abort and reports through */ +@/* IFSR and IFAR. Both are recorded either way, so a reader of the */ +@/* fault info can tell which pair is meaningful, and both entry points */ +@/* converge. */ @/* */ -@/* This has to be assembly, and it has to run first. The fault */ -@/* registers hold only the most recent fault, so anything that runs */ -@/* before the capture and faults itself destroys the evidence. The */ -@/* abort is also taken in Abort mode, with its own banked sp and lr, so */ -@/* C cannot be entered until a stack is known good. */ +@/* This has to be assembly, and it has to run first. The fault */ +@/* registers hold only the most recent fault, so anything that runs */ +@/* before the capture and faults itself destroys the evidence. The */ +@/* abort is also taken in Abort mode, with its own banked sp and lr, */ +@/* so C cannot be entered until a stack is known good. */ @/* */ -@/* THE CONTRACT WITH THE SHARED C HANDLER */ +@/* THE CONTRACT WITH THE SHARED C HANDLER */ @/* */ -@/* _txm_module_manager_memory_fault_handler is common to every module */ -@/* port and it terminates the faulting thread and then calls the */ -@/* application's fault-notify callback. For the second half of that to */ -@/* happen, _tx_thread_terminate has to RETURN -- and terminating the */ -@/* running thread only returns if the kernel believes it is inside an */ -@/* exception. _tx_thread_terminate ends in */ -@/* _tx_thread_system_preempt_check, which calls */ -@/* _tx_thread_system_return whenever _tx_thread_system_state and */ -@/* _tx_thread_preempt_disable are both zero; on this architecture that */ -@/* switches context immediately and never comes back. */ +@/* _txm_module_manager_memory_fault_handler is common to every module */ +@/* port and it terminates the faulting thread and then calls the */ +@/* application's fault-notify callback. For the second half of that */ +@/* to happen, _tx_thread_terminate has to RETURN -- and terminating */ +@/* the running thread only returns if the kernel believes it is inside */ +@/* an exception. _tx_thread_terminate ends in */ +@/* _tx_thread_system_preempt_check, which calls */ +@/* _tx_thread_system_return whenever _tx_thread_system_state and */ +@/* _tx_thread_preempt_disable are both zero; on this architecture that */ +@/* switches context immediately and never comes back. */ @/* */ -@/* So this routine owes the handler three things, exactly as the */ -@/* Cortex-A7 module port's abort vector does: */ +@/* So this routine owes the handler three things, exactly as the */ +@/* Cortex-A7 module port's abort vector does: */ @/* */ -@/* 1. _tx_thread_system_state incremented across the call, so the */ -@/* terminate returns instead of scheduling from Abort mode. */ -@/* 2. _tx_thread_current_ptr cleared afterwards -- the thread it */ -@/* names is terminated and the scheduler must not save into it. */ -@/* 3. an exception return into _tx_thread_schedule in System mode, */ -@/* which is where the next thread is chosen. */ +@/* 1. _tx_thread_system_state incremented across the call, so the */ +@/* terminate returns instead of scheduling from Abort mode. */ +@/* 2. _tx_thread_current_ptr cleared afterwards -- the thread it */ +@/* names is terminated and the scheduler must not save into it. */ +@/* 3. an exception return into _tx_thread_schedule in System mode, */ +@/* which is where the next thread is chosen. */ @/* */ -@/* Without step 1 the notify callback is unreachable, and the */ -@/* _tx_thread_system_return that runs in its place saves a solicited */ -@/* frame on the ABORT stack and writes that Abort-mode sp into the */ -@/* dead thread's stack pointer. It looks like it works, because the */ -@/* thread is never resumed -- but nothing gives the Abort stack back, */ -@/* so each module fault costs it about 56 bytes for the life of the */ -@/* run. The Cortex-M ports do not need step 1: there */ -@/* _tx_thread_system_return only pends PendSV and returns. */ +@/* Without step 1 the notify callback is unreachable, and the */ +@/* _tx_thread_system_return that runs in its place saves a solicited */ +@/* frame on the ABORT stack and writes that Abort-mode sp into the */ +@/* dead thread's stack pointer. It looks like it works, because the */ +@/* thread is never resumed -- but nothing gives the Abort stack back, */ +@/* so each module fault costs it about 56 bytes for the life of the */ +@/* run. */ @/* */ @/**************************************************************************/ @@ -116,7 +116,7 @@ @/**************************************************************************/ -@/* Data abort: a module wrote or read outside a region it owns. */ +@/* Data abort: a module wrote or read outside a region it owns. */ @/**************************************************************************/ .type _txm_module_manager_data_abort, %function @@ -131,7 +131,7 @@ _txm_module_manager_data_abort: @/**************************************************************************/ -@/* Prefetch abort: a module tried to execute outside its code region. */ +@/* Prefetch abort: a module tried to execute outside its code region. */ @/**************************************************************************/ .type _txm_module_manager_prefetch_abort, %function diff --git a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_memory_fault_handler.c b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_memory_fault_handler.c index 62f287e09..729d7456c 100644 --- a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_memory_fault_handler.c +++ b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_memory_fault_handler.c @@ -52,15 +52,13 @@ architecture _tx_thread_system_return switches context immediately and never comes back, so the callback would be unreachable. - The body below is therefore left exactly as the cortex_m33, cortex_a7 and - cortex_m7 ports have it, and the requirement is met where it belongs -- in + The body below is therefore left exactly as the other module ports have it, + and the requirement is met where it belongs -- in txm_module_manager_fault_capture.S, which increments _tx_thread_system_state around this call, clears _tx_thread_current_ptr afterwards and returns into - the scheduler. The Cortex-M ports need no such bracket because their - _tx_thread_system_return only pends PendSV and returns. Anyone tempted to - reorder the two statements below to "fix" a notify callback that does not fire - should look at the abort vector first: the ordering here is upstream's and it - is not the defect. */ + the scheduler. Anyone tempted to reorder the two statements below to "fix" a + notify callback that does not fire should look at the abort vector first: the + ordering here is upstream's and it is not the defect. */ /* Define the user's fault notification callback function pointer. This is setup via the txm_module_manager_memory_fault_notify API. */ diff --git a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_offset_check.c b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_offset_check.c index 09ba7420c..cd8afeddd 100644 --- a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_offset_check.c +++ b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_offset_check.c @@ -25,30 +25,30 @@ /* */ /* DESCRIPTION */ /* */ -/* Compile-time verification of the structure offsets that this port's */ +/* Compile-time verification of the structure offsets that this port's */ /* assembly hard-codes. */ /* */ -/* tx_thread_schedule.S reaches into TX_THREAD and TXM_MODULE_INSTANCE */ -/* with numeric offsets, because assembly has no other way to do it. */ -/* Nothing in the toolchain connects those numbers to the structures */ -/* they describe, so adding a field, reordering an extension or */ -/* building with a different set of ThreadX options silently moves the */ -/* target and the scheduler reads the wrong word. The failure is a */ -/* corrupted region table or a fault in a thread that did nothing wrong, */ -/* a long way from the change that caused it. */ +/* tx_thread_schedule.S reaches into TX_THREAD and TXM_MODULE_INSTANCE */ +/* with numeric offsets, because assembly has no other way to do it. */ +/* Nothing in the toolchain connects those numbers to the structures */ +/* they describe, so adding a field, reordering an extension or */ +/* building with a different set of ThreadX options silently moves the */ +/* target and the scheduler reads the wrong word. The failure is a */ +/* corrupted region table or a fault in a thread that did nothing */ +/* wrong, a long way from the change that caused it. */ /* */ -/* This file exists so that becomes a build error instead. It emits no */ -/* code. */ +/* This file exists so that becomes a build error instead. It emits */ +/* no code. */ /* */ -/* The offsets here are not the same as the Armv8-M module port's, and */ -/* that is the concrete case in point: there the module instance pointer */ -/* sits at 0x90, and here it is 0x94, because the Cortex-R52 port keeps */ -/* tx_thread_vfp_enable ahead of the module fields in */ -/* TX_THREAD_EXTENSION_2. Copying the Armv8-M numbers would have built */ -/* cleanly and misbehaved on the board. */ +/* The offsets here are not the same as the Armv8-M module port's, and */ +/* that is the concrete case in point: there the module instance */ +/* pointer sits at 0x90, and here it is 0x94, because the Cortex-R52 */ +/* port keeps tx_thread_vfp_enable ahead of the module fields in */ +/* TX_THREAD_EXTENSION_2. Copying the Armv8-M numbers would have */ +/* built cleanly and misbehaved on the board. */ /* */ -/* See eclipse-threadx/threadx issue #577, which proposes this check for */ -/* every port rather than only this one. */ +/* See eclipse-threadx/threadx issue #577, which proposes this check */ +/* for every port rather than only this one. */ /* */ /**************************************************************************/ diff --git a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_svc_handler.S b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_svc_handler.S index 0689ffbaa..926af84d7 100644 --- a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_svc_handler.S +++ b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_svc_handler.S @@ -25,26 +25,26 @@ @/* */ @/* DESCRIPTION */ @/* */ -@/* The privilege boundary. A board's supervisor call vector branches */ +@/* The privilege boundary. A board's supervisor call vector branches */ @/* here. */ @/* */ -@/* SVC 1 raises a module thread out of User mode and onto its kernel */ -@/* stack; SVC 2 puts it back. Both are only reachable from the two */ -@/* exact instructions inside _txm_module_manager_user_mode_entry, and */ -@/* that check is what makes the boundary a boundary. Without it a */ -@/* module could execute SVC 1 from anywhere in its own code and come */ -@/* back privileged, which is every protection in this port gone at */ +@/* SVC 1 raises a module thread out of User mode and onto its kernel */ +@/* stack; SVC 2 puts it back. Both are only reachable from the two */ +@/* exact instructions inside _txm_module_manager_user_mode_entry, and */ +@/* that check is what makes the boundary a boundary. Without it a */ +@/* module could execute SVC 1 from anywhere in its own code and come */ +@/* back privileged, which is every protection in this port gone at */ @/* once. */ @/* */ -@/* The two stacks are the other half of it. A module's own stack is in */ -@/* memory the module can write, so the kernel must not run on it: a */ -@/* module could otherwise corrupt kernel state by scribbling on what it */ -@/* believes is its own stack. SVC 1 therefore switches to a kernel */ -@/* stack the module cannot reach, and SVC 2 switches back. */ +@/* The two stacks are the other half of it. A module's own stack is */ +@/* in memory the module can write, so the kernel must not run on it: a */ +@/* module could otherwise corrupt kernel state by scribbling on what */ +@/* it believes is its own stack. SVC 1 therefore switches to a kernel */ +@/* stack the module cannot reach, and SVC 2 switches back. */ @/* */ -@/* Any other SVC number stops. This core's base port does not use SVC */ -@/* at all -- its vector treats one as a fault -- so there is no third */ -@/* caller to accommodate and nothing legitimate to fall through to. */ +@/* Any other SVC number stops. This core's base port does not use SVC */ +@/* at all -- its vector treats one as a fault -- so there is no third */ +@/* caller to accommodate and nothing legitimate to fall through to. */ @/* */ @/**************************************************************************/ diff --git a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_thread_stack_build.S b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_thread_stack_build.S index 1d1d711a1..ad77126b5 100644 --- a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_thread_stack_build.S +++ b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_thread_stack_build.S @@ -71,8 +71,8 @@ $_txm_module_manager_thread_stack_build: @/* */ @/* FUNCTION RELEASE */ @/* */ -@/* _txm_module_manager_thread_stack_build Cortex-R52/GNU */ -@/* 6.5.2 */ +@/* _txm_module_manager_thread_stack_build */ +@/* Cortex-R52/GNU 6.5.2*/ @/* AUTHOR */ @/* */ @/* Frédéric Desbiens, Eclipse Foundation */ diff --git a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_user_mode_entry.S b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_user_mode_entry.S index afc307b51..74446d9f0 100644 --- a/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_user_mode_entry.S +++ b/ports_module/cortex_r52/gnu/module_manager/src/txm_module_manager_user_mode_entry.S @@ -27,20 +27,20 @@ @/* */ @/* The only way a module reaches the kernel. */ @/* */ -@/* A module runs in User mode and cannot execute kernel code or touch */ -@/* kernel memory. When it calls a ThreadX service, the call arrives */ -@/* here: SVC 1 raises privilege, the dispatch function performs the */ -@/* service, SVC 2 drops back to User mode, and the module continues. */ +@/* A module runs in User mode and cannot execute kernel code or touch */ +@/* kernel memory. When it calls a ThreadX service, the call arrives */ +@/* here: SVC 1 raises privilege, the dispatch function performs the */ +@/* service, SVC 2 drops back to User mode, and the module continues. */ @/* */ -@/* This function is the entire privileged surface a module can see. */ -@/* It gets an MPU region of its own -- the one at */ -@/* TXM_MODULE_MPU_KERNEL_ENTRY_INDEX -- because a module must be able */ -@/* to execute these few instructions and nothing else on that side of */ -@/* the boundary. Everything the module is allowed to ask for is */ -@/* decided inside _txm_module_manager_kernel_dispatch, in kernel */ +@/* This function is the entire privileged surface a module can see. */ +@/* It gets an MPU region of its own -- the one at */ +@/* TXM_MODULE_MPU_KERNEL_ENTRY_INDEX -- because a module must be able */ +@/* to execute these few instructions and nothing else on that side of */ +@/* the boundary. Everything the module is allowed to ask for is */ +@/* decided inside _txm_module_manager_kernel_dispatch, in kernel */ @/* memory the module cannot reach. */ @/* */ -@/* SVC 1 and SVC 2 are handled by the port's supervisor call vector. */ +@/* SVC 1 and SVC 2 are handled by the port's supervisor call vector. */ @/* */ @/* CALLS */ @/* */