Skip to content

Commit 246b8d2

Browse files
committed
Fixes for power on L2 SRAM
1 parent cc4a117 commit 246b8d2

3 files changed

Lines changed: 99 additions & 15 deletions

File tree

arch.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,7 @@ ifeq ($(TARGET),nxp_t2080)
995995
ARCH_FLAGS=-mhard-float -mcpu=e6500
996996
CFLAGS+=$(ARCH_FLAGS)
997997
BIG_ENDIAN=1
998-
CFLAGS+=-DMMU -DWOLFBOOT_FDT -DWOLFBOOT_DUALBOOT
998+
CFLAGS+=-DMMU -DWOLFBOOT_FDT -DWOLFBOOT_DUALBOOT -DDEBUG_UART
999999
CFLAGS+=-pipe # use pipes instead of temp files
10001000
CFLAGS+=-feliminate-unused-debug-types
10011001
LDFLAGS+=$(ARCH_FLAGS)

hal/nxp_t2080.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,16 @@ static void hal_reconfigure_cpc_as_cache(void)
455455
__asm__ __volatile__("sync; isync" ::: "memory");
456456
while (*cpc_csr0 & CPCCSR0_CPCFI);
457457

458-
/* CPC remains enabled (CPCE/CPCPE preserved), now all 2MB as cache */
458+
/* Step 8: Enable parity/ECC now that SRAM is released and cache is clean.
459+
* CPCPE was intentionally omitted during ASM init to avoid ECC machine
460+
* checks on uninitialized SRAM (cold power cycle). Safe to enable here:
461+
* SRAM mode is off, CPC is freshly invalidated, no stale data. */
462+
reg = *cpc_csr0;
463+
reg |= CPCCSR0_CPCPE;
464+
*cpc_csr0 = reg;
465+
__asm__ __volatile__("sync; isync" ::: "memory");
466+
467+
/* CPC is now fully enabled (CPCE|CPCPE), all 2MB as L3 cache */
459468

460469
#ifdef DEBUG_UART
461470
wolfBoot_printf("CPC: Released SRAM, full 2MB L2 cache enabled\n");

src/boot_ppc_start.S

Lines changed: 88 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,62 @@ All TLBs for boot will be in TLB1 and supervisor mode (not user)
8787
ori reg, reg, (addr)@l
8888
#endif
8989

90+
/* =========================================================================
91+
* Early ASM UART debug — initializes UART0 before any C code runs.
92+
* Only active when DEBUG_UART is defined (add -DDEBUG_UART to CFLAGS).
93+
* UART0 = CCSRBAR + 0x11C500 = 0xFE11C500 (CCSRBAR TLB must be set first).
94+
* Divisor = 163 (0xA3) gives 115200 baud at SYS_CLK / 16 / 163 ≈ 115200.
95+
* Saves/restores r5 and r6 via SPRG4/SPRG5 (SPR 276/277) so that caller
96+
* register state (e.g. r5 = L2_CLUSTER_BASE, r1 = CPC_BASE) is preserved.
97+
* SPRG4/SPRG5 are free before any OS loads.
98+
* ========================================================================= */
99+
#if defined(DEBUG_UART) && defined(TARGET_nxp_t2080)
100+
.macro uart_init_asm_debug
101+
mtspr 276, r5 /* SPRG4 = save r5 */
102+
mtspr 277, r6 /* SPRG5 = save r6 */
103+
LOAD_ADDR32(r5, 0xFE11C500)
104+
li r6, 0x80 /* DLAB=1 to access divisor regs */
105+
stb r6, 3(r5) /* LCR = 0x80 */
106+
eieio
107+
li r6, 163 /* DLL = 163 (115200 @ 600 MHz SYS_CLK) */
108+
stb r6, 0(r5) /* DLL */
109+
li r6, 0
110+
stb r6, 1(r5) /* DLM = 0 */
111+
eieio
112+
li r6, 0x03 /* 8N1, clear DLAB */
113+
stb r6, 3(r5) /* LCR = 0x03 */
114+
eieio
115+
li r6, 0x07 /* enable + reset TX/RX FIFOs */
116+
stb r6, 2(r5) /* FCR */
117+
li r6, 0
118+
stb r6, 1(r5) /* IER = 0 (no interrupts) */
119+
eieio
120+
mfspr r5, 276 /* restore r5 from SPRG4 */
121+
mfspr r6, 277 /* restore r6 from SPRG5 */
122+
.endm
123+
/* Print one character. char must be an immediate (e.g. '\r', '1').
124+
* Saves/restores r5 and r6 via SPRG4/SPRG5 to preserve caller state. */
125+
.macro uart_putc_debug char
126+
mtspr 276, r5 /* SPRG4 = save r5 */
127+
mtspr 277, r6 /* SPRG5 = save r6 */
128+
LOAD_ADDR32(r5, 0xFE11C500)
129+
.L_up_wait_\@:
130+
lbz r6, 5(r5) /* read LSR */
131+
andi. r6, r6, 0x20 /* check THRE (TX hold reg empty) */
132+
beq .L_up_wait_\@
133+
li r6, \char
134+
stb r6, 0(r5) /* write to THR */
135+
eieio
136+
mfspr r5, 276 /* restore r5 from SPRG4 */
137+
mfspr r6, 277 /* restore r6 from SPRG5 */
138+
.endm
139+
#else
140+
.macro uart_init_asm_debug
141+
.endm
142+
.macro uart_putc_debug char
143+
.endm
144+
#endif /* DEBUG_UART && TARGET_nxp_t2080 */
145+
90146
/* variables from linker script */
91147
.global _start_vector
92148
.global isr_empty
@@ -566,6 +622,10 @@ flash_tlb:
566622
* Note: TLB must be created BEFORE CPC enable (original working sequence)
567623
* ========================================================================= */
568624
#if defined(ENABLE_L2_CACHE) && defined(L2SRAM_ADDR) && (defined(CORE_E5500) || defined(CORE_E6500))
625+
uart_init_asm_debug /* init UART before any SRAM exists */
626+
uart_putc_debug '\r'
627+
uart_putc_debug '\n'
628+
uart_putc_debug '1' /* checkpoint 1: before CPC invalidate */
569629
cpc_setup_sram:
570630
/* T2080RM: 8.4.2.2 - CPC initialization sequence:
571631
* Step 1: Flash invalidate CPC and clear locks (CPCFI | CPCLFC)
@@ -590,6 +650,7 @@ cpc_poll_invalidate:
590650
and. r2, r2, r0
591651
bne cpc_poll_invalidate
592652
isync
653+
uart_putc_debug '2' /* checkpoint 2: CPC invalidate done */
593654

594655
/* Step 3: Configure CPC SRAM control registers */
595656
li r0, 0
@@ -601,11 +662,13 @@ cpc_poll_invalidate:
601662
stw r0, CPCSRCR0(r1)
602663
mbar
603664
isync
665+
uart_putc_debug '3' /* checkpoint 3: CPCSRCR configured */
604666
#endif /* ENABLE_L2_CACHE && L2SRAM_ADDR */
605667

606668
/* Step 3: Configure LAW for SRAM */
607669
#ifdef INITIAL_SRAM_ADDR
608670
#ifndef INITIAL_SRAM_NO_LAW
671+
uart_putc_debug '4' /* checkpoint 4: before SRAM LAW */
609672
init_sram_law:
610673
/* CPC SRAM uses LAW 2 - DO NOT reuse this LAW index elsewhere!
611674
* The stack resides in CPC SRAM; overwriting this LAW causes crashes. */
@@ -630,13 +693,15 @@ init_sram_law:
630693
/* Step 4: Create TLB for SRAM - BEFORE CPC enable (original working order)
631694
* This is for e5500/e6500 CPC SRAM only. e500 has its own init_sram_tlb below. */
632695
#if defined(INITIAL_SRAM_ADDR) && (defined(CORE_E5500) || defined(CORE_E6500))
696+
uart_putc_debug '5' /* checkpoint 5: before set_tlb for SRAM */
633697
init_sram_tlb:
634698
/* Initial SRAM: TLB 1, Entry 9, Supervisor X/R/W, M, TS=0, IPROT
635699
* Original working T2080 code (commit 11f46a51) used MAS2_M. */
636700
set_tlb(1, 9,
637701
INITIAL_SRAM_ADDR, INITIAL_SRAM_ADDR, 0,
638702
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_M, 0,
639703
INITIAL_SRAM_BOOKE_SZ, 1, r3);
704+
uart_putc_debug '6' /* checkpoint 6: set_tlb for SRAM done */
640705
#endif /* INITIAL_SRAM_ADDR && (CORE_E5500 || CORE_E6500) */
641706

642707
/* Step 5: Enable CPC after TLB is configured */
@@ -645,10 +710,15 @@ cpc_enable:
645710
/* R1 = CPC base */
646711
LOAD_ADDR32(r1, CPC_BASE)
647712

648-
/* Enable CPC with parity */
649-
lis r0, (CPCCSR0_CPCE | CPCCSR0_CPCPE)@h
713+
/* Enable CPC WITHOUT parity in SRAM mode.
714+
* SRAM is uninitialized at cold power cycle; enabling CPCPE causes CPC
715+
* to read-modify-write ECC on the first dcbz, which reads uninitialized
716+
* SRAM and triggers an ECC/parity machine check.
717+
* Parity is enabled later when CPC transitions to full cache mode in C. */
718+
lis r0, (CPCCSR0_CPCE)@h
650719
mbar
651720
isync
721+
uart_putc_debug '7' /* checkpoint 7: about to enable CPC */
652722
stw r0, CPCCSR0(r1)
653723
mbar
654724

@@ -658,6 +728,7 @@ cpc_poll_enable:
658728
andis. r2, r2, CPCCSR0_CPCE@h /* check CPCE bit */
659729
beq cpc_poll_enable
660730
isync
731+
uart_putc_debug '8' /* checkpoint 8: CPC enabled */
661732

662733
/* Disable speculation (Errata A-006593) */
663734
lwz r0, CPCHDBCR0(r1)
@@ -689,6 +760,7 @@ l2_poll_invclear:
689760
and. r4, r1, r4
690761
bne l2_poll_invclear
691762
isync
763+
uart_putc_debug 'A' /* checkpoint A: L2 invalidate done */
692764

693765
/* set stash id to (coreID * 2) + 32 + L2 (1) - only core 0 here */
694766
li r4, (32 + 1)
@@ -707,6 +779,7 @@ l2_poll_enable:
707779
andis. r3, r3, L2CSR0_L2E@h /* check bit 31 (L2E) */
708780
beq l2_poll_enable /* loop until enabled */
709781
isync
782+
uart_putc_debug 'B' /* checkpoint B: L2 enabled */
710783

711784
#elif defined(CORE_E5500) /* --- L2 E5500 --- */
712785
l2_setup_cache:
@@ -783,6 +856,7 @@ init_sram_tlb:
783856

784857

785858
#ifdef ENABLE_L1_CACHE
859+
uart_putc_debug 'E' /* checkpoint E: entering L1 setup */
786860
setup_l1:
787861
#if defined(CORE_E5500) || defined(CORE_E6500)
788862
/* set L1 stash id = 32: (coreID * 2) + 32 + L1 CT (0) */
@@ -792,9 +866,11 @@ setup_l1:
792866
#ifndef BUILD_LOADER_STAGE1
793867
/* L1 Instruction Cache */
794868
bl icache_enable;
869+
uart_putc_debug 'F' /* checkpoint F: icache_enable returned */
795870
#endif
796871
/* L1 Data Cache */
797872
bl dcache_enable;
873+
uart_putc_debug 'G' /* checkpoint G: dcache_enable returned */
798874

799875
#ifdef L1_CACHE_ADDR
800876
l1_tlb:
@@ -840,17 +916,15 @@ cache_sram_init_loop:
840916
bdnz cache_sram_init_loop
841917
#elif defined(L2SRAM_ADDR)
842918
cache_sram_init:
843-
/* Zero CPC SRAM via dcbz.
844-
* With MAS2_M (memory-coherent), dcbz allocates zeroed cache lines.
845-
* This initializes SRAM and avoids ECC/parity issues from uninitialized data. */
846-
LOAD_ADDR32(r3, L2SRAM_ADDR)
847-
li r0, 0
848-
LOAD_ADDR32(r2, (L2SRAM_SIZE / CACHE_LINE_SIZE))
849-
mtctr r2
850-
1:
851-
dcbz r0, r3
852-
addi r3, r3, CACHE_LINE_SIZE
853-
bdnz 1b
919+
/* CPC SRAM: no dcbz init needed.
920+
* dcbz generates a coherent "allocate-and-zero" transaction on CoreNet.
921+
* On cold power cycle this transaction hangs (CPC SRAM does not support
922+
* it before the first regular store hits the SRAM). Since CPCPE (ECC)
923+
* is intentionally disabled in SRAM mode, there are no parity bits to
924+
* initialize. The stack stores in setup_stack below use regular stw,
925+
* which CPC SRAM handles correctly. */
926+
uart_putc_debug 'H' /* checkpoint H: skipping dcbz, entering setup_stack */
927+
uart_putc_debug 'C' /* checkpoint C: (skipped dcbz loop) */
854928
#endif /* L1_CACHE_ADDR */
855929

856930
setup_stack:
@@ -875,6 +949,7 @@ setup_stack:
875949
ori r3, r3, (MSR_CE | MSR_ME | MSR_DE)@l
876950
mtmsr r3
877951
isync
952+
uart_putc_debug 'D' /* checkpoint D: stack ready, entering C */
878953

879954
#ifdef USE_GOT
880955
GET_GOT

0 commit comments

Comments
 (0)