Skip to content

Read the TCM configuration off the part, and corrected what we thought we knew - #615

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:feature/r52-s32z280-tcm
Aug 14, 2026
Merged

Read the TCM configuration off the part, and corrected what we thought we knew#615
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:feature/r52-s32z280-tcm

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

The BSP has recorded since bring-up that the TCMs are inaccessible at reset
"because nothing has programmed the TCM region registers yet". Reading those
registers shows the reason was wrong.

ATCM  0x0000011F   64KB, 1 wait state, ENABLED at EL2 and EL1/EL0
BTCM  0x00000014   16KB, 0 wait states, disabled
CTCM  0x00000114   16KB, 1 wait state, disabled

Every BASEADDRESS field is zero, so ATCM is live as 64KB at address
0x00000000
, not at the 0x30000000 the reference manual documents. The reads
that faulted were of an address the TCM is not at. ATCM's enables reset set because
CFGTCMBOOTx is tied high on this part, which the Cortex-R52 TRM gives as the one
exception to "at reset all bits are 0 apart from SIZE and WAITSTATES". BTCM and CTCM
really are disabled.

The sizes and wait states match the S32Z2 reference manual exactly — TCMA 64KB with
one wait state, TCMB 16KB with none, TCMC 16KB with one — so the TRM's field layout,
NXP's documented configuration and the silicon all agree. That agreement is the
point of reading before writing.

ECC changes what "enable TCM" means

IMP_MEMPROTCTLR reads 0x00000011: RAMPROTIMP and RAMPROTEN both set, so ECC
is implemented and on. TRM 6.2.2 therefore applies rather than being hypothetical
— a TCM location must be written before it is read, or the read reports an error.
That would look exactly like "the TCM is not accessible" and send the reader back to
region registers which were already correct.

The preload widths are not uniform either: ATCM needs 64-bit aligned STRD or
STM
where BTCM and CTCM accept 32-bit stores, so a C loop over unsigned int
would leave ATCM's check bits invalid.

This change reads only

tcm.c reads and decodes; nothing is programmed. The layouts in tcm.h are quoted
from TRM r1p3 section 3.3.94 table 3-136 and section 3.3.76 table 3-114, not
inferred from a neighbouring register — BASEADDRESS is [31:13] where
IMP_PERIPHPREGIONR uses [31:12], and assuming the analogy would have been wrong
by one bit in exactly the way the PRBAR shift was.

The boot image reports all of it and flags any size that disagrees with the
reference manual, so a part configured differently says so rather than being
silently assumed to match this one.

Next

Programming the bases, preloading with the correct store widths per bank, adding an
MPU region, and verifying by write-and-read before anything real is placed there.
Separate change, because the correction above stands on its own.

…t we knew

The BSP has recorded since bring-up that the TCMs are inaccessible at reset
"because nothing has programmed the TCM region registers yet". Reading those
registers shows the reason was wrong.

    ATCM  0x0000011F   64KB, 1 wait state, ENABLED at EL2 and EL1/EL0
    BTCM  0x00000014   16KB, 0 wait states, disabled
    CTCM  0x00000114   16KB, 1 wait state, disabled

Every BASEADDRESS field is zero, so ATCM is live as 64KB at address 0x00000000,
not at the 0x30000000 the reference manual documents. The reads that faulted were
of an address the TCM is not at. ATCM's enables reset set because CFGTCMBOOTx is
tied high on this part, which the Cortex-R52 TRM gives as the one exception to
"at reset all bits are 0 apart from SIZE and WAITSTATES". BTCM and CTCM really
are disabled.

The sizes and wait states match the S32Z2 reference manual exactly -- TCMA 64KB
with one wait state, TCMB 16KB with none, TCMC 16KB with one -- so the TRM's field
layout, NXP's documented configuration and the silicon all agree. That agreement
is the point of reading before writing.

ECC is implemented and enabled: IMP_MEMPROTCTLR reads 0x00000011, both RAMPROTIMP
and RAMPROTEN set. TRM 6.2.2 therefore applies rather than being hypothetical: a
TCM location must be written before it is read, or the read reports an error --
which looks exactly like "the TCM is not accessible" and sends the reader back to
region registers that were already correct. The preload widths differ too, ATCM
needing 64-bit aligned STRD or STM where BTCM and CTCM accept 32-bit stores, so a
C loop over unsigned int would leave ATCM's check bits invalid.

tcm.c reads and decodes only; nothing is programmed here. The layouts in tcm.h are
quoted from TRM r1p3 section 3.3.94 table 3-136 and section 3.3.76 table 3-114,
not inferred from a neighbouring register: BASEADDRESS is [31:13] where
IMP_PERIPHPREGIONR uses [31:12], and assuming the analogy would have been wrong by
one bit in the same way the PRBAR shift was.

The boot image reports all of it and flags any size that disagrees with the
reference manual, so a part configured differently says so rather than being
silently assumed to match this one.

Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit 27891f3 into eclipse-threadx:dev Aug 14, 2026
4 checks passed
@fdesbiens
fdesbiens deleted the feature/r52-s32z280-tcm branch August 14, 2026 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant