From 3d62d44e46ce33388e620ead92747f9d56c01b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Mon, 28 Sep 2026 18:08:46 -0400 Subject: [PATCH 1/2] Removed the Cortex-M asides from the Cortex-R52 module port Four comments in the Cortex-R52 module port explained what the Cortex-M ports do instead. A reader working on this port cannot act on any of it: the behaviour described belongs to a different architecture, and the surrounding comments already say what this port does and why. The remaining text is unchanged. The abort vector still explains the three things it owes the fault handler and what omitting the first costs, the fault handler still explains why its two statements are ordered as they are, and the preamble still says that every GNU module port writes the entry-point words the same way. Comment-only. The port builds clean, 203 targets, zero warnings. Assisted-by: Claude Code (Opus 5) --- .../fvp_baser_aemv8r/txm_module_preamble.S | 3 +-- .../example_build/s32z280_evb/txm_module_preamble.S | 3 +-- .../src/txm_module_manager_fault_capture.S | 3 +-- .../src/txm_module_manager_memory_fault_handler.c | 12 +++++------- 4 files changed, 8 insertions(+), 13 deletions(-) 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..54a526449 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 @@ -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/txm_module_preamble.S b/ports_module/cortex_r52/gnu/example_build/s32z280_evb/txm_module_preamble.S index 19bd89318..54a526449 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 @@ -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_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..b9b8cafc1 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 @@ -71,8 +71,7 @@ @/* 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. */ +@/* run. */ @/* */ @/**************************************************************************/ 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. */ From 2a78af531987535f40617d2fc4bb348d767a5f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Mon, 28 Sep 2026 18:09:11 -0400 Subject: [PATCH 2/2] Aligned the banner comments in the Cortex-R52 ports The header and function banner comments in the Cortex-R52 port and its module port do not close on the right border. 990 of 4,228 banner lines sat one to three columns off, and in the module port that was 42 per cent of them. Measured against the ports the convention came from, Cortex-A7 and Cortex-M33 are at zero and Cortex-R5 at 2 per cent, so this is the R52 tree rather than the house style. Lines whose text already fitted are re-padded. Where the text itself ran past the border the trailing words move down to the next line, which pushes the paragraph along until every line fits, so no wording is shortened and no sentence is recut by hand. The bar widths were already correct in every file and are untouched. One line is left over and is a real exception: _txm_module_manager_thread_stack_build is long enough that its name and the release column cannot share a line at this width. Verified: the banner text is word-for-word identical before and after in all 45 files, the port builds at 203 targets with zero warnings, and all eleven changed assembly files assemble. Assisted-by: Claude Code (Opus 5) --- .../example_build/fvp_baser_aemv8r/board.h | 3 +- .../example_build/fvp_baser_aemv8r/cache.c | 27 +- .../example_build/fvp_baser_aemv8r/cache.h | 35 +- .../example_build/fvp_baser_aemv8r/console.c | 6 +- .../example_build/fvp_baser_aemv8r/demo_clz.c | 6 +- .../example_build/fvp_baser_aemv8r/demo_fiq.c | 44 +-- .../example_build/fvp_baser_aemv8r/demo_m2.c | 3 +- .../example_build/fvp_baser_aemv8r/demo_m3.c | 15 +- .../example_build/fvp_baser_aemv8r/demo_m5.c | 8 +- .../example_build/fvp_baser_aemv8r/demo_mpu.c | 15 +- .../fvp_baser_aemv8r/demo_nesting.c | 42 +-- .../fvp_baser_aemv8r/demo_verify.c | 10 +- .../example_build/fvp_baser_aemv8r/entry.S | 6 +- .../example_build/fvp_baser_aemv8r/gicv3.c | 57 +-- .../fvp_baser_aemv8r/irq_dispatch.c | 26 +- .../gnu/example_build/fvp_baser_aemv8r/mpu.c | 34 +- .../example_build/fvp_baser_aemv8r/timer.c | 3 +- .../tx_initialize_low_level.S | 12 +- .../fvp_baser_aemv8r/uart_pl011.c | 6 +- .../gnu/example_build/s32z280_evb/bsp_boot.c | 23 +- .../gnu/example_build/s32z280_evb/cache.c | 8 +- .../s32z280_evb/demo_fiq_s32z280.c | 50 +-- .../s32z280_evb/demo_nesting_s32z280.c | 34 +- .../example_build/s32z280_evb/demo_s32z280.c | 93 ++--- .../s32z280_evb/demo_vfp_s32z280.c | 2 +- .../gnu/example_build/s32z280_evb/entry.S | 94 ++--- .../gnu/example_build/s32z280_evb/gicv3.c | 77 ++-- .../example_build/s32z280_evb/irq_dispatch.c | 55 +-- .../gnu/example_build/s32z280_evb/mpu.c | 19 +- .../gnu/example_build/s32z280_evb/tcm.c | 11 +- .../gnu/example_build/s32z280_evb/tcm.h | 48 +-- .../example_build/s32z280_evb/thread_mpu.c | 30 +- .../example_build/s32z280_evb/thread_mpu.h | 26 +- .../gnu/example_build/s32z280_evb/timer.c | 17 +- .../s32z280_evb/tx_initialize_low_level.S | 8 +- .../cortex_r52/gnu/src/tx_port_offset_check.c | 4 +- .../fvp_baser_aemv8r/module_blob.S | 28 +- .../fvp_baser_aemv8r/sample_threadx_module.c | 79 +++-- .../sample_threadx_module_manager.c | 251 ++++++------- .../sample_threadx_module_properties.c | 231 ++++++------ .../fvp_baser_aemv8r/txm_module_preamble.S | 22 +- .../example_build/s32z280_evb/module_blob.S | 22 +- .../s32z280_evb/sample_threadx_module.c | 79 +++-- .../sample_threadx_module_manager.c | 333 +++++++++--------- .../s32z280_evb/txm_module_preamble.S | 22 +- .../gnu/module_lib/src/txm_module_gcc_setup.S | 72 ++-- ...xm_module_manager_external_memory_enable.c | 4 +- .../src/txm_module_manager_fault_capture.S | 83 ++--- .../src/txm_module_manager_offset_check.c | 38 +- .../src/txm_module_manager_svc_handler.S | 30 +- .../txm_module_manager_thread_stack_build.S | 4 +- .../src/txm_module_manager_user_mode_entry.S | 22 +- 52 files changed, 1158 insertions(+), 1119 deletions(-) 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 54a526449..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. */ @/* */ @/**************************************************************************/ 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 54a526449..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. */ @/* */ @/**************************************************************************/ 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 b9b8cafc1..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,53 +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. */ +@/* 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. */ @/* */ @/**************************************************************************/ @@ -115,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 @@ -130,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_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 */ @/* */