Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/test-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,24 @@ jobs:

nxp_t2080_test:
uses: ./.github/workflows/test-build-powerpc.yml
# T2080 RDB DDR register values are not yet populated (placeholders in
# nxp_t2080.h), so CI must select a board with complete DDR config.
nxp_t2080_test_naii_68ppc2:
uses: ./.github/workflows/test-build-powerpc.yml
with:
arch: ppc
config-file: ./config/examples/nxp-t2080.config
make-args: CFLAGS_EXTRA=-DBOARD_NAII_68PPC2

# VPX3-152 compile test: validates board-specific code paths build cleanly.
# Uses default config addresses (128MB layout); real hardware needs the
# VPX3-152 address overrides uncommented in .config.
nxp_t2080_vpx3152_test:
uses: ./.github/workflows/test-build-powerpc.yml
with:
arch: ppc
config-file: ./config/examples/nxp-t2080.config
make-args: CFLAGS_EXTRA=-DBOARD_CW_VPX3152

nxp_ls1028a_test:
uses: ./.github/workflows/test-build.yml
Expand Down
121 changes: 83 additions & 38 deletions docs/Targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -4009,16 +4009,28 @@ Flash factory_custom.bin to NOR base 0xE800_0000

## NXP QorIQ T2080 PPC

The NXP QorIQ T2080 is a PPC e6500 based processor (four cores). Support has been tested with the NAII 68PPC2.
The NXP QorIQ T2080 is a PPC e6500 based processor (four cores). Three board
variants are supported:

| Board | Config Define | Oscillator | DDR | NOR Flash |
|-------|---------------|-----------|-----|-----------|
| T2080 RDB (default) | _(none)_ | 66.66 MHz | DDR3L SODIMM | 128 MB @ `0xE8000000` |
| Curtiss-Wright VPX3-152 | `BOARD_CW_VPX3152` | 66.667 MHz | 4 GB DDR3L | 256 MB @ `0xF0000000` |
| NAII 68PPC2 | `BOARD_NAII_68PPC2` | 100 MHz | 8 GB DDR3 | 128 MB @ `0xE8000000` |

> **Note:** The T2080 RDB DDR register values are placeholder stubs (all zeros
> with TODO comments in `hal/nxp_t2080.h`). DDR initialization will not succeed
> until you populate them from a U-Boot register dump. The NAII 68PPC2 and
> CW VPX3-152 DDR configs are populated and tested.

Example configuration: [/config/examples/nxp-t2080.config](/config/examples/nxp-t2080.config).
Stock layout is default; for NAII 68PPC2, uncomment the "# NAII 68PPC2:" lines and comment the stock lines.
See [Board Selection](#board-selection) below for per-board setup.

### Design NXP T2080 PPC

The QorIQ requires a Reset Configuration Word (RCW) to define the boot parameters, which resides at the start of the flash (0xE8000000).
The QorIQ requires a Reset Configuration Word (RCW) to define the boot parameters, which resides at the start of the flash (`0xE8000000` for 128 MB boards, `0xF0000000` for the 256 MB CW VPX3-152).

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()`.
The flash boot entry point is the last 4 bytes of the NOR flash region (`0xEFFFFFFC` for 128 MB flash, `0xFFFFFFFC` for 256 MB flash), 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()`.

#### Boot Sequence and Hardware Constraints

Expand All @@ -4041,7 +4053,7 @@ CPC SRAM is unreliable for stores on cold power-on — L1 dirty-line evictions
through CoreNet to CPC cause bus errors (silent CPU checkstop with `MSR[ME]=0`).
The fix (matching U-Boot) uses L1 locked D-cache as the initial 16KB stack:
`dcbz` allocates cache lines without bus reads, `dcbtls` locks them so they
are never evicted. The locked lines at `L1_CACHE_ADDR` (0xF8E00000) are
are never evicted. The locked lines at `L1_CACHE_ADDR` (`0xF8E00000`; `0xEE800000` on VPX3-152) are
entirely core-local. After DDR init in `hal_init()`, the stack relocates to
DDR and the CPC switches from SRAM to L3 cache mode.

Expand All @@ -4052,9 +4064,16 @@ boot, allowing L1 I-cache to cache instruction fetches while preventing
speculative prefetch to the IFC. C code switches to `MAS2_I | MAS2_G` during
flash write/erase (command mode), then `MAS2_M` for full caching afterward.

**CCSRBAR Relocation (CW VPX3-152 only)**

The default CCSRBAR at `0xFE000000` (16 MB) falls within the VPX3-152's 256 MB
flash VA range (`0xF0000000`–`0xFFFFFFFF`). The startup assembly relocates
CCSRBAR to `0xEF000000` (just below flash). The CPC SRAM and L1 cache addresses
are also relocated to `0xEE900000`/`0xEE800000` to avoid overlap.

**RAMFUNCTION Constraints**

The NAII 68PPC2 NOR flash (two S29GL01GS x8 in parallel, 16-bit bus) enters
The NOR flash (two S29GL01GS x8 in parallel, 16-bit bus) enters
command mode bank-wide — instruction fetches during program/erase return status
data instead of code. All flash write/erase functions are marked `RAMFUNCTION`,
placed in `.ramcode`, copied to DDR, and remapped via TLB9. Key rules:
Expand Down Expand Up @@ -4094,30 +4113,38 @@ machine check (exceptions instead of checkstop), debug, and recoverable
interrupt enable. Branch prediction (BUCSR) is deferred to `hal_init()` after
DDR stack relocation.

**UART Debug Checkpoints (`DEBUG_UART=1`)**
### Building wolfBoot for NXP T2080 PPC

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`).

#### Board Selection

Assembly startup emits characters to UART0 (0xFE11C500, 115200 baud):
Copy the example config and select your board:

**T2080 RDB (default):**
```
1 - CPC invalidate start A - L2 cluster enable start
2 - CPC invalidate done B - L2 cluster enabled
3 - CPC SRAM configured E - L1 cache setup
4 - SRAM LAW configured F - L1 I-cache enabled
5 - Flash TLB configured G - L1 D-cache enabled
6 - CCSRBAR TLB configured D - Stack ready (L1 locked cache)
7 - SRAM TLB configured Z - About to jump to C code
8 - CPC enabled
cp ./config/examples/nxp-t2080.config .config
```

### Building wolfBoot for NXP T2080 PPC
**Curtiss-Wright VPX3-152:**
```
cp ./config/examples/nxp-t2080.config .config
```
Then in `.config`, uncomment `CFLAGS_EXTRA+=-DBOARD_CW_VPX3152` and all lines
marked with `# CW VPX3-152` (flash offset, SRAM address, origin, partition addresses,
DTS addresses).

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`).
**NAII 68PPC2:**
```
cp ./config/examples/nxp-t2080.config .config
```
Then in `.config`, uncomment `CFLAGS_EXTRA+=-DBOARD_NAII_68PPC2`.

#### Build

The `make` creates a `factory.bin` image that can be programmed at `0xE8080000`
(For NAII 68PPC2, first edit `nxp-t2080.config` to uncomment the NAII 68PPC2 lines.)
The `make` creates a `factory.bin` image that can be programmed to the application partition address.

```
cp ./config/examples/nxp-t2080.config .config
make clean
make keytools
make
Expand Down Expand Up @@ -4146,19 +4173,31 @@ CROSS_COMPILE_PATH=/opt/fsl-qoriq/2.0/sysroots/ppce6500-fsl-linux/usr

### Programming NXP T2080 PPC

NOR Flash Region: `0xE8000000 - 0xEFFFFFFF` (128 MB)
NOR Flash Regions:
- **T2080 RDB / NAII 68PPC2**: `0xE8000000 - 0xEFFFFFFF` (128 MB)
- **CW VPX3-152**: `0xF0000000 - 0xFFFFFFFF` (256 MB)

Flash Layout (with files):
Flash Layout (T2080 RDB / NAII 68PPC2, 128 MB flash):

| Description | File | Address |
| ----------- | ---- | ------- |
| Reset Configuration Word (RCW) | `68PPC2_RCW_v0p7.bin` | `0xE8000000` |
| Reset Configuration Word (RCW) | _(board-specific)_ | `0xE8000000` |
| Frame Manager Microcode | `fsl_fman_ucode_t2080_r1.0.bin` | `0xE8020000` |
| Signed Application | `test-app/image_v1_signed.bin` | `0xE8080000` |
| wolfBoot | `wolfboot.bin` | `0xEFF40000` |
| Boot Entry Point (with offset jump to init code) | | `0xEFFFFFFC` |
| wolfBoot | `wolfboot.bin` | `0xEFFE0000` |
| Boot Entry Point (offset jump to init code) | | `0xEFFFFFFC` |

Flash Layout (CW VPX3-152, 256 MB flash):

| Description | File | Address |
| ----------- | ---- | ------- |
| Reset Configuration Word (RCW) | _(board-specific)_ | `0xF0000000` |
| Frame Manager Microcode | `fsl_fman_ucode_t2080_r1.0.bin` | `0xF0020000` |
| Signed Application | `test-app/image_v1_signed.bin` | `0xF0080000` |
| wolfBoot | `wolfboot.bin` | `0xFFFE0000` |
| Boot Entry Point (offset jump to init code) | | `0xFFFFFFFC` |

Or program the `factory.bin` to `0xE8080000`
Or program the `factory.bin` to the application partition address.

Example Boot Debug Output (with `DEBUG_UART=1`):

Expand Down Expand Up @@ -4197,11 +4236,11 @@ See these TRACE32 demo script files:
```
DO flash_cfi.cmm

FLASH.ReProgram 0xEFF40000--0xEFFFFFFF /Erase
Data.LOAD.binary wolfboot.bin 0xEFF40000
FLASH.ReProgram 0xEFFE0000--0xEFFFFFFF /Erase
Data.LOAD.binary wolfboot.bin 0xEFFE0000
FLASH.ReProgram.off

Data.LOAD.binary wolfboot.bin 0xEFF40000 /Verify
Data.LOAD.binary wolfboot.bin 0xEFFE0000 /Verify
```

Note: To disable the flash protection bits use:
Expand All @@ -4219,7 +4258,11 @@ Data.Set 0xE8000000 %W 0x9090
Data.Set 0xE8000000 %W 0x0000
```

#### Flash Programming with CodeWarrior TAP
#### Flash Programming with CodeWarrior TAP (Experimental)

> **Note:** CodeWarrior TAP debugging has not been validated for this target.
> Lauterbach TRACE32 is the recommended debug probe. The following steps are
> provided for reference only.

In CodeWarrior use the `Flash Programmer` tool (see under Commander View -> Miscellaneous)
* Connection: "CodeWarrior TAP Connection"
Expand All @@ -4231,11 +4274,11 @@ In CodeWarrior use the `Flash Programmer` tool (see under Commander View -> Misc

```
tftp 1000000 wolfboot.bin
protect off eff40000 +C0000
erase eff40000 +C0000
cp.b 1000000 eff40000 C0000
protect on eff40000 +C0000
cmp.b 1000000 eff40000 C0000
protect off effe0000 +20000
erase effe0000 +20000
cp.b 1000000 effe0000 20000
protect on effe0000 +20000
cmp.b 1000000 effe0000 20000
```

### Debugging NXP T2080 PPC
Expand Down Expand Up @@ -4265,9 +4308,11 @@ sYmbol.SourcePATH.SetBaseDir ~/wolfBoot
Data.LOAD.Elf wolfboot.elf /NoCODE /StripPART "/home/username/wolfBoot/"
```

#### CodeWarrior TAP
#### CodeWarrior TAP (Experimental)

This is an example for debugging the T2080 with CodeWarrior TAP, however we were not successful using it. The Lauterbach is what we ended up using to debug.
> **Note:** CodeWarrior TAP debugging has not been validated for this target.
> Lauterbach TRACE32 is the recommended debug probe. The following steps are
> provided for reference only.

Start GDB Proxy:

Expand Down
22 changes: 20 additions & 2 deletions hal/nxp_t2080.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,9 @@ static void hal_reconfigure_cpc_as_cache(void)
*dst++ = *src++;
}

/* Ensure all stores have drained before flushing cache lines */
__asm__ __volatile__("sync" ::: "memory");

/* Flush D-cache and invalidate I-cache for the DDR copy */
flush_cache(DDR_RAMCODE_ADDR, ramcode_size);

Expand Down Expand Up @@ -663,6 +666,13 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
int ret = 0;
uint32_t i, sector, offset, nwords;
const uint32_t width_bytes = FLASH_CFI_WIDTH / 8;
uint32_t addr_off = address;

/* Bounds check */
if (addr_off >= FLASH_BASE_ADDR)
addr_off -= FLASH_BASE_ADDR;
if (addr_off + (uint32_t)len > FLASH_BANK_SIZE)
return -1;

/* Enforce alignment to flash bus width */
if ((address % width_bytes) != 0 || (len % width_bytes) != 0) {
Expand Down Expand Up @@ -741,6 +751,13 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
{
int ret = 0;
uint32_t sector;
uint32_t addr_off = address;

/* Bounds check */
if (addr_off >= FLASH_BASE_ADDR)
addr_off -= FLASH_BASE_ADDR;
if (addr_off + (uint32_t)len > FLASH_BANK_SIZE)
return -1;

/* adjust for flash base */
if (address >= FLASH_BASE_ADDR)
Expand Down Expand Up @@ -848,7 +865,7 @@ extern uint32_t _bootpg_addr;
static void hal_mp_up(uint32_t bootpg, uint32_t spin_table_ddr)
{
uint32_t all_cores, active_cores, whoami;
int timeout = 50, i;
int timeout = 10000, i; /* 10000 * 100us = 1s, matches U-Boot convention */

whoami = get32(PIC_WHOAMI); /* Get current running core number */
all_cores = ((1 << CPU_NUMCORES) - 1); /* mask of all cores */
Expand Down Expand Up @@ -990,7 +1007,8 @@ static void hal_mp_init(void)

void hal_prepare_boot(void)
{

/* Intentionally empty: pre-boot cleanup (cache flush, interrupt disable)
* is handled by boot_ppc.c:do_boot(). */
}

#ifdef MMU
Expand Down
7 changes: 6 additions & 1 deletion hal/nxp_t2080.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,12 @@ enum ifc_amask_sizes {
#define DDR_ERR_INT_EN_VAL 0x0000001D
#define DDR_ERR_SBE_VAL 0x00010000
#else
/* T2080 RDB: DDR register values */
/* T2080 RDB DDR register values are not yet populated.
* To complete this, boot U-Boot on T2080 RDB and run the register dump
* commands below, then replace the 0x00000000 placeholders with actual values. */
#ifdef ENABLE_DDR
#error "T2080 RDB DDR register values not populated. See TODO comments in nxp_t2080.h. Define BOARD_CW_VPX3152 or BOARD_NAII_68PPC2, or fill in DDR values from a U-Boot register dump."
#endif
/* TODO: Fill ALL values from Phase 1 U-Boot register dump:
* md.l 0xfe008000 4; md.l 0xfe008010 4 (CS BNDS)
* md.l 0xfe008080 4; md.l 0xfe0080c0 4 (CS CONFIG)
Expand Down
8 changes: 4 additions & 4 deletions src/boot_ppc_mp.S
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ branch_prediction:
mr r4, r0
mr r5, r4
#endif
slwi r8, r5, 6 /* spin table is padded to 64 bytes */
slwi r8, r5, 6 /* multiply by ENTRY_SIZE (64 bytes) */
/* use r10 for the spin table base address */
add r10, r3, r8

Expand Down Expand Up @@ -268,7 +268,7 @@ _second_half_boot_page:
li r8, 3
stw r8, ENTRY_ADDR_LOWER(r10)

/* mask branch address (64MB) to setup tlb */
/* Align branch address to 64MB boundary for TLB mapping below */
rlwinm r12, r4, 0, 0, 5

/* setup registers before jump */
Expand All @@ -280,7 +280,7 @@ _second_half_boot_page:
li r4, 0
li r5, 0
li r6, 0
lis r7, (64 * 1024 * 1024)@h
lis r7, (64 * 1024 * 1024)@h /* r7 = IMA size (64MB per ePAPR) */
li r8, 0
li r9, 0

Expand Down Expand Up @@ -309,7 +309,7 @@ _second_half_boot_page:
rfi

/* Reserve space for spin table entries */
.align 6 /* 64-bytes */
.align 6 /* 64-byte alignment for spin table entries (ENTRY_SIZE) */
.globl _spin_table
_spin_table:
.space CPU_NUMCORES * ENTRY_SIZE
Expand Down
18 changes: 15 additions & 3 deletions src/boot_ppc_start.S
Original file line number Diff line number Diff line change
Expand Up @@ -341,14 +341,26 @@ setup_interrupts:
ori r9, r9, (CCSRBAR + 0x1000)@l

create_temp_ccsr:
/* Create a temporary TLB entry for new and old location */
/* CCSRBAR: TLB 0, Entry 0, Supervisor R/W, IG, TS=0, 4KB */
/* Create temporary TLB0 entries for CCSRBAR relocation.
*
* TLB0 on e6500 is 4-way set-associative (2048 entries, 512 sets).
* The "esel" parameter selects the WAY within a set; the SET is
* determined by the virtual address (EPN). These two entries map
* different EPNs (CCSRBAR vs CCSRBAR+0x1000), so they fall in
* different TLB0 sets and do not overwrite each other.
*
* We use different ways (0 and 1) for visual clarity. Both entries
* are cleaned up by the TLB0 flash-invalidate (MMUCSR0) after
* relocation completes. */

/* CCSRBAR new location: TLB0 Way 0, Supervisor R/W, IG, TS=0, 4KB */
set_tlb(0, 0,
CCSRBAR, CCSRBAR, CCSRBAR_PHYS_HIGH,
MAS3_SR | MAS3_SW, MAS2_I | MAS2_G, 0,
BOOKE_PAGESZ_4K, 0, r3);

set_tlb(0, 0,
/* CCSRBAR old location: TLB0 Way 1, Supervisor R/W, IG, TS=0, 4KB */
set_tlb(0, 1,
CCSRBAR + 0x1000, CCSRBAR_DEF, 0,
MAS3_SR | MAS3_SW, MAS2_I | MAS2_G, 0,
BOOKE_PAGESZ_4K, 0, r3);
Expand Down
Loading