summaryrefslogtreecommitdiff
path: root/arch/openrisc
diff options
context:
space:
mode:
authorJulius Baxter <juliusbaxter@gmail.com>2012-05-05 12:32:11 +0000
committerWolfgang Denk <wd@denx.de>2012-08-09 23:37:45 +0200
commit3874a377451e4d1f45710f5bf801dd96e8b8f67e (patch)
treec9ecb29bc7b72a91affc6ab25e8950cb5ebc483c /arch/openrisc
parenteb0b43f264077fb7ff53b479dce76324a8aaa696 (diff)
openrisc: Work around potential relocation issues
When reset code is in flash, the jump instructions emitted by the compiler are relative instead of absolute jumps. A fix to the reset code to make correct jumps to the beginning of code relocated to RAM have also been added. Signed-off-by: Julius Baxter <juliusbaxter@gmail.com>
Diffstat (limited to 'arch/openrisc')
-rw-r--r--arch/openrisc/cpu/cpu.c6
-rw-r--r--arch/openrisc/cpu/start.S13
2 files changed, 13 insertions, 6 deletions
diff --git a/arch/openrisc/cpu/cpu.c b/arch/openrisc/cpu/cpu.c
index 25cd6249d2b..73ecc6f766f 100644
--- a/arch/openrisc/cpu/cpu.c
+++ b/arch/openrisc/cpu/cpu.c
@@ -151,7 +151,11 @@ extern void __reset(void);
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
disable_interrupts();
- __reset();
+ /* Code the jump to __reset here as the compiler is prone to
+ emitting a bad jump instruction if the function is in flash */
+ __asm__("l.movhi r1,hi(__reset); \
+ l.ori r1,r1,lo(__reset); \
+ l.jr r1");
/* not reached, __reset does not return */
return 0;
}
diff --git a/arch/openrisc/cpu/start.S b/arch/openrisc/cpu/start.S
index 3a4271750e8..39c80e134fc 100644
--- a/arch/openrisc/cpu/start.S
+++ b/arch/openrisc/cpu/start.S
@@ -26,8 +26,11 @@
#define HANDLE_EXCEPTION \
l.addi r1, r1, -EXCEPTION_STACK_SIZE ;\
+ l.sw 0x00(r1), r2 ;\
l.sw 0x1c(r1), r9 ;\
- l.jal _exception_handler ;\
+ l.movhi r2,hi(_exception_handler) ;\
+ l.ori r2,r2,lo(_exception_handler) ;\
+ l.jalr r2 ;\
l.nop ;\
l.lwz r9, 0x1c(r1) ;\
l.addi r1, r1, EXCEPTION_STACK_SIZE ;\
@@ -79,8 +82,9 @@ __reset:
l.bnf .L_relocvectors
l.addi r4,r4, 4
#endif
-
- l.j _start
+ l.movhi r4,hi(_start)
+ l.ori r4,r4,lo(_start)
+ l.jr r4
l.nop
/* bus error */
@@ -262,8 +266,7 @@ _start:
.type _exception_handler,@function
_exception_handler:
- /* Store state (r9 already saved)*/
- l.sw 0x00(r1), r2
+ /* Store state (r2 and r9 already saved)*/
l.sw 0x04(r1), r3
l.sw 0x08(r1), r4
l.sw 0x0c(r1), r5