Commit graph

36 commits

Author SHA1 Message Date
Sean Anderson
85768134b4 riscv: Ensure gp is NULL or points to valid data
This ensures constructs like `if (gd & gd->...) { ... }` work when
accessing the global data pointer. Without this change, it was possible for
a very early trap to cause _exit_trap to directly or indirectly (through
printf) to read arbitrary memory. This could cause a second trap,
preventing show_regs from being printed.

printf (and specifically puts) uses gd to determine what function to print
with. These functions in turn use gd to find the serial device, etc.
However, before accessing gd, puts first checks to see if it is non-NULL.
This indicates an existing (perhaps undocumented) assumption that either gd
is NULL or it is completely valid.

Before this patch, gd either points to unexpected data (because it retains
the value it did from the prior-stage) or points to uninitialized data
(because it has not yet been initialized by board_init_f_init_reserve)
until the hart has acquired available_harts_lock. This can cause two
problems, depending on the value of gd->flags. If GD_FLG_SERIAL_READY is
unset, then some garbage data will be printed to stdout, but there will not
be a second trap. However, if GD_FLG_SERIAL_READY is set, then puts will
try to print with serial_puts, which will likely cause a second trap.

After this patch, gd is zero up until either a hart has set it in
wait_for_gd_init, or until it is set by arch_init_gd. This prevents its
usage before its data is initialized because both handle_trap and puts
ensure that gd is nonzero before using it. After gd has been set, it is OK
to access it because its data has been cleared (and so flags is valid).

XIP cannot use locks because flash is not writable. This leaves it
vulnerable to the same class of bugs regarding already-pending IPIs as
before this series. Fixing that would require finding another method of
synchronization, which is outside the scope of this series.

Fixes: 7c6ca03eae ("riscv: additional crash information")
Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Rick Chen <rick@andestech.com>
2020-09-30 08:54:52 +08:00
Sean Anderson
309995b315 riscv: Consolidate fences into AMOs for available_harts_lock
We can reduce the number of instructions needed to use available_harts_lock
by using the aq and rl suffixes for AMOs.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Rick Chen <rick@andestech.com>
2020-09-30 08:54:52 +08:00
Sean Anderson
c41045411b Revert "riscv: Clear pending interrupts before enabling IPIs"
Clearing MIP.MSIP is not guaranteed to do anything by the spec. In
addition, most existing RISC-V hardware does nothing when this bit is set.

The following commits "riscv: Use a valid bit to ignore already-pending
IPIs" and "riscv: Clear pending IPIs on initialization" should implement
the original intent of the reverted commit in a more robust manner.

This reverts commit 9472630337.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Rick Chen <rick@andestech.com>
2020-09-30 08:54:52 +08:00
Leo Yu-Chi Liang
e491e15a3f riscv: Fix linking error when building u-boot-spl with no SMP support
Switch off SMP support when building u-boot-spl would cause linking error as follow:
undefined reference to 'secondary hart relocate' and 'smp_call_function'.
Add macro to wrap up proper code region that needs SMP configuration on.

Signed-off by: Leo Liang <ycliang@andestech.com>
Cc: rick@andestech.com
Reviewed-by: Bin Meng <bin.meng@windriver.com>
2020-07-24 14:56:13 +08:00
Sean Anderson
9472630337 riscv: Clear pending interrupts before enabling IPIs
On some platforms (k210), the previous stage bootloader may have not
cleared pending IPIs before transferring control to U-Boot. This can cause
race conditions, as multiple harts all attempt to initialize the IPI
controller at once. This patch clears IPIs before enabling them, ensuring
that only one hart modifies shared memory at once.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Rick Chen <rick@andestech.com>
2020-07-01 15:01:21 +08:00
Atish Patra
d4ea649f17 riscv: Provide a mechanism to fix DT for reserved memory
In RISC-V, M-mode software can reserve physical memory regions
by setting appropriate physical memory protection (PMP) csr. As the
PMP csr are accessible only in M-mode, S-mode U-Boot can not read
this configuration directly. However, M-mode software can pass this
information via reserved-memory node in device tree so that S-mode
software can access this information.

This patch provides a framework to copy to the reserved-memory node
from one DT to another. This will be used to update the DT used by
U-Boot and the DT passed to the next stage OS.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
2020-04-23 10:14:16 +08:00
Bin Meng
191636e448 riscv: Introduce SPL_SMP Kconfig option for U-Boot SPL
With SBI v0.2 HSM extension, only a single hart need to boot and
enter operating system. The booting hart can bring up secondary
harts one by one afterwards.

For U-Boot running in SPL, SMP can be turned on, while in U-Boot
proper, SMP can be optionally turned off if using SBI v0.2 HSM.

Introduce a new SPL_SMP Kconfig option to support this.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-04-23 10:14:06 +08:00
Bin Meng
84dc9d2690 riscv: Merge unnecessary SMP ifdefs in start.S
Two consecutive SMP ifdefs blocks can be combined into one.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-04-23 10:14:06 +08:00
Sean Anderson
404339759e riscv: Remove unnecessary instruction
The add instruction on risc-v can have any three sources and targets, so there
is no need for an intermediate mov.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Rick Chen <rick@andestech.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
2020-02-10 14:51:52 +08:00
Simon Glass
941338725d common: Move relocate_code() to init.h
This is an init function so move it out of the common header. Avoid using
the typedef so that we don't have to include the global_data header file.

Also tidy up the function style in comments while we are here.

Signed-off-by: Simon Glass <sjg@chromium.org>
2020-01-17 13:26:49 -05:00
Lukas Auer
90ae281437 riscv: add option to wait for ack from secondary harts in smp functions
Add a wait option to smp_call_function() to wait for the secondary harts
to acknowledge the call-function request. The request is considered to
be acknowledged once each secondary hart has cleared the corresponding
IPI.

As part of the call-function request, the secondary harts invalidate the
instruction cache after clearing the IPI. This adds a delay between
acknowledgment (clear IPI) and fulfillment (call function) of the
request. We want to use the acknowledgment to be able to judge when the
request has been completed. Remove the delay by clearing the IPI after
cache invalidation and just before calling the function from the
request.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Rick Chen <rick@andestech.com>
Tested-by: Rick Chen <rick@andestech.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2019-12-10 08:23:10 +08:00
Rick Chen
444c46413f riscv: Fix clear bss loop in the start-up code
For RV64, it will use sd instruction to clear t0
register, and the increament will be 8 bytes. So
if the difference between__bss_strat and __bss_end
was not 8 bytes aligned, the clear bss loop will
overflow and acks like system hang.

Signed-off-by: Rick Chen <rick@andestech.com>
Cc: KC Lin <kclin@andestech.com>
Cc: Alan Kao <alankao@andestech.com>
2019-12-10 08:23:10 +08:00
Marcus Comstedt
f6cb427fdc riscv: update fix_rela_dyn
The addend is now added for RELOC_TYPE relocs.  Also, changed the loop
structure so that all the R_RISCV_RELATIVE relocs are not required to
be at the beginning of the list.

Signed-off-by: Marcus Comstedt <marcus@mc.pp.se>
Cc: Rick Chen <rick@andestech.com>
2019-09-03 09:30:41 +08:00
Lukas Auer
c7e1effb96 riscv: support SPL stack and global data relocation
To support relocation of the stack and global data on RISC-V, the
secondary harts must be notified of the change using IPIs. We can reuse
the hart relocation code for this purpose. It uses global data to store
the new stack pointer and global data pointer for the secondary harts.
This means that we cannot update the global data pointer of the main
hart in spl_relocate_stack_gd(), because the secondary harts have not
yet been relocated at this point. It is updated after the secondary
harts have been notified.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2019-08-26 16:07:42 +08:00
Lukas Auer
8c59f2023c riscv: add SPL support
U-Boot SPL on the generic RISC-V CPU supports two boot flows, directly
jumping to the image and via OpenSBI firmware. In the first case, both
U-Boot SPL and proper must be compiled to run in the same privilege
mode. Using OpenSBI firmware, U-Boot SPL must be compiled for machine
mode and U-Boot proper for supervisor mode.

To be able to use SPL, boards have to provide a supported SPL boot
device.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2019-08-26 16:07:42 +08:00
Lukas Auer
fbfd92bf9b riscv: add run mode configuration for SPL
U-Boot SPL can be run in a different privilege mode from U-Boot proper.
Add new configuration entries for SPL to allow the run mode to be
configured independently of U-Boot proper.

Extend all uses of the CONFIG_RISCV_SMODE and CONFIG_RISCV_MMODE
configuration symbols to also cover the SPL equivalents. Ensure that
files compatible with only one privilege mode are not included in builds
targeting an incompatible privilege mode.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2019-08-26 16:07:42 +08:00
Bin Meng
4d2583dba1 riscv: Access CSRs using CSR numbers
We should prefer accessing CSRs using their CSR numbers
because:
1. It compiles fine with older toolchains.
2. We can use latest CSR names in #define macro names of CSR
   numbers as-per RISC-V spec.
3. We can access newly added CSRs even if toolchain does not
   recognize newly added CSRs by name.

This commit is inspired from Linux kernel commit a3182c91ef4e
("RISC-V: Access CSRs using CSR numbers").

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Rick Chen <rick@andestech.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
2019-08-15 13:42:28 +08:00
Rick Chen
f9281b8905 riscv: prior_stage_fdt_address should only be used when OF_PRIOR_STAGE is enabled
This patch will fix prior_stage_fdt_address write failure problem, when
AE350 boots from flash.

When AE350 boots from flash, prior_stage_fdt_address will be flash
address, we shall avoid it to be written.

Signed-off-by: Rick Chen <rick@andestech.com>
Cc: Greentime Hu <greentime@andestech.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
2019-05-09 16:46:46 +08:00
Rick Chen
bdce38965e 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 <rick@andestech.com>
Cc: Greentime Hu <greentime@andestech.com>
Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
2019-05-09 16:46:46 +08:00
Lukas Auer
8ac39e2974 riscv: hang if relocation of secondary harts fails
Print an error message and hang if smp_call_function() returns an error,
indicating that relocation of the secondary harts has failed.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2019-04-08 09:44:26 +08:00
Lukas Auer
e043240252 riscv: do not rely on hart ID passed by previous boot stage
RISC-V U-Boot expects the hart ID to be passed to it via register a0 by
the previous boot stage. Machine mode firmware such as BBL and OpenSBI
do this when starting their payload (U-Boot) in supervisor mode. If
U-Boot is running in machine mode, this task must be handled by the boot
ROM. Explicitly populate register a0 with the hart ID from the mhartid
CSR to avoid possible problems on RISC-V processors with a boot ROM that
does not handle this task.

Suggested-by: Rick Chen <rick@andestech.com>
Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Rick Chen <rick@andestech.com>
Tested-by: Rick Chen <rick@andestech.com>
2019-04-08 09:44:26 +08:00
Lukas Auer
3dea63c844 riscv: add support for multi-hart systems
On RISC-V, all harts boot independently. To be able to run on a
multi-hart system, U-Boot must be extended with the functionality to
manage all harts in the system. All harts entering U-Boot are registered
in the available_harts mask stored in global data. A hart lottery system
as used in the Linux kernel selects the hart U-Boot runs on. All other
harts are halted. U-Boot can delegate functions to them using
smp_call_function().

Every hart has a valid pointer to the global data structure and a 8KiB
stack by default. The stack size is set with CONFIG_STACK_SIZE_SHIFT.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
2019-04-08 09:44:26 +08:00
Lukas Auer
1446b26f76 riscv: save hart ID in register tp instead of s0
The hart ID passed by the previous boot stage is currently stored in
register s0. If we divert the control flow inside a function, which is
required as part of multi-hart support, the function epilog may not be
called, clobbering register s0. Save the hart ID in the unallocatable
register tp instead to protect the hart ID.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Rick Chen <rick@andestech.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2019-04-08 09:44:26 +08:00
Lukas Auer
2503ccc55f riscv: delay initialization of caches and debug UART
Move the initialization of the caches and the debug UART until after
board_init_f_init_reserve. This is in preparation for SMP support, where
code prior to this point will be executed by all harts. This ensures
that initialization will only be performed once on the main hart running
U-Boot.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
2019-04-08 09:44:26 +08:00
Bin Meng
51ab4570f3 riscv: Save boot hart id to the global data
At present the hart id passed via a0 in the U-Boot entry is saved
to s0 at the beginning but does not preserve later. Save it to the
global data structure so that it can be used later.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Anup Patel <anup@brainfault.org>
2018-12-18 09:56:27 +08:00
Bin Meng
4b3f5ed5ac riscv: Move trap handler codes to mtrap.S
Currently the M-mode trap handler codes are in start.S. For future
extension, move them to a separate file mtrap.S.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Anup Patel <anup@brainfault.org>
2018-12-18 09:56:27 +08:00
Rick Chen
48cbf62460 riscv: ax25-ae350: Pass dtb address to u-boot with a1 register
ax25-ae350 use CONFIG_OF_BOARD via a2 and CONFIG_SYS_SDRAM_BASE
to boot from ram which allow the board to override the fdt
address originally.

But after this patch
riscv: save hart ID and device tree passed by prior boot stage
It provide prior_stage_fdt_address which offer a temporary
memory address to keep the dtb address passing from loader(gdb)
to u-boot with a1.

So passing via a2 and CONFIG_SYS_SDRAM_BASE is redundant and
can be removed. And it also somehow may corrupted BBL if it
was be arranged in CONFIG_SYS_SDRAM_BASE.

In board_fdt_blob_setup()
When boting from ram:
prior_stage_fdt_address will be use to reserved dtb temporarily.

When booting from ROM:
dtb will be pre-burned in CONFIG_SYS_FDT_BASE, if it is flash base.
Or CONFIG_SYS_FDT_BASE maybe a memory map space (NOT RAM or ROM)
which is provided by HW.

Signed-off-by: Rick Chen <rick@andestech.com>
Cc: Greentime Hu <greentime@andestech.com>
2018-12-05 14:14:16 +08:00
Anup Patel
d2db2a8fa4 riscv: Add kconfig option to run U-Boot in S-mode
This patch adds kconfig option RISCV_SMODE to run U-Boot in
S-mode. When this opition is enabled we use s<xyz> CSRs instead
of m<xyz> CSRs.

It is important to note that there is no equivalent S-mode CSR
for misa and mhartid CSRs so we expect M-mode runtime firmware
(BBL or equivalent) to emulate misa and mhartid CSR read.

In-future, we will have more patches to avoid accessing misa and
mhartid CSRs from S-mode.

Signed-off-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
2018-12-05 14:13:53 +08:00
Rick Chen
52923c6db7 riscv: cache: Implement i/dcache [status, enable, disable]
AndeStar RISC-V(V5) provide mcache_ctl register which
can configure I/D cache as enabled or disabled.

This CSR will be encapsulated by CONFIG_RISCV_NDS.
If you want to configure cache on AndeStar V5
AE350 platform. YOu can enable [*] AndeStar V5 ISA support
by make menuconfig.

This approach also provide the expansion when the
vender specific features are going to join in.

Signed-off-by: Rick Chen <rick@andestech.com>
Cc: Greentime Hu <greentime@andestech.com>
2018-11-26 13:58:01 +08:00
Lukas Auer
5d8b2e7711 riscv: save hart ID and device tree passed by prior boot stage
Store the hart ID and device tree passed by the prior boot stage (in a0
and a1) in registers s0 and s1. Replace one use of s1 in start.S to
avoid overwriting it.

The device tree is also stored in memory to make it available to U-Boot
with the configuration CONFIG_OF_PRIOR_STAGE.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Rick Chen <rick@andestech.com>
2018-11-26 13:57:32 +08:00
Lukas Auer
31f9058994 riscv: do not blindly modify the mstatus CSR
The mstatus CSR includes WPRI (writes preserve values, reads ignore
values) fields and must therefore not be set to zero without preserving
these fields. It is not apparent why mstatus is set to zero here since
it is not required for U-Boot to run. Remove it.

This instruction and others encode zero as an immediate.  RISC-V has the
zero register for this purpose. Replace the immediates with the zero
register.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Rick Chen <rick@andestech.com>
2018-11-26 13:57:32 +08:00
Lukas Auer
8bfa231cc6 riscv: remove unused labels in start.S
The labels nmi_vector, trap_vector and handle_reset in start.S are not
used for RISC-V. Remove them.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
2018-11-26 13:57:32 +08:00
Bin Meng
c95cafd0b1 Drop CONFIG_INIT_CRITICAL
This is now deprecated and no board is using it. Drop it.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
2018-11-26 13:57:31 +08:00
Lukas Auer
2a23ac6107 riscv: align mtvec on a 4-byte boundary
The machine trap-vector base address (mtvec) must be aligned on a 4-byte
boundary. Add the necessary align directive to trap_entry.

This patch also removes the global directive for trap_entry, which is
not required.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
2018-11-26 13:57:31 +08:00
Lukas Auer
c55309c091 riscv: fix inconsistent use of spaces and tabs in start.S
start.S uses both tabs and spaces after instructions. Fix this by only
using tabs after instructions.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Rick Chen <rick@andestech.com>
2018-11-26 13:57:31 +08:00
Bin Meng
b5369c5813 riscv: Make start.S available for all targets
Currently start.S is inside arch/riscv/cpu/ax25/, but it can be
common for all RISC-V targets.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
2018-10-03 17:48:14 +08:00
Renamed from arch/riscv/cpu/ax25/start.S (Browse further)