Skip to content

Commit ec28be7

Browse files
committed
Progress with T2080 port refresh
1 parent a90d60f commit ec28be7

5 files changed

Lines changed: 158 additions & 57 deletions

File tree

hal/nxp_ppc.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,17 @@
118118
#define ENABLE_L1_CACHE
119119
#define ENABLE_L2_CACHE
120120

121-
#define L2SRAM_ADDR (0xF8F00000UL) /* CPC as SRAM (1MB) */
122-
#define L2SRAM_SIZE (1024UL * 1024UL)
121+
/* T2080 CPC SRAM config - 512KB per T2080RM */
122+
#define L2SRAM_ADDR (0xF8F80000UL) /* CPC as SRAM (512KB) */
123+
#define L2SRAM_SIZE (512UL * 1024UL)
123124

124125
#define INITIAL_SRAM_ADDR L2SRAM_ADDR
125126
/* CPC SRAM transactions traverse the CoreNet interconnect, which
126-
* requires a LAW to route them. LAW_TRGT_DDR_1 is used as a routing
127-
* target; the CPC intercepts the transaction before it reaches DDR. */
128-
#define INITIAL_SRAM_LAW_SZ LAW_SIZE_1MB
127+
* requires a LAW to route them. LAW_TRGT_DDR_1 (0x10) is the CPC
128+
* target per T2080RM Table 2-2 (Target ID Assignments). */
129+
#define INITIAL_SRAM_LAW_SZ LAW_SIZE_512KB
129130
#define INITIAL_SRAM_LAW_TRGT LAW_TRGT_DDR_1
130-
#define INITIAL_SRAM_BOOKE_SZ BOOKE_PAGESZ_1M
131+
#define INITIAL_SRAM_BOOKE_SZ BOOKE_PAGESZ_512K
131132

132133
#define ENABLE_INTERRUPTS
133134

@@ -303,6 +304,7 @@
303304
#ifdef CORE_E6500
304305
/* T2080: 2MB CPC, 16 ways, 128KB per way */
305306
#define CPCSRCR0_SRAMSZ_256 (0x1 << 1) /* ways 14-15, 256KB */
307+
#define CPCSRCR0_SRAMSZ_512 (0x2 << 1) /* ways 12-15, 512KB */
306308
#define CPCSRCR0_SRAMSZ_1024 (0x3 << 1) /* ways 8-15, 1MB */
307309
#define CPCSRCR0_SRAMSZ_2048 (0x4 << 1) /* ways 0-15, 2MB */
308310
#else /* CORE E5500 */
@@ -691,12 +693,12 @@ extern void dcache_disable(void);
691693
#else
692694
/* Assembly version */
693695
#ifdef CORE_E6500
694-
/* e6500 has 64-bit MAS registers - must clear upper 32 bits.
695-
* Using lis would sign-extend values with bit 15 set (e.g., 0xC000xxxx).
696-
* Use li 0; oris; ori pattern for all MAS registers. */
696+
/* e6500 has 64-bit MAS registers. On 64-bit PPC, lis sign-extends to 64 bits.
697+
* Any MAS value with bit 31 set (MAS1=0xC..., MAS2/MAS3 high addresses) gets
698+
* upper 32 bits = 0xFFFFFFFF. Hardware may require reserved upper bits = 0.
699+
* Use "li 0; oris; ori" pattern for MAS1, MAS2, MAS3 to avoid sign-extension. */
697700
#define set_tlb(tlb, esel, epn, rpn, urpn, perms, winge, ts, tsize, iprot, reg) \
698-
li reg, 0; \
699-
oris reg, reg, BOOKE_MAS0(tlb, esel, 0)@h; \
701+
lis reg, BOOKE_MAS0(tlb, esel, 0)@h; \
700702
ori reg, reg, BOOKE_MAS0(tlb, esel, 0)@l; \
701703
mtspr MAS0, reg;\
702704
li reg, 0; \

hal/nxp_t2080.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ static void hal_flash_init(void)
221221
#endif /* ENABLE_IFC */
222222
}
223223

224-
static void hal_ddr_init(void)
224+
void hal_ddr_init(void)
225225
{
226226
#ifdef ENABLE_DDR
227227
uint32_t reg;
@@ -358,8 +358,8 @@ static void hal_cpld_init(void)
358358
set32(IFC_AMASK(3), IFC_AMASK_64KB);
359359
set32(IFC_CSOR(3), 0);
360360

361-
/* IFC - CPLD */
362-
set_law(2, CPLD_BASE_PHYS_HIGH, CPLD_BASE,
361+
/* IFC - CPLD (use LAW 5; LAW 2 is used for CPC SRAM) */
362+
set_law(5, CPLD_BASE_PHYS_HIGH, CPLD_BASE,
363363
LAW_TRGT_IFC, LAW_SIZE_4KB, 1);
364364

365365
/* CPLD - TBL=1, Entry 17 */

hal/nxp_t2080.ld

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ MEMORY
1313
{
1414
FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@
1515

16-
/* CPC as SRAM - 1MB */
17-
RAM (rwx) : ORIGIN = 0xF8F00000, LENGTH = 0x100000
16+
/* CPC as SRAM - 512KB (T2080 supports up to 2MB, using 512KB)
17+
* Layout: .ramcode at bottom, stack grows down from top */
18+
RAM (rwx) : ORIGIN = 0xF8F80000, LENGTH = 0x80000
1819

1920
/* DDR - 2GB */
2021
DRAM (rwx) : ORIGIN = 0x00000000, LENGTH = 0x7FFFFFFF
@@ -57,7 +58,21 @@ SECTIONS
5758
.gnu.hash : { *(.gnu.hash) }
5859
.rela.dyn : { *(.rela.dyn) }
5960

60-
_stored_data = .;
61+
/* Store flash location for .ramcode copy */
62+
_stored_ramcode = .;
63+
64+
/* RAMFUNCTION code in CPC SRAM - copied before DDR is used
65+
* This ensures memcpy/memmove are available early */
66+
.ramcode : AT (_stored_ramcode)
67+
{
68+
_start_ramcode = .;
69+
KEEP(*(.ramcode))
70+
. = ALIGN(4);
71+
_end_ramcode = .;
72+
} > RAM
73+
74+
/* Calculate where .data starts in flash (after .ramcode) */
75+
_stored_data = _stored_ramcode + (_end_ramcode - _start_ramcode);
6176

6277
.data : AT (_stored_data)
6378
{
@@ -68,8 +83,6 @@ SECTIONS
6883
*(.plt*)
6984
*(.dynamic)
7085
. = ALIGN(4);
71-
KEEP(*(.ramcode))
72-
. = ALIGN(4);
7386
_end_data = .;
7487
} > DRAM
7588

@@ -88,5 +101,7 @@ SECTIONS
88101

89102
}
90103

91-
PROVIDE(_start_heap = ORIGIN(RAM));
104+
/* Heap starts after .ramcode in CPC SRAM */
105+
PROVIDE(_start_heap = _end_ramcode);
106+
/* Stack at top of CPC SRAM, grows down */
92107
PROVIDE(_end_stack = ORIGIN(RAM) + (LENGTH(RAM)) );

src/boot_ppc.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ extern unsigned int __bss_end__;
3131
extern unsigned int _stored_data;
3232
extern unsigned int _start_data;
3333
extern unsigned int _end_data;
34+
/* .ramcode section (RAMFUNCTION) - may be in separate memory region */
35+
extern unsigned int _stored_ramcode;
36+
extern unsigned int _start_ramcode;
37+
extern unsigned int _end_ramcode;
3438

3539
extern void main(void);
3640
extern void hal_early_init(void);
@@ -124,12 +128,33 @@ void boot_entry_C(void)
124128
volatile const unsigned int *src;
125129
volatile unsigned int *end;
126130

131+
/* Copy .ramcode section FIRST - to CPC SRAM which is already available.
132+
* This makes RAMFUNCTION code (memcpy, memmove) available before DDR.
133+
* Use volatile to prevent compiler from transforming to memcpy call. */
134+
src = (volatile const unsigned int*)&_stored_ramcode;
135+
dst = (volatile unsigned int*)&_start_ramcode;
136+
end = (volatile unsigned int*)&_end_ramcode;
137+
while (dst < end) {
138+
*dst = *src;
139+
dst++;
140+
src++;
141+
}
142+
143+
#ifndef BUILD_LOADER_STAGE1
144+
/* Flush D-cache and invalidate I-cache for .ramcode in CPC SRAM.
145+
* PowerPC I/D caches are not coherent — explicit dcbst+icbi required. */
146+
if ((uint32_t)&_end_ramcode > (uint32_t)&_start_ramcode) {
147+
flush_cache((uint32_t)&_start_ramcode,
148+
(uint32_t)&_end_ramcode - (uint32_t)&_start_ramcode);
149+
}
150+
#endif
151+
152+
/* Now initialize DDR and other hardware */
127153
hal_early_init();
128154

129-
/* Copy the .data section from flash to RAM.
155+
/* Copy the .data section from flash to DDR.
130156
* Use volatile to prevent the compiler from transforming this loop
131-
* into a memcpy() call — memcpy is RAMFUNCTION in .data and hasn't
132-
* been copied to DDR yet at this point. */
157+
* into a memcpy() call. */
133158
src = (volatile const unsigned int*)&_stored_data;
134159
dst = (volatile unsigned int*)&_start_data;
135160
end = (volatile unsigned int*)&_end_data;
@@ -140,12 +165,7 @@ void boot_entry_C(void)
140165
}
141166

142167
#ifndef BUILD_LOADER_STAGE1
143-
/* Flush D-cache and invalidate I-cache for .data region.
144-
* The .ramcode section (RAMFUNCTION code like memcpy) is within .data
145-
* and was just copied to DDR through D-cache. Without this flush, the
146-
* I-cache will fetch stale/uninitialized DDR content when calling
147-
* RAMFUNCTION code, causing instruction fetch failures.
148-
* PowerPC I/D caches are not coherent — explicit dcbst+icbi required. */
168+
/* Flush D-cache and invalidate I-cache for .data region in DDR. */
149169
flush_cache((uint32_t)&_start_data,
150170
(uint32_t)&_end_data - (uint32_t)&_start_data);
151171
#endif

src/boot_ppc_start.S

Lines changed: 92 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -560,70 +560,116 @@ flash_tlb:
560560
#endif
561561
#endif /* ENABLE_DDR */
562562

563+
/* =========================================================================
564+
* CPC SRAM Initialization
565+
* Order: 1) CPC invalidate, 2) CPCSRCR config, 3) LAW, 4) TLB, 5) CPC enable
566+
* Note: TLB must be created BEFORE CPC enable (original working sequence)
567+
* ========================================================================= */
568+
#if defined(ENABLE_L2_CACHE) && defined(L2SRAM_ADDR) && (defined(CORE_E5500) || defined(CORE_E6500))
569+
cpc_setup_sram:
570+
/* T2080RM: 8.4.2.2 - CPC initialization sequence:
571+
* Step 1: Flash invalidate CPC and clear locks (CPCFI | CPCLFC)
572+
* Step 2: Poll until invalidate completes
573+
* Step 3: Configure SRAM control registers (CPCSRCR1, CPCSRCR0)
574+
* Step 4: Configure LAW for SRAM routing (done after this block)
575+
* Step 5: Enable CPC with parity (CPCE | CPCPE)
576+
* Step 6: Create TLB for SRAM access
577+
* The LAW (DDR_1) provides CoreNet routing; CPC intercepts before DDR. */
578+
579+
/* R1 = CPC base - preserve across LAW setup */
580+
LOAD_ADDR32(r1, CPC_BASE)
581+
582+
/* Step 1: Flash invalidate CPC and clear all locks */
583+
lis r0, (CPCCSR0_CPCFI | CPCCSR0_CPCLFC)@h
584+
ori r0, r0, (CPCCSR0_CPCFI | CPCCSR0_CPCLFC)@l
585+
stw r0, CPCCSR0(r1)
586+
587+
/* Step 2: Poll until CPCFI and CPCLFC clear */
588+
cpc_poll_invalidate:
589+
lwz r2, CPCCSR0(r1)
590+
and. r2, r2, r0
591+
bne cpc_poll_invalidate
592+
isync
593+
594+
/* Step 3: Configure CPC SRAM control registers */
595+
li r0, 0
596+
stw r0, CPCSRCR1(r1) /* SRAM high address = 0 */
597+
/* SRAM low address - use LOAD_ADDR32 on e6500 to avoid sign extension */
598+
LOAD_ADDR32(r0, L2SRAM_ADDR)
599+
/* Enable SRAM and set size (must match L2SRAM_SIZE = 512KB) */
600+
ori r0, r0, (CPCSRCR0_SRAMSZ_512 | CPCSRCR0_SRAMEN)
601+
stw r0, CPCSRCR0(r1)
602+
mbar
603+
isync
604+
#endif /* ENABLE_L2_CACHE && L2SRAM_ADDR */
605+
606+
/* Step 3: Configure LAW for SRAM */
563607
#ifdef INITIAL_SRAM_ADDR
564608
#ifndef INITIAL_SRAM_NO_LAW
565609
init_sram_law:
566-
/* Intial SRAM LAW 2 */
610+
/* CPC SRAM uses LAW 2 - DO NOT reuse this LAW index elsewhere!
611+
* The stack resides in CPC SRAM; overwriting this LAW causes crashes. */
567612
#define INITIAL_SRAM_LAW (LAWAR_ENABLE | \
568613
LAWAR_TRGT_ID(INITIAL_SRAM_LAW_TRGT) | \
569614
INITIAL_SRAM_LAW_SZ)
570615
LOAD_ADDR32(r9, CCSRBAR + LAWBAR_BASE(2))
571616
li r0, 0 /* UPPER=0 */
572617
/* Use LOAD_ADDR32 on e6500 to avoid sign-extension for addresses >= 0x80000000 */
573-
LOAD_ADDR32(r1, INITIAL_SRAM_ADDR)
618+
LOAD_ADDR32(r3, INITIAL_SRAM_ADDR)
574619
LOAD_ADDR32(r2, INITIAL_SRAM_LAW)
575620
stw r0, 0(r9) /* LAWBARH */
576-
stw r1, 4(r9) /* LAWBARL */
621+
stw r3, 4(r9) /* LAWBARL */
577622
sync
578623
stw r2, 8(r9) /* LAWAR */
579624
/* read back LAWAR (per 2.3.2 Configuring Local Access Windows) */
580625
lwz r2, 8(r9)
581626
isync
582627
#endif /* !INITIAL_SRAM_NO_LAW */
628+
#endif /* INITIAL_SRAM_ADDR */
583629

630+
/* Step 4: Create TLB for SRAM - BEFORE CPC enable (original working order)
631+
* This is for e5500/e6500 CPC SRAM only. e500 has its own init_sram_tlb below. */
632+
#if defined(INITIAL_SRAM_ADDR) && (defined(CORE_E5500) || defined(CORE_E6500))
584633
init_sram_tlb:
585634
/* Initial SRAM: TLB 1, Entry 9, Supervisor X/R/W, M, TS=0, IPROT
586-
* CPC SRAM uses cacheable memory-coherent (M) access.
587-
* TLB is created BEFORE l2_setup_sram per old working code. */
635+
* Original working T2080 code (commit 11f46a51) used MAS2_M. */
588636
set_tlb(1, 9,
589637
INITIAL_SRAM_ADDR, INITIAL_SRAM_ADDR, 0,
590638
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_M, 0,
591639
INITIAL_SRAM_BOOKE_SZ, 1, r3);
592-
#endif
593-
594-
#ifdef ENABLE_L2_CACHE
640+
#endif /* INITIAL_SRAM_ADDR && (CORE_E5500 || CORE_E6500) */
595641

596-
#if defined(CORE_E5500) || defined(CORE_E6500) /* --- L2 E5500/E6500 --- */
597-
#ifdef L2SRAM_ADDR
598-
l2_setup_sram:
599-
/* T2080RM: 8.4.2.2 - CPC initialization
600-
* Configure SRAM control registers, then enable CPC with parity.
601-
* The LAW (DDR_1) provides CoreNet routing; CPC intercepts before DDR.
602-
* SRAM is zeroed later via dcbz through cacheable TLB (MAS2_M). */
642+
/* Step 5: Enable CPC after TLB is configured */
643+
#if defined(ENABLE_L2_CACHE) && defined(L2SRAM_ADDR) && (defined(CORE_E5500) || defined(CORE_E6500))
644+
cpc_enable:
603645
/* R1 = CPC base */
604646
LOAD_ADDR32(r1, CPC_BASE)
605647

606-
/* Configure CPC SRAM control registers */
607-
li r0, 0
608-
stw r0, CPCSRCR1(r1) /* SRAM high address = 0 */
609-
/* SRAM low address - use LOAD_ADDR32 on e6500 to avoid sign extension */
610-
LOAD_ADDR32(r0, L2SRAM_ADDR)
611-
/* Enable SRAM and set size (must match L2SRAM_SIZE) */
612-
ori r0, r0, (CPCSRCR0_SRAMSZ_1024 | CPCSRCR0_SRAMEN)
613-
stw r0, CPCSRCR0(r1)
614-
615648
/* Enable CPC with parity */
616649
lis r0, (CPCCSR0_CPCE | CPCCSR0_CPCPE)@h
617650
mbar
618651
isync
619652
stw r0, CPCCSR0(r1)
620653
mbar
621654

655+
/* Verify CPC is enabled by reading back CPCCSR0 */
656+
cpc_poll_enable:
657+
lwz r2, CPCCSR0(r1)
658+
andis. r2, r2, CPCCSR0_CPCE@h /* check CPCE bit */
659+
beq cpc_poll_enable
660+
isync
661+
622662
/* Disable speculation (Errata A-006593) */
623663
lwz r0, CPCHDBCR0(r1)
624664
oris r0, r0, CPCHDBCR0_SPEC_DIS@h
625665
stw r0, CPCHDBCR0(r1)
626-
#endif /* L2SRAM_ADDR */
666+
mbar
667+
isync
668+
#endif /* ENABLE_L2_CACHE && L2SRAM_ADDR */
669+
670+
#ifdef ENABLE_L2_CACHE
671+
#if defined(CORE_E5500) || defined(CORE_E6500) /* --- L2 E5500/E6500 --- */
672+
/* Note: CPC SRAM setup moved above for correct T2080RM sequence */
627673

628674
#if defined(CORE_E6500) /* --- L2 E6500 --- */
629675
l2_setup_cache:
@@ -653,6 +699,13 @@ l2_poll_invclear:
653699
isync
654700
LOAD_ADDR32(r4, (L2CSR0_L2E | L2CSR0_L2PE))
655701
stw r4, L2CSR0(r5)
702+
mbar
703+
704+
/* Verify L2 is enabled by reading back L2CSR0 */
705+
l2_poll_enable:
706+
lwz r3, L2CSR0(r5)
707+
andis. r3, r3, L2CSR0_L2E@h /* check bit 31 (L2E) */
708+
beq l2_poll_enable /* loop until enabled */
656709
isync
657710

658711
#elif defined(CORE_E5500) /* --- L2 E5500 --- */
@@ -714,6 +767,17 @@ l2_setup_sram:
714767
stw r1, L2SRBAR0(r5)
715768
mbar
716769
#endif /* L2SRAM_ADDR */
770+
771+
#ifdef INITIAL_SRAM_ADDR
772+
init_sram_tlb:
773+
/* Initial SRAM: TLB 1, Entry 9, Supervisor X/R/W, M, TS=0, IPROT
774+
* For e500, L2 SRAM uses cacheable memory-coherent (M) access.
775+
* TLB is created AFTER l2_setup_sram configures L2 as SRAM. */
776+
set_tlb(1, 9,
777+
INITIAL_SRAM_ADDR, INITIAL_SRAM_ADDR, 0,
778+
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_M, 0,
779+
INITIAL_SRAM_BOOKE_SZ, 1, r3);
780+
#endif /* INITIAL_SRAM_ADDR */
717781
#endif /* CORE_E500 */
718782
#endif /* ENABLE_L2_CACHE */
719783

@@ -776,9 +840,9 @@ cache_sram_init_loop:
776840
bdnz cache_sram_init_loop
777841
#elif defined(L2SRAM_ADDR)
778842
cache_sram_init:
779-
/* Zero CPC SRAM via cache (MAS2_M = cacheable, memory coherent).
780-
* dcbz allocates zeroed cache lines without reading from CPC,
781-
* avoiding ECC/parity issues from uninitialized SRAM. */
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. */
782846
LOAD_ADDR32(r3, L2SRAM_ADDR)
783847
li r0, 0
784848
LOAD_ADDR32(r2, (L2SRAM_SIZE / CACHE_LINE_SIZE))

0 commit comments

Comments
 (0)