GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
extra-y = start.o
obj-y += cpu.o mtrap.o
@@ -0,0 +1,24 @@
config RISCV_NDS
bool
select ARCH_EARLY_INIT_R
imply CPU
imply CPU_RISCV
imply RISCV_TIMER
imply ANDES_PLIC if (RISCV_MMODE || SPL_RISCV_MMODE)
imply ANDES_PLMT if (RISCV_MMODE || SPL_RISCV_MMODE)
imply SPL_CPU_SUPPORT
imply SPL_OPENSBI
imply SPL_LOAD_FIT
help
Run U-Boot on AndeStar V5 platforms and use some specific features
which are provided by Andes Technology AndeStar V5 families.
if RISCV_NDS
config RISCV_NDS_CACHE
bool "AndeStar V5 families specific cache support"
depends on RISCV_MMODE || SPL_RISCV_MMODE
help
Provide Andes Technology AndeStar V5 families specific cache support.
endif
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2017 Andes Technology Corporation
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
obj-y := cpu.o
obj-y += cache.o
@@ -0,0 +1,171 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2017 Andes Technology Corporation
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
*/
#include <common.h>
#include <cpu_func.h>
#include <dm.h>
#include <dm/uclass-internal.h>
#include <cache.h>
#include <asm/csr.h>
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
/* mcctlcommand */
#define CCTL_REG_MCCTLCOMMAND_NUM 0x7cc
/* D-cache operation */
#define CCTL_L1D_WBINVAL_ALL 6
#endif
#endif
#ifdef CONFIG_V5L2_CACHE
static void _cache_enable(void)
{
struct udevice *dev = NULL;
uclass_find_first_device(UCLASS_CACHE, &dev);
if (dev)
cache_enable(dev);
}
static void _cache_disable(void)
{
struct udevice *dev = NULL;
uclass_find_first_device(UCLASS_CACHE, &dev);
if (dev)
cache_disable(dev);
}
#endif
void flush_dcache_all(void)
{
#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL);
#endif
#endif
#endif
}
void flush_dcache_range(unsigned long start, unsigned long end)
{
flush_dcache_all();
}
void invalidate_dcache_range(unsigned long start, unsigned long end)
{
flush_dcache_all();
}
void icache_enable(void)
{
#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
asm volatile (
"csrr t1, mcache_ctl\n\t"
"ori t0, t1, 0x1\n\t"
"csrw mcache_ctl, t0\n\t"
);
#endif
#endif
#endif
}
void icache_disable(void)
{
#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
asm volatile (
"fence.i\n\t"
"csrr t1, mcache_ctl\n\t"
"andi t0, t1, ~0x1\n\t"
"csrw mcache_ctl, t0\n\t"
);
#endif
#endif
#endif
}
void dcache_enable(void)
{
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
asm volatile (
"csrr t1, mcache_ctl\n\t"
"ori t0, t1, 0x2\n\t"
"csrw mcache_ctl, t0\n\t"
);
#endif
#ifdef CONFIG_V5L2_CACHE
_cache_enable();
#endif
#endif
#endif
}
void dcache_disable(void)
{
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL);
asm volatile (
"csrr t1, mcache_ctl\n\t"
"andi t0, t1, ~0x2\n\t"
"csrw mcache_ctl, t0\n\t"
);
#endif
#ifdef CONFIG_V5L2_CACHE
_cache_disable();
#endif
#endif
#endif
}
int icache_status(void)
{
int ret = 0;
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
asm volatile (
"csrr t1, mcache_ctl\n\t"
"andi %0, t1, 0x01\n\t"
: "=r" (ret)
:
: "memory"
);
#endif
#endif
return ret;
}
int dcache_status(void)
{
int ret = 0;
#ifdef CONFIG_RISCV_NDS_CACHE
#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE)
asm volatile (
"csrr t1, mcache_ctl\n\t"
"andi %0, t1, 0x02\n\t"
: "=r" (ret)
:
: "memory"
);
#endif
#endif
return ret;
}
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2017 Andes Technology Corporation
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
*/
/* CPU specific code */
#include <common.h>
#include <cpu_func.h>
#include <irq_func.h>
#include <asm/cache.h>
/*
* cleanup_before_linux() is called just before we call linux
* it prepares the processor for linux
*
* we disable interrupt and caches.
*/
int cleanup_before_linux(void)
{
disable_interrupts();
/* turn off I/D-cache */
cache_flush();
icache_disable();
dcache_disable();
return 0;
}
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <cpu.h>
#include <dm.h>
#include <log.h>
#include <asm/encoding.h>
#include <dm/uclass-internal.h>
/*
* The variables here must be stored in the data section since they are used
* before the bss section is available.
*/
#ifdef CONFIG_OF_PRIOR_STAGE
phys_addr_t prior_stage_fdt_address __attribute__((section(".data")));
#endif
#ifndef CONFIG_XIP
u32 hart_lottery __attribute__((section(".data"))) = 0;
/*
* The main hart running U-Boot has acquired available_harts_lock until it has
* finished initialization of global data.
*/
u32 available_harts_lock = 1;
#endif
static inline bool supports_extension(char ext)
{
#ifdef CONFIG_CPU
struct udevice *dev;
char desc[32];
uclass_find_first_device(UCLASS_CPU, &dev);
if (!dev) {
debug("unable to find the RISC-V cpu device\n");
return false;
}
if (!cpu_get_desc(dev, desc, sizeof(desc))) {
/* skip the first 4 characters (rv32|rv64) */
if (strchr(desc + 4, ext))
return true;
}
return false;
#else /* !CONFIG_CPU */
#if CONFIG_IS_ENABLED(RISCV_MMODE)
return csr_read(CSR_MISA) & (1 << (ext - 'a'));
#else /* !CONFIG_IS_ENABLED(RISCV_MMODE) */
#warning "There is no way to determine the available extensions in S-mode."
#warning "Please convert your board to use the RISC-V CPU driver."
return false;
#endif /* CONFIG_IS_ENABLED(RISCV_MMODE) */
#endif /* CONFIG_CPU */
}
static int riscv_cpu_probe(void)
{
#ifdef CONFIG_CPU
int ret;
/* probe cpus so that RISC-V timer can be bound */
ret = cpu_probe_all();
if (ret)
return log_msg_ret("RISC-V cpus probe failed\n", ret);
#endif
return 0;
}
int arch_cpu_init_dm(void)
{
int ret;
ret = riscv_cpu_probe();
if (ret)
return ret;
/* Enable FPU */
if (supports_extension('d') || supports_extension('f')) {
csr_set(MODE_PREFIX(status), MSTATUS_FS);
csr_write(CSR_FCSR, 0);
}
if (CONFIG_IS_ENABLED(RISCV_MMODE)) {
/*
* Enable perf counters for cycle, time,
* and instret counters only
*/
csr_write(CSR_MCOUNTEREN, GENMASK(2, 0));
/* Disable paging */
if (supports_extension('s'))
csr_write(CSR_SATP, 0);
}
return 0;
}
int arch_early_init_r(void)
{
return riscv_cpu_probe();
}
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
config GENERIC_RISCV
bool
select ARCH_EARLY_INIT_R
imply CPU
imply CPU_RISCV
imply RISCV_TIMER
imply SIFIVE_CLINT if (RISCV_MMODE || SPL_RISCV_MMODE)
imply CMD_CPU
imply SPL_CPU_SUPPORT
imply SPL_OPENSBI
imply SPL_LOAD_FIT
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
obj-y += dram.o
obj-y += cpu.o
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <dm.h>
#include <irq_func.h>
/*
* cleanup_before_linux() is called just before we call linux
* it prepares the processor for linux
*
* we disable interrupt and caches.
*/
int cleanup_before_linux(void)
{
disable_interrupts();
cache_flush();
return 0;
}
/* To enumerate devices on the /soc/ node, create a "simple-bus" driver */
static const struct udevice_id riscv_virtio_soc_ids[] = {
{ .compatible = "riscv-virtio-soc" },
{ }
};
U_BOOT_DRIVER(riscv_virtio_soc) = {
.name = "riscv_virtio_soc",
.id = UCLASS_SIMPLE_BUS,
.of_match = riscv_virtio_soc_ids,
.flags = DM_FLAG_PRE_RELOC,
};
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <fdtdec.h>
#include <init.h>
#include <linux/sizes.h>
DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
{
return fdtdec_setup_mem_size_base();
}
int dram_init_banksize(void)
{
return fdtdec_setup_memory_banksize();
}
ulong board_get_usable_ram_top(ulong total_size)
{
#ifdef CONFIG_64BIT
/*
* Ensure that we run from first 4GB so that all
* addresses used by U-Boot are 32bit addresses.
*
* This in-turn ensures that 32bit DMA capable
* devices work fine because DMA mapping APIs will
* provide 32bit DMA addresses only.
*/
if (gd->ram_top > SZ_4G)
return SZ_4G;
#endif
return gd->ram_top;
}
@@ -0,0 +1,103 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* M-mode Trap Handler 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>
*
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
*/
#include <common.h>
#include <asm/encoding.h>
#ifdef CONFIG_32BIT
#define LREG lw
#define SREG sw
#define REGBYTES 4
#else
#define LREG ld
#define SREG sd
#define REGBYTES 8
#endif
.text
/* trap entry */
.align 2
.global 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, MODE_PREFIX(cause)
csrr a1, MODE_PREFIX(epc)
mv a2, sp
jal handle_trap
csrw MODE_PREFIX(epc), a0
LREG x1, 1 * 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)
LREG x2, 2 * REGBYTES(sp)
addi sp, sp, 32 * REGBYTES
MODE_PREFIX(ret)
@@ -0,0 +1,414 @@
/* 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>
#include <generated/asm-offsets.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 .data
secondary_harts_relocation_error:
.ascii "Relocation of secondary harts has failed, error %d\n"
.section .text
.globl _start
_start:
#if CONFIG_IS_ENABLED(RISCV_MMODE)
csrr a0, CSR_MHARTID
#endif
/* save hart id and dtb pointer */
mv tp, a0
mv s1, a1
la t0, trap_entry
csrw MODE_PREFIX(tvec), t0
/* mask all interrupts */
csrw MODE_PREFIX(ie), zero
#ifdef CONFIG_SMP
/* check if hart is within range */
/* tp: hart id */
li t0, CONFIG_NR_CPUS
bge tp, t0, hart_out_of_bounds_loop
#endif
#ifdef CONFIG_SMP
/* set xSIE bit to receive IPIs */
#if CONFIG_IS_ENABLED(RISCV_MMODE)
li t0, MIE_MSIE
#else
li t0, SIE_SSIE
#endif
csrs MODE_PREFIX(ie), t0
#endif
/*
* Set stackpointer in internal/ex RAM to call board_init_f
*/
call_board_init_f:
li t0, -16
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
li t1, CONFIG_SPL_STACK
#else
li t1, CONFIG_SYS_INIT_SP_ADDR
#endif
and sp, t1, t0 /* force 16 byte alignment */
call_board_init_f_0:
mv a0, sp
jal board_init_f_alloc_reserve
/*
* Set global data pointer here for all harts, uninitialized at this
* point.
*/
mv gp, a0
/* setup stack */
#ifdef CONFIG_SMP
/* tp: hart id */
slli t0, tp, CONFIG_STACK_SIZE_SHIFT
sub sp, a0, t0
#else
mv sp, a0
#endif
#ifndef CONFIG_XIP
/*
* Pick hart to initialize global data and run U-Boot. The other harts
* wait for initialization to complete.
*/
la t0, hart_lottery
li s2, 1
amoswap.w s2, t1, 0(t0)
bnez s2, wait_for_gd_init
#else
bnez tp, secondary_hart_loop
#endif
#ifdef CONFIG_OF_PRIOR_STAGE
la t0, prior_stage_fdt_address
SREG s1, 0(t0)
#endif
jal board_init_f_init_reserve
/* save the boot hart id to global_data */
SREG tp, GD_BOOT_HART(gp)
#ifndef CONFIG_XIP
la t0, available_harts_lock
fence rw, w
amoswap.w zero, zero, 0(t0)
wait_for_gd_init:
la t0, available_harts_lock
li t1, 1
1: amoswap.w t1, t1, 0(t0)
fence r, rw
bnez t1, 1b
/* register available harts in the available_harts mask */
li t1, 1
sll t1, t1, tp
LREG t2, GD_AVAILABLE_HARTS(gp)
or t2, t2, t1
SREG t2, GD_AVAILABLE_HARTS(gp)
fence rw, w
amoswap.w zero, zero, 0(t0)
/*
* Continue on hart lottery winner, others branch to
* secondary_hart_loop.
*/
bnez s2, secondary_hart_loop
#endif
/* Enable cache */
jal icache_enable
jal dcache_enable
#ifdef CONFIG_DEBUG_UART
jal debug_uart_init
#endif
mv a0, zero /* a0 <-- boot_flags = 0 */
la t5, board_init_f
jalr t5 /* jump to board_init_f() */
#ifdef CONFIG_SPL_BUILD
spl_clear_bss:
la t0, __bss_start
la t1, __bss_end
beq t0, t1, spl_stack_gd_setup
spl_clear_bss_loop:
SREG zero, 0(t0)
addi t0, t0, REGBYTES
blt t0, t1, spl_clear_bss_loop
spl_stack_gd_setup:
jal spl_relocate_stack_gd
/* skip setup if we did not relocate */
beqz a0, spl_call_board_init_r
mv s0, a0
/* setup stack on main hart */
#ifdef CONFIG_SMP
/* tp: hart id */
slli t0, tp, CONFIG_STACK_SIZE_SHIFT
sub sp, s0, t0
#else
mv sp, s0
#endif
/* set new stack and global data pointer on secondary harts */
spl_secondary_hart_stack_gd_setup:
la a0, secondary_hart_relocate
mv a1, s0
mv a2, s0
mv a3, zero
jal smp_call_function
/* hang if relocation of secondary harts has failed */
beqz a0, 1f
mv a1, a0
la a0, secondary_harts_relocation_error
jal printf
jal hang
/* set new global data pointer on main hart */
1: mv gp, s0
spl_call_board_init_r:
mv a0, zero
mv a1, zero
jal board_init_r
#endif
/*
* 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:
#ifdef CONFIG_SMP
/* tp: hart id */
slli t0, tp, CONFIG_STACK_SIZE_SHIFT
sub sp, s2, t0
#else
mv sp, s2
#endif
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
*/
j 10f
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)
j 10f
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 s5, t4, t0
LREG t0, -(REGBYTES)(t1) /* t0 <-- addend */
LREG t5, REGBYTES(s5)
add t5, t5, t0
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, 6b
/*
* trap update
*/
la t0, trap_entry
add t0, t0, t6
csrw MODE_PREFIX(tvec), 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 */
beq t0, t1, relocate_secondary_harts
clbss_l:
SREG zero, 0(t0) /* clear loop... */
addi t0, t0, REGBYTES
blt t0, t1, clbss_l
relocate_secondary_harts:
#ifdef CONFIG_SMP
/* send relocation IPI */
la t0, secondary_hart_relocate
add a0, t0, t6
/* store relocation offset */
mv s5, t6
mv a1, s2
mv a2, s3
mv a3, zero
jal smp_call_function
/* hang if relocation of secondary harts has failed */
beqz a0, 1f
mv a1, a0
la a0, secondary_harts_relocation_error
jal printf
jal hang
/* restore relocation offset */
1: mv t6, s5
#endif
/*
* We are done. Do not return, instead branch to second part of board
* initialization, now running from RAM.
*/
call_board_init_r:
jal invalidate_icache_all
jal flush_dcache_all
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() */
#ifdef CONFIG_SMP
hart_out_of_bounds_loop:
/* Harts in this loop are out of bounds, increase CONFIG_NR_CPUS. */
wfi
j hart_out_of_bounds_loop
#endif
#ifdef CONFIG_SMP
/* SMP relocation entry */
secondary_hart_relocate:
/* a1: new sp */
/* a2: new gd */
/* tp: hart id */
/* setup stack */
slli t0, tp, CONFIG_STACK_SIZE_SHIFT
sub sp, a1, t0
/* update global data pointer */
mv gp, a2
#endif
secondary_hart_loop:
wfi
#ifdef CONFIG_SMP
csrr t0, MODE_PREFIX(ip)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
andi t0, t0, MIE_MSIE
#else
andi t0, t0, SIE_SSIE
#endif
beqz t0, secondary_hart_loop
mv a0, tp
jal handle_ipi
#endif
j secondary_hart_loop
@@ -0,0 +1,82 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Based on arch/riscv/cpu/u-boot.lds, which is
* Copyright (C) 2017 Andes Technology Corporation
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
*
* and arch/mips/cpu/u-boot-spl.lds.
*/
MEMORY { .spl_mem : ORIGIN = IMAGE_TEXT_BASE, LENGTH = IMAGE_MAX_SIZE }
MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
OUTPUT_ARCH("riscv")
ENTRY(_start)
SECTIONS
{
. = ALIGN(4);
.text : {
arch/riscv/cpu/start.o (.text)
*(.text*)
} > .spl_mem
. = ALIGN(4);
.rodata : {
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
} > .spl_mem
. = ALIGN(4);
.data : {
*(.data*)
} > .spl_mem
. = ALIGN(4);
.got : {
__got_start = .;
*(.got.plt) *(.got)
__got_end = .;
} > .spl_mem
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
} > .spl_mem
. = ALIGN(4);
.binman_sym_table : {
__binman_sym_start = .;
KEEP(*(SORT(.binman_sym*)));
__binman_sym_end = .;
} > .spl_mem
. = ALIGN(4);
/DISCARD/ : { *(.rela.plt*) }
.rela.dyn : {
__rel_dyn_start = .;
*(.rela*)
__rel_dyn_end = .;
} > .spl_mem
. = ALIGN(4);
.dynsym : {
__dyn_sym_start = .;
*(.dynsym)
__dyn_sym_end = .;
} > .spl_mem
. = ALIGN(4);
_end = .;
.bss : {
__bss_start = .;
*(.bss*)
. = ALIGN(8);
__bss_end = .;
} > .bss_mem
}
@@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2017 Andes Technology Corporation
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
*/
OUTPUT_ARCH("riscv")
ENTRY(_start)
SECTIONS
{
. = ALIGN(4);
.text : {
arch/riscv/cpu/start.o (.text)
}
/* This needs to come before *(.text*) */
.efi_runtime : {
__efi_runtime_start = .;
*(.text.efi_runtime*)
*(.rodata.efi_runtime*)
*(.data.efi_runtime*)
__efi_runtime_stop = .;
}
.text_rest : {
*(.text*)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : {
__global_pointer$ = . + 0x800;
*(.data*)
}
. = ALIGN(4);
.got : {
__got_start = .;
*(.got.plt) *(.got)
__got_end = .;
}
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN(4);
.efi_runtime_rel : {
__efi_runtime_rel_start = .;
*(.rel*.efi_runtime)
*(.rel*.efi_runtime.*)
__efi_runtime_rel_stop = .;
}
. = ALIGN(4);
/DISCARD/ : { *(.rela.plt*) }
.rela.dyn : {
__rel_dyn_start = .;
*(.rela*)
__rel_dyn_end = .;
}
. = ALIGN(4);
.dynsym : {
__dyn_sym_start = .;
*(.dynsym)
__dyn_sym_end = .;
}
. = ALIGN(4);
_end = .;
.bss : {
__bss_start = .;
*(.bss*)
. = ALIGN(8);
__bss_end = .;
}
}