mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-11 13:56:30 +00:00
83d290c56f
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
292 lines
6.3 KiB
ArmAsm
292 lines
6.3 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
/*
|
|
* Startup Code for RISC-V Core
|
|
*
|
|
* Copyright (c) 2017 Microsemi Corporation.
|
|
* Copyright (c) 2017 Padmarao Begari <Padmarao.Begari@microsemi.com>
|
|
*
|
|
* Copyright (C) 2017 Andes Technology Corporation
|
|
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
|
|
*/
|
|
|
|
#include <asm-offsets.h>
|
|
#include <config.h>
|
|
#include <common.h>
|
|
#include <elf.h>
|
|
#include <asm/encoding.h>
|
|
|
|
#ifdef CONFIG_32BIT
|
|
#define LREG lw
|
|
#define SREG sw
|
|
#define REGBYTES 4
|
|
#define RELOC_TYPE R_RISCV_32
|
|
#define SYM_INDEX 0x8
|
|
#define SYM_SIZE 0x10
|
|
#else
|
|
#define LREG ld
|
|
#define SREG sd
|
|
#define REGBYTES 8
|
|
#define RELOC_TYPE R_RISCV_64
|
|
#define SYM_INDEX 0x20
|
|
#define SYM_SIZE 0x18
|
|
#endif
|
|
|
|
.section .text
|
|
.globl _start
|
|
_start:
|
|
j handle_reset
|
|
|
|
nmi_vector:
|
|
j nmi_vector
|
|
|
|
trap_vector:
|
|
j trap_entry
|
|
|
|
.global trap_entry
|
|
handle_reset:
|
|
li t0, CONFIG_SYS_SDRAM_BASE
|
|
SREG a2, 0(t0)
|
|
la t0, trap_entry
|
|
csrw mtvec, t0
|
|
csrwi mstatus, 0
|
|
csrwi mie, 0
|
|
|
|
/*
|
|
* Do CPU critical regs init only at reboot,
|
|
* not when booting from ram
|
|
*/
|
|
#ifdef CONFIG_INIT_CRITICAL
|
|
jal cpu_init_crit /* Do CPU critical regs init */
|
|
#endif
|
|
|
|
/*
|
|
* Set stackpointer in internal/ex RAM to call board_init_f
|
|
*/
|
|
call_board_init_f:
|
|
li t0, -16
|
|
li t1, CONFIG_SYS_INIT_SP_ADDR
|
|
and sp, t1, t0 /* force 16 byte alignment */
|
|
|
|
#ifdef CONFIG_DEBUG_UART
|
|
jal debug_uart_init
|
|
#endif
|
|
|
|
call_board_init_f_0:
|
|
mv a0, sp
|
|
jal board_init_f_alloc_reserve
|
|
mv sp, a0
|
|
jal board_init_f_init_reserve
|
|
|
|
mv a0, zero /* a0 <-- boot_flags = 0 */
|
|
la t5, board_init_f
|
|
jr t5 /* jump to board_init_f() */
|
|
|
|
/*
|
|
* void relocate_code (addr_sp, gd, addr_moni)
|
|
*
|
|
* This "function" does not return, instead it continues in RAM
|
|
* after relocating the monitor code.
|
|
*
|
|
*/
|
|
.globl relocate_code
|
|
relocate_code:
|
|
mv s2, a0 /* save addr_sp */
|
|
mv s3, a1 /* save addr of gd */
|
|
mv s4, a2 /* save addr of destination */
|
|
|
|
/*
|
|
*Set up the stack
|
|
*/
|
|
stack_setup:
|
|
mv sp, s2
|
|
la t0, _start
|
|
sub t6, s4, t0 /* t6 <- relocation offset */
|
|
beq t0, s4, clear_bss /* skip relocation */
|
|
|
|
mv t1, s4 /* t1 <- scratch for copy_loop */
|
|
la t3, __bss_start
|
|
sub t3, t3, t0 /* t3 <- __bss_start_ofs */
|
|
add t2, t0, t3 /* t2 <- source end address */
|
|
|
|
copy_loop:
|
|
LREG t5, 0(t0)
|
|
addi t0, t0, REGBYTES
|
|
SREG t5, 0(t1)
|
|
addi t1, t1, REGBYTES
|
|
blt t0, t2, copy_loop
|
|
|
|
/*
|
|
* Update dynamic relocations after board_init_f
|
|
*/
|
|
fix_rela_dyn:
|
|
la t1, __rel_dyn_start
|
|
la t2, __rel_dyn_end
|
|
beq t1, t2, clear_bss
|
|
add t1, t1, t6 /* t1 <- rela_dyn_start in RAM */
|
|
add t2, t2, t6 /* t2 <- rela_dyn_end in RAM */
|
|
|
|
/*
|
|
* skip first reserved entry: address, type, addend
|
|
*/
|
|
bne t1, t2, 7f
|
|
|
|
6:
|
|
LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */
|
|
li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */
|
|
bne t5, t3, 8f /* skip non-RISCV_RELOC entries */
|
|
LREG t3, -(REGBYTES*3)(t1)
|
|
LREG t5, -(REGBYTES)(t1) /* t5 <-- addend */
|
|
add t5, t5, t6 /* t5 <-- location to fix up in RAM */
|
|
add t3, t3, t6 /* t3 <-- location to fix up in RAM */
|
|
SREG t5, 0(t3)
|
|
7:
|
|
addi t1, t1, (REGBYTES*3)
|
|
ble t1, t2, 6b
|
|
|
|
8:
|
|
la t4, __dyn_sym_start
|
|
add t4, t4, t6
|
|
|
|
9:
|
|
LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */
|
|
srli t0, t5, SYM_INDEX /* t0 <--- sym table index */
|
|
andi t5, t5, 0xFF /* t5 <--- relocation type */
|
|
li t3, RELOC_TYPE
|
|
bne t5, t3, 10f /* skip non-addned entries */
|
|
|
|
LREG t3, -(REGBYTES*3)(t1)
|
|
li t5, SYM_SIZE
|
|
mul t0, t0, t5
|
|
add s1, t4, t0
|
|
LREG t5, REGBYTES(s1)
|
|
add t5, t5, t6 /* t5 <-- location to fix up in RAM */
|
|
add t3, t3, t6 /* t3 <-- location to fix up in RAM */
|
|
SREG t5, 0(t3)
|
|
10:
|
|
addi t1, t1, (REGBYTES*3)
|
|
ble t1, t2, 9b
|
|
|
|
/*
|
|
* trap update
|
|
*/
|
|
la t0, trap_entry
|
|
add t0, t0, t6
|
|
csrw mtvec, t0
|
|
|
|
clear_bss:
|
|
la t0, __bss_start /* t0 <- rel __bss_start in FLASH */
|
|
add t0, t0, t6 /* t0 <- rel __bss_start in RAM */
|
|
la t1, __bss_end /* t1 <- rel __bss_end in FLASH */
|
|
add t1, t1, t6 /* t1 <- rel __bss_end in RAM */
|
|
li t2, 0x00000000 /* clear */
|
|
beq t0, t1, call_board_init_r
|
|
|
|
clbss_l:
|
|
SREG t2, 0(t0) /* clear loop... */
|
|
addi t0, t0, REGBYTES
|
|
bne t0, t1, clbss_l
|
|
|
|
/*
|
|
* We are done. Do not return, instead branch to second part of board
|
|
* initialization, now running from RAM.
|
|
*/
|
|
call_board_init_r:
|
|
la t0, board_init_r
|
|
mv t4, t0 /* offset of board_init_r() */
|
|
add t4, t4, t6 /* real address of board_init_r() */
|
|
/*
|
|
* setup parameters for board_init_r
|
|
*/
|
|
mv a0, s3 /* gd_t */
|
|
mv a1, s4 /* dest_addr */
|
|
|
|
/*
|
|
* jump to it ...
|
|
*/
|
|
jr t4 /* jump to board_init_r() */
|
|
|
|
/*
|
|
* trap entry
|
|
*/
|
|
trap_entry:
|
|
addi sp, sp, -32*REGBYTES
|
|
SREG x1, 1*REGBYTES(sp)
|
|
SREG x2, 2*REGBYTES(sp)
|
|
SREG x3, 3*REGBYTES(sp)
|
|
SREG x4, 4*REGBYTES(sp)
|
|
SREG x5, 5*REGBYTES(sp)
|
|
SREG x6, 6*REGBYTES(sp)
|
|
SREG x7, 7*REGBYTES(sp)
|
|
SREG x8, 8*REGBYTES(sp)
|
|
SREG x9, 9*REGBYTES(sp)
|
|
SREG x10, 10*REGBYTES(sp)
|
|
SREG x11, 11*REGBYTES(sp)
|
|
SREG x12, 12*REGBYTES(sp)
|
|
SREG x13, 13*REGBYTES(sp)
|
|
SREG x14, 14*REGBYTES(sp)
|
|
SREG x15, 15*REGBYTES(sp)
|
|
SREG x16, 16*REGBYTES(sp)
|
|
SREG x17, 17*REGBYTES(sp)
|
|
SREG x18, 18*REGBYTES(sp)
|
|
SREG x19, 19*REGBYTES(sp)
|
|
SREG x20, 20*REGBYTES(sp)
|
|
SREG x21, 21*REGBYTES(sp)
|
|
SREG x22, 22*REGBYTES(sp)
|
|
SREG x23, 23*REGBYTES(sp)
|
|
SREG x24, 24*REGBYTES(sp)
|
|
SREG x25, 25*REGBYTES(sp)
|
|
SREG x26, 26*REGBYTES(sp)
|
|
SREG x27, 27*REGBYTES(sp)
|
|
SREG x28, 28*REGBYTES(sp)
|
|
SREG x29, 29*REGBYTES(sp)
|
|
SREG x30, 30*REGBYTES(sp)
|
|
SREG x31, 31*REGBYTES(sp)
|
|
csrr a0, mcause
|
|
csrr a1, mepc
|
|
mv a2, sp
|
|
jal handle_trap
|
|
csrw mepc, a0
|
|
|
|
/*
|
|
* Remain in M-mode after mret
|
|
*/
|
|
li t0, MSTATUS_MPP
|
|
csrs mstatus, t0
|
|
LREG x1, 1*REGBYTES(sp)
|
|
LREG x2, 2*REGBYTES(sp)
|
|
LREG x3, 3*REGBYTES(sp)
|
|
LREG x4, 4*REGBYTES(sp)
|
|
LREG x5, 5*REGBYTES(sp)
|
|
LREG x6, 6*REGBYTES(sp)
|
|
LREG x7, 7*REGBYTES(sp)
|
|
LREG x8, 8*REGBYTES(sp)
|
|
LREG x9, 9*REGBYTES(sp)
|
|
LREG x10, 10*REGBYTES(sp)
|
|
LREG x11, 11*REGBYTES(sp)
|
|
LREG x12, 12*REGBYTES(sp)
|
|
LREG x13, 13*REGBYTES(sp)
|
|
LREG x14, 14*REGBYTES(sp)
|
|
LREG x15, 15*REGBYTES(sp)
|
|
LREG x16, 16*REGBYTES(sp)
|
|
LREG x17, 17*REGBYTES(sp)
|
|
LREG x18, 18*REGBYTES(sp)
|
|
LREG x19, 19*REGBYTES(sp)
|
|
LREG x20, 20*REGBYTES(sp)
|
|
LREG x21, 21*REGBYTES(sp)
|
|
LREG x22, 22*REGBYTES(sp)
|
|
LREG x23, 23*REGBYTES(sp)
|
|
LREG x24, 24*REGBYTES(sp)
|
|
LREG x25, 25*REGBYTES(sp)
|
|
LREG x26, 26*REGBYTES(sp)
|
|
LREG x27, 27*REGBYTES(sp)
|
|
LREG x28, 28*REGBYTES(sp)
|
|
LREG x29, 29*REGBYTES(sp)
|
|
LREG x30, 30*REGBYTES(sp)
|
|
LREG x31, 31*REGBYTES(sp)
|
|
addi sp, sp, 32*REGBYTES
|
|
mret
|
|
|
|
#ifdef CONFIG_INIT_CRITICAL
|
|
cpu_init_crit:
|
|
ret
|
|
#endif
|