From bdce38965e79143ed58bf1c6d39c650ff3dfefd1 Mon Sep 17 00:00:00 2001 From: Rick Chen Date: Tue, 30 Apr 2019 13:49:33 +0800 Subject: [PATCH] riscv: Introduce CONFIG_XIP to support booting from flash When U-Boot boots from flash, during the boot process, hart_lottery and available_harts_lock variable addresses point to flash which is not writable. This causes boot failures on AE350. Introduce a config option CONFIG_XIP to support such configuration. Signed-off-by: Rick Chen Cc: Greentime Hu Reviewed-by: Lukas Auer Reviewed-by: Bin Meng --- arch/riscv/Kconfig | 7 +++++++ arch/riscv/cpu/cpu.c | 2 ++ arch/riscv/cpu/start.S | 6 ++++++ arch/riscv/include/asm/global_data.h | 2 ++ arch/riscv/lib/asm-offsets.c | 2 ++ arch/riscv/lib/smp.c | 2 ++ 6 files changed, 21 insertions(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index ae8ff7b765..362f3cdc65 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -162,6 +162,13 @@ config SBI_IPI default y if RISCV_SMODE depends on SMP +config XIP + bool "XIP mode" + help + XIP (eXecute In Place) is a method for executing code directly + from a NOR flash memory without copying the code to ram. + Say yes here if U-Boot boots from flash directly. + config STACK_SIZE_SHIFT int default 13 diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index c32de8a4c3..0cfd7d61a7 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -16,6 +16,7 @@ * before the bss section is available. */ phys_addr_t prior_stage_fdt_address __attribute__((section(".data"))); +#ifndef CONFIG_XIP u32 hart_lottery __attribute__((section(".data"))) = 0; /* @@ -23,6 +24,7 @@ u32 hart_lottery __attribute__((section(".data"))) = 0; * finished initialization of global data. */ u32 available_harts_lock = 1; +#endif static inline bool supports_extension(char ext) { diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index a4433fbd6b..3402d09a05 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -98,6 +98,7 @@ call_board_init_f_0: 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. @@ -106,6 +107,9 @@ call_board_init_f_0: li s2, 1 amoswap.w s2, t1, 0(t0) bnez s2, wait_for_gd_init +#else + bnez tp, secondary_hart_loop +#endif la t0, prior_stage_fdt_address SREG s1, 0(t0) @@ -115,6 +119,7 @@ call_board_init_f_0: /* 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) @@ -141,6 +146,7 @@ wait_for_gd_init: * secondary_hart_loop. */ bnez s2, secondary_hart_loop +#endif /* Enable cache */ jal icache_enable diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index dffcd45bf0..b74bd7e738 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -27,7 +27,9 @@ struct arch_global_data { #ifdef CONFIG_SMP struct ipi_data ipi[CONFIG_NR_CPUS]; #endif +#ifndef CONFIG_XIP ulong available_harts; +#endif }; #include diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c index f998402bd1..4fa4fd3714 100644 --- a/arch/riscv/lib/asm-offsets.c +++ b/arch/riscv/lib/asm-offsets.c @@ -14,7 +14,9 @@ int main(void) { DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart)); +#ifndef CONFIG_XIP DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts)); +#endif return 0; } diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c index caa292ccd2..cc66f15567 100644 --- a/arch/riscv/lib/smp.c +++ b/arch/riscv/lib/smp.c @@ -63,9 +63,11 @@ static int send_ipi_many(struct ipi_data *ipi) continue; } +#ifndef CONFIG_XIP /* skip if hart is not available */ if (!(gd->arch.available_harts & (1 << reg))) continue; +#endif gd->arch.ipi[reg].addr = ipi->addr; gd->arch.ipi[reg].arg0 = ipi->arg0; -- 2.25.1