summaryrefslogtreecommitdiff
path: root/firmware/fw_base.S
AgeCommit message (Collapse)Author
2026-06-28firmware: Fix comment after relocation completionZong Li
After relocation is done, the code is running from the load address, not the link address. Fix the comment to correctly reflect this. Signed-off-by: Zong Li <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2026-05-09lib: sbi: Move Zkr entropy initialization from fw_base.S to init_coldbootEvgeny Voevodin
Current placement of entropy initialization via Zkr extension requires a trap-based mechanism to handle absent Zkr extension case. In presence of Smrnmi extension no trap-based mechanisms should be used before Smrnmi is detected and enabled otherwise trap will jump to undefined location. Move stack guard initialization into init_coldboot function body after device tree has been parsed so we know if Zkr extension is implemented by the platform which helps to avoid trap-based discovery. init_coldboot() is a safe place to initialize entropy because it doesn't return so no check of __stack_chk_guard against value on entry will be done. Signed-off-by: Evgeny Voevodin <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/acd52b0f3468758bc5f09e6a45662341b31d4d87.1778176768.git.evvoevod@tenstorrent.com Signed-off-by: Anup Patel <[email protected]>
2026-05-09firmware: Add RNMI handler infrastructureEvgeny Voevodin
Implement basic Resumable NMI (RNMI) handler support for the RISC-V Smrnmi extension. The new _trap_rnmi_handler assembly entry point saves context using the Smrnmi MN* CSRs (MNSCRATCH, MNEPC, MNSTATUS, MNCAUSE) and returns via mnret. It dispatches to sbi_trap_rnmi_handler(), which optionally calls a platform-specific ops->rnmi_handler callback for actual NMI processing. If no platform handler is registered or it fails, the event is reported as an unhandled NMI. The RNMI handler reuses the generic trap context structure but stores MN* CSR values (MNEPC, MNSTATUS, MNCAUSE) into the corresponding generic fields (mepc, mstatus, cause) for compatibility with existing trap infrastructure. Signed-off-by: Evgeny Voevodin <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/050ae6d2762ba8d5b9dfb3cc1960a23aa3d6c549.1778176768.git.evvoevod@tenstorrent.com Signed-off-by: Anup Patel <[email protected]>
2026-05-09include: sbi_scratch: Add tmp1 scratch space for RNMI context savingEvgeny Voevodin
RNMI handlers use MNSCRATCH instead of MSCRATCH and need separate scratch space from regular trap handling. Add tmp1 for RNMI context while tmp0 remains for regular traps. Signed-off-by: Evgeny Voevodin <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/0a5d241fa1db03e71a3f56be24708cbbc8037e28.1778176768.git.evvoevod@tenstorrent.com Signed-off-by: Anup Patel <[email protected]>
2026-02-20firmware: Initialize stack guard via ZkrXiang W
Try to initialize stack protection guard via the zkr extension. Signed-off-by: Xiang W <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2025-12-28lib: atomics: fix AMO test macrosVladimir Kondratiev
The "RISC-V C API" [1] defines architecture extension test macros says naming rule for the test macros is __riscv_<ext_name>, where <ext_name> is all lower-case. Three extensions dealing with atomics implementation are: "zaamo" consists of AMO instructions, "zalrsc" - LR/SC, "a" extension means both "zaamo" and "zalrsc" Built-in test macros are __riscv_a, __riscv_zaamo and __riscv_zalrsc. Alternative to the __riscv_a macro name, __riscv_atomic, is deprecated. Use correct test macro __riscv_zaamo for the AMO variant of atomics. It used to be __riscv_atomic that is both deprecated and incorrect because it tests for the "a" extension; i.e. both "zaamo" and "zalrsc" If ISA enables only zaamo but not zalrsc, code as it was would not compile. Older toolchains may have neither __riscv_zaamo nor __riscv_zalrsc, so query __riscv_atomic - it should be treated as both __riscv_zaamo and __riscv_zalrsc, in all present cases __riscv_zaamo is more favorable so take is as alternative for __riscv_zaamo [1] https://github.com/riscv-non-isa/riscv-c-api-doc Signed-off-by: Vladimir Kondratiev <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2025-07-22firmware: Replace sole uses of REGBYTES with __SIZEOF_LONG__Jessica Clarke
This code has nothing to do with the ISA's registers, it's about the format of ELF relocations. As such, __SIZEOF_LONG__, being a language / ABI-level property, is a more appropriate constant to use. This also makes it easier to support CHERI, where general-purpose registers are extended to be capabilities, not just integers, and so the register size is not the same as the machine word size. This also happens to make it more correct for RV64ILP32, where the registers are 64-bit integers but the ABI is 32-bit (both for long and for the ELF format), though properly supporting that ABI is not part of the motivation here, just a consequence of improving the code for CHERI. Signed-off-by: Jessica Clarke <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2025-07-21firmware: Rename __rel_dyn_start/end to __rela_dyn_start/endJessica Clarke
We are using and expecting the RELA format, not the REL format, and this is the conventional linker-generated name for the start/end symbols, so use it rather than confusing things by making it look like we're accessing .rel.dyn, which would be in the REL format with no explicit addend. Signed-off-by: Jessica Clarke <[email protected]> Reviewed-by: Samuel Holland <[email protected]> Tested-by: Samuel Holland <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2025-07-20firmware: Initial compiler built-in stack protector supportAlvin Chang
Add __stack_chk_fail() and __stack_chk_guard variable which are used by compiler built-in stack protector. This patch just try to support stack-protector so the value of the stack guard variable is simply fixed for now. It could be improved by deriving from a random number generator, such as Zkr extension or any platform-specific random number sources. Introduce three configurations for the stack protector: 1. CONFIG_STACK_PROTECTOR to enable the stack protector feature by providing "-fstack-protector" compiler flag 2. CONFIG_STACK_PROTECTOR_STRONG to provide "-fstack-protector-strong" 3. CONFIG_STACK_PROTECTOR_ALL to provide "-fstack-protector-all" Instead of fixing the compiler flag of stack-protector feature as "-fstack-protector", we derive it from the introduced Kconfig configurations. The compiler flag "stack-protector-cflags-y" is defined as Makefile "immediately expanded variables" with ":=". Thus, the stronger configuration of the stack protector can overwrite the preceding one. Signed-off-by: Alvin Chang <[email protected]> Reviewed-by: Yu-Chien Peter Lin <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2025-03-28lib: Emit lr and sc instructions based on -march flagsChao-ying Fu
When -march=rv64im_zalrsc_zicsr is used, provide atomic operations and locks using lr and sc instructions only. Signed-off-by: Chao-ying Fu <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
2025-02-12firmware: fw_base.S: Fix comments for _wait_for_boot_hartXiang W
Due to some historical issues, the value of BOOT_STATUS_BOOT_HART_DONE has changed and the comment message needs to be corrected. Signed-off-by: Xiang W <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-10-26lib: sbi: add Smdbltrp ISA extension supportClément Léger
Add support for the Smdbltrp[1] ISA extension. First thing to do is clearing MDT on entry after setting the first MTVEC (since MDT is reset to 1). Additionally, during trap handling, clear MDT once all critical CSRs have been saved and in return path, restore MSTATUS/H before restoring MEPC to avoid taking another trap which would clobber it. Link: https://github.com/riscv/riscv-double-trap/releases/download/v0.56/riscv-double-trap.pdf [1] Signed-off-by: Clément Léger <[email protected]> Reviewed-by: Samuel Holland <[email protected]>
2024-09-27firmware: fw_base.S: fix multi-core boot bug.dong.yang
In a multi-core startup scenario, if both _try_lottery and _wait_for_boot_hart use the data in the _boot_status address, when a CPU enters OpenSBI later than boot hart set the _boot_status to BOOT_STATUS_BOOT_HART_DONE, the CPU will modify _boot_status to 1 by amoswap.w and will never be awakened in _wait_for_boot_hart. So let _try_lottery and _boot_status use data from two addresses. Fixes: 8151105af5e4 ("firmware: fw_base.S: Remove _relocate_lottery") Signed-off-by: dong.yang <[email protected]> Reviewed-by: Xing Xiaoguang <[email protected]> Reviewed-by: Xiang W <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-09-25include: sbi: Store the hart index in struct sbi_scratchSamuel Holland
This is a more efficient way to get the index of the current hart than calling a function to loop through the hartindex -> hartid lookup table. Signed-off-by: Samuel Holland <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-09-25firmware: Simplify FDT header endianness conversionSamuel Holland
Reduce the code size by using single-byte loads instead of bit manipulation. This method also does the right thing on (hypothetical) big-endian systems. Signed-off-by: Samuel Holland <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-05-23firmware: Bring back FW_TEXT_START as an optional parameterAnup Patel
Bring back FW_TEXT_START as an optional parameter to allow users explicitly specify compile time address for loading debug symbols. When not specified, the FW_TEXT_START is assumed to be 0. Fixes: d4d2582eef7a ("firmware: remove FW_TEXT_START") Signed-off-by: Anup Patel <[email protected]> Tested-by: Clément Léger <[email protected]>
2024-04-10firmware: remove FW_TEXT_STARTXiang W
Now opensbi can run at any address via dynamic relocation. We can remove FW_TEXT_START. Signed-off-by: Xiang W <[email protected]> Reviewed-by: Anup Patel <[email protected]> Tested-by: Anup Patel <[email protected]>
2024-04-05firmware: remove copy-base relocationXiang W
Remove copy-base relocations that are no longer needed. Signed-off-by: Xiang W <[email protected]> Reviewed-by: Samuel Holland <[email protected]> Tested-by: Samuel Holland <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-03-19lib: sbi: Introduce trap contextAnup Patel
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 <[email protected]> Reviewed-by: Samuel Holland <[email protected]> Tested-by: Samuel Holland <[email protected]>
2024-03-19include: sbi: Add trap_context pointer in struct sbi_scratchAnup Patel
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 <[email protected]> Reviewed-by: Samuel Holland <[email protected]> Tested-by: Samuel Holland <[email protected]>
2024-03-19lib: sbi: Remove sbi_trap_exit() and related codeAnup Patel
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 <[email protected]> Reviewed-by: Samuel Holland <[email protected]> Tested-by: Samuel Holland <[email protected]>
2024-03-09firmware: fw_base.S: fix _reset_regsXiang W
a3 and a4 cannot be reset because used in fw_platform_init. Signed-off-by: Xiang W <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-03-09firmware: fw_base.S: Remove _relocate_lotteryXiang W
Remove _relocate_lottery and use _boot_status instead. Signed-off-by: Xiang W <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-03-09firmware: fw_base: Simplified setup trap handlerXiang W
The same detection was done twice when setting mtvec and trap_exit. Merging can reduce code size. Signed-off-by: Xiang W <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-03-09firmware: fw_base.S: Simplify address getXiang W
Simplify address get and remove _link_start _link_end _load_start. Signed-off-by: Xiang W <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-02-06firmware: fw_base.S: remove _runtime_offsetXiang W
_runtime_offset is a variable not used elsewhere, so remove it. Signed-off-by: Xiang W <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-02-06firmware: fw_base.S: Improve loading u32Xiang W
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2024-02-05fw_base.S: Fix comment errorsZhang Runmin
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2023-11-16firmware: fw_base.S: Fix boot hart status synchronizationGuo Ren
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 <[email protected]> Signed-off-by: Guo Ren <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2023-10-06firmware: Remove handling of R_RISCV_{32,64}Vivian Wang
Since everything is statically linked, we won't actually have R_RISCV_{32,64} relocations. No need to handle these. Fixes: 0f20e8adcf42 ("firmware: Support position independent execution") Signed-off-by: Vivian Wang <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2023-08-06fw_base.S: Fix assembler error with clang 16+Mitchell Horne
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2023-06-21firmware: Fix find hart indexXiang W
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2023-06-05platform: Allow platforms to specify heap sizeAnup Patel
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 <[email protected]> Reviewed-by: Andrew Jones <[email protected]>
2023-04-17firmware: Change to use positive offset to access relocation entriesBin Meng
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]> Reviewed-by: Xiang W <[email protected]>
2023-04-17firmware: Optimize loading relocation typeBin Meng
't5' already contains relocation type so don't bother reloading it. Signed-off-by: Bin Meng <[email protected]> Reviewed-by: Anup Patel <[email protected]> Reviewed-by: Xiang W <[email protected]>
2023-04-06lib: sbi_hart: clear mip csr during hart initMayuresh Chitale
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2023-02-08firmware: Not to clear all the MIPNick Hu
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 <[email protected]> Signed-off-by: Jim Shu <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2023-01-27firmware: Fix fw_rw_offset computation in fw_base.SJessica Clarke
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: c10e3fe5f9a1 ("firmware: Add RW section offset in scratch") Signed-off-by: Jessica Clarke <[email protected]> Reported-by: Lad Prabhakar <[email protected]> Tested-by: Lad Prabhakar <[email protected]> Tested-by: Anup Patel <[email protected]> Signed-off-by: Anup Patel <[email protected]>
2023-01-23firmware: Add RW section offset in scratchHimanshu Chauhan
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2022-12-05firmware: Minor optimization for relocateDongdong Zhang
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 <[email protected]> Reviewed-by: Bin Meng <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2022-03-27firmware: Fix code for accessing hart_count and stack_sizeXiang W
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2021-12-23firmware: Move memcpy/memset mapping to fw_base.SAnup Patel
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 <[email protected]> Reviewed-by: Atish Patra <[email protected]>
2021-07-27firmware: use _fw_start for load addressXiang W
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2021-07-17firmware: Remove the unhelpful alignment codes before fdt relocationBin Meng
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2021-07-11fw_base: Put data in .data rather than .textJessica Clarke
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 <[email protected]> Reviewed-by: Bin Meng <[email protected]> Tested-by: Bin Meng <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2021-07-11fw_base: Don't mark fw_platform_init as both global and weakJessica Clarke
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 <[email protected]> Reviewed-by: Bin Meng <[email protected]> Tested-by: Bin Meng <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2021-07-11firmware: Minor optimization in _scratch_init()Bin Meng
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 <[email protected]> Reviewed-by: Xiang W <[email protected]> Reviewed-by: Atish Patra <[email protected]>
2021-04-05firmware: Remove redundant add instruction from trap restore pathAnup Patel
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 <[email protected]> Reviewed-by: Xiang W <[email protected]>
2021-04-01firware: optimize the exception exit codeXiang W
There are two copies of the same abnormal exit code, this patch deletes one Signed-off-by: Xiang W <[email protected]> Reviewed-by: Anup Patel <[email protected]>
2021-03-19firmware: Support position independent executionVincent Chen
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 <[email protected]> Reviewed-by: Anup Patel <[email protected]>