mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-20 03:38:43 +00:00
7a9d109b00
This is in preparation for adapting this board to function correctly on a physical MIPS Malta board. The board is moved into an "imgtec" vendor directory at the same time in order to ready us for any other boards supported by Imagination in the future. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
267 lines
4.9 KiB
ArmAsm
267 lines
4.9 KiB
ArmAsm
/*
|
|
* Startup Code for MIPS32 CPU-core
|
|
*
|
|
* Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#include <asm-offsets.h>
|
|
#include <config.h>
|
|
#include <asm/regdef.h>
|
|
#include <asm/mipsregs.h>
|
|
|
|
#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
|
|
* 64-bit addresses.
|
|
*/
|
|
.macro setup_c0_status set clr
|
|
.set push
|
|
mfc0 t0, CP0_STATUS
|
|
or t0, ST0_CU0 | \set | 0x1f | \clr
|
|
xor t0, 0x1f | \clr
|
|
mtc0 t0, CP0_STATUS
|
|
.set noreorder
|
|
sll zero, 3 # ehb
|
|
.set pop
|
|
.endm
|
|
|
|
.set noreorder
|
|
|
|
.globl _start
|
|
.text
|
|
_start:
|
|
/* 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_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 */
|
|
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
|
|
|
|
/* Init Timer */
|
|
mtc0 zero, CP0_COUNT
|
|
mtc0 zero, CP0_COMPARE
|
|
|
|
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
|
/* CONFIG0 register */
|
|
li t0, CONF_CM_UNCACHED
|
|
mtc0 t0, CP0_CONFIG
|
|
#endif
|
|
|
|
/* Initialize $gp */
|
|
bal 1f
|
|
nop
|
|
.word _gp
|
|
1:
|
|
lw gp, 0(ra)
|
|
|
|
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
|
/* Initialize any external memory */
|
|
la t9, lowlevel_init
|
|
jalr t9
|
|
nop
|
|
|
|
/* Initialize caches... */
|
|
la t9, mips_cache_reset
|
|
jalr t9
|
|
nop
|
|
|
|
/* ... and enable them */
|
|
li t0, CONFIG_SYS_MIPS_CACHE_MODE
|
|
mtc0 t0, CP0_CONFIG
|
|
#endif
|
|
|
|
/* 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
|
|
|
|
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 <-- __image_copy_end
|
|
move t1, a2
|
|
|
|
add gp, s1 # 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. */
|
|
sub a1, t1, s2 # a1 <-- size
|
|
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
|
|
jr t0
|
|
nop
|
|
|
|
.word __rel_dyn_end
|
|
.word __rel_dyn_start
|
|
.word __image_copy_end
|
|
.word _GLOBAL_OFFSET_TABLE_
|
|
.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 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(t8)
|
|
beqz t1, 2f
|
|
add t1, s1
|
|
sw t1, 0(t8)
|
|
2:
|
|
addi t2, 1
|
|
blt t2, t3, 1b
|
|
addi t8, 4
|
|
|
|
/* 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.
|
|
*/
|
|
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, s0 # a0 <-- gd
|
|
la t9, board_init_r
|
|
jr t9
|
|
move a1, s2
|
|
|
|
.end relocate_code
|