Commit Graph

81 Commits

Author SHA1 Message Date
Anup Patel
abea949721 lib: sbi: Introduce trap context
Club the struct sbi_trap_regs and struct sbi_trap_info a new
struct sbi_trap_context (aka trap context) which must be saved
by low-level trap handler before calling sbi_trap_handler().

To track nested traps, the struct sbi_scratch points to the current
trap context and the trap context has pointer to pervious context
of previous trap.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
2024-03-19 11:31:22 +05:30
Anup Patel
60ffc154c8 include: sbi: Add trap_context pointer in struct sbi_scratch
To track nested traps, the struct sbi_scratch needs a pointer the
current trap context so add trap_context pointer in struct sbi_context.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
2024-03-19 11:31:20 +05:30
Anup Patel
ebb697ad8c lib: sbi: Remove sbi_trap_exit() and related code
Over the years, no uses of sbi_trap_exit() have been found so remove
it and also remove related code from fw_base.S and sbi_scratch.h.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
2024-03-19 11:31:18 +05:30
Xiang W
526b9ce079 firmware: fw_base.S: fix _reset_regs
a3 and a4 cannot be reset because used in fw_platform_init.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-09 18:16:04 +05:30
Xiang W
8151105af5 firmware: fw_base.S: Remove _relocate_lottery
Remove _relocate_lottery and use _boot_status instead.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-09 18:14:46 +05:30
Xiang W
b27b7c6d88 firmware: fw_base: Simplified setup trap handler
The same detection was done twice when setting mtvec and trap_exit.
Merging can reduce code size.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-09 18:04:39 +05:30
Xiang W
fdf5589f04 firmware: fw_base.S: Simplify address get
Simplify address get and remove _link_start _link_end _load_start.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-09 17:54:50 +05:30
Xiang W
9c8b18eb01 firmware: fw_base.S: remove _runtime_offset
_runtime_offset is a variable not used elsewhere, so remove it.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-06 12:33:25 +05:30
Xiang W
4c6b7cb76b firmware: fw_base.S: Improve loading u32
lwu exists under the current rv64 and should also exist under the rv128
in the future, so I modified the conditions of conditional compilation
so that it can adapt to the future situation

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-06 12:29:31 +05:30
Zhang Runmin
21caaa3f56 fw_base.S: Fix comment errors
When calling '_reset_regs', it'll reset all registers except some
specific registers (ra, a0, a1, and a2).

Both boot HART and non-boot HARTs will execute the '_start_warm'
function. Therefore, when '_reset_regs' is called in '_start_warm', it
will reset all registers except some specific registers (ra, a0, a1 and
a2) for both boot HART and non-boot HARTs.

Signed-off-by: Zhang Runmin <fmrt19zrmin@163.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-05 10:30:42 +05:30
Guo Ren
fccdf41d32 firmware: fw_base.S: Fix boot hart status synchronization
It's wrong to put the fence after setting the boot status flag because
all relocation operations must be finished before setting the status
flag. So, this fence must be put before the setting status flag, and
there is no use in putting a fence between _start_warm and setting
status flag.

Also, nop can't delay other harts too much, so use div instead, just
like Linux cpu_relax. Current opensbi force enables “M” Standard
Extension, and mul instructions have been used in the fw_base.S.

After the above two fixes, the boot hart index param of the
fw_dynamic_info could be guaranteed properly for all platforms.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 16:19:42 +05:30
Vivian Wang
2a6d72534d firmware: Remove handling of R_RISCV_{32,64}
Since everything is statically linked, we won't actually have
R_RISCV_{32,64} relocations. No need to handle these.

Fixes: 0f20e8adcf ("firmware: Support position independent execution")
Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 09:21:23 +05:30
Mitchell Horne
94197a8c49 fw_base.S: Fix assembler error with clang 16+
Attempting to build OpenSBI with clang 16 and the following command:

   $ make LLVM=1 PLATFORM=generic

Results in the following error:

    AS        platform/generic/firmware/fw_dynamic.o
   /tmp/fw_dynamic-d000a6.s:429:9: error: symbol '_fw_start' can not be undefined in a subtraction expression
    .dword _fw_rw_start - _fw_start

Work around this issue by eliminating the __fw_rw_offset variable and
performing the offset calculation at run-time instead. This takes
advantage of the fact that the a4 register contains the value of
_fw_start.

Signed-off-by: Mitchell Horne <mhorne@FreeBSD.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-08-06 11:06:02 +05:30
Xiang W
d64942f0e4 firmware: Fix find hart index
After the loop to find the hartid is launched, assigning -1 to
index will fail in the subsequent compare instruction bge. Fix
This.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-06-21 10:20:51 +05:30
Anup Patel
5cf9a54016 platform: Allow platforms to specify heap size
We extend struct sbi_platform and struct sbi_scratch to allow platforms
specify the heap size to the OpenSBI firmwares. The OpenSBI firmwares
will use this information to determine the location of heap and provide
heap base address in per-HART scratch space.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:45:33 +05:30
Bin Meng
e41dbb507c firmware: Change to use positive offset to access relocation entries
The codes currently skip the very first relocation entry, but later
reference the elements in the relocation entry using minus offsets.

Change to use positive offsets so that there is no need to skip the
first relocation entry.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-04-17 08:55:55 +05:30
Bin Meng
f692289ed4 firmware: Optimize loading relocation type
't5' already contains relocation type so don't bother reloading it.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-04-17 08:55:49 +05:30
Mayuresh Chitale
8e90259da8 lib: sbi_hart: clear mip csr during hart init
If mip.SEIP bit is not cleared then on HiFive Unmatched board it causes
spurious external interrupts. This breaks the boot up of HiFive Unmatched
board. Hence it is required to bring the mip CSR to a known state during
hart init and avoid spurious interrupts.

Fixes: d9e7368 ("firmware: Not to clear all the MIP")
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-04-06 18:52:03 +05:30
Nick Hu
8050081f68 firmware: Not to clear all the MIP
In generic behavior of QEMU, if the pending bits of PLIC are still set and
we clear the SEIP, the QEMU may not set the SEIP back immediately and the
interrupt may not be handled anymore until the new interrupts arrived and
QEMU set the SEIP back which is a generic behavior in QEMU.

Signed-off-by: Nick Hu <nick.hu@sifive.com>
Signed-off-by: Jim Shu <jim.shu@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-08 10:39:20 +05:30
Jessica Clarke
c8ea836ee3 firmware: Fix fw_rw_offset computation in fw_base.S
It seems BFD just does totally nonsensical things for SHN_ABS symbols
when producing position-independent outputs (both -pie and -shared)
for various historical reasons, and so SHN_ABS symbols are still
subject to relocation as far as BFD is concerned (except AArch64,
which fixes it in limited cases that don’t apply here...).

The above affects the _fw_rw_offset provided through fw_base.ldS
linker script which results in OpenSBI firmware failing to boot
when loaded at an address different from FW_TEXT_START.

Fixes: c10e3fe5f9 ("firmware: Add RW section offset in scratch")
Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
Reported-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Tested-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-01-27 08:39:49 +05:30
Himanshu Chauhan
c10e3fe5f9 firmware: Add RW section offset in scratch
Add the RW section offset, provided by _fw_rw_offset symbol,
to the scratch structure. This will be used to program
separate pmp entry for RW section.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-23 10:06:14 +05:30
Dongdong Zhang
cfbabb9ec6 firmware: Minor optimization for relocate
The t3 register stores the address of _load_end. If relocation is not
required, it is unnecessary to calculate the address of _load_end.

This can reduce the operation time of two instructions.

Signed-off-by: Dongdong Zhang <zhangdongdong@eswincomputing.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-05 10:47:38 +05:30
Xiang W
b6b7220a47 firmware: Fix code for accessing hart_count and stack_size
lwu exists under the current rv64 and should also exist under the rv128
in the future, so I modified the conditions of conditional compilation
so that it can adapt to the future situation

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-03-27 08:53:27 +05:30
Anup Patel
d30bde36d5 firmware: Move memcpy/memset mapping to fw_base.S
Some of the external firmwares using OpenSBI as library are facing
issues with the weak memcpy() and memset() aliases in libsbi.a so
we move these to fw_base.S. This way mapping of implicit memcpy()
or memset() calls to sbi_memcpy() or sbi_memset() will only be done
for OpenSBI firmwares.
(Refer, https://github.com/riscv-software-src/opensbi/issues/234)

In addition, we also add memmove() and memcmp() mappings in fw_base.S
because as-per the GCC documentation the freestanding environment must
provide memcpy(), memmove(), memset(), and memcmp().

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2021-12-23 17:46:09 +05:30
Xiang W
74db0acbe5 firmware: use _fw_start for load address
The previous code uses _start as the load address, this default .entry is
the first segment, using _fw_start does not need to make this assumption.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2021-07-27 15:20:49 +05:30
Bin Meng
8a1475b5a1 firmware: Remove the unhelpful alignment codes before fdt relocation
If the device tree is at an address that is not __SIZEOF_POINTER__
aligned, the fdt relocation code tries to align both source and
destination address to __SIZEOF_POINTER__ before the memory copy.
But such alignment can lead to unexpected results if either source
or destination address is not aligned.

In fact libfdt requires that the device tree must be at an 8-byte
aligned address. Hence remove the unhelpful alignment codes.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2021-07-17 17:13:43 +05:30
Jessica Clarke
397afe5ba1 fw_base: Put data in .data rather than .text
The -N linker option is supposed to make .text writable, but GNU ld and
LLD differ in interpreting what that means. GNU ld will happily let you
have relocations in it, but LLD will see that the input section is
read-only (even though the output section is writable) and give an
error. It's unclear if either of them intend to have that behaviour in
this edge case, but regardless there's no reason not to just put the
data in a writable .data section.

Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2021-07-11 17:33:30 +05:30
Jessica Clarke
7f1be8a624 fw_base: Don't mark fw_platform_init as both global and weak
These are mutually exclusive. GNU as and LLVM both let later binding
directives override earlier ones so this works as intended, but LLVM 12
turned this into a warning as there's no good reason to do such a thing
and could be a potential bug. Thus, remove the redundant and incorrect
.globl directive for fw_platform_init.

Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2021-07-11 17:20:42 +05:30
Bin Meng
14c7f71c0d firmware: Minor optimization in _scratch_init()
Before entering _scratch_init(), register t3 already holds a copy
of the firmware end address, hence there is no need to calculate
it again. This reduces 3 instructions in each _scratch_init() loop.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2021-07-11 11:41:50 +05:30
Anup Patel
e71a7c10a9 firmware: Remove redundant add instruction from trap restore path
The "add sp, a0, zero" instruction in the trap restore path is redundant
and can be avoided if TRAP_RESTORE_xyz() assembly macros use a0 as the
base register instead of sp.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2021-04-05 15:39:28 +05:30
Xiang W
4ef2f5d3e6 firware: optimize the exception exit code
There are two copies of the same abnormal exit code, this patch deletes one

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2021-04-01 10:48:35 +05:30
Vincent Chen
0f20e8adcf firmware: Support position independent execution
Enable OpenSBI to support position independent execution. Because the
position independent code will cause an additional GOT reference when
accessing the global variables, it will reduce performance a bit. Therefore,
the position independent execution is disabled by default. Users can
through specifying "FW_PIC=y" on the make command to enable this feature.

In theory, after enabling position-independent execution, the OpenSBI
can run at arbitrary address with appropriate alignment. Therefore, the
original relocation mechanism will be skipped. In other words, OpenSBI will
directly run at the load address without any code movement.

Signed-off-by: Vincent Chen <vincent.chen@sifive.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2021-03-19 15:00:50 +05:30
Vincent Chen
22d8ee9758 firmware: Use lla to access all global symbols
When OpenSBI is compiled as fPIE mode, the assembler will translate "la"
to GOT reference pattern. It will cause to cost an additional load
instruction when obtaining the symbol address. However, if the symbol
locates within the positive or negative 2GB region, we can use "lla"
instead of "la" to avoid unneeded GOT references. This patch assumes that
the OpenSBI image excluding the payload does not exceed 2GB. Based on
this assumption, all "la" instructions are replaced by "lla" to avoid
performance degradation when compiling as fPIE mode.

Signed-off-by: Vincent Chen <vincent.chen@sifive.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2021-03-19 14:57:45 +05:30
Anup Patel
b7df5e4392 lib: sbi: Introduce sbi_trap_exit() API
We introduce sbi_trap_exit() API which can help non-firmware
(i.e. generic or platform) code to force exit trap/interrupt
handling and resume execution at context pointed by parameter
"const struct sbi_trap_regs *regs".

This new sbi_trap_exit() API will help Keystone Enclave project
to resume execution of enclave from custom SBI call handler.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2021-01-07 09:53:17 +05:30
Anup Patel
2677324f90 firmware: fw_base: Optimize trap handler for RV32 systems
On RV32 systems, we have two CSRs for M-mode status (MSTATUS and
MSTATUSH) when H-extension is implemented. This means we have to
save/restore MSTATUSH for RV32 systems only when H-extension is
implemented. The current _trap_handler() has extra instructions
(roughly 10) for conditional save/restore of MSTATUSH CSR.

These extra instructions in RV32 _trap_handler() can be avoided
if we create separate low-level trap handler for RV32 systems
having H-extension. This patch optimizes low-level trap handler
for RV32 systems accordingly.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
2020-12-01 17:14:32 +05:30
Anup Patel
9c07c513aa firmware: Remove FW_PAYLOAD_FDT_PATH compile-time option
The FW_PAYLOAD_FDT_PATH compile-time option is replaced by
FW_FDT_PATH compile-time option which is more flexible and
common across all OpenSBI firmwares.

This patch removes FW_PAYLOAD_FDT_PATH and updates related
documentation to use FW_FDT_PATH.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-10-18 10:29:59 +05:30
Anup Patel
6ca096977d firmware: Add common FW_FDT_PATH compile-time option
Currently, only FW_PAYLOAD has mechanism to embed external
FDT using FW_PAYLOAD_FDT_PATH compile-time option.

This patch adds a common FW_FDT_PATH compile-time option to
embed external FDT for all OpenSBI firmwares (i.e FW_JUMP,
FW_PAYLOAD, and FW_DYNAMIC).

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-10-18 10:28:26 +05:30
Anup Patel
4b18a2acc2 firmware: fw_base: Improve exception stack setup in trap handler
Currently, the low-level trap handler (i.e. _trap_handler()) uses
branch instructions to conditionally setup exception stack based
on which mode trap occured.

This patch implements exception stack setup using xor instructions
which is faster with same number of instructions due to lack of
branch instructions.

The new exception stack setup approach can be best described by the
following pseudocode:

 Came_From_M_Mode = ((MSTATUS.MPP < PRV_M) ? 1 : 0) - 1;
 Exception_Stack = TP ^ (Came_From_M_Mode & (SP ^ TP))

 Came_From_M_Mode = 0    ==>    Exception_Stack = TP
 Came_From_M_Mode = -1   ==>    Exception_Stack = SP

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-08-14 14:35:47 +05:30
Anup Patel
86ec5341e4 firmware: Allow fw_platform_init() to return updated FDT location
Currently, the fw_platform_init() does not return anything but we can
further improve by allowing fw_platform_init() to return updated FDT
location.

It is certainly not mandatory for fw_platform_init() to return a new
location of FDT (or modify FDT). In fact, the fw_platform_init() can
always return the original FDT location (i.e. 'arg1') unmodified.

This new capability of fw_platform_init() will allow platforms to:
1. Have multiple built-in FDTs and select one
2. Modify FDT before using based on platform specific straps or OTP

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-06-05 09:02:34 +05:30
Anup Patel
4ce6b7a82a firmware: fw_base: Don't OR forced FW_OPTIONS
Currently, we are ORing FW_OPTIONS with the options passed by
previous booting stage to fw_dynamic. This causes confusion
because compiling fw_dynamic with FW_OPTIONS=0x2 does not force
enable boot prints as the U-Boot SPL passes options=0x1 in
fw_dyanmic_info.

The best thing to do is always prefer FW_OPTIONS when available.
This is intuitive for OpenSBI users and easy in debugging.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-06-05 09:02:32 +05:30
Anup Patel
64f140830d firmware: fw_base: Make builtin DTB available to fw_platform_init()
Currently, fw_prev_arg1() is called after fw_platform_init() which
caused builtin DTB to be not available to fw_platform_init().

To allow builtin DTB available to fw_platform_init(), we should
call fw_save_info() and fw_prev_arg1() before fw_platform_init().

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-06-05 09:02:30 +05:30
Daniel Schaefer
38a4b54cdc firmware: Correct spelling mistakes
Signed-off-by: Daniel Schaefer <git@danielschaefer.me>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2020-05-18 10:42:29 +05:30
Anup Patel
4d063538f0 firmware: fw_base: Introduce optional fw_platform_init()
We add optional fw_platform_init() function which will allow
platform specific code to update "struct sbi_platform platform"
before it is used.

The fw_platform_init() can be a regular C function so before
callint it we:
1. zero-out BSS section
2. Setup temporary trap handler to catch bugs
3. Setup temporary stack pointer

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-05-01 10:33:02 +05:30
Charles Papon
5bdf022d07 firmware: fw_base: Remove CSR_MTVEC update check
Remove unnecessary CSR_MTVEC read to reduce the openSBI CSR requirement.

Mux are costly in FPGA. Allowing CSR_MTVEC to be write only is usefull
for the FMax/Area of FPGA softcore.

https://github.com/SpinalHDL/opensbi.git branch mtvec

Signed-off-by: Charles Papon <charles.papon.90@gmail.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2020-05-01 09:28:38 +05:30
Anup Patel
40b221baff lib: sbi_trap: Simplify sbi_trap_handler() API
This patch simplify sbi_trap_handler() API as follows:
1. Remove current hartid local variable because sbi_trap_handler()
   itself does not need it.
2. Remove scratch parameter because none of the functions directly
   called by sbi_trap_handler() require it.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-03-28 13:32:23 +05:30
Anup Patel
c51f02cf14 include: sbi_platform: Introduce HART index to HART id table
A platform can have discontinuous and/or sparse HART ids so we
cannot always assume a set of HARTs with continuous HART ids.

This patch adds support for discontinuous and sparse HART ids by
introducing HART index to HART id table. This table has platform
hart_count entries and it maps HART index to HART id.

The HART index to HART id table has only two restrictions:
1. HART index < sbi_platform hart_count
2. HART id < SBI_HARTMASK_MAX_BITS

Example1:
Let's say we have a platform with 2 HART ids 11 and 22, for such a
a platform:
hart_count = 2
hart_index2id[0] = 11
hart_index2id[1] = 22

Example2:
Let's say we have a platform with 5 HARTs ids 0, 1, 2, 3, and 4
but out of these HART with id 0 is not usable so for such a platform:
hart_count = 5
hart_index2id[0] = -1U
hart_index2id[1] = 1
hart_index2id[2] = 2
hart_index2id[3] = 3
hart_index2id[4] = 4
OR
hart_count = 4
hart_index2id[0] = 1
hart_index2id[1] = 2
hart_index2id[2] = 3
hart_index2id[3] = 4

With HART index to HART id table in place, the hart_disabled()
callback is now redundant so we remove it as well.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2020-03-19 09:30:01 +05:30
Anup Patel
eeae3d9582 firmware: fw_base: Optimize _hartid_to_scratch() implementation
This patch optimizes _hartid_to_scratch() in following ways:
1. Use caller saved registers instead of callee saved registers
   so that we don't need to save/restore registers on stack
2. Remove second redundant mul instruction by re-arranging
   instructions

Overall, we reduce 9 instructions in _hartid_to_scratch()
implementation.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
2020-03-13 12:18:51 +05:30
Andreas Schwab
6ffe1bed09 firmware: Fix placement of .align directives
Move the .align directives after switching the section.  We want to align
the start of the current section, not the end of the previous section.
This also obsoletes the misguided workaround of disabling relaxation.

Signed-off-by: Andreas Schwab <schwab@suse.de>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
2020-01-10 09:30:27 +05:30
Anup Patel
7a13beb213 firmware: Add preferred boot HART field in struct fw_dynamic_info
It has been reported that link address range of previous booting stage
(such as U-Boot SPL) can overlap the link address rage of FW_DYNAMIC.

This means self-relocation in FW_DYNAMIC can potentially corrupt
previous booting stage if any of the secondary HART enter FW_DYNAMIC
before primary HART.

To tackle this, we add preferred boot HART field (i.e boot_hart) in
struct fw_dyanmic_info. We use this field to force secondary HARTs
into relocation wait loop till preferred/primary boot HART enters
FW_DYNAMIC completes self-relocation. If preferred boot HART is not
available then we fall back to relocation lottery approach.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2019-11-15 17:41:18 +05:30
Anup Patel
98f4a20899 firmware: Introduce relocation lottery
Instead of forcing HART0 to do the relocation and scratch init
work, we should have an atomic lottery to decide which HART does
the relocation and scratch init.

This way any HART can be boot/main HART.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Atish Patra <atish.patra@wdc.com>
2019-11-05 08:50:04 +05:30