X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=arch%2Fmips%2Fcpu%2Fmips32%2Fstart.S;h=3b5b622abedf06ffba3534692d7fba027569ed52;hb=f1c64a08106db5ce87b6afe76785e2d4fddcff63;hp=65acf7d2a12958b54aaa946e8025724dacb0ca1a;hpb=4dc7412afa4fe47a02805525e415656d67764839;p=u-boot diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 65acf7d2a1..3b5b622abe 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -3,32 +3,39 @@ * * Copyright (c) 2003 Wolfgang Denk * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ #include #include +#include #include #include #ifndef CONFIG_SYS_MIPS_CACHE_MODE #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT +#endif + +#ifndef CONFIG_SYS_INIT_SP_ADDR +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ + CONFIG_SYS_INIT_SP_OFFSET) +#endif + +#ifdef CONFIG_32BIT +# define MIPS_RELOC 3 +# define STATUS_SET 0 +#endif + +#ifdef CONFIG_64BIT +# ifdef CONFIG_SYS_LITTLE_ENDIAN +# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ + (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym)) +# else +# define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ + ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24) +# endif +# define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) +# define STATUS_SET ST0_KX #endif /* @@ -47,20 +54,17 @@ .set pop .endm -#define RVECENT(f,n) \ - b f; nop -#define XVECENT(f,bev) \ - b f ; \ - li k0,bev - .set noreorder .globl _start .text _start: - RVECENT(reset,0) # U-boot entry point - RVECENT(reset,1) # software reboot -#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG + /* U-boot entry point */ + b reset + nop + + .org 0x10 +#if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG) /* * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to * access external NOR flashes. If the board boots from NOR flash the @@ -69,152 +73,56 @@ _start: * device with correct parameters. This config option is board-specific. */ .word CONFIG_SYS_XWAY_EBU_BOOTCFG + .word 0x0 +#elif defined(CONFIG_MALTA) + /* + * Linux expects the Board ID here. + */ + .word 0x00000420 # 0x420 (Malta Board with CoreLV) .word 0x00000000 -#else - RVECENT(romReserved,2) #endif - RVECENT(romReserved,3) - RVECENT(romReserved,4) - RVECENT(romReserved,5) - RVECENT(romReserved,6) - RVECENT(romReserved,7) - RVECENT(romReserved,8) - RVECENT(romReserved,9) - RVECENT(romReserved,10) - RVECENT(romReserved,11) - RVECENT(romReserved,12) - RVECENT(romReserved,13) - RVECENT(romReserved,14) - RVECENT(romReserved,15) - RVECENT(romReserved,16) - RVECENT(romReserved,17) - RVECENT(romReserved,18) - RVECENT(romReserved,19) - RVECENT(romReserved,20) - RVECENT(romReserved,21) - RVECENT(romReserved,22) - RVECENT(romReserved,23) - RVECENT(romReserved,24) - RVECENT(romReserved,25) - RVECENT(romReserved,26) - RVECENT(romReserved,27) - RVECENT(romReserved,28) - RVECENT(romReserved,29) - RVECENT(romReserved,30) - RVECENT(romReserved,31) - RVECENT(romReserved,32) - RVECENT(romReserved,33) - RVECENT(romReserved,34) - RVECENT(romReserved,35) - RVECENT(romReserved,36) - RVECENT(romReserved,37) - RVECENT(romReserved,38) - RVECENT(romReserved,39) - RVECENT(romReserved,40) - RVECENT(romReserved,41) - RVECENT(romReserved,42) - RVECENT(romReserved,43) - RVECENT(romReserved,44) - RVECENT(romReserved,45) - RVECENT(romReserved,46) - RVECENT(romReserved,47) - RVECENT(romReserved,48) - RVECENT(romReserved,49) - RVECENT(romReserved,50) - RVECENT(romReserved,51) - RVECENT(romReserved,52) - RVECENT(romReserved,53) - RVECENT(romReserved,54) - RVECENT(romReserved,55) - RVECENT(romReserved,56) - RVECENT(romReserved,57) - RVECENT(romReserved,58) - RVECENT(romReserved,59) - RVECENT(romReserved,60) - RVECENT(romReserved,61) - RVECENT(romReserved,62) - RVECENT(romReserved,63) - XVECENT(romExcHandle,0x200) # bfc00200: R4000 tlbmiss vector - RVECENT(romReserved,65) - RVECENT(romReserved,66) - RVECENT(romReserved,67) - RVECENT(romReserved,68) - RVECENT(romReserved,69) - RVECENT(romReserved,70) - RVECENT(romReserved,71) - RVECENT(romReserved,72) - RVECENT(romReserved,73) - RVECENT(romReserved,74) - RVECENT(romReserved,75) - RVECENT(romReserved,76) - RVECENT(romReserved,77) - RVECENT(romReserved,78) - RVECENT(romReserved,79) - XVECENT(romExcHandle,0x280) # bfc00280: R4000 xtlbmiss vector - RVECENT(romReserved,81) - RVECENT(romReserved,82) - RVECENT(romReserved,83) - RVECENT(romReserved,84) - RVECENT(romReserved,85) - RVECENT(romReserved,86) - RVECENT(romReserved,87) - RVECENT(romReserved,88) - RVECENT(romReserved,89) - RVECENT(romReserved,90) - RVECENT(romReserved,91) - RVECENT(romReserved,92) - RVECENT(romReserved,93) - RVECENT(romReserved,94) - RVECENT(romReserved,95) - XVECENT(romExcHandle,0x300) # bfc00300: R4000 cache vector - RVECENT(romReserved,97) - RVECENT(romReserved,98) - RVECENT(romReserved,99) - RVECENT(romReserved,100) - RVECENT(romReserved,101) - RVECENT(romReserved,102) - RVECENT(romReserved,103) - RVECENT(romReserved,104) - RVECENT(romReserved,105) - RVECENT(romReserved,106) - RVECENT(romReserved,107) - RVECENT(romReserved,108) - RVECENT(romReserved,109) - RVECENT(romReserved,110) - RVECENT(romReserved,111) - XVECENT(romExcHandle,0x380) # bfc00380: R4000 general vector - RVECENT(romReserved,113) - RVECENT(romReserved,114) - RVECENT(romReserved,115) - RVECENT(romReserved,116) - RVECENT(romReserved,116) - RVECENT(romReserved,118) - RVECENT(romReserved,119) - RVECENT(romReserved,120) - RVECENT(romReserved,121) - RVECENT(romReserved,122) - RVECENT(romReserved,123) - RVECENT(romReserved,124) - RVECENT(romReserved,125) - RVECENT(romReserved,126) - RVECENT(romReserved,127) - /* - * We hope there are no more reserved vectors! - * 128 * 8 == 1024 == 0x400 - * so this is address R_VEC+0x400 == 0xbfc00400 - */ + .org 0x200 + /* TLB refill, 32 bit task */ +1: b 1b + nop + + .org 0x280 + /* XTLB refill, 64 bit task */ +1: b 1b + nop + + .org 0x300 + /* Cache error exception */ +1: b 1b + nop + + .org 0x380 + /* General exception */ +1: b 1b + nop + + .org 0x400 + /* Catch interrupt exceptions */ +1: b 1b + nop + + .org 0x480 + /* EJTAG debug exception */ +1: b 1b + nop + .align 4 reset: /* Clear watch registers */ - mtc0 zero, CP0_WATCHLO - mtc0 zero, CP0_WATCHHI + MTC0 zero, CP0_WATCHLO + MTC0 zero, CP0_WATCHHI /* WP(Watch Pending), SW0/1 should be cleared */ mtc0 zero, CP0_CAUSE - setup_c0_status 0 0 + setup_c0_status STATUS_SET 0 /* Init Timer */ mtc0 zero, CP0_COUNT @@ -226,21 +134,26 @@ reset: mtc0 t0, CP0_CONFIG #endif - /* Initialize $gp */ + /* + * Initialize $gp, force pointer sized alignment of bal instruction to + * forbid the compiler to put nop's between bal and _gp. This is + * required to keep _gp and ra aligned to 8 byte. + */ + .align PTRLOG bal 1f nop - .word _gp + PTR _gp 1: - lw gp, 0(ra) + PTR_L gp, 0(ra) #ifndef CONFIG_SKIP_LOWLEVEL_INIT /* Initialize any external memory */ - la t9, lowlevel_init + PTR_LA t9, lowlevel_init jalr t9 nop /* Initialize caches... */ - la t9, mips_cache_reset + PTR_LA t9, mips_cache_reset jalr t9 nop @@ -250,11 +163,34 @@ reset: #endif /* Set up temporary stack */ - li sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET + PTR_LI t0, -16 + PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR + and sp, t1, t0 # force 16 byte alignment + PTR_SUB sp, sp, GD_SIZE # reserve space for gd + and sp, sp, t0 # force 16 byte alignment + move k0, sp # save gd pointer +#ifdef CONFIG_SYS_MALLOC_F_LEN + PTR_LI t2, CONFIG_SYS_MALLOC_F_LEN + PTR_SUB sp, sp, t2 # reserve space for early malloc + and sp, sp, t0 # force 16 byte alignment +#endif + move fp, sp + + /* Clear gd */ + move t0, k0 +1: + sw zero, 0(t0) + blt t0, t1, 1b + PTR_ADDI t0, 4 + +#ifdef CONFIG_SYS_MALLOC_F_LEN + PTR_ADDU t0, k0, GD_MALLOC_BASE # gd->malloc_base offset + sw sp, 0(t0) +#endif - la t9, board_init_f + PTR_LA t9, board_init_f jr t9 - nop + move ra, zero /* * void relocate_code (addr_sp, gd, addr_moni) @@ -270,18 +206,19 @@ reset: .ent relocate_code relocate_code: move sp, a0 # set new stack pointer + move fp, sp move s0, a1 # save gd in s0 move s2, a2 # save destination address in s2 - li t0, CONFIG_SYS_MONITOR_BASE - sub s1, s2, t0 # s1 <-- relocation offset + PTR_LI t0, CONFIG_SYS_MONITOR_BASE + PTR_SUB s1, s2, t0 # s1 <-- relocation offset - la t3, in_ram - lw t2, -12(t3) # t2 <-- uboot_end_data + PTR_LA t3, in_ram + PTR_L t2, -(3 * PTRSIZE)(t3) # t2 <-- __image_copy_end move t1, a2 - add gp, s1 # adjust gp + PTR_ADD gp, s1 # adjust gp /* * t0 = source address @@ -291,25 +228,26 @@ relocate_code: 1: lw t3, 0(t0) sw t3, 0(t1) - addu t0, 4 + PTR_ADDU t0, 4 blt t0, t2, 1b - addu t1, 4 + PTR_ADDU t1, 4 /* If caches were enabled, we would have to flush them here. */ - sub a1, t1, s2 # a1 <-- size - la t9, flush_cache + PTR_SUB a1, t1, s2 # a1 <-- size + PTR_LA t9, flush_cache jalr t9 move a0, s2 # a0 <-- destination address /* Jump to where we've relocated ourselves */ - addi t0, s2, in_ram - _start + PTR_ADDI t0, s2, in_ram - _start jr t0 nop - .word _GLOBAL_OFFSET_TABLE_ - .word uboot_end_data - .word uboot_end - .word num_got_entries + PTR __rel_dyn_end + PTR __rel_dyn_start + PTR __image_copy_end + PTR _GLOBAL_OFFSET_TABLE_ + PTR num_got_entries in_ram: /* @@ -318,45 +256,65 @@ in_ram: * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object * generated by GNU ld. Skip these reserved entries from relocation. */ - lw t3, -4(t0) # t3 <-- num_got_entries - lw t4, -16(t0) # t4 <-- _GLOBAL_OFFSET_TABLE_ - add t4, s1 # t4 now holds relocated _G_O_T_ - addi t4, t4, 8 # skipping first two entries - li t2, 2 + PTR_L t3, -(1 * PTRSIZE)(t0) # t3 <-- num_got_entries + PTR_L t8, -(2 * PTRSIZE)(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ + PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_ + PTR_ADDI t8, t8, 2 * PTRSIZE # skipping first two entries + PTR_LI t2, 2 1: - lw t1, 0(t4) + PTR_L t1, 0(t8) beqz t1, 2f - add t1, s1 - sw t1, 0(t4) + PTR_ADD t1, s1 + PTR_S t1, 0(t8) 2: - addi t2, 1 + PTR_ADDI t2, 1 blt t2, t3, 1b - addi t4, 4 + PTR_ADDI t8, PTRSIZE - /* Clear BSS */ - lw t1, -12(t0) # t1 <-- uboot_end_data - lw t2, -8(t0) # t2 <-- uboot_end - add t1, s1 # adjust pointers - add t2, s1 + /* Update dynamic relocations */ + PTR_L t1, -(4 * PTRSIZE)(t0) # t1 <-- __rel_dyn_start + PTR_L t2, -(5 * PTRSIZE)(t0) # t2 <-- __rel_dyn_end + + b 2f # skip first reserved entry + PTR_ADDI t1, 2 * PTRSIZE - sub t1, 4 1: - addi t1, 4 - bltl t1, t2, 1b - sw zero, 0(t1) + lw t8, -4(t1) # t8 <-- relocation info + + PTR_LI t3, MIPS_RELOC + bne t8, t3, 2f # skip non-MIPS_RELOC entries + nop + + PTR_L t3, -(2 * PTRSIZE)(t1) # t3 <-- location to fix up in FLASH + + PTR_L t8, 0(t3) # t8 <-- original pointer + PTR_ADD t8, s1 # t8 <-- adjusted pointer + + PTR_ADD t3, s1 # t3 <-- location to fix up in RAM + PTR_S t8, 0(t3) + +2: + blt t1, t2, 1b + PTR_ADDI t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes + + /* + * Clear BSS + * + * GOT is now relocated. Thus __bss_start and __bss_end can be + * accessed directly via $gp. + */ + PTR_LA t1, __bss_start # t1 <-- __bss_start + PTR_LA t2, __bss_end # t2 <-- __bss_end + +1: + PTR_S zero, 0(t1) + blt t1, t2, 1b + PTR_ADDI t1, PTRSIZE move a0, s0 # a0 <-- gd - la t9, board_init_r + move a1, s2 + PTR_LA t9, board_init_r jr t9 - move a1, s2 + move ra, zero .end relocate_code - - /* Exception handlers */ -romReserved: - b romReserved - nop - -romExcHandle: - b romExcHandle - nop