diff --git a/src/arch/ppc/init/crt0.S.lb b/src/arch/ppc/init/crt0.S.lb index ea4ea925dd..5c5b5f4716 100644 --- a/src/arch/ppc/init/crt0.S.lb +++ b/src/arch/ppc/init/crt0.S.lb @@ -33,40 +33,48 @@ system_reset: #if USE_DCACHE_RAM == 1 #define DCACHE_RAM_END (DCACHE_RAM_BASE + DCACHE_RAM_SIZE - 1) /* - * Setup stack in cache + * Set up stack in cache. The SP must be 16-byte (4-word) aligned + * for SYSV EABI or 8-byte (2-word) aligned for PPC EABI, so we make + * it 16-byte aligned to cover both cases. Also we have to ensure that + * the first word is located within the cache. */ - lis r1, DCACHE_RAM_END@ha - addi r1, r1, DCACHE_RAM_END@l - stwu r0,-64(r1) - stwu r1,-24(r1) + lis r1, (DCACHE_RAM_BASE+DCACHE_RAM_SIZE)@h + ori r1, r1, (DCACHE_RAM_BASE+DCACHE_RAM_SIZE)@l + lis r0, 0 + stwu r0, -4(r1) + stwu r0, -4(r1) + stwu r0, -4(r1) + stwu r0, -4(r1) +#if 0 /* * Clear stack */ - lis r4, DCACHE_RAM_BASE@ha - addi r4, r4, DCACHE_RAM_BASE@l - lis r7, DCACHE_RAM_END@ha - addi r7, r7, DCACHE_RAM_END@l + lis r4, DCACHE_RAM_BASE@h + ori r4, r4, DCACHE_RAM_BASE@l + lis r7, DCACHE_RAM_END@h + ori r7, r7, DCACHE_RAM_END@l lis r5, 0 1: stwx r5, 0, r4 addi r4, r4, 4 cmp 0, 0, r4, r7 ble 1b sync +#endif /* * Set up the EABI pointers, before we enter any C code */ - lis r13, _SDA_BASE_@ha - addi r13, r13, _SDA_BASE_@l - lis r2, _SDA2_BASE_@ha - addi r2, r2, _SDA2_BASE_@l + lis r13, _SDA_BASE_@h + ori r13, r13, _SDA_BASE_@l + lis r2, _SDA2_BASE_@h + ori r2, r2, _SDA2_BASE_@l /* * load start address into SRR0 for rfi */ - lis r3, ppc_main@ha - addi r3, r3, ppc_main@l + lis r3, ppc_main@h + ori r3, r3, ppc_main@l mtspr SRR0, r3 /* @@ -79,8 +87,8 @@ system_reset: /* * If something returns after rfi then die */ - lis r3, dead@ha - addi r3, r3, dead@l + lis r3, dead@h + ori r3, r3, dead@l mtlr r3 /*