mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-10-06 14:22:18 +00:00
696a3b2a53
Get the start and end address for clearing BSS from the newly introduced symbols __bss_start and __bss_end. After GOT is relocated, those symbols are already pointing to the correct addresses. Also optimize the loop by moving the address incrementation to the delay slot to avoid the initial sub instruction. Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
165 lines
3.4 KiB
ArmAsm
165 lines
3.4 KiB
ArmAsm
/*
|
|
* Startup Code for MIPS32 XBURST CPU-core
|
|
*
|
|
* Copyright (c) 2010 Xiangfu Liu <xiangfu@sharism.cc>
|
|
*
|
|
* 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
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <version.h>
|
|
#include <asm/regdef.h>
|
|
#include <asm/mipsregs.h>
|
|
#include <asm/addrspace.h>
|
|
#include <asm/cacheops.h>
|
|
|
|
.set noreorder
|
|
|
|
.globl _start
|
|
.text
|
|
_start:
|
|
/* Initialize $gp */
|
|
bal 1f
|
|
nop
|
|
.word _gp
|
|
1:
|
|
lw gp, 0(ra)
|
|
|
|
/* Set up temporary stack */
|
|
li sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET
|
|
|
|
la t9, board_init_f
|
|
jr t9
|
|
nop
|
|
|
|
/*
|
|
* void relocate_code (addr_sp, gd, addr_moni)
|
|
*
|
|
* This "function" does not return, instead it continues in RAM
|
|
* after relocating the monitor code.
|
|
*
|
|
* a0 = addr_sp
|
|
* a1 = gd
|
|
* a2 = destination address
|
|
*/
|
|
.globl relocate_code
|
|
.ent relocate_code
|
|
relocate_code:
|
|
move sp, a0 # set new stack pointer
|
|
|
|
li t0, CONFIG_SYS_MONITOR_BASE
|
|
sub t6, a2, t0 # t6 <-- relocation offset
|
|
|
|
la t3, in_ram
|
|
lw t2, -12(t3) # t2 <-- uboot_end_data
|
|
move t1, a2
|
|
|
|
add gp, t6 # adjust gp
|
|
|
|
/*
|
|
* t0 = source address
|
|
* t1 = target address
|
|
* t2 = source end address
|
|
*/
|
|
1:
|
|
lw t3, 0(t0)
|
|
sw t3, 0(t1)
|
|
addu t0, 4
|
|
blt t0, t2, 1b
|
|
addu t1, 4
|
|
|
|
/* If caches were enabled, we would have to flush them here. */
|
|
|
|
/* flush d-cache */
|
|
li t0, KSEG0
|
|
addi t1, t0, CONFIG_SYS_DCACHE_SIZE
|
|
2:
|
|
cache INDEX_WRITEBACK_INV_D, 0(t0)
|
|
bne t0, t1, 2b
|
|
addi t0, CONFIG_SYS_CACHELINE_SIZE
|
|
|
|
sync
|
|
|
|
/* flush i-cache */
|
|
li t0, KSEG0
|
|
addi t1, t0, CONFIG_SYS_ICACHE_SIZE
|
|
3:
|
|
cache INDEX_INVALIDATE_I, 0(t0)
|
|
bne t0, t1, 3b
|
|
addi t0, CONFIG_SYS_CACHELINE_SIZE
|
|
|
|
/* Invalidate BTB */
|
|
mfc0 t0, CP0_CONFIG, 7
|
|
nop
|
|
ori t0, 2
|
|
mtc0 t0, CP0_CONFIG, 7
|
|
nop
|
|
|
|
/* Jump to where we've relocated ourselves */
|
|
addi t0, a2, in_ram - _start
|
|
jr t0
|
|
nop
|
|
|
|
.word _GLOBAL_OFFSET_TABLE_
|
|
.word uboot_end_data
|
|
.word uboot_end
|
|
.word num_got_entries
|
|
|
|
in_ram:
|
|
/*
|
|
* 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.
|
|
*/
|
|
lw t3, -4(t0) # t3 <-- num_got_entries
|
|
lw t4, -16(t0) # t4 <-- _GLOBAL_OFFSET_TABLE_
|
|
add t4, t6 # t4 now holds relocated _G_O_T_
|
|
addi t4, t4, 8 # skipping first two entries
|
|
li t2, 2
|
|
1:
|
|
lw t1, 0(t4)
|
|
beqz t1, 2f
|
|
add t1, t6
|
|
sw t1, 0(t4)
|
|
2:
|
|
addi t2, 1
|
|
blt t2, t3, 1b
|
|
addi t4, 4
|
|
|
|
/*
|
|
* Clear BSS
|
|
*
|
|
* GOT is now relocated. Thus __bss_start and __bss_end can be
|
|
* accessed directly via $gp.
|
|
*/
|
|
la t1, __bss_start # t1 <-- __bss_start
|
|
la t2, __bss_end # t2 <-- __bss_end
|
|
|
|
1:
|
|
sw zero, 0(t1)
|
|
blt t1, t2, 1b
|
|
addi t1, 4
|
|
|
|
move a0, a1 # a0 <-- gd
|
|
la t9, board_init_r
|
|
jr t9
|
|
move a1, a2
|
|
|
|
.end relocate_code
|