X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=arch%2Fmips%2Fcpu%2Fmips32%2Fstart.S;h=70ad198cc9d2a54888d447a8641345bc5faa491a;hb=5b9c79a81db80c3f9e50c77477957cd803429af8;hp=e661d4625fc5f0167c24159fe8028f4a5a2685f5;hpb=91809608a44f7d90be4c630f09c9de54cc3852d8;p=oweals%2Fu-boot.git diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index e661d4625f..70ad198cc9 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -3,23 +3,7 @@ * * 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 @@ -27,6 +11,10 @@ #include #include +#ifndef CONFIG_SYS_MIPS_CACHE_MODE +#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT +#endif + /* * For the moment disable interrupts, mark the kernel mode and * set ST0_KX so that the CPU does not spit fire when using @@ -43,228 +31,115 @@ .set pop .endm - .macro setup_c0_status_reset -#ifdef CONFIG_64BIT - setup_c0_status ST0_KX 0 -#else - setup_c0_status 0 0 -#endif - .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 */ -#if defined(CONFIG_INCA_IP) - .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */ - .word 0x00000000 /* phase of the flash */ -#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 + /* 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 + * internal BootROM does a blind read at address 0xB0000010 to read the + * initial configuration for that EBU in order to access the flash + * device with correct parameters. This config option is board-specific. + */ + .word CONFIG_SYS_XWAY_EBU_BOOTCFG + .word 0x0 +#elif defined(CONFIG_QEMU_MALTA) + /* + * Linux expects the Board ID here. */ + .word 0x00000420 # 0x420 (Malta Board with CoreLV) + .word 0x00000000 +#endif + + .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. - */ + /* Clear watch registers */ mtc0 zero, CP0_WATCHLO mtc0 zero, CP0_WATCHHI - /* WP(Watch Pending), SW0/1 should be cleared. */ + /* WP(Watch Pending), SW0/1 should be cleared */ mtc0 zero, CP0_CAUSE - setup_c0_status_reset + setup_c0_status 0 0 /* Init Timer */ mtc0 zero, CP0_COUNT mtc0 zero, CP0_COMPARE -#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) +#ifndef CONFIG_SKIP_LOWLEVEL_INIT /* CONFIG0 register */ li t0, CONF_CM_UNCACHED mtc0 t0, CP0_CONFIG -#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ +#endif - /* Initialize $gp. - */ + /* Initialize $gp */ bal 1f - nop + nop .word _gp 1: lw gp, 0(ra) -#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) - /* Initialize any external memory. - */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + /* Initialize any external memory */ la t9, lowlevel_init jalr t9 - nop + nop - /* Initialize caches... - */ + /* Initialize caches... */ la t9, mips_cache_reset jalr t9 - nop + nop - /* ... and enable them. - */ - li t0, CONF_CM_CACHABLE_NONCOHERENT + /* ... and enable them */ + li t0, CONFIG_SYS_MIPS_CACHE_MODE mtc0 t0, CP0_CONFIG -#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ - - /* Set up temporary stack. - */ -#ifdef CONFIG_SYS_INIT_RAM_LOCK_MIPS - li a0, CONFIG_SYS_INIT_SP_OFFSET - la t9, mips_cache_lock - jalr t9 - nop #endif - li t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET - la sp, 0(t0) + /* Set up temporary stack */ + li sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET la t9, board_init_f jr t9 - nop + nop /* * void relocate_code (addr_sp, gd, addr_moni) @@ -279,62 +154,47 @@ reset: .globl relocate_code .ent relocate_code relocate_code: - move sp, a0 /* Set new stack pointer */ + move sp, a0 # set new stack pointer + + 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 + la t3, in_ram - lw t2, -12(t3) /* t2 <-- uboot_end_data */ + lw t2, -12(t3) # t2 <-- __image_copy_end move t1, a2 - move s2, a2 /* s2 <-- destination address */ - /* - * Fix $gp: - * - * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address - */ - move t6, gp - sub gp, CONFIG_SYS_MONITOR_BASE - add gp, a2 /* gp now adjusted */ - sub s1, gp, t6 /* s1 <-- relocation offset */ + add gp, s1 # adjust gp /* * t0 = source address * t1 = target address * t2 = source end address */ - - /* - * Save destination address and size for later usage in flush_cache() - */ - move s0, a1 /* save gd in s0 */ - move a0, t1 /* a0 <-- destination addr */ - sub a1, t2, t0 /* a1 <-- size */ - 1: lw t3, 0(t0) sw t3, 0(t1) addu t0, 4 - ble t0, t2, 1b - addu t1, 4 /* delay slot */ + blt t0, t2, 1b + addu t1, 4 - /* If caches were enabled, we would have to flush them here. - */ - - /* a0 & a1 are already set up for flush_cache(start, size) */ + /* If caches were enabled, we would have to flush them here. */ + sub a1, t1, s2 # a1 <-- size la t9, flush_cache jalr t9 - nop + move a0, s2 # a0 <-- destination address - /* Jump to where we've relocated ourselves. - */ + /* Jump to where we've relocated ourselves */ addi t0, s2, in_ram - _start jr t0 - nop + nop - .word _gp + .word __rel_dyn_end + .word __rel_dyn_start + .word __image_copy_end .word _GLOBAL_OFFSET_TABLE_ - .word uboot_end_data - .word uboot_end .word num_got_entries in_ram: @@ -344,47 +204,64 @@ 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_ */ - lw t5, -20(t0) /* t5 <-- _gp */ - sub t4, t5 /* compute offset*/ - add t4, t4, gp /* t4 now holds relocated _GLOBAL_OFFSET_TABLE_ */ - addi t4, t4, 8 /* Skipping first two entries. */ + lw t3, -4(t0) # t3 <-- num_got_entries + lw t8, -8(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ + add t8, s1 # t8 now holds relocated _G_O_T_ + addi t8, t8, 8 # skipping first two entries li t2, 2 1: - lw t1, 0(t4) + lw t1, 0(t8) beqz t1, 2f - add t1, s1 - sw t1, 0(t4) + add t1, s1 + sw t1, 0(t8) 2: addi t2, 1 blt t2, t3, 1b - addi t4, 4 /* delay slot */ + addi t8, 4 - /* Clear BSS. + /* Update dynamic relocations */ + lw t1, -16(t0) # t1 <-- __rel_dyn_start + lw t2, -20(t0) # t2 <-- __rel_dyn_end + + b 2f # skip first reserved entry + addi t1, 8 + +1: + lw t8, -4(t1) # t8 <-- relocation info + + li t3, 3 + bne t8, t3, 2f # skip non R_MIPS_REL32 entries + nop + + lw t3, -8(t1) # t3 <-- location to fix up in FLASH + + lw t8, 0(t3) # t8 <-- original pointer + add t8, s1 # t8 <-- adjusted pointer + + add t3, s1 # t3 <-- location to fix up in RAM + sw t8, 0(t3) + +2: + blt t1, t2, 1b + addi t1, 8 # each rel.dyn entry is 8 bytes + + /* + * Clear BSS + * + * GOT is now relocated. Thus __bss_start and __bss_end can be + * accessed directly via $gp. */ - lw t1, -12(t0) /* t1 <-- uboot_end_data */ - lw t2, -8(t0) /* t2 <-- uboot_end */ - add t1, s1 /* adjust pointers */ - add t2, s1 + la t1, __bss_start # t1 <-- __bss_start + la t2, __bss_end # t2 <-- __bss_end - sub t1, 4 1: - addi t1, 4 - bltl t1, t2, 1b - sw zero, 0(t1) /* delay slot */ + sw zero, 0(t1) + blt t1, t2, 1b + addi t1, 4 - move a0, s0 /* a0 <-- gd */ + move a0, s0 # a0 <-- gd la t9, board_init_r jr t9 - move a1, s2 /* delay slot */ + move a1, s2 .end relocate_code - - /* Exception handlers. - */ -romReserved: - b romReserved - -romExcHandle: - b romExcHandle