nds32: Support relocation.

Enable pie option for relocation.

Signed-off-by: rick <rick@andestech.com>
Cc: Andes <uboot@andestech.com>
This commit is contained in:
rick 2016-04-14 14:32:27 +08:00 committed by Andes
parent 06572f0301
commit d607f6fa99
6 changed files with 77 additions and 74 deletions

View File

@ -19,4 +19,4 @@ PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -mrelax
PLATFORM_RELFLAGS += -gdwarf-2 PLATFORM_RELFLAGS += -gdwarf-2
PLATFORM_CPPFLAGS += -D__nds32__ -G0 -ffixed-10 -fpie PLATFORM_CPPFLAGS += -D__nds32__ -G0 -ffixed-10 -fpie
LDFLAGS_u-boot = --gc-sections --relax LDFLAGS_u-boot = --gc-sections --relax -pie

View File

@ -6,6 +6,8 @@
* SPDX-License-Identifier: GPL-2.0+ * SPDX-License-Identifier: GPL-2.0+
*/ */
.pic
.text .text
#include <common.h> #include <common.h>
@ -248,16 +250,11 @@ relo_base:
*/ */
li $r5, AHBC_BSR6_A li $r5, AHBC_BSR6_A
lwi $r8, [$r5] lwi $r8, [$r5]
li $r4, 0xfff00000 li $r4, 0xfff00000 /* r4 = bank6 base */
and $r4, $r4, $r8 and $r4, $r4, $r8
la $r5, _start@GOTOFF
li $r5, 0x0 la $r6, _end@GOTOFF
la $r1, relo_base /* get $pc or $lp */
sub $r2, $r0, $r1
sethi $r6, hi20(_end)
ori $r6, $r6, lo12(_end)
add $r6, $r6, $r2
1: 1:
lwi.p $r7, [$r5], #4 lwi.p $r7, [$r5], #4
swi.p $r7, [$r4], #4 swi.p $r7, [$r4], #4

View File

@ -9,6 +9,8 @@
* SPDX-License-Identifier: GPL-2.0+ * SPDX-License-Identifier: GPL-2.0+
*/ */
.pic
#include <asm-offsets.h> #include <asm-offsets.h>
#include <config.h> #include <config.h>
#include <common.h> #include <common.h>
@ -116,6 +118,18 @@ IRQ_STACK_START_IN:
*/ */
reset: reset:
/*
* gp = ~0 for burn mode
* = ~load_address for load mode
*/
reset_gp:
.relax_hint 0
sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_-8)
.relax_hint 0
ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_-4)
add5.pc $gp
set_ivb: set_ivb:
li $r0, 0x0 li $r0, 0x0
@ -124,20 +138,31 @@ set_ivb:
/* set IVIC, vector size: 4 bytes, base: 0x0 */ /* set IVIC, vector size: 4 bytes, base: 0x0 */
mtsr $r0, $ivb mtsr $r0, $ivb
load_lli:
#ifndef CONFIG_SKIP_LOWLEVEL_INIT #ifndef CONFIG_SKIP_LOWLEVEL_INIT
jal load_lowlevel_init jal lowlevel_init
jral $p0 /*
* gp = ~VMA for burn mode
* = ~load_address for load mode
*/
update_gp:
.relax_hint 0
sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_-8)
.relax_hint 0
ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_-4)
add5.pc $gp
#endif #endif
/*
* do critical initializations first (shall be in short time)
* do self_relocation ASAP.
*/
/* /*
* Set the N1213 (Whitiger) core to superuser mode * Set the N1213 (Whitiger) core to superuser mode
* According to spec, it is already when reset * According to spec, it is already when reset
*/ */
turnoff_wtdog:
#ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG #ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG
jal load_turnoff_watchdog jal turnoff_watchdog
jral $p0
#endif #endif
/* /*
@ -145,7 +170,7 @@ turnoff_wtdog:
* not when booting from ram * not when booting from ram
*/ */
#ifdef CONFIG_INIT_CRITICAL #ifdef CONFIG_INIT_CRITICAL
bal cpu_init_crit ! Do CPU critical regs init jal cpu_init_crit ! Do CPU critical regs init
#endif #endif
/* /*
@ -174,6 +199,11 @@ call_board_init_f:
* after relocating the monitor code. * after relocating the monitor code.
* *
*/ */
/*
* gp = ~RAM_SIZE - TEXT_SIZE for burn/load mode
*/
.globl relocate_code .globl relocate_code
relocate_code: relocate_code:
move $r4, $r0 /* save addr_sp */ move $r4, $r0 /* save addr_sp */
@ -184,49 +214,43 @@ relocate_code:
stack_setup: stack_setup:
move $sp, $r4 move $sp, $r4
la $r0, _start la $r0, _start@GOTOFF
beq $r0, $r6, clear_bss /* skip relocation */ beq $r0, $r6, clear_bss /* skip relocation */
move $r1, $r6 /* r1 <- scratch for copy_loop */ la $r1, _end@GOTOFF
la $r3, __bss_start move $r2, $r6 /* r2 <- scratch for copy_loop */
sub $r3, $r3, $r0 /* r3 <- __bss_start_ofs */
add $r2, $r0, $r3 /* r2 <- source end address */
copy_loop: copy_loop:
lwi.p $r7, [$r0], #4 lwi.p $r7, [$r0], #4
swi.p $r7, [$r1], #4 swi.p $r7, [$r2], #4
blt $r0, $r2, copy_loop blt $r0, $r1, copy_loop
/* /*
* fix relocations related issues * fix relocations related issues
*/ */
fix_relocations: fix_relocations:
l.w $r0, _TEXT_BASE /* r0 <- Text base */ l.w $r0, _TEXT_BASE@GOTOFF /* r0 <- Text base */
sub $r9, $r6, $r0 /* r9 <- relocation offset */ sub $r9, $r6, $r0 /* r9 <- relocation offset */
fix_got: la $r7, __rel_dyn_start@GOTOFF
/* add $r7, $r7, $r9 /* r2 <- rel __got_start in RAM */
* Now we want to update GOT. la $r8, __rel_dyn_end@GOTOFF
* add $r8, $r8, $r9 /* r2 <- rel __got_start in RAM */
* GOT[0] is reserved. GOT[1] is also reserved for the dynamic object li $r3, #0x2a /* R_NDS32_RELATIVE */
* generated by GNU ld. Skip these reserved entries from relocation. 1:
*/ lmw.bim $r0, [$r7], $r2 /* r0,r1,r2 <- adr,type,addend */
la $r2, __got_start /* r2 <- rel __got_start in FLASH */ bne $r1, $r3, 2f
add $r2, $r2, $r9 /* r2 <- rel __got_start in RAM */
la $r3, __got_end /* r3 <- rel __got_end in FLASH */ add $r0, $r0, $r9
add $r3, $r3, $r9 /* r3 <- rel __got_end in RAM */ add $r2, $r2, $r9
addi $r2, $r2, #8 /* skipping first two entries */ sw $r2, [$r0]
fix_got_loop: 2:
lwi $r0, [$r2] /* r0 <- location in FLASH to fix up */ blt $r7, $r8, 1b
add $r0, $r0, $r9 /* r0 <- location fix up to RAM */
swi.p $r0, [$r2], #4 /* r0 <- store fix into .got in RAM */
blt $r2, $r3, fix_got_loop
clear_bss: clear_bss:
la $r0, __bss_start /* r0 <- rel __bss_start in FLASH */ la $r0, __bss_start@GOTOFF /* r0 <- rel __bss_start in FLASH */
add $r0, $r0, $r9 /* r0 <- rel __bss_start in FLASH */ add $r0, $r0, $r9 /* r0 <- rel __bss_start in FLASH */
la $r1, __bss_end /* r1 <- rel __bss_end in RAM */ la $r1, __bss_end@GOTOFF /* r1 <- rel __bss_end in RAM */
add $r1, $r1, $r9 /* r0 <- rel __bss_end in RAM */ add $r1, $r1, $r9 /* r0 <- rel __bss_end in RAM */
li $r2, 0x00000000 /* clear */ li $r2, 0x00000000 /* clear */
@ -240,7 +264,7 @@ clbss_l:
* initialization, now running from RAM. * initialization, now running from RAM.
*/ */
call_board_init_r: call_board_init_r:
la $r0, board_init_r la $r0, board_init_r@GOTOFF
move $lp, $r0 /* offset of board_init_r() */ move $lp, $r0 /* offset of board_init_r() */
add $lp, $lp, $r9 /* real address of board_init_r() */ add $lp, $lp, $r9 /* real address of board_init_r() */
/* setup parameters for board_init_r */ /* setup parameters for board_init_r */
@ -275,8 +299,8 @@ cpu_init_crit:
/* Flush caches and TLB */ /* Flush caches and TLB */
/* Invalidate caches */ /* Invalidate caches */
bal invalidate_icac jal invalidate_icac
bal invalidate_dcac jal invalidate_dcac
/* Flush TLB */ /* Flush TLB */
mfsr $p0, $MMU_CFG mfsr $p0, $MMU_CFG
@ -299,24 +323,6 @@ cpu_init_crit:
2: 2:
ret ret
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
load_lowlevel_init:
la $r6, lowlevel_init
la $r7, load_lli + 4
sub $p0, $r6, $r7
add $p0, $p0, $lp
ret
#endif
#ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG
load_turnoff_watchdog:
la $r6, turnoff_watchdog
la $r7, turnoff_wtdog + 4
sub $p0, $r6, $r7
add $p0, $p0, $lp
ret
#endif
/* /*
* Invalidate I$ * Invalidate I$
*/ */

View File

@ -31,25 +31,28 @@ SECTIONS
.got : { .got : {
__got_start = .; __got_start = .;
*(.got.plt) *(.got) *(.got.plt) *(.got)
__got_end = .; __got_end = .;
} }
. = .;
. = ALIGN(4); . = ALIGN(4);
.u_boot_list : { .u_boot_list : {
KEEP(*(SORT(.u_boot_list*))); KEEP(*(SORT(.u_boot_list*)));
} }
. = ALIGN(4); . = ALIGN(4);
/DISCARD/ : { *(.rela.plt*) }
.rela.dyn : {
__rel_dyn_start = .;
*(.rela*)
__rel_dyn_end = .;
}
_end = .; _end = .;
.bss : { .bss : {
__bss_start = .; __bss_start = .;
*(.bss) *(.bss)
. = ALIGN(4); . = ALIGN(4);
__bss_end = .; __bss_end = .;
} }

View File

@ -9,6 +9,4 @@
#ifndef _ASM_CONFIG_H_ #ifndef _ASM_CONFIG_H_
#define _ASM_CONFIG_H_ #define _ASM_CONFIG_H_
#define CONFIG_NEEDS_MANUAL_RELOC
#endif #endif

View File

@ -28,7 +28,6 @@
#define CONFIG_CMDLINE_TAG /* send commandline to Kernel */ #define CONFIG_CMDLINE_TAG /* send commandline to Kernel */
#define CONFIG_SETUP_MEMORY_TAGS /* send memory definition to kernel */ #define CONFIG_SETUP_MEMORY_TAGS /* send memory definition to kernel */
#define CONFIG_INITRD_TAG /* send initrd params */ #define CONFIG_INITRD_TAG /* send initrd params */
#define CONFIG_NEEDS_MANUAL_RELOC
#ifndef CONFIG_SKIP_LOWLEVEL_INIT #ifndef CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_MEM_REMAP #define CONFIG_MEM_REMAP