summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/ppc/init/crt0.S.lb44
1 files changed, 26 insertions, 18 deletions
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
/*