Skip to content

Commit 3397332

Browse files
committed
NXP T2080 Port Refresh
1 parent 5f13d7d commit 3397332

File tree

13 files changed

+2230
-629
lines changed

13 files changed

+2230
-629
lines changed

.github/workflows/test-configs.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,6 @@ jobs:
182182
arch: ppc
183183
config-file: ./config/examples/nxp-t1024.config
184184

185-
nxp_t2080_68ppc2_test:
186-
uses: ./.github/workflows/test-build.yml
187-
with:
188-
arch: ppc
189-
config-file: ./config/examples/nxp-t2080-68ppc2.config
190-
191185
nxp_t2080_test:
192186
uses: ./.github/workflows/test-build.yml
193187
with:

arch.mk

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,12 +627,19 @@ endif
627627
ifeq ($(ARCH),PPC)
628628
CROSS_COMPILE?=powerpc-linux-gnu-
629629
LDFLAGS+=-Wl,--build-id=none
630-
CFLAGS+=-DARCH_PPC -DFAST_MEMCPY
630+
CFLAGS+=-DARCH_PPC -DFAST_MEMCPY -ffreestanding -fno-tree-loop-distribute-patterns
631631

632632
ifeq ($(DEBUG_UART),0)
633633
CFLAGS+=-fno-builtin-printf
634634
endif
635635

636+
# Target-specific CPU flags
637+
ifeq ($(TARGET),nxp_t2080)
638+
CFLAGS+=-mcpu=e6500 -mno-altivec -mbss-plt
639+
else ifeq ($(TARGET),nxp_t1024)
640+
CFLAGS+=-mcpu=e5500
641+
endif
642+
636643
# Prune unused functions and data
637644
CFLAGS+=-ffunction-sections -fdata-sections
638645
LDFLAGS+=-Wl,--gc-sections
@@ -994,6 +1001,7 @@ ifeq ($(TARGET),nxp_t2080)
9941001
LDFLAGS+=$(ARCH_FLAGS)
9951002
LDFLAGS+=-Wl,--hash-style=both # generate both sysv and gnu symbol hash table
9961003
LDFLAGS+=-Wl,--as-needed # remove weak functions not used
1004+
OBJS+=src/boot_ppc_mp.o # support for spin table
9971005
UPDATE_OBJS:=src/update_ram.o
9981006
OBJS+=src/fdt.o
9991007
endif

config/examples/nxp-t2080-68ppc2.config

Lines changed: 0 additions & 55 deletions
This file was deleted.

config/examples/nxp-t2080.config

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
# NXP T2080 wolfBoot Configuration Template
2+
13
ARCH=PPC
24
TARGET=nxp_t2080
35
SIGN?=ECC384
46
HASH?=SHA384
7+
IMAGE_HEADER_SIZE?=512
58
DEBUG?=0
9+
DEBUG_SYMBOLS?=1
610
DEBUG_UART?=1
711
VTOR?=1
812
CORTEX_M0?=0
@@ -15,27 +19,42 @@ ALLOW_DOWNGRADE?=0
1519
NVM_FLASH_WRITEONCE?=0
1620
WOLFBOOT_VERSION?=0
1721
NO_MPU?=0
18-
SPMATH?=0
19-
SPMATHALL?=1
20-
RAM_CODE?=0
22+
SPMATH?=1
23+
SPMATHALL?=0
24+
RAM_CODE?=1
2125
DUALBANK_SWAP?=0
22-
PKA?=1
2326
WOLFTPM?=0
24-
WOLFBOOT_ORIGIN?=0xEFFF0000
25-
WOLFBOOT_PARTITION_SIZE?=0x20000
27+
OPTIMIZATION_LEVEL?=1
28+
29+
# NOR Base Address
30+
ARCH_FLASH_OFFSET?=0xEFFE0000
31+
32+
# Flash Sector Size
2633
WOLFBOOT_SECTOR_SIZE?=0x10000
2734

28-
ARCH_FLASH_OFFSET?=0xEFFF0000
29-
BOOTLOADER_PARTITION_SIZE=0x10000
35+
# wolfBoot start address
36+
WOLFBOOT_ORIGIN?=0xEFFE0000
37+
# wolfBoot partition size (custom)
38+
BOOTLOADER_PARTITION_SIZE=0x20000
3039

31-
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xEFFD0000
40+
# Application Partition Size
41+
WOLFBOOT_PARTITION_SIZE?=0x20000
42+
# Location in Flash for Application Partition
43+
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xEFFC0000
44+
# Load Partition to RAM Address
3245
WOLFBOOT_LOAD_ADDRESS?=0x19000
33-
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0xEFFB0000
46+
47+
# Location in Flash for Update Partition
48+
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0xEFFA0000
3449

3550
# Location of temporary sector used during updates
36-
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xEFFA0000
51+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xEFF90000
3752

3853
# DTS (Device Tree)
3954
WOLFBOOT_DTS_BOOT_ADDRESS?=0xE8040000
4055
WOLFBOOT_DTS_UPDATE_ADDRESS?=0xE8050000
56+
# DTS Load to RAM Address
4157
WOLFBOOT_LOAD_DTS_ADDRESS?=0x200000
58+
59+
# Optional QSPI flash test (erase/write/read on update partition)
60+
#CFLAGS_EXTRA+=-DTEST_FLASH

docs/Targets.md

Lines changed: 156 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3065,16 +3065,144 @@ Flash factory_custom.bin to NOR base 0xEC00_0000
30653065

30663066
The NXP QorIQ T2080 is a PPC e6500 based processor (four cores). Support has been tested with the NAII 68PPC2.
30673067

3068-
Example configurations for this target are provided in:
3069-
* NXP T2080: [/config/examples/nxp-t2080.config](/config/examples/nxp-t2080.config).
3070-
* NAII 68PPC2: [/config/examples/nxp-t2080-68ppc2.config](/config/examples/nxp-t2080-68ppc2.config).
3068+
Example configuration: [/config/examples/nxp-t2080.config](/config/examples/nxp-t2080.config).
3069+
Stock layout is default; for NAII 68PPC2, uncomment the "# NAII 68PPC2:" lines and comment the stock lines.
30713070

30723071
### Design NXP T2080 PPC
30733072

30743073
The QorIQ requires a Reset Configuration Word (RCW) to define the boot parameters, which resides at the start of the flash (0xE8000000).
30753074

30763075
The flash boot entry point is `0xEFFFFFFC`, which is an offset jump to wolfBoot initialization boot code. Initially the PowerPC core enables only a 4KB region to execute from. The initialization code (`src/boot_ppc_start.S`) sets the required CCSR and TLB for memory addressing and jumps to wolfBoot `main()`.
30773076

3077+
#### Boot Sequence and Cache Architecture
3078+
3079+
The T2080 e6500 boot sequence has several hardware-specific constraints that
3080+
differ from other QorIQ parts. Understanding the cache hierarchy and memory
3081+
path is critical for reliable cold power-on boot.
3082+
3083+
**Memory Hierarchy (Core to External):**
3084+
3085+
```
3086+
CPU Core → L1 Cache (32KB I + 32KB D) → L2 Cluster Cache (256KB per cluster)
3087+
→ CoreNet Fabric → CPC (2MB, configurable as SRAM or L3 cache)
3088+
→ DDR Controller → DDR SDRAM
3089+
→ IFC Controller → NOR Flash
3090+
```
3091+
3092+
**Cold Boot Initial Stack: L1 Locked Data Cache**
3093+
3094+
On cold power cycle, the CoreNet Platform Cache (CPC) configured as SRAM is
3095+
unreliable for store operations. The CPC SRAM is accessed through the CoreNet
3096+
interconnect fabric: `Core → L1 → L2 → CoreNet → CPC`. When the L1 data
3097+
cache evicts dirty cache lines to CPC SRAM during cold power-on, the CoreNet
3098+
bus transaction generates a bus error resulting in a machine check exception.
3099+
With `MSR[ME]=0` (the default at reset), this causes a CPU checkstop (silent
3100+
hang). This was confirmed by inserting a `sync` instruction after stack
3101+
stores — the `sync` forces the L1 store buffer to drain through CoreNet to
3102+
CPC SRAM, and the hang moved to the `sync` instruction, proving the bus error.
3103+
3104+
The `stwu` (store word with update) instructions used to build the initial
3105+
stack frame appeared to work because the stores remained in the L1 data cache
3106+
write buffer and were never committed to CPC SRAM. The hang manifested later
3107+
when L1 cache pressure caused eviction of the stack cache lines to CPC SRAM.
3108+
3109+
**Solution:** Use L1 locked data cache as the initial 16KB stack (matching the
3110+
U-Boot approach). The `dcbz` instruction allocates a cache line and fills it
3111+
with zeros without generating a bus read (the data is CPU-generated). The
3112+
`dcbtls` instruction locks the cache line so it is never evicted. With
3113+
`WIMGE=0` (cacheable, non-coherent) in the TLB entry, `dcbz` does not
3114+
generate any CoreNet coherency transaction. The locked cache lines are
3115+
entirely core-local — no external bus access occurs.
3116+
3117+
The implementation in `boot_ppc_start.S`:
3118+
3119+
1. L1 I-cache and D-cache are enabled (`icache_enable`, `dcache_enable`)
3120+
2. Four 4KB TLB0 entries are created for `L1_CACHE_ADDR` (0xF8E00000), a
3121+
virtual address with no backing physical memory
3122+
3. A `dcbz` + `dcbtls` loop allocates and locks 256 cache lines
3123+
(16KB = half of the 32KB L1 D-cache) at that address
3124+
4. On e6500, `dcbtls 2` (L2 lock) is issued before `dcbtls 0` (L1 lock)
3125+
to lock in both cache levels
3126+
5. The stack pointer is set to `L1_CACHE_ADDR + 0x4000 - 64` (top of the
3127+
16KB locked region minus the ABI-required initial frame)
3128+
6. All `stwu` stores to build the stack frame hit L1 locked cache —
3129+
no CoreNet, no CPC SRAM, no bus error
3130+
3131+
The CPC SRAM hardware (LAW, TLB, CPC enable) is still configured during early
3132+
assembly, but is not used for the stack. After DDR is initialized in C code
3133+
(`hal_init()`), the stack is relocated to DDR, and the CPC is reconfigured
3134+
from SRAM mode to full L3 cache mode.
3135+
3136+
Configuration in `hal/nxp_ppc.h`:
3137+
3138+
```c
3139+
#define L1_CACHE_ADDR (0xF8E00000UL) /* L1 locked dcache, no backing memory */
3140+
#define L2SRAM_ADDR (0xF8F00000UL) /* CPC as SRAM (deferred to C code) */
3141+
```
3142+
3143+
**Flash TLB: Write-Through + Guarded (W|G)**
3144+
3145+
The flash TLB entry uses `MAS2_W | MAS2_G` (Write-Through + Guarded):
3146+
- **Write-Through (W):** Allows the L1 I-cache to cache flash instruction
3147+
fetches during XIP boot, significantly improving performance over
3148+
Cache-Inhibited (`MAS2_I`) which forces every instruction fetch through the
3149+
IFC to flash.
3150+
- **Guarded (G):** Prevents speculative prefetch to the IFC controller, which
3151+
could interfere with flash command sequences.
3152+
3153+
After DDR stack relocation, C code switches the flash TLB to `MAS2_I | MAS2_G`
3154+
for flash write/erase operations (when the flash bank enters command mode), or
3155+
to `MAS2_M` for full caching after operations complete.
3156+
3157+
**MSR Configuration**
3158+
3159+
The initial MSR at reset is 0. The assembly startup sets `MSR[DE]` (Debug
3160+
Enable) early for JTAG debugging. After the stack is established, MSR is set to:
3161+
- `MSR[CE]` — Critical interrupt enable
3162+
- `MSR[ME]` — Machine check enable (exceptions instead of checkstop)
3163+
- `MSR[DE]` — Debug enable
3164+
- `MSR[RI]` — Recoverable interrupt (allows clean exception recovery)
3165+
3166+
**Branch Prediction**
3167+
3168+
Branch prediction (BUCSR) is disabled during assembly startup and enabled
3169+
after DDR stack relocation in `hal_init()`. This matches the reference
3170+
implementation and avoids potential branch predictor issues during the
3171+
transition from L1 locked cache to DDR stack.
3172+
3173+
**e6500 64-bit GPR Considerations**
3174+
3175+
The e6500 core has 64-bit General Purpose Registers even in 32-bit mode.
3176+
The `lis` (Load Immediate Shifted) instruction sign-extends the 16-bit
3177+
immediate to 64 bits. For addresses with bit 31 set (>= 0x80000000), such
3178+
as flash addresses in the 0xEFxxxxxx range, `lis` produces incorrect
3179+
64-bit values (e.g., `lis r3, 0xEFFE` → `0xFFFFFFFF_EFFE0000`). This causes
3180+
TLB misses on `blr` (branch to link register) because the CPU uses all 64
3181+
bits for the effective address.
3182+
3183+
The `LOAD_ADDR32` macro avoids this: `li reg, 0` (clears all 64 bits) followed
3184+
by `oris` and `ori` to set only the lower 32 bits. This is used for all
3185+
address loads in the assembly startup, including the `boot_entry_C` branch
3186+
target, `RESET_VECTOR`, TLB EPN/RPN values, and CCSRBAR addresses.
3187+
3188+
**UART Debug Checkpoints**
3189+
3190+
With `DEBUG_UART=1`, the assembly startup emits single-character checkpoints
3191+
to UART0 (0xFE11C500, 115200 baud). The `uart_putc_debug` macro
3192+
saves/restores r5 and r6 via SPRG4/SPRG5 (SPR 276/277) to avoid clobbering
3193+
registers during the critical L2 and CPC initialization sequences.
3194+
3195+
```
3196+
1 - CPC invalidate start A - L2 cluster enable start
3197+
2 - CPC invalidate done B - L2 cluster enabled
3198+
3 - CPC SRAM configured E - L1 cache setup
3199+
4 - SRAM LAW configured F - L1 I-cache enabled
3200+
5 - Flash TLB configured G - L1 D-cache enabled
3201+
6 - CCSRBAR TLB configured D - Stack ready (L1 locked cache)
3202+
7 - SRAM TLB configured Z - About to jump to C code
3203+
8 - CPC enabled
3204+
```
3205+
30783206
RM 4.3.3 Boot Space Translation
30793207
30803208
"When each core comes out of reset, its MMU has one 4 KB page defined at 0x0_FFFF_Fnnn. Each core begins execution with the instruction at effective address 0x0_FFFF_FFFC. To get this instruction, the core's first instruction fetch is a burst read of boot code from effective address 0x0_FFFF_FFC0."
@@ -3084,9 +3212,10 @@ RM 4.3.3 Boot Space Translation
30843212
By default wolfBoot will use `powerpc-linux-gnu-` cross-compiler prefix. These tools can be installed with the Debian package `gcc-powerpc-linux-gnu` (`sudo apt install gcc-powerpc-linux-gnu`).
30853213
30863214
The `make` creates a `factory.bin` image that can be programmed at `0xE8080000`
3215+
(For NAII 68PPC2, first edit `nxp-t2080.config` to uncomment the NAII 68PPC2 lines.)
30873216
30883217
```
3089-
cp ./config/examples/nxp-t2080-68ppc2.config .config
3218+
cp ./config/examples/nxp-t2080.config .config
30903219
make clean
30913220
make keytools
30923221
make
@@ -3129,28 +3258,33 @@ Flash Layout (with files):
31293258
31303259
Or program the `factory.bin` to `0xE8080000`
31313260
3132-
Example Boot Debug Output:
3133-
3134-
```
3135-
wolfBoot Init
3136-
Part: Active 0, Address E8080000
3137-
Image size 1028
3261+
Example Boot Debug Output (with `DEBUG_UART=1`):
3262+
3263+
```
3264+
12345678ABEFGDZIJQRSKwolfBoot Init
3265+
Build: Feb 27 2026 12:27:15
3266+
IFC CSPR0: 0x141 (WP set)
3267+
DDR Test: PASSED
3268+
Ramcode: copied 5584 bytes to DDR, TLB9 remapped
3269+
CPC: Released SRAM, full 2MB L2 cache enabled
3270+
Flash: caching enabled (L1+L2+CPC)
3271+
MP: Starting cores (boot page 0x7FFFF000, spin table 0x7FFFE100)
3272+
Internal flash test at 0xEFFA0000
3273+
WP clear: CSPR0=0x101 (OK)
3274+
PPB: sector 1021 protected (0x723A), erasing all PPBs
3275+
PPB: erase complete
3276+
Erasing sector 1021...
3277+
Erase sector 1021: OK
3278+
...
31383279
Firmware Valid
3139-
Loading 1028 bytes to RAM at 19000
3140-
Failed parsing DTB to load.
3141-
Booting at 19000
3280+
Booting at 0x19000
31423281
Test App
3143-
3144-
0x00000001
3145-
0x00000002
3146-
0x00000003
3147-
0x00000004
3148-
0x00000005
3149-
0x00000006
3150-
0x00000007
3151-
...
31523282
```
31533283
3284+
The `12345678ABEFGDZIJQRSK` prefix is the assembly startup checkpoint
3285+
sequence (see UART Debug Checkpoints above). Without `DEBUG_UART=1`, only
3286+
the C-level output starting from `wolfBoot Init` is shown.
3287+
31543288
#### Flash Programming with Lauterbach
31553289
31563290
See these TRACE32 demo script files:

0 commit comments

Comments
 (0)