sparc: Update startup code to take PIC mode into account

Signed-off-by: Francois Retief <fgretief@spaceteq.co.za>
This commit is contained in:
Francois Retief 2015-10-28 09:06:41 +02:00
parent b6b280ce07
commit 0070109f68
2 changed files with 82 additions and 38 deletions

View file

@ -57,6 +57,27 @@ MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
#error Must define number of SPARC register windows, default is 8
#endif
/* Macros to load address into a register. Uses GOT table for PIC */
#ifdef __PIC__
#define SPARC_PIC_THUNK_CALL(reg) \
sethi %pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \
call __sparc_get_pc_thunk.reg; \
add %##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg;
#define SPARC_LOAD_ADDRESS(sym, got, reg) \
sethi %gdop_hix22(sym), %##reg; \
xor %##reg, %gdop_lox10(sym), %##reg; \
ld [%##got + %##reg], %##reg, %gdop(sym);
#else
#define SPARC_PIC_THUNK_CALL(reg)
#define SPARC_LOAD_ADDRESS(sym, got, tmp) \
set sym, %##reg;
#endif
#define STACK_ALIGN 8
#define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
@ -307,9 +328,10 @@ cpu_init_unreloc:
/* un relocated end address of monitor */
#define DATA_END __init_end
SPARC_PIC_THUNK_CALL(l7)
reloc:
set TEXT_START,%g2
set DATA_END,%g3
SPARC_LOAD_ADDRESS(TEXT_START, l7, g2)
SPARC_LOAD_ADDRESS(DATA_END, l7, g3)
set CONFIG_SYS_RELOC_MONITOR_BASE,%g4
reloc_loop:
ldd [%g2],%l0
@ -336,8 +358,8 @@ reloc_loop:
clr_bss:
/* clear bss area (the relocated) */
set __bss_start,%g2
set __bss_end,%g3
SPARC_LOAD_ADDRESS(__bss_start, l7, g2)
SPARC_LOAD_ADDRESS(__bss_end, l7, g3)
sub %g3,%g2,%g3
add %g3,%g4,%g3
clr %g1 /* std %g0 uses g0 and g1 */
@ -352,15 +374,15 @@ clr_bss_16:
/* add offsets to GOT table */
fixup_got:
set __got_start,%g4
set __got_end,%g3
SPARC_LOAD_ADDRESS(__got_start, l7, g4)
SPARC_LOAD_ADDRESS(__got_end, l7, g3)
/*
* new got offset = (old GOT-PTR (read with ld) -
* CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) +
* Destination Address (from define)
*/
set CONFIG_SYS_RELOC_MONITOR_BASE,%g2
set TEXT_START, %g1
SPARC_LOAD_ADDRESS(TEXT_START, l7, g1)
add %g4,%g2,%g4
sub %g4,%g1,%g4
add %g3,%g2,%g3
@ -378,8 +400,8 @@ got_loop:
nop
prom_relocate:
set __prom_start, %g2
set __prom_end, %g3
SPARC_LOAD_ADDRESS(__prom_start, l7, g2)
SPARC_LOAD_ADDRESS(__prom_end, l7, g3)
set CONFIG_SYS_PROM_OFFSET, %g4
prom_relocate_loop:
@ -403,14 +425,14 @@ prom_relocate_loop:
nop
/* Call relocated init functions */
jump:
set cpu_init_f2,%o1
SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1)
set CONFIG_SYS_RELOC_MONITOR_BASE,%o2
add %o1,%o2,%o1
sub %o1,%g1,%o1
call %o1
clr %o0
set board_init_f,%o1
SPARC_LOAD_ADDRESS(board_init_f, l7, o1)
set CONFIG_SYS_RELOC_MONITOR_BASE,%o2
add %o1,%o2,%o1
sub %o1,%g1,%o1

View file

@ -57,6 +57,27 @@ MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
#error Must define number of SPARC register windows, default is 8
#endif
/* Macros to load address into a register. Uses GOT table for PIC */
#ifdef __PIC__
#define SPARC_PIC_THUNK_CALL(reg) \
sethi %pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \
call __sparc_get_pc_thunk.reg; \
add %##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg;
#define SPARC_LOAD_ADDRESS(sym, got, reg) \
sethi %gdop_hix22(sym), %##reg; \
xor %##reg, %gdop_lox10(sym), %##reg; \
ld [%##got + %##reg], %##reg, %gdop(sym);
#else
#define SPARC_PIC_THUNK_CALL(reg)
#define SPARC_LOAD_ADDRESS(sym, got, tmp) \
set sym, %##reg;
#endif
#define STACK_ALIGN 8
#define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
@ -229,7 +250,7 @@ clear_window:
bge clear_window
save
wininit:
wiminit:
set WIM_INIT, %g3
mov %g3, %wim
@ -248,9 +269,10 @@ cpu_init_unreloc:
/* un relocated end address of monitor */
#define DATA_END __init_end
SPARC_PIC_THUNK_CALL(l7)
reloc:
set TEXT_START,%g2
set DATA_END,%g3
SPARC_LOAD_ADDRESS(TEXT_START, l7, g2)
SPARC_LOAD_ADDRESS(DATA_END, l7, g3)
set CONFIG_SYS_RELOC_MONITOR_BASE,%g4
reloc_loop:
ldd [%g2],%l0
@ -277,8 +299,8 @@ reloc_loop:
clr_bss:
/* clear bss area (the relocated) */
set __bss_start,%g2
set __bss_end,%g3
SPARC_LOAD_ADDRESS(__bss_start, l7, g2)
SPARC_LOAD_ADDRESS(__bss_end, l7, g3)
sub %g3,%g2,%g3
add %g3,%g4,%g3
clr %g1 /* std %g0 uses g0 and g1 */
@ -293,15 +315,15 @@ clr_bss_16:
/* add offsets to GOT table */
fixup_got:
set __got_start,%g4
set __got_end,%g3
SPARC_LOAD_ADDRESS(__got_start, l7, g4)
SPARC_LOAD_ADDRESS(__got_end, l7, g3)
/*
* new got offset = (old GOT-PTR (read with ld) -
* CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) +
* Destination Address (from define)
*/
set CONFIG_SYS_RELOC_MONITOR_BASE,%g2
set TEXT_START, %g1
SPARC_LOAD_ADDRESS(TEXT_START, l7, g1)
add %g4,%g2,%g4
sub %g4,%g1,%g4
add %g3,%g2,%g3
@ -319,8 +341,8 @@ got_loop:
nop
prom_relocate:
set __prom_start, %g2
set __prom_end, %g3
SPARC_LOAD_ADDRESS(__prom_start, l7, g2)
SPARC_LOAD_ADDRESS(__prom_end, l7, g3)
set CONFIG_SYS_PROM_OFFSET, %g4
prom_relocate_loop:
@ -358,14 +380,14 @@ snoop_detect:
nop
/* Call relocated init functions */
jump:
set cpu_init_f2,%o1
SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1)
set CONFIG_SYS_RELOC_MONITOR_BASE,%o2
add %o1,%o2,%o1
sub %o1,%g1,%o1
call %o1
clr %o0
set board_init_f,%o1
SPARC_LOAD_ADDRESS(board_init_f, l7, o1)
set CONFIG_SYS_RELOC_MONITOR_BASE,%o2
add %o1,%o2,%o1
sub %o1,%g1,%o1