1919 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2020 */
2121#include <stdint.h>
22+ #include <string.h>
2223#include "target.h"
2324#include "printf.h"
2425#include "image.h" /* for RAMFUNCTION */
3233#define ENABLE_BUS_CLK_CALC
3334
3435#ifndef BUILD_LOADER_STAGE1
35- #define ENABLE_MP /* multi-core support */
36+ /* TODO: Fix e6500 MP initialization - secondary cores not responding.
37+ * Disable MP for now to focus on getting basic boot working. */
38+ /* #define ENABLE_MP */ /* multi-core support */
3639#endif
3740
3841/* Forward declarations */
@@ -370,6 +373,64 @@ static void hal_cpld_init(void)
370373#endif
371374}
372375
376+ #ifdef ENABLE_DDR
377+ /* Relocate stack from CPC SRAM to DDR for more stack space.
378+ * Call this after DDR is initialized and verified working.
379+ * This allows signature verification (ECC P384) which needs ~20-30KB stack. */
380+ static void hal_relocate_stack_to_ddr (void )
381+ {
382+ uint32_t new_sp = DDR_STACK_TOP - 64 ; /* 64-byte alignment, room for frame */
383+
384+ /* Zero the DDR stack area for clean operation */
385+ memset ((void * )DDR_STACK_BASE , 0 , DDR_STACK_SIZE );
386+
387+ /* Switch stack pointer from CPC SRAM to DDR.
388+ * r1 is the stack pointer in PowerPC ABI. */
389+ __asm__ __volatile__(
390+ "mr 1, %0\n" /* Move new stack address to r1 */
391+ "sync\n"
392+ :
393+ : "r" (new_sp )
394+ : "memory"
395+ );
396+
397+ #ifdef DEBUG_UART
398+ wolfBoot_printf ("Stack relocated to DDR (SP=0x%x)\n" , new_sp );
399+ #endif
400+ }
401+
402+ /* Release CPC SRAM back to L2 cache mode after stack is relocated to DDR.
403+ * This gives us the full 2MB CPC as instruction/data cache for better performance. */
404+ static void hal_reconfigure_cpc_as_cache (void )
405+ {
406+ volatile uint32_t * cpc_csr0 = (volatile uint32_t * )(CPC_BASE + CPCCSR0 );
407+ volatile uint32_t * cpc_srcr0 = (volatile uint32_t * )(CPC_BASE + CPCSRCR0 );
408+ uint32_t reg ;
409+
410+ /* Step 1: Flush the CPC to ensure no stale SRAM data.
411+ * IMPORTANT: Read-modify-write to preserve CPCE/CPCPE enable bits! */
412+ reg = * cpc_csr0 ;
413+ reg |= CPCCSR0_CPCFL ;
414+ * cpc_csr0 = reg ;
415+ __asm__ __volatile__("sync; isync" ::: "memory" );
416+
417+ /* Step 2: Poll until flush completes (CPCFL clears) */
418+ do {
419+ reg = * cpc_csr0 ;
420+ } while (reg & CPCCSR0_CPCFL );
421+
422+ /* Step 3: Disable SRAM mode - release ways back to cache */
423+ * cpc_srcr0 = 0 ; /* Clear SRAMEN and SRAMSZ */
424+ __asm__ __volatile__("sync; isync" ::: "memory" );
425+
426+ /* CPC remains enabled (CPCE/CPCPE preserved), now with all ways as cache */
427+
428+ #ifdef DEBUG_UART
429+ wolfBoot_printf ("CPC: Released SRAM, full L2 cache enabled\n" );
430+ #endif
431+ }
432+ #endif /* ENABLE_DDR */
433+
373434#if defined(DEBUG_UART ) && defined(ENABLE_DDR )
374435/* DDR memory test - writes patterns and verifies readback */
375436static int hal_ddr_test (void )
@@ -381,6 +442,7 @@ static int hal_ddr_test(void)
381442 int errors = 0 ;
382443 uint32_t reg ;
383444
445+ #ifdef DEBUG_DDR
384446 /* Show DDR controller status */
385447 reg = get32 (DDR_SDRAM_CFG );
386448 wolfBoot_printf ("DDR: SDRAM_CFG=0x%x (MEM_EN=%d)\n" , reg ,
@@ -412,6 +474,7 @@ static int hal_ddr_test(void)
412474 return -1 ;
413475 }
414476 }
477+ #endif /* DEBUG_DDR */
415478
416479 /* Check if DDR is enabled */
417480 if (!(get32 (DDR_SDRAM_CFG ) & DDR_SDRAM_CFG_MEM_EN )) {
@@ -426,6 +489,7 @@ static int hal_ddr_test(void)
426489 return -1 ;
427490 }
428491
492+ #ifdef DEBUG_DDR
429493 /* Show DDR chip select configuration */
430494 wolfBoot_printf ("DDR CS0: BNDS=0x%x CFG=0x%x\n" ,
431495 get32 (DDR_CS_BNDS (0 )), get32 (DDR_CS_CONFIG (0 )));
@@ -437,28 +501,24 @@ static int hal_ddr_test(void)
437501 get32 (DDR_DDRDSR_1 ), get32 (DDR_DDRDSR_2 ));
438502 wolfBoot_printf ("DDR DDRCDR_1=0x%x DDRCDR_2=0x%x\n" ,
439503 get32 (DDR_DDRCDR_1 ), get32 (DDR_DDRCDR_2 ));
504+ #endif /* DEBUG_DDR */
440505
441506 /* Check for pre-existing DDR errors */
442507 reg = get32 (DDR_ERR_DETECT );
443- wolfBoot_printf ("DDR ERR_DETECT=0x%x\n" , reg );
444508 if (reg != 0 ) {
445- wolfBoot_printf ("DDR: ERROR - Pre-existing DDR errors!\n" );
509+ wolfBoot_printf ("DDR: ERR_DETECT=0x%x (errors present)\n" , reg );
510+ #ifdef DEBUG_DDR
446511 wolfBoot_printf (" Bit 31 (MME): %d - Multiple errors\n" , (reg >> 31 ) & 1 );
447512 wolfBoot_printf (" Bit 7 (APE): %d - Address parity\n" , (reg >> 7 ) & 1 );
448513 wolfBoot_printf (" Bit 3 (ACE): %d - Auto calibration\n" , (reg >> 3 ) & 1 );
449514 wolfBoot_printf (" Bit 2 (CDE): %d - Correctable data\n" , (reg >> 2 ) & 1 );
450- wolfBoot_printf ( "DDR: Skipping memory test due to errors\n" );
515+ #endif
451516 return -1 ;
452517 }
453518
519+ #ifdef DEBUG_DDR
454520 wolfBoot_printf ("DDR Test: base=0x%x\n" , DDR_ADDRESS );
455- wolfBoot_printf ("DDR: Attempting simple read at 0x%x...\n" , DDR_ADDRESS );
456-
457- /* First just try to read - don't write yet */
458- {
459- volatile uint32_t val = * ddr ;
460- wolfBoot_printf ("DDR: Read returned 0x%x\n" , val );
461- }
521+ #endif
462522
463523 for (i = 0 ; i < (int )(sizeof (test_offsets )/sizeof (test_offsets [0 ])); i ++ ) {
464524 uint32_t offset = test_offsets [i ];
@@ -476,7 +536,7 @@ static int hal_ddr_test(void)
476536 readback = * addr ;
477537
478538 if (readback != pattern ) {
479- wolfBoot_printf (" FAIL: @0x%x wrote 0x%x read 0x%x\n" ,
539+ wolfBoot_printf ("DDR FAIL: @0x%x wrote 0x%x read 0x%x\n" ,
480540 (uint32_t )addr , pattern , readback );
481541 errors ++ ;
482542 }
@@ -507,6 +567,9 @@ void hal_init(void)
507567#ifdef DEBUG_UART
508568 uart_init ();
509569 uart_write ("wolfBoot Init\n" , 14 );
570+ #ifndef WOLFBOOT_REPRODUCIBLE_BUILD
571+ wolfBoot_printf ("Build: %s %s\n" , __DATE__ , __TIME__ );
572+ #endif
510573#endif
511574
512575 hal_flash_init ();
@@ -526,8 +589,27 @@ void hal_init(void)
526589 hal_mp_init ();
527590#endif
528591
529- #if defined(DEBUG_UART ) && defined(ENABLE_DDR )
592+ #ifdef ENABLE_DDR
593+ /* Test DDR (when DEBUG_UART enabled) */
594+ #ifdef DEBUG_UART
530595 hal_ddr_test ();
596+ #endif
597+ /* TODO: Implement proper assembly-based stack relocation to DDR.
598+ * The current C-based approach corrupts return addresses because:
599+ * 1. hal_init's return address is saved on CPC SRAM stack
600+ * 2. Stack switch changes SP to DDR (zeroed area)
601+ * 3. CPC release makes old stack contents invalid
602+ * 4. Function returns read garbage addresses
603+ *
604+ * For now, keep using CPC SRAM stack (1MB should be enough for P384).
605+ * Stack relocation needs to be done in assembly with proper LR handling.
606+ */
607+ #if 0 /* Disabled until proper assembly implementation */
608+ {
609+ hal_relocate_stack_to_ddr ();
610+ hal_reconfigure_cpc_as_cache ();
611+ }
612+ #endif
531613#endif
532614}
533615
0 commit comments