From d607f6fa99a67dd1b40c08ba21ca6f3aaff933ce Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 14 Apr 2016 14:32:27 +0800 Subject: [PATCH] nds32: Support relocation. Enable pie option for relocation. Signed-off-by: rick Cc: Andes --- arch/nds32/config.mk | 2 +- arch/nds32/cpu/n1213/ag101/lowlevel_init.S | 13 +-- arch/nds32/cpu/n1213/start.S | 120 +++++++++++---------- arch/nds32/cpu/n1213/u-boot.lds | 13 ++- arch/nds32/include/asm/config.h | 2 - include/configs/adp-ag101p.h | 1 - 6 files changed, 77 insertions(+), 74 deletions(-) diff --git a/arch/nds32/config.mk b/arch/nds32/config.mk index 5ac9f90402..ca76641773 100644 --- a/arch/nds32/config.mk +++ b/arch/nds32/config.mk @@ -19,4 +19,4 @@ PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -mrelax PLATFORM_RELFLAGS += -gdwarf-2 PLATFORM_CPPFLAGS += -D__nds32__ -G0 -ffixed-10 -fpie -LDFLAGS_u-boot = --gc-sections --relax +LDFLAGS_u-boot = --gc-sections --relax -pie diff --git a/arch/nds32/cpu/n1213/ag101/lowlevel_init.S b/arch/nds32/cpu/n1213/ag101/lowlevel_init.S index 1a94868734..abdd340479 100644 --- a/arch/nds32/cpu/n1213/ag101/lowlevel_init.S +++ b/arch/nds32/cpu/n1213/ag101/lowlevel_init.S @@ -6,6 +6,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ +.pic + .text #include @@ -248,16 +250,11 @@ relo_base: */ li $r5, AHBC_BSR6_A lwi $r8, [$r5] - li $r4, 0xfff00000 + li $r4, 0xfff00000 /* r4 = bank6 base */ and $r4, $r4, $r8 - - li $r5, 0x0 - 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 + la $r5, _start@GOTOFF + la $r6, _end@GOTOFF 1: lwi.p $r7, [$r5], #4 swi.p $r7, [$r4], #4 diff --git a/arch/nds32/cpu/n1213/start.S b/arch/nds32/cpu/n1213/start.S index 8b7f8f4540..7b2b637af3 100644 --- a/arch/nds32/cpu/n1213/start.S +++ b/arch/nds32/cpu/n1213/start.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ +.pic + #include #include #include @@ -116,6 +118,18 @@ IRQ_STACK_START_IN: */ 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: li $r0, 0x0 @@ -124,20 +138,31 @@ set_ivb: /* set IVIC, vector size: 4 bytes, base: 0x0 */ mtsr $r0, $ivb -load_lli: #ifndef CONFIG_SKIP_LOWLEVEL_INIT - jal load_lowlevel_init - jral $p0 + jal lowlevel_init +/* + * 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 +/* + * do critical initializations first (shall be in short time) + * do self_relocation ASAP. + */ + /* * Set the N1213 (Whitiger) core to superuser mode * According to spec, it is already when reset */ -turnoff_wtdog: #ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG - jal load_turnoff_watchdog - jral $p0 + jal turnoff_watchdog #endif /* @@ -145,7 +170,7 @@ turnoff_wtdog: * not when booting from ram */ #ifdef CONFIG_INIT_CRITICAL - bal cpu_init_crit ! Do CPU critical regs init + jal cpu_init_crit ! Do CPU critical regs init #endif /* @@ -174,6 +199,11 @@ call_board_init_f: * after relocating the monitor code. * */ + +/* + * gp = ~RAM_SIZE - TEXT_SIZE for burn/load mode + */ + .globl relocate_code relocate_code: move $r4, $r0 /* save addr_sp */ @@ -184,49 +214,43 @@ relocate_code: stack_setup: move $sp, $r4 - la $r0, _start - + la $r0, _start@GOTOFF beq $r0, $r6, clear_bss /* skip relocation */ - move $r1, $r6 /* r1 <- scratch for copy_loop */ - la $r3, __bss_start - sub $r3, $r3, $r0 /* r3 <- __bss_start_ofs */ - add $r2, $r0, $r3 /* r2 <- source end address */ + la $r1, _end@GOTOFF + move $r2, $r6 /* r2 <- scratch for copy_loop */ copy_loop: lwi.p $r7, [$r0], #4 - swi.p $r7, [$r1], #4 - blt $r0, $r2, copy_loop + swi.p $r7, [$r2], #4 + blt $r0, $r1, copy_loop /* * fix relocations related issues */ fix_relocations: - l.w $r0, _TEXT_BASE /* r0 <- Text base */ - sub $r9, $r6, $r0 /* r9 <- relocation offset */ + l.w $r0, _TEXT_BASE@GOTOFF /* r0 <- Text base */ + sub $r9, $r6, $r0 /* r9 <- relocation offset */ + + la $r7, __rel_dyn_start@GOTOFF + add $r7, $r7, $r9 /* r2 <- rel __got_start in RAM */ + la $r8, __rel_dyn_end@GOTOFF + add $r8, $r8, $r9 /* r2 <- rel __got_start in RAM */ + li $r3, #0x2a /* R_NDS32_RELATIVE */ +1: + lmw.bim $r0, [$r7], $r2 /* r0,r1,r2 <- adr,type,addend */ + bne $r1, $r3, 2f -fix_got: -/* - * Now we want to update GOT. - * - * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object - * generated by GNU ld. Skip these reserved entries from relocation. - */ - la $r2, __got_start /* r2 <- rel __got_start in FLASH */ - add $r2, $r2, $r9 /* r2 <- rel __got_start in RAM */ - la $r3, __got_end /* r3 <- rel __got_end in FLASH */ - add $r3, $r3, $r9 /* r3 <- rel __got_end in RAM */ - addi $r2, $r2, #8 /* skipping first two entries */ -fix_got_loop: - lwi $r0, [$r2] /* r0 <- location in FLASH to fix up */ - 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 + add $r0, $r0, $r9 + add $r2, $r2, $r9 + sw $r2, [$r0] +2: + blt $r7, $r8, 1b 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 */ - 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 */ li $r2, 0x00000000 /* clear */ @@ -240,7 +264,7 @@ clbss_l: * initialization, now running from RAM. */ call_board_init_r: - la $r0, board_init_r + la $r0, board_init_r@GOTOFF move $lp, $r0 /* offset of board_init_r() */ add $lp, $lp, $r9 /* real address of board_init_r() */ /* setup parameters for board_init_r */ @@ -275,8 +299,8 @@ cpu_init_crit: /* Flush caches and TLB */ /* Invalidate caches */ - bal invalidate_icac - bal invalidate_dcac + jal invalidate_icac + jal invalidate_dcac /* Flush TLB */ mfsr $p0, $MMU_CFG @@ -299,24 +323,6 @@ cpu_init_crit: 2: 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$ */ diff --git a/arch/nds32/cpu/n1213/u-boot.lds b/arch/nds32/cpu/n1213/u-boot.lds index b88d7426bd..40db0e6e81 100644 --- a/arch/nds32/cpu/n1213/u-boot.lds +++ b/arch/nds32/cpu/n1213/u-boot.lds @@ -31,25 +31,28 @@ SECTIONS .got : { __got_start = .; - *(.got.plt) *(.got) + *(.got.plt) *(.got) __got_end = .; } - . = .; - . = ALIGN(4); .u_boot_list : { KEEP(*(SORT(.u_boot_list*))); } . = ALIGN(4); - + /DISCARD/ : { *(.rela.plt*) } + .rela.dyn : { + __rel_dyn_start = .; + *(.rela*) + __rel_dyn_end = .; + } _end = .; .bss : { __bss_start = .; *(.bss) - . = ALIGN(4); + . = ALIGN(4); __bss_end = .; } diff --git a/arch/nds32/include/asm/config.h b/arch/nds32/include/asm/config.h index 3d1886e355..054cc4837c 100644 --- a/arch/nds32/include/asm/config.h +++ b/arch/nds32/include/asm/config.h @@ -9,6 +9,4 @@ #ifndef _ASM_CONFIG_H_ #define _ASM_CONFIG_H_ -#define CONFIG_NEEDS_MANUAL_RELOC - #endif diff --git a/include/configs/adp-ag101p.h b/include/configs/adp-ag101p.h index c4e0a21b8d..5cb79f1524 100644 --- a/include/configs/adp-ag101p.h +++ b/include/configs/adp-ag101p.h @@ -28,7 +28,6 @@ #define CONFIG_CMDLINE_TAG /* send commandline to Kernel */ #define CONFIG_SETUP_MEMORY_TAGS /* send memory definition to kernel */ #define CONFIG_INITRD_TAG /* send initrd params */ -#define CONFIG_NEEDS_MANUAL_RELOC #ifndef CONFIG_SKIP_LOWLEVEL_INIT #define CONFIG_MEM_REMAP -- 2.39.5