sparc: leon2: Updates for generic board initialization
Reworked the LEON2 start.S code to call board_init_f function at startup. Also implemented the relocate_code function in assembly to relocate the monitor and setup the stack pointer before calling relocated board_init_r. Add the CONFIG_SYS_GENERIC_BOARD variable to all the LEON2 boards. Signed-off-by: Francois Retief <fgretief@spaceteq.co.za>
This commit is contained in:
parent
a62bba15b5
commit
c837901bf1
|
|
@ -56,11 +56,6 @@ void cpu_init_f(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_init_f2(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int arch_cpu_init(void)
|
int arch_cpu_init(void)
|
||||||
{
|
{
|
||||||
gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
|
gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
|
||||||
|
|
|
||||||
|
|
@ -310,30 +310,62 @@ leon2_init_stackp:
|
||||||
andn %fp, 0x0f, %fp
|
andn %fp, 0x0f, %fp
|
||||||
sub %fp, 64, %sp
|
sub %fp, 64, %sp
|
||||||
|
|
||||||
|
leon2_init_tbr:
|
||||||
|
set CONFIG_SYS_TEXT_BASE, %g2
|
||||||
|
wr %g0, %g2, %tbr
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
cpu_init_unreloc:
|
cpu_init_unreloc:
|
||||||
call cpu_init_f
|
call cpu_init_f
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
board_init_unreloc:
|
||||||
|
call board_init_f
|
||||||
|
clr %o0 ! boot_flags
|
||||||
|
|
||||||
|
dead_unreloc:
|
||||||
|
ba dead_unreloc ! infinte loop
|
||||||
|
nop
|
||||||
|
|
||||||
|
!-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* void relocate_code (addr_sp, gd, addr_moni)
|
||||||
|
*
|
||||||
|
* This "function" does not return, instead it continues in RAM after
|
||||||
|
* relocating the monitor code.
|
||||||
|
*
|
||||||
|
* %o0 = Relocated stack pointer
|
||||||
|
* %o1 = Relocated global data pointer
|
||||||
|
* %o2 = Relocated text pointer
|
||||||
|
*/
|
||||||
|
.globl relocate_code
|
||||||
|
.type relocate_code, #function
|
||||||
|
.align 4
|
||||||
|
relocate_code:
|
||||||
|
SPARC_PIC_THUNK_CALL(l7)
|
||||||
|
|
||||||
/* un relocated start address of monitor */
|
/* un relocated start address of monitor */
|
||||||
#define TEXT_START _text
|
#define TEXT_START _text
|
||||||
|
|
||||||
/* un relocated end address of monitor */
|
/* un relocated end address of monitor */
|
||||||
#define DATA_END __init_end
|
#define DATA_END __init_end
|
||||||
|
|
||||||
SPARC_PIC_THUNK_CALL(l7)
|
|
||||||
reloc:
|
reloc:
|
||||||
SPARC_LOAD_ADDRESS(TEXT_START, l7, g2)
|
SPARC_LOAD_ADDRESS(TEXT_START, l7, g2)
|
||||||
SPARC_LOAD_ADDRESS(DATA_END, l7, g3)
|
SPARC_LOAD_ADDRESS(DATA_END, l7, g3)
|
||||||
set CONFIG_SYS_RELOC_MONITOR_BASE,%g4
|
mov %o2, %g4 ! relocation address
|
||||||
reloc_loop:
|
sub %g4, %g2, %g6 ! relocation offset
|
||||||
ldd [%g2],%l0
|
/* copy .text & .data to relocated address */
|
||||||
ldd [%g2+8],%l2
|
10: ldd [%g2], %l0
|
||||||
std %l0,[%g4]
|
ldd [%g2+8], %l2
|
||||||
std %l2,[%g4+8]
|
std %l0, [%g4]
|
||||||
inc 16,%g2
|
std %l2, [%g4+8]
|
||||||
subcc %g3,%g2,%g0
|
inc 16, %g2 ! src += 16
|
||||||
bne reloc_loop
|
cmp %g2, %g3
|
||||||
inc 16,%g4
|
bcs 10b ! while (src < end)
|
||||||
|
inc 16, %g4 ! dst += 16
|
||||||
|
|
||||||
clr %l0
|
clr %l0
|
||||||
clr %l1
|
clr %l1
|
||||||
|
|
@ -348,49 +380,42 @@ reloc_loop:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* clear bss area (the relocated) */
|
||||||
clr_bss:
|
clr_bss:
|
||||||
/* clear bss area (the relocated) */
|
|
||||||
SPARC_LOAD_ADDRESS(__bss_start, l7, g2)
|
SPARC_LOAD_ADDRESS(__bss_start, l7, g2)
|
||||||
SPARC_LOAD_ADDRESS(__bss_end, l7, g3)
|
SPARC_LOAD_ADDRESS(__bss_end, l7, g3)
|
||||||
sub %g3,%g2,%g3
|
sub %g3,%g2,%g3 ! length of .bss area
|
||||||
add %g3,%g4,%g3
|
add %g3,%g4,%g3
|
||||||
|
/* clearing 16byte a time ==> linker script need to align to 16 byte offset */
|
||||||
clr %g1 /* std %g0 uses g0 and g1 */
|
clr %g1 /* std %g0 uses g0 and g1 */
|
||||||
/* clearing 16byte a time ==> linker script need to align to 16 byte offset */
|
20:
|
||||||
clr_bss_16:
|
std %g0, [%g4]
|
||||||
std %g0,[%g4]
|
std %g0, [%g4+8]
|
||||||
std %g0,[%g4+8]
|
inc 16, %g4 ! ptr += 16
|
||||||
inc 16,%g4
|
cmp %g4, %g3
|
||||||
cmp %g3,%g4
|
bcs 20b ! while (ptr < end)
|
||||||
bne clr_bss_16
|
|
||||||
nop
|
nop
|
||||||
|
|
||||||
/* add offsets to GOT table */
|
/* add offsets to GOT table */
|
||||||
fixup_got:
|
fixup_got:
|
||||||
SPARC_LOAD_ADDRESS(__got_start, l7, g4)
|
SPARC_LOAD_ADDRESS(__got_start, l7, g4)
|
||||||
|
add %g4, %g6, %g4
|
||||||
SPARC_LOAD_ADDRESS(__got_end, l7, g3)
|
SPARC_LOAD_ADDRESS(__got_end, l7, g3)
|
||||||
/*
|
add %g3, %g6, %g3
|
||||||
* new got offset = (old GOT-PTR (read with ld) -
|
30: ld [%g4], %l0 ! load old GOT-PTR
|
||||||
* CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) +
|
#ifdef CONFIG_RELOC_GOT_SKIP_NULL
|
||||||
* Destination Address (from define)
|
cmp %l0, 0
|
||||||
*/
|
be 32f
|
||||||
set CONFIG_SYS_RELOC_MONITOR_BASE,%g2
|
#endif
|
||||||
SPARC_LOAD_ADDRESS(TEXT_START, l7, g1)
|
add %l0, %g6, %l0 ! relocate GOT pointer
|
||||||
add %g4,%g2,%g4
|
st %l0, [%g4]
|
||||||
sub %g4,%g1,%g4
|
32: inc 4, %g4 ! ptr += 4
|
||||||
add %g3,%g2,%g3
|
cmp %g4, %g3
|
||||||
sub %g3,%g1,%g3
|
bcs 30b ! while (ptr < end)
|
||||||
sub %g2,%g1,%g2 ! prepare register with (new base address) -
|
|
||||||
! (old base address)
|
|
||||||
got_loop:
|
|
||||||
ld [%g4],%l0 ! load old GOT-PTR
|
|
||||||
add %l0,%g2,%l0 ! increase with (new base address) -
|
|
||||||
! (old base)
|
|
||||||
st %l0,[%g4]
|
|
||||||
inc 4,%g4
|
|
||||||
cmp %g3,%g4
|
|
||||||
bne got_loop
|
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
#if 0 /* FIXME: Relocated PROM address should be calculated! */
|
||||||
|
|
||||||
prom_relocate:
|
prom_relocate:
|
||||||
SPARC_LOAD_ADDRESS(__prom_start, l7, g2)
|
SPARC_LOAD_ADDRESS(__prom_start, l7, g2)
|
||||||
SPARC_LOAD_ADDRESS(__prom_end, l7, g3)
|
SPARC_LOAD_ADDRESS(__prom_end, l7, g3)
|
||||||
|
|
@ -406,33 +431,42 @@ prom_relocate_loop:
|
||||||
bne prom_relocate_loop
|
bne prom_relocate_loop
|
||||||
inc 16,%g4
|
inc 16,%g4
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
! %o0 = stack pointer (relocated)
|
||||||
|
! %o1 = global data pointer (relocated)
|
||||||
|
! %o2 = text pointer (relocated)
|
||||||
|
|
||||||
|
! %g6 = relocation offset
|
||||||
|
! %l7 = _GLOBAL_OFFSET_TABLE_
|
||||||
|
|
||||||
/* Trap table has been moved, lets tell CPU about
|
/* Trap table has been moved, lets tell CPU about
|
||||||
* the new trap table address
|
* the new trap table address
|
||||||
*/
|
*/
|
||||||
|
update_trap_table_address:
|
||||||
set CONFIG_SYS_RELOC_MONITOR_BASE, %g2
|
wr %g0, %o2, %tbr
|
||||||
wr %g0, %g2, %tbr
|
nop
|
||||||
|
nop
|
||||||
/* call relocate*/
|
|
||||||
nop
|
nop
|
||||||
/* Call relocated init functions */
|
|
||||||
jump:
|
|
||||||
SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1)
|
|
||||||
set CONFIG_SYS_RELOC_MONITOR_BASE,%o2
|
|
||||||
add %o1,%o2,%o1
|
|
||||||
sub %o1,%g1,%o1
|
|
||||||
call %o1
|
|
||||||
clr %o0
|
|
||||||
|
|
||||||
SPARC_LOAD_ADDRESS(board_init_f, l7, o1)
|
update_stack_pointers:
|
||||||
set CONFIG_SYS_RELOC_MONITOR_BASE,%o2
|
mov %o0, %fp
|
||||||
add %o1,%o2,%o1
|
andn %fp, 0x0f, %fp ! align to 16 bytes
|
||||||
sub %o1,%g1,%o1
|
add %fp, -64, %fp ! make space for a window push
|
||||||
call %o1
|
mov %fp, %sp ! setup stack pointer
|
||||||
clr %o0
|
|
||||||
|
jump_board_init_r:
|
||||||
|
mov %o1, %o0 ! relocated global data pointer
|
||||||
|
mov %o2, %o1 ! relocated text pointer
|
||||||
|
SPARC_LOAD_ADDRESS(board_init_r, l7, o3)
|
||||||
|
add %o3, %g6, %o3 ! add relocation offset
|
||||||
|
call %o3
|
||||||
|
nop
|
||||||
|
|
||||||
dead: ta 0 ! if call returns...
|
dead: ta 0 ! if call returns...
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
!------------------------------------------------------------------------------
|
||||||
|
|
||||||
/* Interrupt handler caller,
|
/* Interrupt handler caller,
|
||||||
* reg L7: interrupt number
|
* reg L7: interrupt number
|
||||||
|
|
@ -461,7 +495,11 @@ _irq_entry:
|
||||||
|
|
||||||
RESTORE_ALL
|
RESTORE_ALL
|
||||||
|
|
||||||
!Window overflow trap handler.
|
!------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Window overflow trap handler.
|
||||||
|
*/
|
||||||
.global _window_overflow
|
.global _window_overflow
|
||||||
|
|
||||||
_window_overflow:
|
_window_overflow:
|
||||||
|
|
@ -469,14 +507,12 @@ _window_overflow:
|
||||||
mov %wim, %l3 ! Calculate next WIM
|
mov %wim, %l3 ! Calculate next WIM
|
||||||
mov %g1, %l7
|
mov %g1, %l7
|
||||||
srl %l3, 1, %g1
|
srl %l3, 1, %g1
|
||||||
sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1) , %l4
|
sll %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l4
|
||||||
or %l4, %g1, %g1
|
or %l4, %g1, %g1
|
||||||
|
|
||||||
save ! Get into window to be saved.
|
save ! Get into window to be saved.
|
||||||
mov %g1, %wim
|
mov %g1, %wim
|
||||||
nop;
|
nop; nop; nop
|
||||||
nop;
|
|
||||||
nop
|
|
||||||
st %l0, [%sp + 0];
|
st %l0, [%sp + 0];
|
||||||
st %l1, [%sp + 4];
|
st %l1, [%sp + 4];
|
||||||
st %l2, [%sp + 8];
|
st %l2, [%sp + 8];
|
||||||
|
|
@ -498,8 +534,9 @@ _window_overflow:
|
||||||
jmp %l1 ! Re-execute save.
|
jmp %l1 ! Re-execute save.
|
||||||
rett %l2
|
rett %l2
|
||||||
|
|
||||||
/* Window underflow trap handler. */
|
/*
|
||||||
|
* Window underflow trap handler.
|
||||||
|
*/
|
||||||
.global _window_underflow
|
.global _window_underflow
|
||||||
|
|
||||||
_window_underflow:
|
_window_underflow:
|
||||||
|
|
@ -533,7 +570,7 @@ _window_underflow:
|
||||||
jmp %l1 ! Re-execute restore.
|
jmp %l1 ! Re-execute restore.
|
||||||
rett %l2
|
rett %l2
|
||||||
|
|
||||||
retl
|
!------------------------------------------------------------------------------
|
||||||
|
|
||||||
_nmi_trap:
|
_nmi_trap:
|
||||||
nop
|
nop
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
* (C) Copyright 2003-2005
|
* (C) Copyright 2003-2005
|
||||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||||
*
|
*
|
||||||
* (C) Copyright 2007
|
* (C) Copyright 2007, 2015
|
||||||
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
|
* Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef __CONFIG_H__
|
#ifndef __CONFIG_H__
|
||||||
#define __CONFIG_H__
|
#define __CONFIG_H__
|
||||||
|
|
||||||
|
#define CONFIG_SYS_GENERIC_BOARD
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* High Level Configuration Options
|
* High Level Configuration Options
|
||||||
* (easy to change)
|
* (easy to change)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue