1002 Commits
v1.0 ... master

Author SHA1 Message Date
Max Hsu
84044ee83c lib: utils: fdt: fix "ranges" translation
According to the Device Tree Spec, Chapter 2.3.8 "ranges" [1]:
The parent address size will be determined from the #address-cells
property of the node that defines the parent’s address space.

In fdt_translate_address(), which considered the parent address size
is the child address size, this commit fix the two address sizes
and parsing the address independently.

Signed-off-by: Max Hsu <max.hsu@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250711-dev-maxh-master_fdt_helper-v2-1-9579e1f02ee1@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-23 10:32:14 +05:30
Jessica Clarke
cc546e1a06 include: sbi: Remove unused (LOG_)REGBYTES
These are no longer used, so remove them.

Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250709232932.37622-3-jrtc27@jrtc27.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-22 15:54:27 +05:30
Jessica Clarke
079bf6f0f9 firmware: Replace sole uses of REGBYTES with __SIZEOF_LONG__
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 <jrtc27@jrtc27.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250709232932.37622-2-jrtc27@jrtc27.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-22 15:54:27 +05:30
Jessica Clarke
ffd3ed976d include: sbi: Use array for struct sbi_trap_regs and GET/SET macros
Rather than hand-rolling scaled pointer arithmetic with casts and
shifts, let the compiler do so by indexing an array of GPRs, taking
advantage of the language's type system to scale based on whatever type
the register happens to be. This makes it easier to support CHERI where
the registers are capabilities, not plain integers, and so this pointer
arithmetic would need to change (and currently REGBYTES is both the size
of a register and the size of an integer word upstream).

Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250709232932.37622-1-jrtc27@jrtc27.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-22 15:54:27 +05:30
Manuel Hernández Méndez
0b7c2e0d60 platform: openpiton: fix uninitialized plic_data struct
The plic_data struct was uninitialized. This led to misfunction behavior
since it was subsequently assigned to the global plic struct, and some
struct fields, such as flags and irqchip, contained random values.
The fix proposes to initialize the plic_data to the global plic struct,
so, after parsing the fdt, the fields of the struct will be set to the
default values set in global plic struct definition, or the parsed values
in the fdt, or zero.

Fixes: 4c37451 ("platform: openpiton: Read the device configurations from device tree")
Signed-off-by: Manuel Hernández Méndez <maherme.dev@gmail.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250708180914.1131-1-maherme.dev@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-22 15:26:44 +05:30
Jessica Clarke
e10a45752f firmware: Rename __rel_dyn_start/end to __rela_dyn_start/end
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 <jrtc27@jrtc27.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
Link: https://lore.kernel.org/r/20250710002937.44307-1-jrtc27@jrtc27.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-21 16:39:49 +05:30
Jessica Clarke
4825a3f87f include: sbi: Don't use #pragma when preprocessing device tree sources
Since this persists in the preprocessed output (so that it can affect
the subsequent compilation), it ends up in the input to dtc and is a
syntax error, breaking the k210 build. Ideally we wouldn't add the
-include flag to DTSCPPFLAGS in the first place as this header is wholly
pointless there, but that's a more invasive build system change compared
to just making this header safe to include there.

Fixes: 86c01a73ff ("lib: sbi: Avoid GOT indirection for global symbol references")
Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Xiang W <wxjstz@126.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Link: https://lore.kernel.org/r/20250709232840.37551-1-jrtc27@jrtc27.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-21 16:37:22 +05:30
Xiang W
3876f8cd1e firmware: payload: test: Add SBI shutdown call after test message
Previously, 'make run' would hang in WFI after printing the test message.
This commit adds an SBI ecall to ensure QEMU exits cleanly after the test
payload runs.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Xiang W <wxjstz@126.com>
Link: https://lore.kernel.org/r/20250721010807.460788-1-wxjstz@126.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-21 16:34:03 +05:30
Atish Patra
5b305e30a5 lib: sbi: Only enable TM bit in scounteren
The S-mode should disable Cycle and instruction counter for user space
to avoid side channel attacks. The Linux kernel already does this so that
any random user space code shouldn't be able to monitor cycle/instruction
without higher privilege mode involvement.

Remove the CY/IR bits in scountern in OpenSBI.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Link: https://lore.kernel.org/r/20250513-fix_scounteren-v1-1-01018e0c0b0a@rivosinc.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-21 16:33:03 +05:30
Ben Dooks
663b05a5f7 include: sbi: fix swap errors with newer gcc -Werror=sequence-point
The BSWAPxx() macros are now throwing the following warnings with
newer gcc versions. This is due to throwing an argument in that may
be evaluated more than one (I think) and therefore things like the
example below should be avoided.

Fix by making a set of BSWAPxx() wrappers which specifically only
evaluate 'x' once.

In file included lib/sbi/sbi_mpxy.c:21:
lib/sbi/sbi_mpxy.c: In function ‘sbi_mpxy_write_attrs’:
ib/sbi/sbi_mpxy.c:632:63: error: operation on ‘mem_idx’ may be undefined [-Werror=sequence-point]
  632 |                         attr_val = le32_to_cpu(mem_ptr[mem_idx++]);
      |                                                        ~~~~~~~^~

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Rahul Pathak <rahul@summations.net>
Reviewed-by: Xiang W <wxjstz@126.com>
Link: https://lore.kernel.org/r/20250704122938.897832-1-ben.dooks@codethink.co.uk
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-20 21:15:10 +05:30
Alvin Chang
edfbc1285d firmware: Initial compiler built-in stack protector support
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 <alvinga@andestech.com>
Reviewed-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250703151957.2545958-3-alvinga@andestech.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-20 20:54:34 +05:30
Alvin Chang
ea5abd1f5e lib: sbi: Remove redundant call to sbi_hart_expected_trap_addr()
The variable "sbi_hart_expected_trap" has already been extern variable.
Therefore, the program can directly refer to it instead of calling
sbi_hart_expected_trap_addr().

Signed-off-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250703151957.2545958-2-alvinga@andestech.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-20 20:54:34 +05:30
Yong-Xuan Wang
61083eb504 lib: sbi_list: add a helper for safe list iteration
Some use cases require iterating safe against removal of list entry.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250618025416.5331-1-yongxuan.wang@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-20 20:45:59 +05:30
Yi Pei
b8f370aa37 lib: utils/serial: Clear LSR status and check RBR status
On some platforms, read RBR when it is empty may result in an error.

Signed-off-by: Yi Pei <neopimail@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/CAFPVDjQZ1gpf8-u--RBbAL1Y0FfDN2vZ3g=wBw+Bp-8ppuz3HA@mail.gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-07-20 20:37:18 +05:30
Anup Patel
a32a910691 include: Bump-up version to 1.7
Update the OpenSBI version to 1.7 as part of release preparation.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-30 08:37:30 +05:30
Rahul Pathak
c2671bb69f lib: rpmi: Make RPMI drivers as non-experimental
As RPMI v1.0 specification is frozen, disable the
experimental tag for such RPMI drivers.

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250618053854.2577299-2-rpathak@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-24 08:42:27 +05:30
Rahul Pathak
a5fdef45db lib: utils: Add Implementation ID and Version as RPMI MPXY attributes
The latest frozen RPMI spec has added Implementation ID
and Implementation Version as message protocol specific
mpxy attributes. Add support for these.

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250618053854.2577299-1-rpathak@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-24 08:42:27 +05:30
Chao-ying Fu
13abda5169 lib: sbi_platform: Add platform specific pmp_set() and pmp_disable()
Allow platforms to implement platform specific PMP setup and
PMP disable functions which are called before actual PMP CSRs
are configured.

Also, implement pmp_set() and pmp_disable() for MIPS P8700.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Link: https://lore.kernel.org/r/20250614172756.153902-1-apatel@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-17 09:34:01 +05:30
Jesse Taube
324021423d lib: sbi: dbtr: Fix update_triggers to match SBI
OpenSBI implements sbi_dbtr_update_trig as
`sbi_dbtr_update_trig(unsigned long trig_idx_base,
                      unsigned long trig_idx_mask)`
yet SBI v3.0-rc7 Chapter 19. Debug Triggers Extension [0] declares it as
`sbi_debug_update_triggers(unsigned long trig_count)`

Change update_triggers to match SBI.

[0] https://github.com/riscv-non-isa/riscv-sbi-doc/tree/v3.0-rc7/src/ext-debug-triggers.adoc

Fixes: 97f234f15c ("lib: sbi: Introduce the SBI debug triggers extension support")
Signed-off-by: Jesse Taube <jesse@rivosinc.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Tested-by: Charlie Jenkins <charlie@rivosinc.com>
Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
Link: https://lore.kernel.org/r/20250528154604.571815-1-jesse@rivosinc.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-16 17:01:52 +05:30
Xiang W
03f44e6b82 lib: sbi: Optimize saddr mapping in sbi_dbtr.c
The original implementation mapped saddr individually for each entry.
The updated code now maps saddr for all entries in a single operation.
This change reduces the number of PMP (Physical Memory Protection)
operations, improving efficiency and performance.

Tested-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Signed-off-by: Xiang W <wxjstz@126.com>
Link: https://lore.kernel.org/r/20250514052422.575551-1-wxjstz@126.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-16 16:53:50 +05:30
Jesse Taube
033e0e2353 lib: sbi: dbtr: Fix shared memory layout
The existing sbi_dbtr_shmem_entry has a size of 5 * XLEN with the final
entry being idx. This is in contrast to the SBI v3.0-rc7 Chapter 19.
Debug Triggers Extension [0] where idx and trig_state share the same
offset (0) in shared memory, with a total size of 4 * XLEN for all the
SBI calls.

Replace struct with union to match memory layout described in SBI.

[0] https://github.com/riscv-non-isa/riscv-sbi-doc/tree/v3.0-rc7/src/ext-debug-triggers.adoc

Fixes: 97f234f15c ("lib: sbi: Introduce the SBI debug triggers extension support")
Signed-off-by: Jesse Taube <jesse@rivosinc.com>
Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
Tested-by: Charlie Jenkins <charlie@rivosinc.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Tested-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Link: https://lore.kernel.org/r/20250604135225.842241-1-jesse@rivosinc.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-16 10:14:20 +05:30
Anup Patel
9f64f06193 lib: utils: Fix fdt_parse_aclint_node() for non-contiguous hartid
Currently, the fdt_parse_aclint_node() does not handle non-contiguous
hartid correctly and returns incorrect first_hartid and hart_count.
This is because the for-loop in fdt_parse_aclint_node() skips a hartid
for which hartindex is not available (aka corresponding CPU DT node
is disabled).

For example, on a platform with 4 HARTs (hartid 0, 1, 2, and 3) where
CPU DT nodes with hartid 0 and 2 are disabled, the fdt_parse_aclint_node()
returns first_hartid = 1 and hart_count = 3 which is incorrect.

To address the above issue, drop the sbi_hartid_to_hartindex() check
from the for-loop of fdt_parse_aclint_node().

Fixes: 5e90e54a1a ("lib: utils:Check that hartid is valid")
Reported-by: Maria Mbaye <MameMaria.Mbaye@microchip.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Link: https://lore.kernel.org/r/20250606055810.237441-1-apatel@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-16 09:41:03 +05:30
Anup Patel
7dd09bfeca lib: sbi: Revert entry_count before doing hsm stop in hsm wait loop
Using hsm stop in hsm wait loop causes secondary harts to be stuck
forever in OpenSBI on RISC-V platforms where HSM hart hotplug is
available and all harts come-up at the same time during system
power-on.

For example, lets say we have two harts A and B on a RISC-V platform
with HSM hart hotplug which come-up at the same time during system
power-on. The hart A enters OpenSBI before hart B hence it becomes
the primary (or cold-boot) hart whereas hart B becomes the secondary
(or warm-boot) hart. The hart A follows the OpenSBI cold-boot path
and registers hsm device before hart B enters OpenSBI. The hart B
eventually enters OpenSBI and follows the OpenSBI warm-boot path
so it will increment it's own entry_count before entering hsm wait
loop where it sees hsm device and stops itself. Later as part of
the Linux boot-up sequence, hart A issues SBI HSM start call to
bring-up hart B but OpenSBI sees entry_count != init_count for
hart B in sbi_hsm_hart_start() hence hsm_device_hart_start() is
not called for hart B resulting in hart B stuck forever in OpenSBI.

To fix the above issue, revert entry_count before doing hsm stop
in hsm wait loop.

Fixes: d844deadec ("lib: sbi: Use hsm stop for hsm wait")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Nick Hu <nick.hu@sifive.com>
Link: https://lore.kernel.org/r/20250527124821.2113467-1-apatel@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-16 09:40:28 +05:30
Inochi Amaoto
6f8bcae4cb lib: utils/irqchip: always parse msi information for each aplic device
OpenSBI only parses MSI information of the first next level subdomain
for now, which makes the root domain misconfigured in some case:
1. the msi is not enabled on the first subdomain of the root domain,
   but other subdomains enable MSI.
2. the root domain is set as direct mode, but its subdomains enable MSI.

So it is needed to parse all child of the root domain, Otherwise, the
some non-root domains are broken. As the specification says, it is
safe to parse the MSI information of all its subdomain and write the
msiaddrcfg register of the non root domain as they are read only.

Parse the aplic MSI information recursively for all aplic device.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
Link: https://lore.kernel.org/r/20250523085348.1690368-1-inochiama@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-16 09:17:28 +05:30
Samuel Holland
771c656181 lib: sbi: fwft: Use only the provided PMLEN value
As of riscv-sbi-doc commit c7d3d1f7dcaa ("ext-fwft: use the provided
value in fwft_set(POINTER_MASKING_PMLEN)"), the SBI implementation must
use only the provided PMLEN value or else fail. It may not fall back to
a larger PMLEN value.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Link: https://lore.kernel.org/r/20250522013503.2556053-1-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-15 18:56:33 +05:30
Clément Léger
f30a54f3b3 lib: sbi: pmu: Remove MIP clearing from pmu_sse_enable()
Clearing MIP at that point means that we can probably lose a pending
interrupt. This should not happen, remove MIP clearing from there.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Link: https://lore.kernel.org/r/20250519083950.739044-3-cleger@rivosinc.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-15 18:44:51 +05:30
Clément Léger
b31a0a2427 lib: sbi: pmu: Add SSE register/unregister() callbacks
As soon as the SSE event is registered, there is no reason not to
delegate the interrupt. Split the PMU SSE enable/disable()
callbacks by moving MIDELEG setting to register/unregister().

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Link: https://lore.kernel.org/r/20250519083950.739044-2-cleger@rivosinc.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-15 18:44:51 +05:30
Khem Raj
6d23a9c570 Makefile: Add flag for reprodubility compiler flags
Provides mechanism to remove absolute paths from binaries using
-ffile-prefix-map

It will help distros (e.g. yocto based ones ) which want to ship
the .elf files but need to scrub absolute paths in objects

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Link: https://lore.kernel.org/r/20250515025931.3383142-1-raj.khem@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-15 18:28:55 +05:30
Chao-ying Fu
66ab965e54 platform: generic: mips: add P8700
Extend generic platform to support MIPS P8700.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250522212141.3198-2-cfu@mips.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-14 21:44:11 +05:30
Ziang Wang
3f8159aa06 lib: utils: hsm: Do not fail on EALREADY in rpmi-hsm fixup.
In case harts are divided into groups that use different
rpmi-hsm channels in different mailboxes, the suspend
state fixup function will return EALREADY on secondary
entry, simply skip on this error.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Ziang Wang <wangziang.ok@bytedance.com>
Link: https://lore.kernel.org/r/20250507074620.3162747-1-wangziang.ok@bytedance.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-14 10:31:32 +05:30
Charlie Jenkins
27347f0902 Makefile: Make $(LLVM) more flexible
Introduce a way for developers to easily switch between LLVM versions
with LLVM=/path/to/llvm/ and LLVM=-version. This is a useful
addition to the existing LLVM=1 variable which will select the first
clang and llvm binutils available on the path.

Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Link: https://lore.kernel.org/r/20250430-improve_llvm_building-v1-1-caae96cc6be6@rivosinc.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-06-14 10:11:11 +05:30
James Raphael Tiovalen
69a0f0245f lib: sbi: pmu: Return SBI_EINVAL if cidx_mask is 0
Currently, when configuring a matching programmable HPM counter with
Sscofpmf being present, cidx_base > 2, and cidx_mask == 0 to monitor
either the CPU_CYCLES or INSTRUCTIONS hardware event,
sbi_pmu_ctr_cfg_match will succeed but it will configure the
corresponding fixed counter instead of the counter specified by the
cidx_base parameter.

During counter configuration, the following issues may arise:
- If the SKIP_MATCH flag is set, an out-of-bounds memory read of the
phs->active_events array would occur, which could lead to undefined
behavior.

- If the CLEAR_VALUE flag is set, the corresponding fixed counter will
be reset, which could be considered unexpected behavior.

- If the AUTO_START flag is set, pmu_ctr_start_hw will silently start
the fixed counter, even though it has already started. From the
supervisor's perspective, nothing has changed, which could be confusing.
The supervisor will not see the SBI_ERR_ALREADY_STARTED error code since
sbi_pmu_ctr_cfg_match does not return the error code of
pmu_ctr_start_hw.

The only way to detect these issues is to check the ctr_idx return value
of sbi_pmu_ctr_cfg_match and compare it with cidx_base.

Fix these issues by returning the SBI_ERR_INVALID_PARAM error code if
the cidx_mask parameter value being passed in is 0 since an invalid
parameter should not lead to a successful sbi_pmu_ctr_cfg_match but with
unexpected side effects.

Following a similar rationale, add the validation check to
sbi_pmu_ctr_start and sbi_pmu_ctr_stop as well since sbi_fls is
undefined when the mask is 0.

This also aligns OpenSBI's behavior with KVM's.

Signed-off-by: James Raphael Tiovalen <jamestiotio@gmail.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Link: https://lore.kernel.org/r/20250520132533.30974-1-jamestiotio@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-20 21:01:14 +05:30
Anup Patel
d4f5a16598 include: sbi: Change SBI spec version to 3.0
Now that SBI v3.0 specification is frozen, change runtime SBI version
implemented by OpenSBI to v3.0. Also, mark extensions defined by the
SBI v3.0 specification as non-experimental.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Link: https://lore.kernel.org/r/20250516122844.113423-1-apatel@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-20 13:47:34 +05:30
Yao Zi
60c3f97de8 lib: utils: fdt: Claim Zicntr if time CSR emulation is possible
OpenSBI is capable of emulating time CSR through an external timer
for HARTs that don't implement a full Zicntr extension. Let's add
Zicntr extension in the FDT if CSR emulation is active.

This avoids hardcoding the extension in the devicetree, which may
confuse pre-SBI bootloaders.

Signed-off-by: Yao Zi <ziyao@disroot.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250516133352.36617-4-ziyao@disroot.org
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-20 13:25:53 +05:30
Yao Zi
7e31dc8052 lib: sbi: hart: Detect existence of cycle and instret CSRs for Zicntr
Zicntr extension specifies three read-only CSRs, time, cycle and
instret. It isn't sufficient to report Zicntr is fully supported with
only time CSR detected.

This patch introduces a bitmap to sbi_hart_features to record
availability of these CSRs, which are detected using traps. Zicntr is
reported as present if and only if three CSRs are all available on the
HARTs.

Sites originally depending on SBI_HART_EXT_ZICNTR for detecting
existence of time CSR are switched to detect SBI_HART_CSR_TIME instead.

Suggested-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Yao Zi <ziyao@disroot.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250516133352.36617-3-ziyao@disroot.org
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-20 13:25:53 +05:30
Alvin Chang
2bb7632649 lib: utils: Fix fdt_mpxy_init() not returning error code
It seems that current implementation doesn't fail on fdt_mpxy_init(),
because platforms might not have any MPXY devices. In fact, if there are
no MPXY devices, fdt_driver_init_all() will return SBI_OK.

More importantly, if there is any MPXY device which fails the
initialization, OpenSBI must check the error code and stop the booting.
Thus, this commit adds the return value for fdt_mpxy_init().

Signed-off-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250430091007.3768180-1-alvinga@andestech.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-20 11:20:57 +05:30
Anup Patel
f3cce5b97f lib: utils/mpxy: Remove p2a_db_index from RPMI system MSI attributes
The discovery of P2A doorbell system MSI index is now through RPMI
shared memory DT node so remove p2a_db_index from RPMI system MSI
attributes and access it as a mailbox channel attribute.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Link: https://lore.kernel.org/r/20250512083827.804151-5-apatel@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-20 11:10:35 +05:30
Anup Patel
8fadfebdd1 lib: utils/mailbox: Parse A2P doorbell value from DT
The A2P doorbell value written to the 32-bit A2P doorbell value
must be discoverd from device tree instead of always using the
default value 1.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Link: https://lore.kernel.org/r/20250512083827.804151-4-apatel@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-20 11:10:35 +05:30
Anup Patel
a79566175c lib: utils/mailbox: Parse P2A doorbell system MSI index from DT
The P2A doorbell system MSI index is expected to be discovered from
device tree instead of RPMI system MSI service group attribute. This
is based on ARC feedback before RPMI spec was frozen.

Let's parse P2A doorbell system MSI index from device tree and also
expose it as rpmi channel attribute to RPMI client drivers.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Link: https://lore.kernel.org/r/20250512083827.804151-3-apatel@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-20 11:10:35 +05:30
Anup Patel
8ca08044c2 lib: utils/mailbox: Update DT register name of A2P doorbell
The latest device tree bindings define A2P doorbell register name as
"a2p-doorbell" so update rpmi_shmem_transport_init() accordingly.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Link: https://lore.kernel.org/r/20250512083827.804151-2-apatel@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-20 11:10:35 +05:30
Chao-ying Fu
8a3071222a lib: Emulate AMO instructions when Zaamo is not available
The AMO instructions are very critical for Linux so allow low-end
RISC-V implementations without Zaamo to boot Linux by emulating AMO
instructions using Zalrsc when OpenSBI is compiled without Zaamo.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Link: https://lore.kernel.org/r/20250519121207.976949-1-apatel@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-20 09:18:03 +05:30
Parshintsev Anatoly
017a161788 Makefile: fix missing .debug_frame DWARF section for GCC
When OpenSBI is built with a relatively new compiler (gcc-13 and greater)
I observed that GDB is unable to produce proper backtraces and some
variable values appear corrupted (even if the associated DWARF
location descriptor is correct).

Turns out that to properly work with debug information, debuggers often
need to unwind the stack. They generally rely on Call Frame Information
(CFI) records provided by the compiler to facilitate this task.
Currently, the GCC compiler offers two mechanisms:

- `.debug_frame` section (as described in the DWARF specification).
- `.eh_frame` sections (as described in LSB documents).

The latter (`.eh_frame`) supports stack unwinding at runtime, providing
a framework for C++ exceptions or enabling backtrace generation using
libraries like libunwind. However, the downside of this approach is that
these sections should be part of loadable segments.

The former (`.debug_frame`) is simply an ordinary debug section.

Starting from GCC 13, Linux targets enable the `-fasynchronous-unwind-tables`
and `-funwind-tables` flags by default. Relevant commit:
https://github.com/gcc-mirror/gcc/commit/3cd08f7168

When these flags are active, the compiler generates `.eh_frame` sections
instead of `.debug_frame`. Since OpenSBI is built using the **Linux
toolchain**, this behavior applies to OpenSBI as well.

The problem arises because the SBI build system uses `-Wl,--gc-sections`,
which discards the `.eh_frame` section.

Possible Fixes:

1. Enforce `.debug_frame` generation – Modify compiler flags to generate
`.debug_frame` instead of `.eh_frame`.
2. Preserve `.eh_frame` in the linker script – Add `KEEP(*(.eh_frame))`
to ensure the section is not discarded.

I chose Option 1 because it avoids any runtime overhead.

Signed-off-by: Parshintsev Anatoly <anatoly.parshintsev@syntacore.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250421124729.36364-1-anatoly.parshintsev@syntacore.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-15 18:52:38 +05:30
Nick Hu
d844deadec lib: sbi: Use hsm stop for hsm wait
If we hotplug a core and then perform a suspend-to-RAM operation on a
multi-core platform, the hotplugged CPU may be woken up along with the rest
of the system, particularly on platforms that wake all cores from the
deepest sleep state. When this happens, the hotplugged CPU enters the
sbi_hsm_wait WFI wait loop instead of transitioning into a
platform-specific low-power state. To address this, we add a HSM stop call
within the wait loop. This allows platforms that support HSM stop to enter
a low-power state when the CPU is unexpectedly woken up.

Signed-off-by: Nick Hu <nick.hu@sifive.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250418064506.15771-1-nick.hu@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-05-15 17:31:11 +05:30
Radim Krčmář
316daaf1c2 lib: sbi_hart: properly reset Ssstateen
sstateen* and hstateen* CSRs must be zeroed by M-mode if the mstateen*
registers are missing, to avoid security issues.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Link: https://lore.kernel.org/r/20250429142549.3673976-10-rkrcmar@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-30 10:14:26 +05:30
Radim Krčmář
937118ca65 lib: sbi_hart: add Ssstateen extension
We already detect Smstateen, but Ssstateen exists as well and it doesn't
have the M-state CSRs.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Link: https://lore.kernel.org/r/20250429142549.3673976-9-rkrcmar@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-30 10:14:26 +05:30
Radim Krčmář
dac15cb910 lib: sbi_hart: reset mstateen0
The current logic clears some bits based on SBI known extensions.
Be safe and do not leave enabled anything that SBI doesn't control.

This is not a breaking change, because the register must be initialized
to 0 by the ISA on reset, but it is better to not depend on it when we
don't need to.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Link: https://lore.kernel.org/r/20250429142549.3673976-8-rkrcmar@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-30 10:14:26 +05:30
Radim Krčmář
8c814b5c9b lib: sbi_hart: fix sstateen emulation
The Sstateen extension defines 4 sstateen registers, but SBI currently
configures the execution environment to throw illegal instruction
exception when accessing sstateen1-3.

SBI should implement all sstateen registers, so delegate the
implementation to hardware by setting the SE bit.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Link: https://lore.kernel.org/r/20250429142549.3673976-7-rkrcmar@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-30 10:14:26 +05:30
Radim Krčmář
6b877fb53b lib: sbi_hart: reset sstateen and hstateen
Not resetting sstateen is a potential security hole, because U might be
able to access state that S does not properly context-switch.
Similar for hstateen with VS and HS.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Link: https://lore.kernel.org/r/20250429142549.3673976-6-rkrcmar@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-30 10:14:26 +05:30
Radim Krčmář
009f77a9f0 lib: sbi_hart: reset hstatus
hstatus.HU must be cleared, because U-mode could otherwise use the
HLS/HSV instructions.  This would allow U-mode to read physical memory
directly if vgatp and vsatp was 0.

The remaining fields don't seem like a security vulnerability now, but
clearing the whole CSR is not an issue, so do that be safe.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Link: https://lore.kernel.org/r/20250429142549.3673976-5-rkrcmar@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-30 10:14:26 +05:30
Radim Krčmář
65e8be4fe8 lib: sbi: use 64 bit csr macros
Switch the most obvious cases to new macros.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Link: https://lore.kernel.org/r/20250429142549.3673976-4-rkrcmar@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-30 10:14:25 +05:30
Radim Krčmář
f82c4bdf8c lib: sbi: add 64 bit csr macros
Most CSRs are XLEN bits wide, but some are 64 bit, so rv32 needs two
accesses, plaguing the code with ifdefs.

Add new helpers that split 64 bit operation into two operations on rv32.

The helpers don't use "csr + 0x10", but append "H" at the end of the csr
name to get a compile-time error when accessing a non 64 bit register.
This has the downside that you have to use the name when accessing them.
e.g. csr_read64(0x1234) or csr_read64(CSR_SATP) won't compile and the
error messages you get for these bugs are not straightforward.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
Link: https://lore.kernel.org/r/20250429142549.3673976-3-rkrcmar@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-30 10:14:25 +05:30
Raj Vishwanathan
99aabc6b84 lib: sbi: Set the scratch allocation to alignment to cacheline size
Set the scratch allocation alignment to cacheline size specified by
riscv,cbom-block-size in the DTS file to avoid two atomic variables
from the same cache line causing livelock on some platforms. If the
cacheline is not specified, we set it a default value.

Signed-off-by: Raj Vishwanathan <Raj.Vishwanathan@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Link: https://lore.kernel.org/r/20250423225045.267983-1-Raj.Vishwanathan@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-24 09:23:47 +05:30
Alvin Chang
4d0128ec58 lib: sbi_domain: Reduce memory usage of per-domain hart context
In current implementation, the length of hartindex_to_context_table[]
array is fixed as SBI_HARTMASK_MAX_BITS. However, the number of harts
supported by the platform might not be SBI_HARTMASK_MAX_BITS and is
usually smaller than SBI_HARTMASK_MAX_BITS. This means it is unnecessary
to allocate such fixed-length array here.

Precisely, current implementation always allocates 1024 bytes for
hartindex_to_context_table[128] on RV64 platform. However, a platform
supports two harts only needs hartindex_to_context_table[2], which only
needs 16 bytes.

This commit calculates needed size of hartindex_to_context_table[]
according to supported number of harts on the platform when registering
per-domain data, so that memory usage of per-domain context data can be
reduced.

Signed-off-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250326062051.3763530-1-alvinga@andestech.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 17:51:01 +05:30
Samuel Holland
2b09a98701 lib: sbi_platform: Remove the vendor_ext_check hook
Now that the generic platform only sets .vendor_ext_provider if the
function is really implemented, there is no need for a separate hook to
check if a vendor extension is implemented.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-11-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 12:32:51 +05:30
Samuel Holland
0dd8a26f1f lib: utils/fdt: Remove fdt_match_node()
This function has been obsoleted by the fdt_driver library and is no
longer used.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-10-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 12:32:51 +05:30
Samuel Holland
1c579675be platform: generic: Initialize overrides with fdt_driver
In addition to deduplicating the code, this also improves the match
selection logic to respect the priority order of the compatible strings,
as implemented in commit 0ffe265fd9 ("lib: utils/fdt: Respect
compatible string fallback priority").

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-9-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 12:32:51 +05:30
Samuel Holland
b80ded7756 platform: generic: Remove platform override hooks
Now that all of the overrides are modifying generic_platform_ops
directly, remove the unused hooks and forwarding functions. The
remaining members of struct platform_override match struct fdt_driver,
so use that type instead. This allows a future commit to reuse the
fdt_driver-based init function.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-8-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 12:32:51 +05:30
Samuel Holland
b353af63e2 platform: generic: Modify platform ops instead of using hooks
Switch all existing platform overrides to use the helper pattern instead
of the platform hooks. After this commit, only the .match_table and
.init members of struct platform_override are used.

There are two minor behavioral differences:
 - For Allwinner D1, fdt_add_cpu_idle_states() is now called before the
   body of generic_final_init(). This should have no functional impact.
 - For StarFive JH7110, if the /chosen/starfive,boot-hart-id property is
   missing, the code now falls back to using generic_coldboot_harts,
   instead of accepting any hart.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-7-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 12:32:51 +05:30
Samuel Holland
2489e1421d platform: generic: Allow replacing platform operations
Currently the generic platform follows the middleware pattern: it
implements the sbi_platform hooks, while providing its own set of hooks
for further customization. This has a few disadvantages: each location
where customization is needed requires a separate platform_override
hook, including places where the generic function does nothing except
forward to a platform_override hook, and the extra layer of function
pointers adds runtime overhead.

Let's restructure the generic platform to follow the helper pattern.
Allow platform overrides to treat the generic platform as a template,
adding or replacing the sbi_platform_operations as needed. Export the
generic implementations, so they can be called as helpers from inside
the override functions. With this pattern, the platform_override
function pointers are replaced by direct calls, and the forwarding
functions can be removed.

The forwarding functions are not exported, since there is no reason for
an override to call them. generic_vendor_ext_check() must be rewritten,
since now there is a new way to override vendor_ext_provider.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-6-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 12:32:50 +05:30
Samuel Holland
e78a0ebdc4 platform: generic: Add an init hook matching fdt_driver
In preparation for reusing the fdt_driver code to match platform
overrides, add a new .init hook matching the type signature from
fdt_driver. This hook replaces the existing .fw_init hook, since
it is called at roughly the same place in the init process.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-5-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 12:32:50 +05:30
Samuel Holland
de777cc633 platform: generic: thead: Avoid casting away const
struct fdt_match expects match data to be const. Follow this expectation
so that no type casting is needed.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-4-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 12:32:50 +05:30
Samuel Holland
ac2e428c4b platform: rzfive: Call andes_pma_setup_regions() only during cold boot
This function accesses the FDT blob, which means it is only valid to
call during cold boot, before a lower privilege level has an opportunity
to clobber that memory.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-3-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 12:32:50 +05:30
Samuel Holland
2a6f7ddf87 platform: generic: andes: Remove inline definitions
The addresses of these functions are used to set function pointers in
struct platform_override, so it is not valid for them to be inline.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250325234342.711447-2-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-23 12:32:50 +05:30
Alvin Chang
fda0742e76 lib: sbi_mpxy: Change MPXY state as per-domain data
OpenSBI supports multiple supervisor domains run on same platform. When
these supervisor domains want to communicate with OpenSBI through MPXY
channels, they will allocate MPXY shared memory from their own memory
regions. Therefore, the MPXY state data structure must be per-domain and
per-hart data structure.

This commit registers per-domain MPXY state data in sbi_mpxy_init(). The
original MPXY state allocated in scratch region is also removed. We also
replace sbi_scratch_thishart_offset_ptr() macro as new
sbi_domain_mpxy_state_thishart_ptr() macro which gets MPXY state from
per-domain data.

Signed-off-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Link: https://lore.kernel.org/r/20250325071314.3113941-1-alvinga@andestech.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-21 11:35:44 +05:30
Jimmy Ho
d2166a9d40 lib: sbi: Handle length of extension name string exceed buffer size error
print error message and turncat the string when length
of extension name string exceed buffer size

Signed-off-by: Jimmy Ho <jimmy.ho@sifive.com>
Reviewed-by: Nick Hu <nick.hu@sifive.com>
Reviewed-by: Zong Li <zong.li@sifive.com>
Link: https://lore.kernel.org/r/20250321001450.11189-1-jimmy.ho@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-21 08:42:01 +05:30
Xiang W
190979b4fc lib: sbi: Remove unnecessary SBI_INIT_LIST_HEAD
No need to initialise the nodes to be added to the linked list

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250319123944.505756-1-wxjstz@126.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-15 11:38:20 +05:30
Xiang W
169b4b8ae2 lib: sbi: Simplify structure member offset checking
Add a macro assert_member_offset() to perform structure member offset
checking.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250319123919.505443-1-wxjstz@126.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-15 11:26:36 +05:30
Xiang W
8b026abc5a lib: sbi: Fix SHMEM_PHYS_ADDR for RV32
Obtaining a 64-bit address under rv32 does not require combining two
32-bit registers because we ignore upper 32-bits on rv32.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250319123832.505033-1-wxjstz@126.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-15 11:22:00 +05:30
Xiang W
ce57cb572e lib: sbi: Add parameter check in sbi_mpxy_set_shmem()
Shared memory needs to be accessed in M-Mode so for now the high
address of shared memory can't non-zero.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250319123719.504622-1-wxjstz@126.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-15 10:19:13 +05:30
Leo Yu-Chi Liang
0442f1318e lib: sbi: Allow programmable counters to monitor cycle/instret events for Andes PMU
Referencing commit 0c304b6619
("lib: sbi: Allow programmable counters to monitor cycle/instret events")
to support this functionality for Andes PMU.

Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Link: https://lore.kernel.org/r/20250328084142.540807-1-ycliang@andestech.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-14 17:28:59 +05:30
Leo Yu-Chi Liang
5ab908d622 docs: pmu_support: fix example typos
The (event ID & "second column mask") should equal
the "first column match value". Modify the example
to fit the description.

Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Link: https://lore.kernel.org/r/20250324043943.2513070-1-ycliang@andestech.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-14 17:25:54 +05:30
Andrew Jones
37eaca4ab3 lib: sbi_ipi: Return error for invalid hartids
sbi_send_ipi() should return SBI_ERR_INVALID_PARAM if even one hartid
constructed from hart_mask_base and hart_mask, is not valid.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250314163021.154530-6-ajones@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-14 15:29:36 +05:30
Andrew Jones
a6e5f8878c sbi: Introduce sbi_hartmask_weight
Provide a function to count the number of set bits in a hartmask,
which builds on a new function for the same that operates on a
bitmask. While at it, improve the performance of sbi_popcount()
which is used in the implementation.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250314163021.154530-5-ajones@ventanamicro.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-14 15:29:19 +05:30
Samuel Holland
2142618f12 Makefile: Avoid repeated evaluation of shell commands
Recursively expanded variables (defined with '=') are expanded at
evaluation time. These version information variables are evaluated
inside a recipe as part of GENFLAGS. As a result, the shell commands
are executed separately for each compiler invocation. Convert the
version information variables to be simply expanded, so the shell
commands are executed only once, at Makefile evaluation time. This
speeds up the build by as much as 75%.

A separate check is needed to maintain the behavior of preferring the
value of OPENSBI_BUILD_TIME_STAMP from the environment.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250313035755.3796610-1-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-13 21:49:14 +05:30
Rajnesh Kanwal
aa40c53ce4 lib: sbi: Enable Control Transfer Records (CTR) Ext using xstateen.
The Control Transfer Records (CTR) extension provides a method to
record a limited branch history in register-accessible internal chip
storage.

This extension is similar to Arch LBR in x86 and BRBE in ARM.
The Extension has been stable and the latest release can be found here
https://github.com/riscv/riscv-control-transfer-records/release

Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250307124451.122828-1-rkanwal@rivosinc.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-13 06:11:43 +05:30
Samuel Holland
afa0e3091b lib: sbi_trap: Add support for vectored interrupts
When redirecting an exception to S-mode, transform the (v)stvec CSR
value as described in the privileged spec to derive the S-mode PC.
Since OpenSBI never redirects interrupts, only synchronous exceptions,
the only action needed is to mask out the (v)stvec.MODE field.

Reported-by: Jan Reinhard <jan.reinhard@sysgo.com>
Closes: https://github.com/riscv-software-src/opensbi/issues/391
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviwed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250305014729.3143535-1-samuel.holland@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-04-13 05:51:17 +05:30
Chao-ying Fu
995f226f3f lib: Emit lr and sc instructions based on -march flags
When -march=rv64im_zalrsc_zicsr is used, provide atomic operations
and locks using lr and sc instructions only.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250226014727.19710-1-cfu@mips.com
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-03-28 18:52:05 +05:30
Junhui Liu
8fe835303c lib: utils/serial: Add PXA UARTs support
The PXA variant of the uart8250 adds the UART Unit Enable bit (UUE) that
needs to be set to enable the XScale PXA UART. And it is required for
some RISC-V SoCs like the Spacemit K1 that implement the PXA UART.

This introduces the "intel,xscale-uart" compatible to handle setting the
UUE bit.

Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250327-pxa-uart-support-v2-1-c4400c1fcd0b@pigmoral.tech
Signed-off-by: Anup Patel <anup@brainfault.org>
2025-03-27 20:20:05 +05:30
Clément Léger
3ac49712e3 lib: sbi: sse: Add support for SSTATUS.SDT
Similarly to what is done for SPELP, handle SSTATUS.SDT upon event
injection. In order to mimick an interrupt, set SDT to 1 for injection and
save its previous value in interrupted_flags[5:5]. Restore it upon
completion.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2025-03-27 18:16:44 +05:30
Clément Léger
b4464b22e4 lib: sbi: sse: Add support for SSTATUS.SPELP
As raised during the ARC review, SPELP was not handled during the event
injection process. Save it as part of the interrupted flags, clear it
before injecting the event and restore it after completion.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2025-03-27 18:16:28 +05:30
Clément Léger
53d322f8ae lib: sbi: sse: Remove superfluous parenthesis around MSTATUS_* values
For some reason, there was a pair of useless parenthesis around MSTATUS_*
value usage. Remove them.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2025-03-27 18:16:19 +05:30
Clément Léger
41fb89cb29 lib: sbi: sse: Rename STATUS* interrupted flags to SSTATUS*
As raised by Andrew on the kvm-unit-test review, this flags are meant to
hold SSTATUS bits in the specification. Rename them to match that.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2025-03-27 18:15:44 +05:30
Clément Léger
1e7258d6a8 lib: sbi: sse: Return SBI_EDENIED for read only parameters.
The SSE specification did specified that read only parameters should
return SBI_EBADRANGE but was modified recently to return SBI_EDENIED.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2025-03-27 18:15:25 +05:30
Clément Léger
5dc7a6db6f lib: sbi: sse: Remove printf from sbi_sse_exit()
This printf is mainly useful for debugging, remove it.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2025-03-27 18:15:10 +05:30
Clément Léger
601bea45c5 lib: sbi: sse: Update SSE event ids
The latest specification added new high priority RAS events and renamed
the PMU to PMU_OVERFLOW.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2025-03-27 18:03:41 +05:30
Raj Vishwanathan
321ca8063b lib: utils: Make sure that hartid and the scratch are aligned
Harts associated with an ACLINT_MSWI need not have sequential hartids.
It is insufficient to use first_hartid and hart_count. To account for
non-sequential hart ids, include the empty hart-ids' generate hart-count.

Signed-off-by: Raj Vishwanathan <Raj.Vishwanathan@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-26 19:11:10 +05:30
Samuel Holland
949c83a799 lib: sbi: Use sbi_hart_count() and sbi_for_each_hartindex()
Simplify the code and improve consistency by using the new macros where
possible. sbi_hart_count() obsoletes sbi_scratch_last_hartindex().

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-24 17:57:20 +05:30
Samuel Holland
757f7acafd lib: sbi_scratch: Add sbi_hart_count() and for_each_hartindex()
There is currently no helper for iterating through the harts in a
system, and code must choose between sbi_scratch_last_hartindex() and
sbi_platform_hart_count() for the loop condition.

sbi_scratch_last_hartindex() has unusual semantics, leading to the
likelihood of off-by-one errors, and sbi_platform_hart_count() is
provided by the platform and so may not be properly bounded.

Add a new helper which definitively reports the number of harts managed
by this OpenSBI instance, i.e. the number of valid hart indexes, and a
convenient iterator macro.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-24 17:56:08 +05:30
Samuel Holland
6b97950cf5 lib: sbi_scratch: Optimize hartid and scratch lookup
The compiler generates much better code for sbi_hartindex_to_hartid()
and sbi_hartindex_to_scratch() when using a constant for the bounds
check. This works out nicely because the underlying arrays are already
a constant size, so the only change needed is to fill the remainder of
each array with the appropriate default/out-of-bounds value. The
ellipsis in the designated initializer is a GCC extension (also
supported by Clang), but avoids runtime initialization of the array.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-24 17:56:05 +05:30
Samuel Holland
ef4ed2dda7 lib: sbi_scratch: Apply bounds check to platform hart_count
The internal limit on the number of harts is SBI_HARTMASK_MAX_BITS, as
this value determines the size of various bitmaps and arrays (including
hartindex_to_hartid_table and hartindex_to_scratch_table). Clamp the
value provided by the platform, and drop the extra array element.

Update the documentation to indicate that hart_index2id must be sized
based on hart_count, and that hart indexes must be contiguous. As of
commit 5e90e54a1a ("lib: utils:Check that hartid is valid"), there is
no restriction on the valid hart ID values.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-24 17:56:04 +05:30
Samuel Holland
86c01a73ff lib: sbi: Avoid GOT indirection for global symbol references
OpenSBI is compiled with -fPIE, which generally implies dynamic linking.
This causes the compiler to generate GOT references for global symbols
in order to support runtime symbol interposition. However, OpenSBI does
not actually perform dynamic linking, so the GOT indirection just adds
unnecessary overhead.

The GOT references can be avoided by declaring global symbols with
hidden visibility, thus making them local to this dynamic object and
non-interposable. GCC/Clang's -fvisibility parameter is insufficient for
this purpose when referencing objects from other translation units;
either __attribute__((visibility(...)) or the pragma is required. Use
the pragma since it is easier to apply to every symbol. Additionally
clean up the one GOT reference from inline assembly.

With this change, a firmware linked with LLD does not contain either a
GOT or a PLT, and a firmware linked with BFD ld contains only a GOT with
a single (unreferenced, legacy) _GLOBAL_OFFSET_TABLE_ entry.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-24 17:00:59 +05:30
Samuel Holland
98c0a3860a Revert "lib: utils/irqchip: Match against more specific compatible strings first"
This reverts commit 6019259dfb.

Now that fdt_driver_init_by_offset() respects the compatible string
fallback priority order, this workaround is no longer necessary.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-24 16:37:52 +05:30
Samuel Holland
0ffe265fd9 lib: utils/fdt: Respect compatible string fallback priority
When matching drivers to DT nodes, always match all drivers against the
first compatible string before considering fallback compatible strings.
This ensures the most specific match is always selected, regardless of
the order of the drivers or match structures, as long as no compatible
string appears in multiple match structures.

Fixes: 1ccc52c427 ("lib: utils/fdt: Add helpers for generic driver initialization")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-24 16:37:06 +05:30
Himanshu Chauhan
b2e8e6986d lib: sbi: Return SBI_EALREADY error code if SSE event is present
Return SBI_EALREADY error code instead of SBI_EINVAL, in case an
event is already added to the supported list.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-23 21:17:36 +05:30
Anup Patel
8573a9b858 scripts: Fix firmware binaries compilation in create-binary-archive.sh
Currently, the generic libsbi.a is compiled in create-binary-archive.sh
before platform specific firmwares so a libsbi.a without any SBI extension
gets linked to the platform specific firmwares. To address this, remove
the temporary build directory in create-binary-archive.sh before using it.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2025-03-23 21:16:25 +05:30
Dongdong Zhang
3e6bd14246 lib: tests: add bitwise operations unit tests
Added unit tests for various bitwise operations using SBI unit
test framework.

Signed-off-by: Dongdong Zhang <zhangdongdong@eswincomputing.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-23 21:06:25 +05:30
Dongdong Zhang
56341e95ae lib: sbi: Fix potential garbage data in string copy functions
In the original implementation of `sbi_strcpy` and `sbi_strncpy`, if the
destination buffer (`dest`) was longer than the source string (`src`),
the functions did not ensure that the remaining bytes in `dest` were
properly null-terminated. This could result in garbage data being
present in the destination buffer after the copy operation, as the
functions only copied characters from `src` without explicitly
terminating `dest`.

Signed-off-by: Dongdong Zhang <zhangdongdong@eswincomputing.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-23 18:38:57 +05:30
Akshay Behl
0b78665a6c lib: add tests for sbi_ecall functionality
This patch adds unit tests for verifying the sbi_ecall version,
impid handling, and extension registration functions. The tests
ensure that the extension registration and unregistration work
as expected.

Signed-off-by: Akshay Behl <akshaybehl231@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-03-23 16:56:54 +05:30
Clément Léger
1ad1991244 lib: sbi: fwft: Return SBI_ERR_DENIED_LOCKED when setting a locked feature
Latest modifications to the spec mandates that a set on a lock feature
returns SBI_ERR_DENIED_LOCKED.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-19 22:13:21 +05:30
Clément Léger
b91ab20cd2 include: sbi: Add SBI_ERR_DENIED_LOCKED
Add SBI_ERR_DENIED_LOCKED and set it as the SBI_LAST_ERR which was
wrongly set to SBI_ERR_BAD_RANGE.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-19 22:10:59 +05:30
Alex Studer
6019259dfb lib: utils/irqchip: Match against more specific compatible strings first
The T-HEAD C90x PLIC has some special quirks, such as the S-mode
delegation bit. OpenSBI currently handles this by checking the compatible
string in the device tree.

However, this matching is done in the order of the fdt_match array. So if
a device tree contains both strings, for example:

	compatible = "thead,c900-plic", "riscv,plic0";

Then OpenSBI will match against the generic "riscv,plic0" string, since
that appears first in the fdt_match array. This means it will fail to set
the S-mode delegation bit, and Linux will fail to boot. In some cases, it
is not possible to change the compatible string to just the T-HEAD PLIC,
as older versions of Linux only recognize the RISC-V compatible string.

This patch fixes that by moving the RISC-V string to the end, ensuring
that the more specific options get matched first.

Signed-off-by: Alex Studer <alex@studer.dev>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-19 21:49:08 +05:30
Samuel Holland
a2c172f526 lib: utils/fdt: Allocate fdt_pmu_evt_select on the heap
This reduces .bss size by 8 KiB, and should reduce overall memory usage
since most platforms will have significantly fewer than 512 entries in
this table. At the same time, it removes the fixed table size limit.
Since the table is only used within fdt_pmu.c, instead of updating the
extern declaration, make the table local to this file.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-19 18:25:17 +05:30
Samuel Holland
f95d1140f6 lib: utils/fdt: Remove redundant PMU property length checks
If a property value is too small, len will be zero after the division
on the next line, so the property will be ignored. This is the same
behavior as when the length check fails. Furthermore, the first two
length checks were already ineffectual, because each item in those
arrays is 12 bytes long, not 8.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-19 18:22:52 +05:30
Samuel Holland
38df94422b lib: utils: Constify FDT driver definitions
The carray referencing these definitions assumes they are const.

Fixes: 6a26726e08 ("lib/utils: reset: Add RPMI System Reset driver")
Fixes: 13f55f33a1 ("lib: utils/suspend: Add RPMI system suspend driver")
Fixes: 33ee9b8240 ("lib: utils/hsm: Add RPMI HSM driver")
Fixes: 591a98bdd5 ("lib: utils/cppc: Add RPMI CPPC driver")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-19 17:47:24 +05:30
Clément Léger
f354400ebf lib: sbi: sse: fix invalid errors returned for sse_hart_mask/unmask()
When called twice, sse_hart_mask()/sse_hart_unmask() should return
SBI_EALREADY_STOPPED/SBI_EALREADY_STARTED. This was currently inverted.

Fixes: b919daf495 ("lib: sbi: Add support to mask/unmask SSE events")
Reported-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-19 17:18:13 +05:30
Anup Patel
1f64fef919 lib: sbi: Fix non-root domain startup
Currently, the sbi_sse_init() in cold boot path is called after
sbi_domain_finalize() so boot HART of non-root domains will start
before SSE cold boot init which can cause warm boot of such HARTs
to crash in sbi_sse_init().

To address the above issue, factor-out the non-root domain startup
from sbi_domain_finalize() function as a separate sbi_domain_startup()
function  which can be called after sbi_sse_init() in cold boot path.

Fixes: 93f7d819fd ("lib: sbi: sse: allow adding new events")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2025-02-19 17:11:39 +05:30
Joel Stanley
fe11dee7ea README: Remove comment about boolin toolchains being 64-bit only
As of January 2025 they have riscv32-ilp32d and riscv64-lp64d:

 https://toolchains.bootlin.com/releases_riscv32-ilp32d.html
 https://toolchains.bootlin.com/releases_riscv64-lp64d.html

Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-18 14:10:54 +05:30
Joel Stanley
f3dfa6488f README: Update toolchain section to mention PIE requirement
Since commit 76d7e9b8ee ("firmware: remove copy-base relocation"), the
Makefile enforces PIE support.

Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-18 14:10:11 +05:30
Joel Stanley
02c7a9bbef README: Any arch host can be used to cross compile
Verified by cross compiling from an arm64 host.

Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-18 14:08:29 +05:30
Anup Patel
ec09918426 lib: sbi: Update MPXY framework and SBI extension as per latest spec
The latest SBI 3.0 spec defines a new sbi_mpxy_get_shmem_size()
function and simplifies sbi_mpxy_set_shmem() function so update
the MPXY framework and SBI extension accordingly.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2025-02-13 11:10:03 +05:30
Anup Patel
61abd975f2 lib: utils: Add MPXY RPMI mailbox driver for System MSI service group
The supervisor software can directly receive most of the system MSIs
except P2A doorbell and MSIs preferred to be handled in M-mode.

Add MPXY RPMI mailbox client driver for the System MSI service group.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2025-02-13 11:10:03 +05:30
Anup Patel
b05e2a1956 include: sbi_utils: Update RPMI service group IDs and BASE service group
The service group ID assignment and some of the BASE services have
changes in the latest RPMI specification so let's update the RPMI
implementation accordingly.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2025-02-13 11:10:03 +05:30
Anup Patel
e4bc55930b lib: utils: Populate MPXY channel attributes from RPMI channel attributes
Use the RPMI mailbox channel attributes to populate MPXY channel
attributes instead of hard coding them.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2025-02-13 11:10:03 +05:30
Anup Patel
91012b475d lib: utils: Implement get_attribute() for the RPMI shared memory mailbox
To allow clients query service group version of a RPMI mailbox channel,
implement get_attribute() callback for the RPMI shared memory mailbox
controller.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2025-02-13 11:10:03 +05:30
Anup Patel
f8272946da include: sbi_utils: Include mailbox.h in rpmi_mailbox.h header
The rpmi_mailbox.h uses structures defined in mailbox.h so let's
include mailbox.h in rpmi_mailbox.h header.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2025-02-13 11:10:03 +05:30
Anup Patel
218de6ff7d lib: utils: Improve variable declarations in MPXY RPMI mailbox client
The local variable declarations should be at the start of function
and preferrably organized like a inverted pyramid.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2025-02-13 11:10:03 +05:30
Anup Patel
879ee6859c lib: utils: Drop notifications from MPXY RPMI mailbox client
Currently, the common MPXY RPMI mailbox client does not support
notifications so no need for dummy notifications support.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2025-02-13 11:10:03 +05:30
Anup Patel
a4876e6c6c lib: sbi: Improve local variable declarations in MPXY framework
The local variable declarations should be at the start of function
and preferrably organized like a inverted pyramid.

Signed-off-by: Anup patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2025-02-13 11:10:03 +05:30
Anup Patel
30437eb204 lib: sbi: Fix capability bit assignment in MPXY framework
The capability bit assignment in MPXY framework does not match the
SBI MPXY extension in latest SBI specification so update it.

Fixes: 7939bf1329 ("lib: sbi: Add SBI Message Proxy (MPXY) framework")
Signed-off-by: Anup patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2025-02-13 11:10:03 +05:30
Anup Patel
75c2057a6f lib: utils: Introduce optional MPXY RPMI service group operations
Some of the RPMI service groups may need additional context and
special handling when transferring messages via underlying mailbox
channel so introduce optional MPXY RPMI service group operations
for this purpose.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2025-02-13 11:10:03 +05:30
Anup Patel
fc1232899d lib: utils: Constantify mpxy_rpmi_mbox_data in mpxy_rpmi_mbox
The mpxy_rpmi_mbox_data is provided by RPMI service group specific
MPXY driver to the common MPXY RPMI mailbox client implementation
so let's constantify mpxy_rpmi_mbox_data in mpxy_rpmi_mbox so that
it is not accidently modified.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2025-02-13 11:10:03 +05:30
Anup Patel
d14340cb31 lib: utils: Split the FDT MPXY RPMI mailbox client into two parts
Instead of having one common FDT MPXY RPMI mailbox client drivers
for various RPMI service groups, split this driver into two parts:
1) Common MPXY RPMI mailbox client library
2) MPXY driver for RPMI clock service group

The above split enables having a separate MPXY driver for each
RPMI clock service group and #1 (above) will allow code sharing
between various MPXY RPMI drivers.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2025-02-13 11:10:03 +05:30
Clément Léger
5ce121b7a1 lib: sbi: increase the size of the string used for extension display
With the "max" QEMU cpu, the displayed extension string is truncated due
to the buffer being too small. Increase it to 256 to display the full
set of extensions correctly.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-13 09:16:05 +05:30
Samuel Holland
434add551c lib: utils: Initialize miscellaneous drivers in one pass
For driver subsystems that are not tightly integrated into the OpenSBI
init sequence, it is not important that the drivers are initialized in
any particular order. By putting all of these drivers in one array, they
can all be initialized with a single pass through the devicetree. This
saves about 10 ms of boot time on HiFive Unmatched.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-12 21:39:25 +05:30
Samuel Holland
e84ba96634 lib: utils/fdt: Remove fdt_find_match()
Now that all drivers are using the fdt_driver functions for
initialization, this function is unused and can be removed.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-12 21:27:54 +05:30
Samuel Holland
9e1a1518d4 lib: utils/irqchip: Use fdt_driver for initialization
The irqchip driver subsystem does not need any extra data, so it can use
`struct fdt_driver` directly. The generic fdt_irqchip_init() performs a
best-effort initialization of all matching DT nodes.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-12 21:22:37 +05:30
Inochi Amaoto
a7f3c159a0 platform: generic: thead: add Sophgo SG2044
The Sophgo SG2044 is a new version of C920, although it supports
sscofpmf, it still needs this pmu quirks its cores.

Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-12 18:00:18 +05:30
Xiang W
82da072eb4 firmware: fw_base.S: Fix comments for _wait_for_boot_hart
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 <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-12 09:34:06 +05:30
Raj Vishwanathan
5e90e54a1a lib: utils:Check that hartid is valid
It is possible that hartid may not be sequential and it should not be validated
against SBI_HARTMASK_MAX_BITS. Instead we should check the index of the hartid,
hart index, against SBI_HARTMASK_MAX_BITS.

Signed-off-by: Raj Vishwanathan <Raj.Vishwanathan@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-12 09:24:09 +05:30
Raj Vishwanathan
4f12f8b02f include: sbi: Align SBI trap registers to a nice boundary
Align SBI_TRAP_CONTEXT_SIZE to a multiple of 16 bytes. If it is not
aligned to 16 bytes for RV64, it can create performance problems.
Aligning it correctly can fix the performance issues.

Signed-off-by: Raj Vishwanathan <Raj.Vishwanathan@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-12 09:14:43 +05:30
Chao Du
3f25380d85 lib: utils: Make the enforce permission bit configurable from DT
The domain_support.md documentation states that the enforce permission
bit (BIT[6]) could be set in the "regions" property of a domain
instance DT node. However, this bit is masked in the current
implementation. This patch unmasks the bit to make it configurable
from DT.

Signed-off-by: Chao Du <duchao@eswincomputing.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-11 17:56:48 +05:30
Huang Borong
a76aca030d lib: utils/fdt: update fdt_parse_aplic_node()
1. Initialize struct imsic_data imsic to 0 at definition to prevent the
   use of uninitialized memory, ensuring the variable starts with known
   values.

2. Remove the redundant memset call on the "aplic" parameter since the
   memory for aplic is allocated using sbi_zalloc() by the caller
   irqchip_aplic_cold_init(), which guarantees it is already set to 0.

Signed-off-by: Huang Borong <huangborong@bosc.ac.cn>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-02-11 16:58:24 +05:30
Leo Yu-Chi Liang
555055d145 include: utils/fdt_helper: fix typo har't'id
s/hard_id/hartid/

Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-01-30 11:15:09 +05:30
Clément Léger
5c7e2c8334 lib: sbi: pmu: add the PMU SSE event only if overflow IRQ is supported
Add the PMU SSE event only if an overflow irq bit is present.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2025-01-30 10:43:16 +05:30
Clément Léger
ecab71e19a lib: sbi: sse: return SBI_ENOTSUPP for unsupported events
If a standard event was not found in the list of events that are handled
by harts but belongs to the standard event list defined by the
specification, return SBI_ENOTSUPP. Without that, we can not
distinguish a non implemented standard event from a non valid one.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2025-01-30 10:42:27 +05:30
Clément Léger
93f7d819fd lib: sbi: sse: allow adding new events
In order to allow events to be dynamically added, remove the existing
static array of events and use a simply linked list of supported events.
This allows us to move the cb_ops into this list and associated it with
an event_id. Drivers can now register cb_ops before bringing up the sse
core to handle additional events (platform ones for instance).

sbi_sse_init() now allocates as many events as present in the linked
list. Events can now be added with sbi_sse_add_event() which allows to
add new supported events with some callback operations if any. If an
event is not to be supported, then sbi_sse_add_event() should not be
called. This approach currently consider that local events are to be
supported on all harts (ie, they all support the same ISA or
dependencies). If per-hart event availability needs to be supported,
then, an is_supported() callback could be added later and called for
each hart.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2025-01-30 10:40:49 +05:30
Clément Léger
147978f312 include: lib: add a simple singly linked list implementation
Add a simple singly linked list implementation when double linked list
are not needed. This allows to easily have statically defined linked
list that can be extended at runtime.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-01-30 10:35:46 +05:30
Clément Léger
e05782b8ff lib: sbi: sse: return an error value from sse_event_get()
Since event support will be checked in the next commits, return a value
from sse_event_get() to allow propagating it. This will be used to
report SBI_ERR_NOT_SUPPORTED when an event isn't supported.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2025-01-30 10:34:14 +05:30
Clément Léger
9d2c9c6ca0 lib: sbi: move sbi_double_trap_handler() to a dedicated header
We will add new functions to sbi_double_trap.c in order to register an
SSE event, split this to a header as part of preparation work.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2025-01-30 10:32:18 +05:30
Clément Léger
3943ddbaab lib: sbi: pmu: fix usage of sbi_pmu_irq_bit()
While sbi_pmu_irq_bit() was used to delegate irq to S-mode, LCOFIP usage
was still hardcoded in various places. This led to change the returned
value of sbi_pmu_irq_bit() to be a bit number rather than a bit mask
since it returns an 'int' and we need to obtain the bit number itself to
handle it in the IRQs handlers. Add a similar function to return the
irq mask which can also be used where the mask is required rather than
the bit itself.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2025-01-30 10:30:45 +05:30
Anup Patel
bd613dd921 include: Bump-up version to 1.6
Update the OpenSBI version to 1.6 as part of release preparation.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <anup@brainfault.org>
2024-12-24 15:28:18 +05:30
Anup Patel
7150db29d7 lib: utils: Fix irqchip registration for PLIC and APLIC
Currently, the same irqchip instance is registered for multiple PLIC
and APLIC instances which causes the sbi_list_for_each_entry() loop
in the sbi_irqchip_init() to hang at boot-time.

To address the above issue, register a separate irqchip instance for
each PLIC and APLIC instance.

Fixes: 2dd6eaf680 ("lib: sbi_irqchip: Call driver warm_init from SBI core")
Reported-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-12-24 14:06:09 +05:30
Anup Patel
551ac0f2d4 lib: sbi: Improve the alignment of boot-time prints
Addition of "Experimental SBI Extensions" to the boot-time prints
disturbs the alignment of other prints so adjust all boot-time
prints accordingly.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-24 12:00:47 +05:30
Anup Patel
06754612f3 lib: sbi: Print list of available SBI extensions at boot-time
Add boot-time prints for list of available standard and experimental
SBI extensions.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-22 11:16:13 +05:30
Michael Neuling
d539d64a23 include: sbi: Fix compiling with C23 enabled compilers
C23 pre-defines bool so we need to gate our defines.

Signed-off-by: Michael Neuling <michaelneuling@tenstorrent.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-21 21:38:50 +05:30
Michael Neuling
91196d76b7 inclue: sbi_utils: Cleanup int vs bool in semihosting_init() definitions
This is needed for a future patches to enable the new C23 language dialect.

Signed-off-by: Michael Neuling <michaelneuling@tenstorrent.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-21 21:21:59 +05:30
Samuel Holland
8d8cc9507b lib: utils: Mark RPMI drivers as experimental
These drivers were merged on an experimental basis without the RPMI
specification being frozen. As a result, they may not be compatible with
the frozen version of the RPMI protocol. Additionally, their devicetree
bindings have not been reviewed and are subject to change. Warn the user
that these drivers make no compatibility guarantees, and that their
behavior and devicetree bindings may change incompatibly in future
versions of OpenSBI.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-21 18:22:47 +05:30
Samuel Holland
0c5dc12d73 platform: generic: Initialize console before other drivers
Initialize serial drivers first, so messages printed by other drivers do
not need to use the early console buffer.

Suggested-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-21 18:21:50 +05:30
Xiang W
f069301654 lib: utils: Improve rpmi_cppc_fc_db_trigger() for RV32
Improve 64-bit operation under rv32 and remove db_val_u32_hi
in rpmi_cppc_fc_db_trigger().

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-19 11:02:30 +05:30
Atish Patra
51dbc57fc7 lib: sbi_pmu: Verify the raw events first during event info
The raw events have same event_idx. Thus, the event info sanity check
only relies on the select mask. The raw event check should be done first
so that regular hardware events can be verified using event idx range
check.

Fixes: e434584216 ("lib: sbi_pmu: Implement SBI PMU event info function")
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-15 14:13:12 +05:30
Atish Patra
0928ca21bc lib: sbi_pmu: Fix the sanity check condition for hw event map
The hardware event map function invoked from platform code should
exclude any raw events as there is a separate function for the raw
events.

Fixes: d8a483fc7f ("lib: sbi_pmu: PMU raw event v2 support")
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-15 14:06:52 +05:30
Ben Dooks
39532d11e9 scripts/carray: change to using single awk invocation to generate .c
The shell script makes multiple call-outs to awk to get information
from the configuration file. It would be easier to just write the
whole thing in one .awk script and have the makefile altered to call
that instead.

There should be no functional difference other than the script type
and has been tested with PLATFORM=generic build. This should be both
quicker and easier to understand.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-15 12:39:59 +05:30
Ben Dooks
2c76548cba script/carry.sh: send error to stderr
Send the errors to stderr, otherwise they end up being
written to the file the script was redirecting to in the
Makefile

Also, use EOF block to make it easier to redirect

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-15 12:30:50 +05:30
Ben Dooks
a36cd1b043 Makefile: remove carry output if scripts/carray.sh fails
If the script fails, we end up trying to build either
an empty or damaged .c file. Just remove it and let
gcc fail on non-existent file.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-15 12:30:47 +05:30
Ben Dooks
c7866d99fe top: add ~ files to .gitignore
Ignore temporary files, and avoid accidentally adding
them to a commit.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-15 12:30:45 +05:30
Clément Léger
b47fcd01b3 lib: sbi: sse: Fix a6 and a7 register content upon injection
The specification states that a6 contains the current hart id and
a7 contains the entry argument. This was inverted in the current
implementation.

Reported-by: Andrew Jones <andrew.jones@linux.dev>
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-15 11:53:53 +05:30
Clément Léger
851e301098 lib: sbi: fix GLOBAL_PLAT_DEFINE
Fix GLOBAL_PLAT_0_START/END definitions. The specification states that
the beginning of the range is 0xc000 and the end is 0xffff.

Reported-by: Andrew Jones <andrew.jones@linux.dev>
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-15 11:52:57 +05:30
Anup Patel
5545602f77 Makefile: Don't enable V-extension using -march option
Enabling V-extension using -march option causes OpenSBI boot-time
hang with LLVM compiler.

As a work-around, don't enable V-extension using -march option and
instead use a custom OpenSBI specific define inform availability of
V-extension to lib/sbi/sbi_trap_v_ldst.c.

Fixes: c2acc5e5b0 ("lib: sbi_misaligned_ldst: Add handling of vector load/store")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-12-15 11:30:48 +05:30
Anup Patel
74c6ea014d lib: utils/fdt_cppc_rpmi: Fix compile error with LLVM
The following error is observed when compiling fdt_cppc_rpmi
driver using LLVM:

lib/utils/cppc/fdt_cppc_rpmi.c:87:3: error: label followed by a declaration is a C23 extension [-Werror,-Wc23-extensions]
   87 |                 u64 db_val_u64 = 0;

To fix the above issue, move the variable declaration at the
start of function.

Fixes: 591a98bdd5 ("lib: utils/cppc: Add RPMI CPPC driver")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-12-15 11:28:13 +05:30
Nylon Chen
c2acc5e5b0 lib: sbi_misaligned_ldst: Add handling of vector load/store
Add misaligned load/store handling for the vector extension
to the sbi_misaligned_ldst library.

This implementation is inspired from the misaligned_vec_ldst
implementation in the riscv-pk project.

Co-developed-by: Zong Li <zong.li@sifive.com>
Signed-off-by: Zong Li <zong.li@sifive.com>
Signed-off-by: Nylon Chen <nylon.chen@sifive.com>
Reviewed-by: Andy Chiu <andy.chiu@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-06 17:43:06 +05:30
Rahul Pathak
c5a8b15e39 lib: utils/mpxy: Add RPMI client driver for MPXY
Add a generic RPMI mailbox client driver which provides a MPXY channel.
Initially, this driver only supports RPMI clock service group but can
be extended to support multiple RPMI service groups.

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:57 +05:30
Anup Patel
32577ec3a1 lib: utils: Add simple FDT based MPXY driver framework
The generic platform can have multiple MPXY drivers so add a simple
FDT based MPXY driver framework.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:54 +05:30
Anup Patel
e67d91cdcc lib: sbi: Implement SBI MPXY extension
Implement the SBI MPXY extension which provides an SBI interface to
the supervisor software for send messages via MPXY framework.

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:52 +05:30
Rahul Pathak
7939bf1329 lib: sbi: Add SBI Message Proxy (MPXY) framework
Introduce SBI Message Proxy (MPXY) framework which allows platform specific
code or drivers to register message protocol specific channels.

This framework enables the supervisor software to send messages belonging
to different message protocols via OpenSBI firmware.

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Co-developed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:50 +05:30
Subrahmanya Lingappa
591a98bdd5 lib: utils/cppc: Add RPMI CPPC driver
Add RPMI based driver for CPPC register read, write and probe.

Signed-off-by: Subrahmanya Lingappa <slingappa@ventanamicro.com>
Co-developed-by: Rahul Pathak <rpathak@ventanamicro.com>
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Co-developed-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:47 +05:30
Anup Patel
54e632b72e lib: utils: Add simple FDT based CPPC driver framework
The generic platform can have multiple CPPC drivers so add a simple
FDT based CPPC driver framework.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:45 +05:30
Subrahmanya Lingappa
33ee9b8240 lib: utils/hsm: Add RPMI HSM driver
The RPMI HSM service group provides set of routine to query and control
power states of a Hart. Add RPMI based Hart State Management (HSM) driver.

Signed-off-by: Subrahmanya Lingappa <slingappa@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:43 +05:30
Anup Patel
ff4769bf08 lib: utils: Add simple FDT based HSM driver framework
The generic platform can have multiple HSM drivers so add a simple
FDT based HSM driver framework.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:40 +05:30
Anup Patel
9d760b810e lib: utils/fdt: Allow dynamic registration of FDT fixup callbacks
It should possible to fixup FDT from any part of OpenSBI so add
fdt_register_general_fixup() which allows dynamic registration of
FDT fixup callbacks.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:38 +05:30
Subrahmanya Lingappa
fdd7263536 lib: sbi: Add optional resume address to hart suspend
Add an optional resume address to the platform specific hart suspend call.

Signed-off-by: Subrahmanya Lingappa <slingappa@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:35 +05:30
Subrahmanya Lingappa
13f55f33a1 lib: utils/suspend: Add RPMI system suspend driver
Add RPMI based system suspend driver.

To test this, execute the follwoing in Linux:
 $ echo mem > /sys/power/state

To wake up, execute the following command on qemu monitor terminal:
 (qemu) system_wakeup

Signed-off-by: Subrahmanya Lingappa <slingappa@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:32 +05:30
Anup Patel
3676324b0e lib: utils: Add simple FDT based system suspend driver framework
The generic platform can have multiple system suspend drivers so add a
simple FDT based system suspend driver framework.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:29 +05:30
Rahul Pathak
6a26726e08 lib/utils: reset: Add RPMI System Reset driver
Add RPMI based driver for system reset and enable it in the generic
platform defconfig

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:27 +05:30
Rahul Pathak
91f46fb47e lib/utils: Add RPMI messaging protocol and shared memory transport support
The RISC-V Platform Management Interface (RPMI) defines a messaging protocol
and shared memory based transport for bi-directional communication with an
on-chip or external microcontroller.

To support RPMI in OpenSBI, add:
1) The RPMI messaging protocol defines and helper macros
2) A FDT mailbox driver for the RPMI shared memory transport

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Co-developed-by: Subrahmanya Lingappa <slingappa@ventanamicro.com>
Signed-off-by: Subrahmanya Lingappa <slingappa@ventanamicro.com>
Co-developed-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:21 +05:30
Anup Patel
2244a34f0d lib: utils/mailbox: Add simple FDT based mailbox framework
Add a simple FDT based mailbox framework which is built on top of the generic
mailbox library. The phandle of FDT mailbox DT node is treated as the unique
mailbox controller ID which is required by the generic mailbox library. The
FDT based mailbox drivers will be probed on-demand from fdt_mailbox_request_chan()
called by the mailbox client drivers.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:19 +05:30
Anup Patel
ad846a7cb8 lib: utils/mailbox: Add generic mailbox library
Add generic mailbox library which is independent of hardware description
format. The OpenSBI platform support or mailbox drivers can register
mailbox controller instances which can be discovered and used by different
mailbox client drivers. Each mailbox controller instance has a unique ID
which can be used by mailbox client drivers for find the mailbox controller
instance. The mailbox client drivers will typically request a mailbox channel
from the mailbox controller and use it to do data transfer with the remote
end of mailbox channel.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:13 +05:30
Rahul Pathak
b49d67b70f lib: Increase ROOT_REGION_MAX to accomodate more memregions
As more drivers adding memregions into root domain, the current static limit
of ROOT_REGION_MAX is not sufficient. Increase the limit to accomodate more
memregions.

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-12-06 09:26:11 +05:30
Atish Patra
e434584216 lib: sbi_pmu: Implement SBI PMU event info function
Allow the supervisor software to query about the event using the
new function. This supports both firmware and hardware events.
The hardware event presence is verified hw_event_map which is populated
via PMU device tree node. The firmware event presence is checked through
event validation function which should take care of both standard and
platform firmware events.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-02 09:52:55 +05:30
Atish Patra
05970d273c lib: sbi_pmu: Add SBI PMU event info function details.
The SBI v3.0 introduced a new function to query about the events
without invoking CFG_MATCH. This allows supervisor software to
identify which events are supported on the platform with single
SBI call instead of a CFG_MATCH for each event.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-02 09:52:52 +05:30
Atish Patra
cf196d80aa lib: sbi_pmu: Remove redundant check for fw events
The pmu_validate_event already has the same check for fw events.
The validate function is called prior to the current function
to find a counter for firmware. That's why, the redudant
check can be removed from the find counter function.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-02 09:52:50 +05:30
Atish Patra
d8a483fc7f lib: sbi_pmu: PMU raw event v2 support
As per the updated ISA specification and SBI PMU v3.0, lower 56
bits are available for the platform to implement mhpmeventX
encoding. Implement the PMU raw event V2 support defined in SBI
v3.0 which allows more bits for platforms to encode the raw events.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-02 09:52:04 +05:30
Igor Melnikov
40e725da03 Makefile: Fix POSIX grep for multiple patterns
grep -e "-mstrict-align\|-mno-unaligned-access" makes use of GNU grep's
backslash-escaped alternation operator \| which is available in basic
regular expression syntax (BRE) mode.

However, in POSIX grep's BRE mode | is an ordinary character which, when
backslash-escaped, matches itself. Therefore, the search pattern becomes
a plain string '-mstrict-align|-mno-unaligned-access' which obviously
never matches the expected error and CC_SUPPORT_STRICT_ALIGN is always set
to y.

When cross-compiling with LLVM on amd64-unknown-openbsd7.6 host for
riscv64-unknown-elf target this results in a compilation error:

clang: error: unsupported option '-mno-unaligned-access' for target
'riscv64-unknown-elf'

Using multiple -e options for this case maintains consistent behaviour
across different grep implementations and fixes the issue.

Signed-off-by: Igor Melnikov <imel@purelymail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-12-01 12:32:18 +05:30
Samuel Holland
a387a8dff0 lib: utils/timer: Use fdt_driver for initialization
The timer driver subsystem does not need any extra data, so it can use
`struct fdt_driver` directly. The generic fdt_timer_init() performs a
best-effort initialization of all matching DT nodes.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:57:20 +05:30
Samuel Holland
a524f0a507 lib: utils/serial: Use fdt_driver for initialization
The serial driver subsystem does not need any extra data, so it can use
`struct fdt_driver` directly. The generic fdt_serial_init() first
attempts to match the chosen stdout device, and upon failure matches the
first available serial device in the DT. It is a fatal error if no such
device is found. This matches the behavior of fdt_driver_init_one().

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:52:58 +05:30
Samuel Holland
6d9ad492db lib: utils/reset: Use fdt_driver for initialization
The reset driver subsystem does not need any extra data, so it can use
`struct fdt_driver` directly. The generic fdt_reset_init() performs a
best-effort initialization of all matching DT nodes. Platform-specific
logic expects exactly one DT node to match a single driver. This is
accomplished by using fdt_driver_init_one() with a local list containing
that one driver.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:48:17 +05:30
Samuel Holland
1f8db2f18f lib: utils/regmap: Use fdt_driver for initialization
The regmap driver subsystem does not need any extra data, so it can use
`struct fdt_driver` directly. It always initializes the driver for a
specific DT node.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:45:29 +05:30
Samuel Holland
5fa510c5f6 lib: utils/ipi: Use fdt_driver for initialization
The ipi driver subsystem does not need any extra data, so it can use
`struct fdt_driver` directly. The generic fdt_ipi_init() performs a
best-effort initialization of all matching DT nodes.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:42:05 +05:30
Samuel Holland
333133edaa lib: utils/i2c: Use fdt_driver for initialization
The i2c driver subsystem does not need any extra data, so it can use
`struct fdt_driver` directly. It always initializes the driver for a
specific DT node.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:38:05 +05:30
Samuel Holland
bef8f9b806 lib: utils/gpio: Use fdt_driver for initialization
FDT gpio drivers have an extra .xlate operation, so they need to embed
the `struct fdt_driver` inside the subsystem-specific type. The gpio
subsystem always initializes the driver for a specific DT node.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:29:12 +05:30
Samuel Holland
10df2d6fb5 scripts/carray.sh: Allow referencing a struct member
It can be useful to embed the objects referenced by a carray inside
another struct. To avoid type punning, the generated carray code must
use the correct type for the enclosing struct and member access to
compute the desired object address.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:23:36 +05:30
Samuel Holland
bb008e5d27 scripts/carray.sh: Avoid useless use of cat
awk(1) takes input files as positional arguments, so there is no need
to read the file with cat(1).

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:17:54 +05:30
Samuel Holland
1ccc52c427 lib: utils/fdt: Add helpers for generic driver initialization
Currently, each driver subsystem contains its own code for matching
drivers against the platform's devicetree blob. This bloats firmware
size because the several FDT scanning loops are almost exact copies of
each other, and is confusing because the loops do have some subtle
differences. Furthermore, the existing match algorithm is inefficient:
it scans the FDT structure separately for each driver in the list. A
faster algorithm scans the FDT blob only once, matching all drivers in
the list for each `compatible` property seen.

Add new helpers implementing this faster algorithm. Since they must
iterate through the list of drivers, the driver structure cannot be
opaque. However, since the driver list is an array of pointers, the
`struct fdt_driver` can be embedded in a subsystem-specific driver
structure if needed. These three helpers cover all existing use cases
for driver initialization within OpenSBI.

An additional benefit of centralized driver initialization is the
consistent use of fdt_node_is_enabled().

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:13:05 +05:30
Samuel Holland
df1c100001 treewide: Make carray arrays const and NULL-terminated
This allows the compiler to generate significantly better code, because
it does not have to maintain either the loop counter or loop limit. Plus
there are half as many symbols to relocate. This also simplifies passing
carray arrays to helper functions.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 17:09:17 +05:30
Nick Hu
23ef9c5f00 sbi: fwft: clear the config lock when warm boot
The hotplug cpu should clear the fwft config's SBI_FWFT_SET_FLAG_LOCK
in the warm boot flow otherwise the cpu can't set the menvcfg.sse by
SBI_EXT_FWFT_SET sbi call and cause the illegal instruction when
accessing the CSR_SSP in kernel.

Signed-off-by: Nick Hu <nick.hu@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 12:13:38 +05:30
Samuel Holland
111772353f lib: sbi_irqchip: Set the IRQ handler when registering a chip
In addition to saving some code size, this moves the decision about
setting the top-level external interrupt handler to the irqchip core,
not the specific driver, which would be needed to support chained
interrupt handlers.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:51:56 +05:30
Samuel Holland
678f5909a3 platform: Drop irqchip warm init and exit hooks
Now that driver lifecycle is managed from within the SBI irqchip core,
platforms need only to initialize the driver once during cold init.
Remove the remaining platform hooks that are no longer used.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:46:36 +05:30
Samuel Holland
2dd6eaf680 lib: sbi_irqchip: Call driver warm_init from SBI core
Currently, each platform keeps track of which irqchip driver is in use
and calls its warm init function. Since the generic platform may use
multiple irqchip drivers, it has logic to track an array of drivers.

The code is simplified and made common across platforms by treating warm
init and exit as properties of the driver, not the platform. Then the
platform's only role is to select and prepare a driver during cold boot.

For now, only add a .warm_init hook, since none of the existing drivers
need an .exit hook. It could be added in the future if needed.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:40:17 +05:30
Samuel Holland
e3e5686ef9 lib: sbi_irqchip: Register devices during cold init
Have the SBI irqchip core keep track of registered irqchip devices. This
is useful for any callbacks the irqchip driver may have, such as for
warm initialization, the external interrupt handler function, and any
future support for handling external interrupts (beyond IPIs) in M-mode.

This improves on the tracking done in fdt_irqchip.c, as it tracks device
instances, not just drivers, so callbacks can target a specific device.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:37:25 +05:30
Samuel Holland
56fddce83f lib: utils/irqchip: Move per-hart data from fdt_plic to plic
The per-hart PLIC pointer is not really specific to FDT platforms. Move
it into the main driver and drop the extra wrapper functions.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:35:01 +05:30
Samuel Holland
c6c22f00f4 lib: utils/irqchip: plic: Common PM save/restore
Move the PLIC save/restore functions inside the driver, so they can be
reused on any platform that needs them. The memory needed to store the
PLIC context is also allocated by the driver. The PM data cannot be
completely encapsulated, as some platforms (including Allwinner D1) need
to program the IRQ enable status to a sideband interrupt controller for
wakeup capability.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 11:28:38 +05:30
Samuel Holland
69448a0790 lib: utils/irqchip: plic: Provide a hartindex to context map
This removes platform-specific arguments to plic_warm_irqchip_init(),
which makes the driver independent from the platform after cold init,
and allows for further refactoring.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 09:36:46 +05:30
Samuel Holland
c26e3fd2ed lib: utils/irqchip: plic: Move delegation to base PLIC driver
This needs to be in the base PLIC driver as part of the power management
save/restore flow.

This is also in preparation for moving the PLIC information in the
scratch area to the base PLIC driver. After that change, the FDT PLIC
layer will be unable to look up the `struct plic_data` after cold boot.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 09:35:11 +05:30
Samuel Holland
a786aed08d lib: utils/irqchip: plic: Allow enabling IRQs by default
Unlike other platforms, Ariane and OpenPiton enable all IRQs by default.
This was described in commit b44e844880 ("Add support for Ariane FPGA
SoC") as "due to some issue of the design." Add this workaround behind a
flag in plic_warm_irqchip_init(), so every platform can use the same
warm init function.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-28 09:35:10 +05:30
Samuel Holland
86d2c1797a platform: Drop IPI warm init and exit hooks
Now that the SBI IPI core clears IPIs at warm boot in a generic way,
none of the drivers or platforms use these hooks, and we can remove
them. Platforms need only to initialize the driver once during cold
init. If other hooks are needed in the future, they can be added to
struct sbi_ipi_device.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 18:21:04 +05:30
Samuel Holland
693afc818f lib: sbi_ipi: Move initial IPI clear to sbi_ipi_init()
sbi_ipi_init() expects the platform warm init function to clear IPIs
on the local hart, but there is already a generic function to do this.
After this change, none of the existing drivers need a warm init
callback.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 18:18:35 +05:30
Samuel Holland
be9752a071 lib: sbi_ipi: Make .ipi_clear always target the current hart
All existing users of this operation target the current hart, and it
seems unlikely that a future user will need to clear the pending IPI
status of a remote hart. Simplify the logic by changing .ipi_clear (and
its wrapper sbi_ipi_raw_clear()) to always operate on the current hart.

This incidentally fixes a bug introduced in commit 78c667b6fc ("lib:
sbi: Prefer hartindex over hartid in IPI framework"), which changed the
.ipi_clear parameter from a hartid to a hart index, but failed to update
the warm_init functions to match.

Fixes: 78c667b6fc ("lib: sbi: Prefer hartindex over hartid in IPI framework")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 18:17:15 +05:30
Zhang RunMin
db8f03e512 include: sbi: Fix typo error
Fix typo in comments describing SBI_SCRATCH_FW_HEAP_SIZE_OFFSET.

Signed-off-by: Zhang RunMin <runmin.zhang@ingenic.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 17:53:32 +05:30
Inochi Amaoto
5d4e3fb2ee platform: introduce DT-based configurable heap size
The default heap size will work for most platforms, but for some
special platforms, the heap is too small to hold all the information
or is too big so that it take too much ram. Introduce configurable
heap should solve this problem and make all generic platforms happy.

Add DT-based heap-size for the generic platform.

Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 17:48:45 +05:30
Inochi Amaoto
dcb68dd17d platform: ensure enough heap size with debug triggers extension
DBTR introduce a big heap allocation to store hart state, this is
allocated percpu and needs big space when CPU number is high.

Increase the percpu part to fix this problem, and decrease the
fixed part to avoid too big heap size.

Fixes: 97f234f (lib: sbi: Introduce the SBI debug triggers extension support)
Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-11 17:40:22 +05:30
Tim Hutt
701948bdec docs: add example of building the Linux kernel
Slightly expand the QEMU docs to explain how to build the flat Linux kernel image.

Signed-off-by: Tim Hutt <tdhutt@gmail.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-09 14:30:41 +05:30
Kele Zhang
0171cfcc70 Makefile: enable --gc-sections
The --gc-sections option enables the linker to perform garbage
collection of unreferenced code and data, thereby reducing the binary
size.

The -ffunction-sections option will place each function into a separate
section, so it is necessary to add .text.* to the linker script.

Signed-off-by: Kele Zhang <zhangcola2003@gmail.com>
Signed-off-by: Yuan Tan <tanyuan@tinylab.org>
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-06 16:29:39 +05:30
Hui Min Mina Chou
369c64517e top: Add .editorconfig to set basic coding styles
EditorConfig [1] ensures consistent coding styles for developers
collaborating on the same project across various editors and IDEs. By
adopting the Linux project's .editorconfig settings [2] and applying
them to OpenSBI, it helps users maintain uniform indentation across
different IDEs and version control systems, improving development
efficiency.

The main difference from Linux project is the addition of
'trim_trailing_whitespace = true', which removes trailing whitespace
before newlines. This change affects only three files in OpenSBI, but
it improves overall code consistency.

 $ grep -nr "\s$" --include={*.{c,dts,h,lds,ldS,mk,s,S.py},Kconfig,Makefile,Makefile.*} .
 ./include/sbi_utils/fdt/fdt_fixup.h:4: * Implement platform specific DT fixups on top of libfdt.
 ./platform/generic/platform.c:79: * The fw_platform_coldboot_harts_init() function is called by fw_platform_init()
 ./platform/generic/platform.c:81: * according to the DT property "cold-boot-harts" in "/chosen/opensbi-config"

Link: https://editorconfig.org/ [1]
Link: https://lore.kernel.org/lkml/ZbAbmchIO8Cd5hNd@surfacebook.localdomain/T/ [2]
Signed-off-by: Hui Min Mina Chou <minachou@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-06 16:25:37 +05:30
Samuel Holland
9782b8847d lib: utils/regmap: Use FDT node offset as regmap ID
Since the FDT is not modified during driver initialization, node offsets
are just as suitable as phandles for use as identifiers: they are stable
and unique. With this change, it is no longer necessary to pass the
phandle to the driver init functions, so these init functions now use
the same prototype as other kinds of drivers.

This matches what is already done for I2C adapters.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-05 17:54:41 +05:30
Samuel Holland
d71150ee70 lib: utils/gpio: Use FDT node offset as GPIO chip ID
Since the FDT is not modified during driver initialization, node offsets
are just as suitable as phandles for use as identifiers: they are stable
and unique. With this change, it is no longer necessary to pass the
phandle to the driver init functions, so these init functions now use
the same prototype as other kinds of drivers.

This matches what is already done for I2C adapters.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-05 17:54:39 +05:30
Samuel Holland
598cf961d8 lib: utils/gpio: Remove fdt_gpio_driver() function
This function looks up a chip's driver by matching known drivers against
chip->driver, but that is equivalent to using chip->driver directly.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-05 17:54:37 +05:30
Samuel Holland
99b01ab610 platform: Drop timer warm init and exit hooks
Now that driver lifecycle is managed from within the SBI timer core,
platforms need only to initialize the driver once during cold init.
Remove the remaining platform hooks that are no longer used.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-05 17:39:31 +05:30
Samuel Holland
4500828743 lib: sbi_timer: Call driver warm_init from SBI core
Currently, the platform's timer device is tracked in two places: the
core SBI implementation has `timer_dev`, and the FDT timer layer has
`current_driver`. The latter is used for warm initialization of the
timer device. However, this warm init is not specific to FDT-based
platforms; other platforms call exactly the same functions from the
same point in the boot sequence.

The code is simplified and made common across platforms by treating warm
init and exit as properties of the driver, not the platform. Then the
platform's only role is to select and prepare a driver during cold boot.

For now, only add a .warm_init hook, since none of the existing drivers
need an .exit hook. It could be added in the future if needed.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-11-05 17:29:13 +05:30
Vladimir Kondratiev
1a2e507d23 lib: sbi: fix number of PMP entries detection
CSR_PMPADDRn lower bits may read all-0 or all-1, depending on
the configuration. For TOR it is all-0, for NAPOT - all-1.

Thus if PMP entry was pre-configured as NAPOT, original code would
stop scanning because value read back not equal to the written one.

Mask lower bits before comparison to fix this

Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-10-28 11:05:14 +05:30
Samuel Holland
62447cd7aa include: sbi: Optimize reads of mhartid and mscratch
csr_read() is marked as volatile and clobbering memory, which is
generally the safe thing to do. However, these two CSRs do not have any
side effects, and the values returned do not change between calls. The
compiler can generate better code if we allow it to reorder calls to
these functions and cache the return value. Introduce csr_read_relaxed()
for this use case.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-10-28 10:51:37 +05:30
Samuel Holland
3e0c170397 lib: utils/gpio: designware: Allocate chips on the heap
This reduces firmware size for SoCs which do not use this driver.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-10-28 10:40:25 +05:30
Clément Léger
c46a937fd9 lib: sbi: add Smdbltrp ISA extension support
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 <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-26 00:00:12 +05:30
Clément Léger
3bc86854ab lib: sbi: implement firmware feature SBI_FWFT_DOUBLE_TRAP
Add support for double trap firmware feature.

Link: https://lists.riscv.org/g/tech-prs/message/985 [1]
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:59:27 +05:30
Clément Léger
b2f77f5fa8 lib: sbi: fwft: factorize menvcfg read/write
MENVCFG access will be used as well for double trap, landing pad and
shadow stack fwft support. Factorize that in a common function.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:58:58 +05:30
Clément Léger
b0a7e4b853 lib: sbi: send a double trap SSE event to supervisor
In case the double trap handler is called and the double trap happened
in supervisor mode, send a double trap SSE event.

NOTE: this commit depends on the ratification of the new SSE event
id for double trap [1].

Link: https://lists.riscv.org/g/tech-prs/message/985 [1]
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:58:39 +05:30
Clément Léger
9c78593269 lib: sbi: add Ssdbltrp ISA extension support
Add Ssdbltrp trap handler support for S-mode double trap handling. If
the trap is received while in VS-mode, then the trap is redirected to
S-mode. If caught while in HS-mode, then an error is returned to the top
trap handler which will panic.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:58:00 +05:30
Clément Léger
80656bdb1d lib: sbi: factorize previous mode computation
Previous privilege mode retrieval from mstatus is done at different
places, factorize it rather than copy/pasting it again.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:53:18 +05:30
Clément Léger
daa282573f lib: sbi: factorize previous virtualization mode read from regs
The same pattern is used at multiple places to verify in which mode
the exception was actually taken. Factorize it.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:52:51 +05:30
Himanshu Chauhan
b919daf495 lib: sbi: Add support to mask/unmask SSE events
Add functions to globally mask/unmask supervisor software events
on the calling hart.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-10-25 23:04:43 +05:30
Anup Patel
ebbd276146 docs: Remove hartindex_to_context_table from domain_support.md
The hartindex_to_context_table field is no longer part of sbi_domain
so remove related documentation from domain_support.md.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-10-25 23:00:15 +05:30
Anup Patel
f609fd8584 lib: sbi_domain: Use domain data support for per-domain hart context
The per-domain hartindex_to_context_table[] is yet another per-domain
data required for implementing hart entry into (or exit from) domain.

Use the recently added domain data support for per-domain hart context
so that a dedicated hartindex_to_context_table[] in struct sbi_domain
is not needed.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
2024-10-25 23:00:10 +05:30
Anup Patel
81d79913a0 lib: sbi: Introduce domain data
Different parts of OpenSBI require their own per-domain data so
introduce domain data (or sbi_domain_data) which can be registered
by any part of OpenSBI. Using the domain data, the domain framework
will create a data pointer for every domain which can be used to
maintain some per-domain state.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
2024-10-25 23:00:07 +05:30
Anup Patel
65d4e9be95 include: sbi: Remove cyclic include in sbi_domain_context.h
The sbi_domain_context.h includes sbi_domain.h and the sbi_domain.h
also includes sbi_domain_context.h. Remove this cyclic include in
sbi_domain_context.h.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:00:04 +05:30
Anup Patel
2d517fce9b lib: utils/fdt: Use sbi_domain_memregion_init() when parsing domains
Use sbi_domain_memregion_init() at the time of parsing domains from
FDT so that sbi_domain_memregion_init() is always used for setting
up all memregions.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:00:02 +05:30
Anup Patel
36c1e4064f lib: sbi_domain: Make sbi_domain_root_add_memregion() as local function
The sbi_domain_root_add_memregion() is only used within sbi_domain
implementation so rename and make it a local function.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 23:00:00 +05:30
Anup Patel
dc5d747af8 lib: utils/irqchip: Use sbi_domain_root_add_memrange() for APLIC
The sbi_domain_root_add_memrange() should be preferred for creating
multiple memregions over a range. Update APLIC driver to use
sbi_domain_root_add_memrange() instead of explicitly registering
memregions.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 22:59:58 +05:30
Anup Patel
abc68e881d lib: utils/irqchip: Use sbi_domain_root_add_memrange() for IMSIC
The sbi_domain_root_add_memrange() should be preferred for creating
multiple memregions over a range. Update IMSIC driver to use
sbi_domain_root_add_memrange() instead of explicitly registering
memregions.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 22:59:56 +05:30
Anup Patel
8576ca4234 lib: utils/ipi: Use sbi_domain_root_add_memrange() for ACLINT mswi
The sbi_domain_root_add_memrange() should be preferred for creating
multiple memregions over a range. Update ACLINT mswi driver to use
sbi_domain_root_add_memrange() instead of explicitly registering
memregions.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-10-25 22:59:54 +05:30
Xiang W
2ffa0a153d lib: sbi: fix missing high 32bits when sbi_cppc_write on rv32
sbi_cppc_write was writing to the a1 register only, which under rv32
would cause the high 32 bits to always be 0. This patch fixes that.

Closes: https://github.com/riscv-software-src/opensbi/issues/334

Signed-off-by: Xiang W <wxjstz@126.com>
Reported-by: Wesley Norris <repnop@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-27 13:09:51 +05:30
dong.yang
3e141a6950 firmware: fw_base.S: fix multi-core boot bug.
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: 8151105af5 ("firmware: fw_base.S: Remove _relocate_lottery")
Signed-off-by: dong.yang <dong.yang@sophgo.com>
Reviewed-by: Xing Xiaoguang <xiaoguang.xing@sophgo.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-27 11:05:37 +05:30
Elyes Haouas
7b3de48cd5 include: sbi: Don't unconditionally define '__always_inline'
Update __always_inline macro define to fix opensbi upstream
build for coreboot.
Refer, https://qa.coreboot.org/job/coreboot-gerrit/257449/testReport/junit/(root)/clang/EMULATION_QEMU_RISCV_RV64_/

Closes: https://github.com/riscv-software-src/opensbi/issues/366
Signed-off-by: Elyes Haouas <ehaouas@noos.fr>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-09-27 10:52:32 +05:30
Samuel Holland
bfa9f9aee7 Makefile: Make .carray.c files depend on carray.sh
Force carray C source files to be regenerated when the script changes,
since their contents depend on the script's output.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-27 10:47:51 +05:30
Samuel Holland
cae230c935 lib: utils/ipi: Fix hartid wrongly used as hart index
Since commit 78c667b6fc ("lib: sbi: Prefer hartindex over hartid in
IPI framework"), The .ipi_clear callback functions take a hart index,
not a hartid. However, these warm_init functions were never updated.

Fixes: 78c667b6fc ("lib: sbi: Prefer hartindex over hartid in IPI framework")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-27 10:42:24 +05:30
Samuel Holland
9155024972 lib: sbi: Remove unused hartid parameters
None of these functions use their hartid parameter.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 16:29:29 +05:30
Samuel Holland
3962be84d4 lib: sbi: Update sbi_{entry,init}_count() to take a hart index
All callers already have the hartindex available, so this removes a
hartid to hartindex conversion.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 16:29:27 +05:30
Samuel Holland
9f86524b58 lib: sbi: Update sbi_domain_is_assigned_hart() to take a hart index
This removes redundant hartid to hartindex conversions from four call
sites and provides a net reduction in code size.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 16:29:25 +05:30
Samuel Holland
fe153c5516 lib: sbi: Use sbi_hartmask in sbi_hsm_hart_interruptible_mask()
This removes several hartid/hartindex conversions, as well as two loops
through the mask for broadcast IPIs.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 16:28:18 +05:30
Samuel Holland
ebe0f31446 lib: sbi: Update __sbi_hsm_hart_get_state() to take a hart index
This removes some hartindex conversions in sbi_system_suspend(), but is
mostly intended to support refactoring sbi_hsm_hart_interruptible_mask()
to work exclusively with struct sbi_hartmask.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 11:30:04 +05:30
Samuel Holland
97b8038916 lib: sbi: Simplify halt broadcast logic
Use the IPI .update callback to exclude the local hart. This allows
reusing the normal logic for broadcasting an IPI to all active harts.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 11:16:53 +05:30
Samuel Holland
633e7cbd50 lib: sbi_ecall_legacy: Use SBI v0.2 encoding for "all harts"
This simplifies the logic so that sbi_hsm_hart_interruptible_mask() is
only called from one place (sbi_ipi_send_many()). A minor functional
change is that the legacy functions can now affect more than XLEN harts
when targeting all harts.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-26 10:44:34 +05:30
Samuel Holland
7f5fa9f9a4 lib: utils/irqchip: Look up IMSIC data by hart index
This avoids needing to map a hartid to a hart index.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-25 18:06:59 +05:30
Samuel Holland
d73a4c741c lib: sbi_sse: Cache the event's target hart index
This avoids needing to map the target hartid to a hart index when
enabling or disabling an event, and provides a net code size reduction.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-25 18:04:25 +05:30
Samuel Holland
15c4e285db lib: sbi: Use current_hartindex() where possible
This avoids calls to the expensive sbi_hartid_to_hartindex() function
and also makes the firmware smaller.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-25 12:03:30 +05:30
Samuel Holland
9d7a983060 include: sbi: Store the hart index in struct sbi_scratch
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 <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-25 12:00:47 +05:30
Samuel Holland
4ac1818197 lib: sbi_init: Remove obsolete hartid check
This check has been obsolete since commit c51f02cf14 ("include:
sbi_platform: Introduce HART index to HART id table"). It originally
filtered out harts that were disabled in the FDT, but those harts are
omitted from the hart_index2id table, so they will hang in fw_base.S
after the "Find HART index" loop and never enter sbi_init().

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-25 10:55:30 +05:30
Samuel Holland
7c40909159 firmware: Simplify FDT header endianness conversion
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 <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-25 09:46:35 +05:30
Deepak Gupta
7179e36ce7 lib: sbi: fwft: implement landing pad and shadow stack fwft interface
Supervisor software can enable control flow integrity features for itself
using fwft feature `SBI_FWFT_LANDING_PAD` and `SBI_FWFT_SHADOW_STACK`.
This patch implements the mechanism to enable both these fwft.

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Clément Léger <cleger@rivosinc.com>
2024-09-23 19:02:48 +05:30
Deepak Gupta
110524441a lib: sbi: sw check exception delegation
zicfiss and zicfilp introduces new exception (cause=18). Delegate this
exception to S mode because cfi violations in U / S will be reported
via this exception.

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2024-09-23 18:59:24 +05:30
Deepak Gupta
c0804ed49a lib: sbi: add zicfilp/zicfiss and elp cfi state reflect back in status
This patch adds support to check for zicfilp / zicfiss extension.

zicfilp record status of hart's ELP state in *status csr. Missing landing
pad sets MPELP in mstatus. When SBI is redirecting back to S/VS/HS, SPELP
is set in sstatus/vsstatus.

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-09-23 18:58:04 +05:30
Deepak Gupta
6758a756c4 include: adding support for Zicfilp / Zicfiss encodings
Zicfilp / Zicfiss extension (see link) introduces b2 (LPE) in menvcfg CSR to
enable landing pads and b3 (SSE) in menvcfg CSR to enable shadow stack and
landing pad for privilege less than M. Additionally extension introduces new
bits in *status for recording landing pad state and a new exception type
`software check exception` with cause=0x12.

Link: https://github.com/riscv/riscv-cfi

Signed-off-by: Deepak Gupta <debug@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2024-09-23 18:55:07 +05:30
Zong Li
570b9ae89a include: sbi_bitops: add ULL version for BIT and GENMASK
Add BIT_ULL and GENMASK_ULL for dealing with 64-bits data on
32-bits CPU, then we don't need to separate the operation to
low part and high part. For instance, the MMIO register is
64 bits wide.

Signed-off-by: Zong Li <zong.li@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-23 18:33:02 +05:30
Samuel Holland
040fcf49ab lib: sbi_domain_context: Fix file permissions
These C source files should not be marked as executable.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-23 18:26:47 +05:30
Samuel Holland
beef2f6937 lib: sbi: Respect scounteren when emulating the time CSR
This optimization creates a correctness issue, as it prevents supervisor
software from restricting VS-mode or U-mode access to the time CSR for
its own purposes.

Closes: https://github.com/riscv-software-src/opensbi/issues/370
Fixes: ebc8ebc0f8 ("lib: sbi: Improve HPM CSR read/write emulation")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-23 18:12:39 +05:30
Atish Patra
00093a2000 docs: Remove github PR as an option
OpenSBI development workflow is mailing list based from the
beginning. Initially, github PRs were added as an option but it turned
out that it is not feasible to support both github PR and mailing list
based workflows. Hence, all the PRs has been redirected to use the
mailing list from a long time. In fact, it is source of confusion to
have both options.

Update the documentation to reflect the reality.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-23 17:55:30 +05:30
Samuel Holland
1cb234b1c9 lib: sbi: fwft: add support for SBI_FWFT_POINTER_MASKING_PMLEN
Add support for controlling the pointer masking mode on harts which
support the Smnpm extension. This extension can only exist on harts
where XLEN >= 64 bits. This implementation selects the mode with the
smallest PMLEN that satisfies the caller's requested lower bound.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-23 17:50:40 +05:30
Samuel Holland
ebfaf1974e lib: sbi: Fix writes to emulated 32-bit htimedelta CSR
Writes to the low half CSR should not affect the high half of the value.
Make this separation explicit by writing to the delta in memory as two
adjacent XLEN-sized values.

Fixes: 1e9f88889f ("lib: Emulate HTIMEDELTA CSR for platforms not having TIME CSR")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-20 21:52:06 +05:30
Samuel Holland
65f04badf7 lib: sbi: Use a linked list to track domains
This removes the compile-time limit on the number of domains. It also
reduces firmware size by about 200 bytes by removing the lookup table.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-20 21:40:32 +05:30
Samuel Holland
792715e4f3 include: sbi_domain: Fix incorrect comments
These comments are inaccurate as of commit db56341dfa ("lib: sbi:
Allow platforms to provide root domain memory regions"), which modified
root domain registration to go through sbi_domain_register() like other
domains.

Fixes: db56341dfa ("lib: sbi: Allow platforms to provide root domain memory regions")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-09-20 21:16:41 +05:30
Anup Patel
c4940a9517 platform: generic: Fix fw_platform_coldboot_harts_init() function
It is possible that the OpenSBI config DT node is present but
the "cold-boot-harts" DT property is not present. In this case,
the fw_platform_coldboot_harts_init() will do nothing which
in-turn causes OpenSBI firmware hang at boot time.

To address the above issue, fallback to the default approach
when the "cold-boot-harts" DT property is not present.

Fixes: 67ce5a763c ("platform: generic: Add support for specify coldboot harts in DT")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-08-27 10:52:03 +05:30
Zhang RunMin
ef4520b1c6 lib: Delete redundant ulong
In `csr_read_allowed` and `csr_write_allowed` macros, has already
converted second param to `ulong`. So delete redundant `ulong`
where uses csr_read/write_allowed macros.

Signed-off-by: Zhang RunMin <runmin.zhang@ingenic.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 14:42:14 +05:30
Gregor Haas
b0ad9e0bdd lib: utils: fdt_domain: Make opensbi-domain optional in CPU node
The domain_support.md documentation states that "the HART to domain instance
assignment can be parsed from the device tree using *optional* DT property
opensbi-domain in each CPU DT node". However, the current implementation does
not treat this parameter as optional when determining which HARTs to assign to
a freshly discovered domain from the device tree, causing an effect where every
HART in the system must be explicitly assigned to a domain only if a domain is
specified in the device tree. Instead, this patch simply ignores CPUs that do
not specify a domain, and does not attempt to assign them into the recently
discovered domain.

Signed-off-by: Gregor Haas <gregorhaas1997@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 14:08:00 +05:30
Daniel Henrique Barboza
c5b6ebd141 Makefile: fix OPENSBI_VERSION_GIT build with submodules
When building OpenSBI via a submodule, OPENSBI_VERSION_GIT can be left
unset in case '.git' isn't a dir. This is the case when building OpenSBI
as a QEMU submodule:

$ cat .git
gitdir: ../../.git/modules/roms/opensbi

As a result, building OpenSBI tag v1.5.1 in QEMU will result in a binary
that will have "OpenSBI v1.5" as a banner.

Use "git rev-parse --git-dir" instead of checking if '.git' is a dir to
detect if the current dir is a git repo.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:59:05 +05:30
Clément Léger
70f3441452 lib: sse: remove unused sse_inject_out() parameter
This parameters was a remnant of a previous version, remove it now that
it is unused.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:15:58 +05:30
Yu Chien Peter Lin
a44df8024b util: atcsmu.c: modify sbi_printf() formatting
Beautify multi-line printing.

Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:10:36 +05:30
Leo Yu-Chi Liang
f7a625884c util: atcsmu.c: fix typo "%s/hard/hart/"
%s/hard/hart

Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:10:35 +05:30
Samuel Holland
8cb7f89d7c lib: utils/fdt: Add fdt_get_address_rw() helper
Help tracking the lifecycle of the FDT blob by indicating which parts of
the firmware modify it, and thus invalidate any previously-obtained
offsets or pointers to data inside the blob.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:03:04 +05:30
Samuel Holland
c36801841e lib: utils/serial: Pass the FDT to fdt_serial_init()
Indicate that this function does not modify the FDT blob, and
deduplicate the call to fdt_get_address().

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:03:01 +05:30
Samuel Holland
fa6dfce017 lib: utils/reset: Pass the FDT to fdt_reset_init()
Indicate that this function does not modify the FDT blob, and
deduplicate the call to fdt_get_address().

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:58 +05:30
Samuel Holland
6e5db7b09c platform: generic: Pass FDT to early/final_init overrides
Several of these override functions access the FDT blob. Explicitly
indicate which callbacks are allowed to modify the FDT blob by passing
the parameter as a possibly-const pointer. This also reduces code size
by deduplicating the call to fdt_get_address().

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:54 +05:30
Samuel Holland
3f964652d9 platform: generic: Constify FDT pointers in fw_platform_init()
Indicate that none of these functions modify the devicetree by
constifying the parameter type.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:51 +05:30
Samuel Holland
b15cc7715a lib: utils/timer: Constify FDT pointers in parsing functions
Indicate that none of these functions modify the devicetree by
constifying the parameter type.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:48 +05:30
Samuel Holland
bd76eb4950 lib: utils/serial: Constify FDT pointers in parsing functions
Indicate that none of these functions modify the devicetree by
constifying the parameter type.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:46 +05:30
Samuel Holland
57a0479302 lib: utils/reset: Constify FDT pointers in parsing functions
Indicate that none of these functions modify the devicetree by
constifying the parameter type.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:42 +05:30
Samuel Holland
1bbda9b26f lib: utils/regmap: Constify FDT pointers in parsing functions
Indicate that none of these functions modify the devicetree by
constifying the parameter type.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:39 +05:30
Samuel Holland
7df1c8126f lib: utils/irqchip: Constify FDT pointers in parsing functions
Indicate that none of these functions modify the devicetree by
constifying the parameter type.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:36 +05:30
Samuel Holland
d561418f22 lib: utils/ipi: Constify FDT pointers in parsing functions
Indicate that none of these functions modify the devicetree by
constifying the parameter type.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:33 +05:30
Samuel Holland
039e810437 lib: utils/i2c: Constify FDT pointers in parsing functions
Indicate that none of these functions modify the devicetree by
constifying the parameter type.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:28 +05:30
Samuel Holland
c585354380 lib: utils/gpio: Constify FDT pointers in parsing functions
Indicate that none of these functions modify the devicetree by
constifying the parameter type.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:27 +05:30
Samuel Holland
33ba4e0567 lib: utils/fdt: Constify FDT parsing functions
Distinguish between functions which modify the devicetree and those
which only extract information from it. Other than the iterators in
fdt_domain.c, this is a mechanical conversion.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:25 +05:30
Samuel Holland
f229a32828 lib: utils/regmap: Fix typo in comment
Balance the quotation marks; double quotes are idiomatic here.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:23 +05:30
Samuel Holland
bcb81f0cbe lib: utils/fdt: Fix fdt_add_cpu_idle_states() prototype
The function prototype should use the same parameter name as the
documentation and the function definition.

Fixes: 33bf917460 ("lib: utils: Add fdt_add_cpu_idle_states() helper function")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-24 13:02:21 +05:30
Yu Chien Peter Lin
56183ca609 lib: utils: fdt_domain: Use consistent device-tree address when next-arg1 is missing
The diagram shown below illustrates the boot-flow involving OP-TEE OS
initialization.

    (1)-----------+
     | U-Boot SPL |
     +------------+
         |
         v
    (2)-------------------------------------------------------------+
     | OpenSBI (fw_dynamic)                                         |
     |                (4)------------------------+                  |
     |                 | optee dispatcher driver |                  |
     +-----------------+-------^---------|-------+------------------+
M-mode   |                     |         |
---------+--[trusted domain]---+----.----+--[untrusted domain]-------
S-mode   |  (coldboot domain)  |    |    |
         v                     |    |    v
    (3)---------------------------+ |(5)----------------------------+
     | OP-TEE OS                  | | | U-Boot                      |
     +----------------------------+ | +-----------------------------+
                                    |    |
                                    |    v
                                    |(6)----------------------------+
                                    | | Linux                       |
                                    | +-----------------------------+

As OP-TEE OS has device-tree node fixups that need to be passed
through to the next boot stages, e.g. the reserved memory node:

  reserved-memory {
    #address-cells = <2>;
    #size-cells = <2>;
    ranges;
    optee_core@f1000000 {
      no-map;
      reg = <0x0 0xf1000000   // OP-TEE OS base address
             0x0 0x01000000>;
    };
    <...>
  };

Instead of using 0x0 as the default value, allow identical next-arg1
to be used by non-coldboot domain (i.e., untrusted domain) when the
property is not provided.

Also, update the description of next-arg1 property in the document.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-23 14:17:29 +05:30
Ben Zong-You Xie
3d1f53b173 platform: generic: andes: add a new Andes SBI call to free a PMA entry
Add a new Andes SBI call to free a PMA entry, and reset the memory
attributes for the corresponding NAPOT region.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-23 14:10:30 +05:30
Ben Zong-You Xie
aa56084c4d platform: generic: andes: add a new Andes SBI call to set up a PMA entry
Implement a new Andes SBI call, which is to set up a NAPOT region
with given memory attributes.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-23 14:08:19 +05:30
Ben Zong-You Xie
4a72abb5f4 platform: generic: andes: add Andes SBI call to probe Andes PMA feature
Add a new Andes SBI call to check whether PPMA is supported by hardware
or not.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-23 14:05:39 +05:30
Ben Zong-You Xie
17100394f9 platform: generic: Kconfig: add the description for Andes PMA feature
Describe Andes PPMA in the config option, and select it for AE350
platform.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-23 14:03:45 +05:30
Dongdong Zhang
d4322eebd0 lib: sbi: Enhance CSR Handling in system_opcode_insn
- Completed TODO in `system_opcode_insn` to ensure CSR read/write
  instruction handling.
- Refactored to use new macros `GET_RS1_NUM` and `GET_CSR_NUM`.
- Updated `GET_RM` macro and replaced hardcoded funct3 values with
  constants (`CSRRW`, `CSRRS`, `CSRRC`, etc.).
- Removed redundant `GET_RM` from `riscv_fp.h`.
- Improved validation and error handling for CSR instructions.

This patch enhances the clarity and correctness of CSR handling
in `system_opcode_insn`.

Signed-off-by: Dongdong Zhang <zhangdongdong@eswincomputing.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-23 13:36:49 +05:30
Gregor Haas
b9c091ed89 lib: sbi: Implement aligned memory allocators
This change adds a simple implementation of sbi_aligned_alloc(), for future use
in allocating aligned memory for SMMTT tables.

Signed-off-by: Gregor Haas <gregorhaas1997@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-09 08:51:27 +05:30
Gregor Haas
cda0014795 lib: sbi: Allocate from beginning of heap blocks
In the next commit, we'll add a new sbi_memalign() function. In order to
allocate aligned memory, we'll sometimes need to allocate from the middle of a
heap block, effectively splitting it in two. Allocating from the beginning of a
heap block in the nonaligned case more closely matches this behavior, reducing
the complexity of understanding the heap implementation.

Signed-off-by: Gregor Haas <gregorhaas1997@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-09 08:51:26 +05:30
Gregor Haas
8b898c4e50 lib: sbi: Support multiple heaps
The upcoming SMMTT implementation will require some larger contiguous memory
regions for the memory tracking tables. We plan to specify the memory region
for these tables as a reserved-memory node in the device tree, and then
dynamically allocate individual tables out of this region. These changes to the
SBI heap allocator will allow us to explicitly create and allocate from a
dedicated heap tied to the table memory region.

Signed-off-by: Gregor Haas <gregorhaas1997@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-09 08:51:24 +05:30
Carlos López
6a090ee9dc lib: sbi: check result of pmp_get() in is_pmp_entry_mapped()
pmp_get() may return an error if the given entry, given by the caller
of is_pmp_entry_mapped(), is invalid. This results in the output
parameters for pmp_get() being uninitialized. To avoid using garbage
values, check the result and return early if necessary.

This issue is not being hit because at the moment
is_pmp_entry_mapped() is only being called from a single site with a
valid hardcoded value.

Signed-off-by: Carlos López <carlos.lopezr4096@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-02 08:45:10 +05:30
Carlos López
41bb668315 lib: sbi: fwft: fix incorrect size passed to sbi_zalloc()
The fwt_hart_state struct inciludes a flexible array member, so its
allocation size will be that of the struct itself, plus that of each
of the members in the array. When calculating this size, instead of
taking the size of the struct, the size of a pointer to it was taken,
which is incorrect. Luckily, this happenned to not produce memory
corruption because the size of the non-flexible members of the struct
is the same as the size of a pointer.

Signed-off-by: Carlos López <carlos.lopezr4096@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-02 08:45:07 +05:30
Carlos López
d2353c9e22 lib: sbi: dbtr: fix potential NULL pointer dereferences
In several dbtr functions, we first check that the dbtr trigger is not
NULL and that its state is what we expect. However, it only makes
sense to perform the second check if the dbtr trigger is not NULL.
Othwerwise we will dereference a NULL pointer. Thus, change the
condition so that it shortcuts to the first check if necessary.

Signed-off-by: Carlos López <carlos.lopezr4096@gmail.com>
Reviewed-By: Anup Patel <anup@brainfault.org>
2024-08-02 08:45:05 +05:30
Eric Lin
df997c6e55 include: Adjust Sscofpmf mhpmevent mask for upper 8 bits
Currently, OpenSBI reserves the upper 16 bits in mhpmevent for
the Sscofpmf extension.

However, according to the Sscofpmf extension specification[1],
it only defines the upper 8 bits in mhpmevent for privilege mode
inhibit and counter overflow disable. Other bits are defined by
the platform for event selection.

Since vendors might define raw event encoding exceeding 48 bits in
mhpmevent, we should adjust the MHPMEVENT_SSCOF_MASK to support it.

Link: https://github.com/riscvarchive/riscv-count-overflow [1]
Signed-off-by: Eric Lin <eric.lin@sifive.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-08-02 08:43:27 +05:30
Anup Patel
bb7267a07f lib: sbi: Introduce an early console buffer for caching early prints
The console device is registered by platform only in early_init()
callback so any prints before this point will be lost. Introduce an
early console buffer for caching prints before platform early_init().

For crashes before platform early_init(), users can simply dump the
contents of the console_early_buffer[] string using a debugger. The
relative address of the console_early_buffer[] string can be found
using following two commands:

CONSOLE_EARLY_FIFO_ADDR=`${CROSS_COMPILE}objdump -D \
build/platform/generic/firmware/fw_dynamic.elf | \
grep "<console_early_fifo>:" | awk '{print $1}'`

${CROSS_COMPILE}objdump -R build/platform/generic/firmware/fw_dynamic.elf | \
grep $CONSOLE_EARLY_FIFO_ADDR | awk '{print $3}'

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-By: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-07-24 12:18:41 +05:30
Anup Patel
d35c76a766 include: sbi: Add macros to create FIFO as local or global variable
The FIFO data structure is quite handy of variety of use-case so add
SBI_FIFO_INITIALIZER() and SBI_FIFO_DEFINE() helper macros to create
FIFO as local or global variable.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-By: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-07-24 12:18:39 +05:30
Anup Patel
94c3c53a56 lib: sbi: Allow forceful queueing of data in sbi_fifo_enqueue()
Extend sbi_fifo_enqueue() to allow forceful queueing by droping
data from the tail.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-By: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-07-24 12:18:36 +05:30
Anup Patel
9a275fc153 lib: sbi: Optimize fifo enqueue/dequeue for basic data types
Don't use sbi_memcpy() for basic data types in fifo enqueue/dequeue
instead use direct type-cast and assignment.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-By: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-07-24 12:18:35 +05:30
Anup Patel
119b15a553 lib: sbi: Remove sbi_console_init() and console_init() platform callback
Now that all platforms have been updated to initialize serial console
device in early_init(), the sbi_console_init() and console_init()
platform callback are redundant hence remove them.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-By: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-07-24 12:18:33 +05:30
Anup Patel
9e8a18fd0d platform: Setup serial console device in early_init()
The sbi_console_init() does not do any special initialization so
setup serial console device in early_init() so that console prints
work as early as possible.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-By: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-07-24 12:18:31 +05:30
Samuel Holland
4afb57c9eb lib: sbi_hsm: Save/restore menvcfg only when it exists
Attempting to access the menvcfg CSR raises an illegal instruction
exception on hardware which implements Sm1p11 or older.

Fixes: e9ee9678ba ("lib: sbi: fwft: add support for SBI_FWFT_PTE_AD_HW_UPDATING")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-07-24 10:42:46 +05:30
Conor Dooley
f7a92f6b67 lib: utils/fdt: Add support for parsing riscv,isa-extensions
A new property has been added, with an extensive rationale at [1], that
can be used in place of "riscv,isa" to indicate what extensions are
supported by a given platform that is a list of strings rather than a
single string. There are some differences between the new property,
"riscv,isa-extensions" and the incumbent "riscv,isa" - chief among them
for the sake of parsing being the list of strings, as opposed to a
string. Another advantage is strictly defined meanings for each string
in a dt-binding, rather than deriving meaning from RVI standards. This
may likely to some divergence over time, but, at least for now, there's
no relevant differences between the two for an M-Mode program.

Add support for the new property in OpenSBI, prioritising it, before
falling back to the, now deprecated, "riscv,isa" property if it is not
present.

Link: https://lore.kernel.org/all/20230702-eats-scorebook-c951f170d29f@spud/ [1]
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-07-23 11:12:56 +05:30
Dongdong Zhang
b7e7e66026 lib: tests: add math test suite
This patch introduces a new math test suite to the SBI unit
tests. The changes include:

* Updating lib/sbi/tests/objects.mk to include
  math_test_suite and sbi_math_test.o.
* Adding a new file lib/sbi/tests/sbi_math_test.c which
  contains tests for log2roundup function using various cases.

The addition of this test suite ensures that mathematical
functions are verified and work as expected.

Signed-off-by: Dongdong Zhang <zhangdongdong@eswincomputing.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-07-23 10:17:51 +05:30
Dongdong Zhang
c5c1d04346 lib: tests: enhance test output with colored pass/fail messages
This patch improves the readability of the SBI unit test
output by adding color-coded status messages.

Adding ANSI color codes for green (pass) and red (fail)
in sbi_unit_test.c.

Now, the test results will be displayed in green for passed
tests and red for failed tests, making it easier to quickly
distinguish between them.

Signed-off-by: Dongdong Zhang <zhangdongdong@eswincomputing.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-07-23 10:13:50 +05:30
Ivan Orlov
0a66754295 docs: writing tests: update cleaning instructions
After the changes introduced by the previous patches are applied, there
is no need of the manual removal of the `build/` directory every time
new test is added. Running `make clean` should be enough to regenerate
the carray-related files.

Update the documentation correspondingly.

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-07-04 12:11:52 +05:30
Ben Dooks
1ede0cab0e Makefile: remove any .carray.c during clean
Now we've renamed the carray output files to .carray.c
we can now use find to remove them.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-07-04 12:11:50 +05:30
Ben Dooks
fd9e8b17ed Makefile: change to using .carray.c for carray files
We would like to clean any files generated by the carray
scripts by just searching for the filename as the current
make system turns f.carray into f.o. Change to make the
make system turn f.carray into f.carray.o

note, command to go through .mk files changing the .o
in the .mk files is:
find . -type f -name "*.carray" | xargs -t -I fname /bin/bash -x -c ' fn=`basename -s .carray fname`; echo "$fn"; sed -i `dirname fname `/objects.mk -e s/"$fn".o/"$fn".carray.o/g'

Link: https://patchwork.ozlabs.org/project/opensbi/patch/20240401213438.590209-2-ivan.orlov0322@gmail.com/
Reported-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-07-04 12:11:45 +05:30
Ivan Orlov
75ad25ab59 scripts/carray.sh: Add comment to generated files
Add a comment about where auto-generated file came from to the carray.sh
output. This should help avoiding confusion for the developers looking
at the build artifacts and finding .c files there.

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-07-04 10:52:37 +05:30
Samuel Holland
d8608e615f lib: sbi_emulate_csr: Do not log illegal CSR accesses
Illegal CSR accesses from lower privilege modes are delegated to S-mode
and do not necessarily indicate a bug. Supervisor software may want to
emulate some CSRs, or may intentionally disable access to certain
existing CSRs, and thus will expect traps when those CSRs are accessed.

For example, Linux disables sstatus.VS by default in order to detect
when userspace first accesses vector register state; this includes the
CSRs defined by the V extesion. As a result, if the first vector
instruction in a process is a CSR access, OpenSBI will log the illegal
instruction exception, even though there is no unexpected or erroneous
behavior occurring.

Since the illegal instruction exception is delegated to S-mode, S-mode
software should be responsible for reporting the exception, not OpenSBI.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-07-04 10:42:16 +05:30
Dongdong Zhang
c531adbf08 .github: Add repo lockdown GitHub workflow and update .gitignore
This commit adds a new GitHub Actions workflow for repository
lockdown. The workflow triggers when a pull request is opened, and it
notifies the contributor to use the OpenSBI mailing list for patch
reviews.

Additionally, the .gitignore file is updated to include the .github
directory.

Signed-off-by: Dongdong Zhang <zhangdongdong@eswincomputing.com>
Reviewed-by: Anup Patel <anup@branifault.org>
2024-07-04 10:31:39 +05:30
Anup Patel
455de672dd include: Bump-up version to 1.5
This patch updates OpenSBI version to 1.5 as part of
release preparation.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <anup@brainfault.org>
2024-06-30 14:03:26 +05:30
Sergey Matyukevich
23b7badeee lib: sbi: check incoming dbtr shmem address
Current Debug Trigger SBI extension proposal suggests to activate
shmem area and obtain its physical address from S-mode software
in the following way:

: If both `shmem_phys_lo` and `shmem_phys_hi` parameters are not
: all-ones bitwise then `shmem_phys_lo` specifies the lower XLEN
: bits and `shmem_phys_hi` specifies the upper XLEN bits of the
: shared memory physical base address. The `shmem_phys_lo` MUST
: be `(XLEN / 8)` byte aligned and the size of shared memory is
: assumed to be `trig_max * (XLEN / 2)` bytes.

For more details see the current version of the proposal:
- https://lists.riscv.org/g/tech-debug/message/1302

On the other hand, on RV32, the M-mode can only access the first 4GB of
the physical address space because M-mode does not have MMU to access
full 34-bit physical address space. Similarly, on RV64, the M-mode can
only access memory addressed by 64 bits.

This commit checks shmem address in function sbi_dbtr_setup_shmem
to make sure that shmem_phys_hi part of the valid address is zero.
Besides, the macro DBTR_SHMEM_MAKE_PHYS is updated to take into
account only low XLEN part.

Signed-off-by: Sergey Matyukevich <geomatsi@gmail.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-06-28 08:36:46 +05:30
Jacob Lin
0e45b63471 docs: Fix wrong filename
Correct the compiled FW_PAYLOAD firmware ELF filename.

Signed-off-by: Jacob Lin <lovetaeyeon507@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-28 08:34:15 +05:30
Clément Léger
caae2f7d45 lib: sbi: fwft: return SBI_EINVAL rather than SBI_ERR_INVALID_PARAM
Error code returned by the ecall handles should use the defines from
sbi_ecall_interface.h rather than sbi_error.h.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-26 18:14:49 +05:30
Clément Léger
e8717d1264 lib: sbi: fwft: check feature value to be exactly 1 or 0
As stated by the spec and pointed out by Andrew Jones, the value passed
for MISALIGNED_EXC_DELEG and PTE_AD_HW_UPDATING should be either 0 or 1.
Add check for these values and return SBI_EINVAL if not.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-26 18:13:54 +05:30
Clément Léger
ecef14d573 lib: sbi: implement SBI FWFT extension
The SBI FWFT extension defines a set of function that can be called
to control the configuration of some platform features (misaligned
trap delegation, etc). This patch implements sbi_fwft_set() and
sbi_fwft_get() as defined in the specification [1].

Link: https://lists.riscv.org/g/tech-prs/message/924 [1]
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-19 18:15:28 +05:30
Clément Léger
e9ee9678ba lib: sbi: fwft: add support for SBI_FWFT_PTE_AD_HW_UPDATING
Add support for SBI_FWFT_PTE_AD_HW_UPDATING based on SVADU presence.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-19 18:11:26 +05:30
Clément Léger
c97a1d5891 lib: sbi: fwft: add support for SBI_FWFT_MISALIGNED_EXC_DELEG
Add support for SBI_FWFT_MISALIGNED_EXC_DELEG withing FWFT support. This
support allows to delegate misaligned accesses traps.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-19 18:10:36 +05:30
Clément Léger
aa5a859369 lib: sbi: add support for firmware features extension
This extension allows the software running in supervisor mode to control
the behavior of various features of the SBI [1]. Implement the support
for such extension.

Link: https://lists.riscv.org/g/tech-prs/message/924 [1]
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-19 18:09:22 +05:30
Yong-Xuan Wang
53844c98d0 lib: sbi: Add support for Svade and Svadu extensions
Add support for Svade and Svadu extensions. When both are present in the
device tree, the M-mode firmware should select the Svade extension
to comply with the RVA23 profile, which mandates Svade and lists Svadu as
an optional extension.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-18 16:41:32 +05:30
Ben Zong-You Xie
52dcf351cd platform: generic: andes: Add support for RV32 to set up PMA
Like PMP, the behaviors to configure PMA will be different from
RV64 and RV32. RV64 uses two Andes custom CSRs, pmacfg0 and pmacfg2,
but RV32 uses four Andes custom CSRs, pmacfg0 ~ pmacfg3. This patch
adds support to PMA for RV32.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-18 16:19:47 +05:30
Ben Zong-You Xie
f09f16430a platform: generic: andes: Refine Andes PMA related code
This patch refines the Andes PMA related code. The main change is
refactor andes_pma_[read|write]_cfg() and andes_pma_[read|write]_addr()
into new functions andes_pma_[read|write]_num().

Also, fix some coding style problems.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-18 16:15:22 +05:30
Gabriel Somlo
7830e98785 lib: serial: fix RX path in litex-uart
When used to read characters from the terminal (e.g., when the SBI
console is used via ecall from linux with `console=hvc0`), we must
acknowledge receipt of each character to "pop" it off the LiteUART
hardware queue, and allow the next character to be made available.

Fixes: 52af6e4b ("lib: utils: Add LiteX UART support")
Suggested-by: Dolu1990 <charles.papon.90@gmail.com>
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-13 21:54:09 +05:30
Xiang W
62e178a0a7 lib: utils/reset: Try initializing all reset devices in dt
In DT, multiple reset devices may use the same driver, and they
may have different priorities. If rc is returned after the first
initialization, the highest priority device may be lost.

Fixes: a73ff043e9 (lib: utils/reset: Fix fdt_reset to search for more dt nodes)
Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-13 21:48:03 +05:30
Yu Chien Peter Lin
3a94a32580 sbi: sbi_domain_context: Fix trap context for domain context switching
Save/restore sbi_trap_context during domain context switching to
ensure proper trap handling and isolation. This maintains correct
domain-specific state, avoiding context corruption.

Fixes: abea949721 ("lib: sbi: Introduce trap context")
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Alvin Chang <alvinga@andestech.com>
Tested-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Yong Li <yong.li@intel.com>
Tested-by: Yong Li <yong.li@intel.com>
2024-06-13 19:21:27 +05:30
Xiang W
a73ff043e9 lib: utils/reset: Fix fdt_reset to search for more dt nodes
If there are multiple dt nodes, the previous code only tries to match
the first one, which may lose initialization.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-13 18:49:51 +05:30
Xiang W
b5c984bd08 lib: utils/reset: Skip initialize reset when dt is not enabled
When the dt node has a status property and the value is not ok or
okay, skip initializing reset.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-13 18:40:38 +05:30
Xiang W
86bbe6c52f lib: utils/serial: Fix fdt_serial to match more dt nodes
If there are multiple dt nodes, the previous code only tries to match
the first one, which may lose initialization.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-13 18:39:37 +05:30
Xiang W
179e00a320 lib: utils/serial: Skip initialize serial when dt is not enabled
When the dt node has a status property and the value is not ok or
okay, skip initializing serial.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-13 18:36:49 +05:30
Xiang W
b1c7c750f7 lib: utils/irqchip: Skip initialize irqchip when dt is not enabled
When the dt node has a status property and the value is not ok or
okay, skip initializing irqchip.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-13 18:33:52 +05:30
Xiang W
5e3ad7d577 lib: utils/timer: Skip initialize timer when dt is not enabled
When the dt node has a status property and the value is not ok or
okay, skip initializing timer.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-13 18:31:40 +05:30
Xiang W
c5be0e1ed1 lib: utils/ipi: Skip initialize ipi when dt is not enabled
When the dt node has a status property and the value is not ok or
okay, skip initializing ipi.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-06-13 18:30:27 +05:30
Anup Patel
df3db6a901 lib: utils/fdt: Fix DT property for APLIC delegation
During Linux AIA driver review, the APLIC DT property for interrupt
delegation was renamed to "riscv,delegation" so let's use the new DT
property name and fallback to old DT property name if the new DT
property name is not available.

Fixes: 34612193af ("lib: utils/irqchip: Add FDT based driver for APLIC")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-06-05 10:54:59 +05:30
Inochi Amaoto
d962db2807 lib: utils/gpio: respect flag GPIO_FLAG_ACTIVE_LOW
"gpio-poweroff" and "gpio-restart" always set gpio to high to
active the function, but some chips need a low signal to active.
Fortunately, it can be achieved by setting GPIO_FLAG_ACTIVE_LOW
for the gpio. Implement this flag support for the gpio library
so the gpio reset can function well.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-23 15:42:52 +05:30
Clément Léger
ae5ef1848d lib: sbi: sse: handle missing writable attributes
The spec states that a6, a7, flags and sepc are writable but the
implementation was not allowing that. Add support for these 4 writable
attributes.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-23 10:53:02 +05:30
Cyan Yang
858754a544 lib: utils/irqchip: Add sanity checks in imsic_get_data() and imsic_get_target_file()
Add extra sanity checks to prevent the caller getting the invalid result from
imsic_get_data() or imsic_get_target_file() when imsic is not initialized
correctly.

Signed-off-by: Cyan Yang <cyan.yang@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-23 10:51:29 +05:30
Anup Patel
96f0a2e3ea firmware: Bring back FW_TEXT_START as an optional parameter
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: d4d2582eef ("firmware: remove FW_TEXT_START")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Clément Léger <cleger@rivosinc.com>
2024-05-23 10:50:23 +05:30
Cheng Yang
e3a30a2c91 lib: utils/irqchip: Check before initializing imsic
The current mlevel imsic check is only for the platform, which
may cause hart without imsic in the platform to trigger an
illegal instruction exception when initializing imsic. For
example, the platform contains a management hart that only
supports wired interrupts.

This patch will check if each hart supports Smaia extension
before doing imsic initialization to avoid triggering illegal
instruction exceptions.

Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-16 10:21:16 +05:30
Inochi Amaoto
2bed4c1c57 platform: generic: thead: add Sophgo CV18XX/SG200X series
The Sophgo CV18XX/SG200X series SoCs have a standard C906
core. Add support for it.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-16 10:18:44 +05:30
Anup Patel
533067d182 lib: sbi: Put event after use in sbi_sse_exit() loop
Currently, the sbi_sse_exit() gets event in a loop but does not put
it back after use. This results in global events remaining locked
causing hangs on sub-sequent calls to sse_event_get() for global
events.

Fixes: c8cdf01d8f ("lib: sbi: Add support for Supervisor Software Events extension")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-05-15 11:54:43 +05:30
Inochi Amaoto
ea9cf6aa28 utils/reset: Add SG2042 hwmon MCU support.
SG2042 uses an onboard MCU to provide reset function.
Add reset driver to support this onboard MCU.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-15 11:47:15 +05:30
Xiang W
1cb792d606 lib: sbi: simplify inline function in sbi_dtbr.c
The inline function can simplify the code by setting some call
restrictions. This ensures logical smoothness

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-13 16:50:49 +05:30
Xiang W
7b37da3cb0 lib: sbi: fix return type of sbi_dbtr_shmem_disabled
Modify the return value of the sbi_dbtr_shmem_disabled function to
bool to make the semantics clearer.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-13 16:40:05 +05:30
Xiang W
e065c3cd5d lib: sbi: Fixed memory permission check in sbi_dbtr_setup_shmem
The previous code detected shmem_phys_hi and shmem_phys_lo as two
addresses. fix this bug

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-05-13 16:39:39 +05:30
Xiang W
7f54527029 lib: sbi: fix DBTR_SHMEM_MAKE_PHYS for RV64
Obtaining a 64-bit address under rv64 does not require combining
32-bit registers

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-05-13 16:38:35 +05:30
Xiang W
744f495653 lib: sbi: Removal unnecessary check dbtr_thishart_state_ptr
After getting hart_shmem_base, dbtr_thishart_state_ptr cannot be
empty. So remove check code.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-05-13 16:37:56 +05:30
Xiang W
4953bd721a lib: sbi: fix hart_shmem_base
When only phys_hi is equal to SBI_DBTR_SHMEM_INVALID_ADDR, it may be
a legal address. The old code would modify the legal address.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
2024-05-13 16:35:20 +05:30
Yangyu Chen
019a8e69a1 platform: generic: thead: add Canaan Kendryte K230
Canaan Kendryte K230 SoC has T-Head C908 cores inside. The dt-binding has
been merged into the linux kernel [1]. However, it has early version of
C908 core which does not have Sscofpmf and need to use T-Head PMU
extension. Thus, we add a K230 compatible string to thead_generic_match
and set quirk for T-Head PMU.

[1] https://lore.kernel.org/linux-riscv/tencent_4D85743622F39109466913393EE2F6C5980A@qq.com/

Signed-off-by: Yangyu Chen <cyy@cyyself.name>
Reviewed-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-09 18:10:25 +05:30
Yangyu Chen
33e21c9476 platform: generic: thead: separate T-Head PMU Errata
As Guo Ren said from the kernel mailing list [1], future T-Head CPUs,
including the newer versions of T-Head C908, will feature standard
Sscofpmf extension. For these CPUs, T-Head's implementation of PMU
Overflow Interrupts may not needed anymore. In this case, we shouldn't
apply T-Head PMU for all T-Head CPUs. Thus, this patch separated T-Head PMU
errata.

[1] https://lore.kernel.org/linux-riscv/Zh9sUUUT09LZb0MO@gmail.com/

Signed-off-by: Yangyu Chen <cyy@cyyself.name>
Reviewed-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-09 18:09:05 +05:30
Ben Zong-You Xie
2b93ce0954 platform: andes: Change all occurrences of andes45 to andes
To make the framework suit all Andes CPUs, change all occurrences of
andes45 to andes.

In addition, we fix some coding style problems and remove an unused
macro in andes.h.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-09 17:57:51 +05:30
Ben Zong-You Xie
f68b3aed9d platform: andes: Rename files with the prefix andes45
Rename files with the prefix andes45 to andes.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-09 17:56:50 +05:30
Alvin Chang
17e829129d sbi: sbi_domain_context: Add spinlock for updating domain assigned_harts
Add spinlock protection to avoid race condition on assigned_harts
during domain context switching. Also, rename/add variables for
accessing the corresponding domain of target/current context.

Signed-off-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 20:11:30 +05:30
Pope B.Lei
1d89a9da64 lib: sbi: Refine the settings for switching to Virtual Supervisor Mode.
Although Mstatus.MPV is set, before executing mret, access to VS mode
registers should use the actual register addresses, not the pseudonyms
of S registers.

Signed-off-by: Pope B.Lei <popeblei@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 18:12:24 +05:30
Clément Léger
033104da08 lib: sbi: sse: check handler entry to belong to supervisor mode
When registering an SSE event, check for the handler_entry_pc to belong
to supervisor mode domain using sbi_domain_check_addr_range().

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reported-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 17:31:08 +05:30
Clément Léger
bd007658f8 lib: sbi: sse: use PRV_S instead of hardcoded value for mode
Rather then passing 1 to sbi_domain_check_addr_range() for supervisor
mode, use PRV_S.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 17:29:36 +05:30
Clément Léger
ce3c82cb2e lib: sbi: sse: call enable callback before sending IPI
Move the enable callback call before sending the IPI. Even though the
event is locked and no race condition can happen, this is more logical.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reported-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 17:28:44 +05:30
Clément Léger
d528dbfd4b lib: sbi: sse: remove superfluous sbi_list_empty() check
The list loop below that check is actually not looping if the list is
empty so there was no need for this check.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reported-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 17:27:31 +05:30
Clément Léger
22ff75099c lib: sbi: sse: simplify 32bits overflow check
Rather than checking 32bits overflow with some absolute value, check the
value to be different from the cast itself.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reported-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 17:26:14 +05:30
Clément Léger
7aa80ea495 lib: sbi: sse: rename sse_hart_unlock() to sse_enabled_event_unlock()
There was a naming incoherency between enabled events list lock/unlock.
Rename sse_hart_unlock() to sse_enabled_event_unlock() to be coherent
and reword comments above lock()/unlock() functions.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 17:25:28 +05:30
Clément Léger
c21c99db6a lib: sbi: sse: fix typos, comments and spacing errors
Fix some errors spotted by Samuel while reviewing the SSE implementation.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reported-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 17:24:11 +05:30
Ivan Orlov
7b1ed968e4 lib: tests: Add test for spinlocks
Implement the test which covers some of the functions from the
`riscv_locks.h` file. This test consists of 3 test cases:

1) For lock/unlock functions
2) Unsuccessful trylock (the lock was previously taken)
3) Successful trylock (the lock is free and can be taken)

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 11:27:30 +05:30
Ivan Orlov
7bdf41ad1e lib: tests: Add test for atomic_t
Implement the test which covers some of the functions from the
`riscv_atomic.h` header file. The test contains 9 test cases:

1) atomic read/write test
2) add/return test
3) sub/return test
4) cmpxchg test
5) atomic_xchg test
6) atomic_raw_set_bit test
7) atomic_raw_clear_bit test
8) atomic_set_bit test
9) atomic_clear_bit test

Some of the test cases operate on the `test_atomic` variable. It gets
initialized in the suite init function.

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 11:27:29 +05:30
Ivan Orlov
f6243d9ce5 lib: tests: Add test suite init function
Allow to define an init function for the test suite. It could help us
to initialize global variable once, and use them in multiple test cases
after the initialization.

For instance, if multiple test cases use the same atomic_t var, it
could be helpful to call ATOMIC_INIT once during the suite
initialization.

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-05-07 11:27:13 +05:30
Xiang W
d4d2582eef firmware: remove FW_TEXT_START
Now opensbi can run at any address via dynamic relocation. We can
remove FW_TEXT_START.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2024-04-10 09:50:24 +05:30
Heinrich Schuchardt
73344d4724 lib: utils: check correct value in fdt_node_offset_by_compatible
After calling fdt_node_offset_by_compatible() we must check its return
value and not an unrelated value.

Addresses-Coverity-ID: 1584993 Logically dead code
Fixes: 67ce5a763c ("platform: generic: Add support for specify coldboot harts in DT")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-10 09:38:26 +05:30
Heinrich Schuchardt
37e1544a86 lib: sbi: sse_event_get() may return NULL
sse_event_get() may return NULL. We should not dereference the return value
in sbi_sse_exit() without checking.

Fixes: c8cdf01d8f ("lib: sbi: Add support for Supervisor Software Events extension")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-10 09:38:24 +05:30
Clément Léger
68bc031a76 lib: sbi: Add missing sscrind and sscfg extensions in sbi_hart_ext[]
The sbi_hart_ext[] array is missing these two extensions ids. It is
expected that this array contains all the extensions declaration at the
same index of the SBI_HART_EXT_* define. Without this, when adding a new
extension, there is a mismatch between ids and extension names and it
can even display corrupted extension names.

Addresses-Coverity-ID: 1584994 Out-of-bounds read
Fixes: 6bb6b61c27 ("lib: sbi: Add support for smcsrind and smcdeleg")
Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-10 09:33:58 +05:30
Samuel Holland
a7c5c2cbd2 Makefile: Remove unnecessary dependencies
The rule included from auto.conf.cmd adds a dependency on every Kconfig
file, so these two Kconfig files do not need to be specified again here.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2024-04-08 10:08:20 +05:30
Samuel Holland
268feab294 Makefile: Respect manual changes to .config
The .config file may be manually edited or copied from another location.
Since genconfig.py is responsible for generating auto.conf (the Makefile
fragment) and autoconf.h (the C header) from .config, it must be run any
time .config changes, not just when running menuconfig.

Fixes: 662e631cce ("Makefile: Add initial kconfig support for each platform")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2024-04-07 12:05:37 +05:30
Yu Chien Peter Lin
29ecda9c20 sbi: sbi_domain_context: Check privilege spec version before accessing S-mode CSRs
SCOUNTEREN and SENVCFG may not be supported on certain RISC-V core,
so check the existence of these CSRs via privilege spec version to
prevent illegal instructions.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Signed-off-by: Alvin Chang <alvinga@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-05 18:02:29 +05:30
Anup Patel
7862c244bc lib: sbi: Wakeup non-coldboot HARTs early in the coldboot path
Currently, all non-coldboot HARTs busy spin in wait_for_coldboot()
until the entire coldboot init sequence is completed.

This means:
1) On QEMU, all non-coldboot HARTs will eat host CPU time and
   also slow down the coldboot HART until the entire coldboot
   init sequence is completed.
2) On real HW, all non-coldboot HARTs will consume more CPU
   power until the entire coldboot init sequence is completed.

To address this, wake up all non-coldboot HARTs as early as
possible in the coldboot init sequence.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-04-05 17:48:25 +05:30
Anup Patel
beb0cd177f lib: sbi: Simplify wait_for_coldboot() implementation
On QEMU virt machine with large number of HARTs, some of the HARTs
randomly fail to come out of wait_for_coldboot() due to one of the
following race-conditions:

1) Failing HARTs are not able to acquire the coldboot_lock and
   update the coldboot_hartmask in wait_for_coldboot() before
   the coldboot HART acquires the coldboot_lock and sends IPI
   in wake_coldboot_harts() hence the failing HARTs never
   receive IPI from the coldboot HART.

2) Failing HARTs acquire the coldbood_lock and update the
   coldboot_hartmask before coldboot HART does sbi_scratch_init()
   so the sbi_hartmask_set_hartid() does not update the
   coldboot_hartmask on the failing HARTs hence they never
   receive IPI from the coldboot HART.

To address this, use a simple busy-loop in wait_for_coldboot() for
polling on coldboot_done flag.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2024-04-05 17:48:23 +05:30
Samuel Holland
f5375bc15e platform: generic: allwinner: Optimize current hart scratch access
The address of the local scratch area is stored in each hart's mscratch
CSR. It is more efficient to read the CSR than to compute the address
from the hart ID.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-05 17:34:25 +05:30
Samuel Holland
b94396c7dd lib: utils/timer: Optimize current hart scratch access
The address of the local scratch area is stored in each hart's mscratch
CSR. It is more efficient to read the CSR than to compute the address
from the hart ID.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-05 17:34:24 +05:30
Vivian Wang
5c9a73565f include: sbi: Support byteorder macros in assembly
Avoid using C types and casts if sbi/sbi_byteorder.h is included in
assembly code

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-05 17:23:51 +05:30
Clément Léger
06fc453ec1 lib: sbi: Add SSE support for PMU events
Add SSE callbacks registration to PMU driver in order to disable
interrupt delegation for PMU interrupts. When interrupts are
undelegated send the PMU SSE event upon LCOFIP IRQ.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-05 17:09:39 +05:30
Clément Léger
09ad21445f lib: sbi: Implement SBI SSE extension
The SBI SSE extension defines a set of function that can be called to
register and handle supervisor sofwtare events. This patch implements
all of the functionality defined in the specification.

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-05 15:49:02 +05:30
Clément Léger
c8cdf01d8f lib: sbi: Add support for Supervisor Software Events extension
This extension [1] allows to deliver events from SBI to supervisor via
a software mechanism. This extension defines events (either local or
global) which are signaled by the SBI on specific signal sources (IRQ,
exceptions, etc) and are injected to be executed in supervisor mode.

[1] https://lists.riscv.org/g/tech-prs/message/798

Signed-off-by: Clément Léger <cleger@rivosinc.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-05 15:47:30 +05:30
Xiang W
76d7e9b8ee firmware: remove copy-base relocation
Remove copy-base relocations that are no longer needed.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-04-05 15:05:25 +05:30
Christoph Müllner
5186da687d platform: generic: allwinner: sun20i-d1: Remove duplicated CSR definitions
All T-Head CSRs are already defined in thead/c9xx_encoding.h.
Let's reuse the values from there instead of redefining them with
a slightly different name.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-20 11:05:13 +05:30
Ivan Orlov
3b2f89e3d6 docs: writing_tests: Make docs correspond the latest changes
We should store test object files list in the `libsbi-objs-y` Makefile
variable, not in `libsbitests-objs-y`. Update the documentation
correspondingly.

Since we don't use the `console_dev` static variable directly in the
`sbi_console_test` unit test anymore, remove the paragraph which says
that we do.

Fixes: 86224ec36a ("docs/writing_tests: Update tests paths")
Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-20 11:02:58 +05:30
Anup Patel
f7d0050755 lib: sbi: Extend sbi_trap_error() to dump state in a nested trap
The sbi_trap_error() should dump state of all in-flight traps upon
failure in a nested trap so extend it accordingly.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
2024-03-19 11:31:41 +05:30
Anup Patel
5b11f16c3c lib: sbi: Pass trap context pointer to sbi_ecall_handler()
To be consistent with other trap handlers, pass trap context pointer
to sbi_ecall_handler().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Clément Léger <cleger@rivosinc.com>
2024-03-19 11:31:39 +05:30
Anup Patel
43d346c0c1 lib: sbi: Remove regs parameter from trap irq handling functions
The trap irq handling functions no longer require regs parameter
so remove it.

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:35 +05:30
Anup Patel
d84e7eb7f0 lib: sbi: Remove regs paramter of sbi_irqchip_process()
The irqchip handlers will typically not need pointer to trap registers
so remove regs parameter of sbi_irqchip_process().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Clément Léger <cleger@rivosinc.com>
2024-03-19 11:31:33 +05:30
Anup Patel
f414cf931e lib: sbi: Simplify parameters of sbi_illegal_insn_handler()
The struct sbi_trap_context already has the information needed by
sbi_illegal_insn_handler() so directly pass struct sbi_trap_context
pointer to this function.

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:31 +05:30
Anup Patel
fea33a9334 lib: sbi: Simplify parameters of misaligned and access fault handlers
The struct sbi_trap_context already has the information needed by
misaligned load/store and access fault load/store handlers so directly
pass struct sbi_trap_context pointer to these functions.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Tested-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Clément Léger <cleger@rivosinc.com>
2024-03-19 11:31:28 +05:30
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
Samuel Holland
2e8517865a lib: sbi: Remove epc from struct sbi_trap_info
In the only places this value is used, it duplicates mepc from
struct sbi_trap_regs.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-19 11:31:16 +05:30
Ivan Orlov
86224ec36a docs/writing_tests: Update tests paths
Since the tests should be moved to the lib/sbi/tests directory, the
documentation should be updated correspondingly. So, update the paths
where they have to be changed.

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-19 11:20:49 +05:30
Ivan Orlov
5c992a115a lib: tests: Move tests to a separate directory
Move all of the SBIUnit-related code into the lib/sbi/tests directory.
Update 'Makefile' to index objects from the tests subdirectory.

I don't think creating the full separate list of Makefile variables
(libsbitests-objs-path-y, libsbitests-object-mks, etc. as it is done for
libsbiutils) is necessary for the tests because:

1) `lib/sbi/tests/objects.mk` is already indexed into
'libsbi-objects-mks' since the find expression for the libsbi-object-mks
variable looks for objects.mk files in the nested directories as well).

2) Tests are tightly coupled with the `lib/sbi/` sources, therefore it
may be reasonable to store the list of lib/sbi and lib/sbi/tests object
files together in the libsbi-objs-path-y variable.

Additionally, update relative paths in the tests where necessary.

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-19 11:20:40 +05:30
Bo Gan
81e3ba77a6 lib: sbi: call platform load/store emulators
sbi_load/store_access_handler now tries to call platform emulators
if defined. Otherwise, redirects the fault. If the platform code
returns failure, this means the H/S/U has accessed the emulated
devices in an unexpected manner, which is very likely caused by
buggy code in H/S/U. We redirect the fault, so lower privileged
level can get notified, and act accordingly. (E.g., oops in Linux)

We let the handler truly fail if the trap was originated from M mode.
In this case, something must be very wrong and we should just fail.

Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:56:02 +05:30
Bo Gan
ddf3b649f1 include: sbi: add emulate_load/store handler to platform ops
This patch allows the platform to define load/store emulators. This
enables a platform to trap-and-emulate special devices or filter
access to existing physical devices.

Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:54:14 +05:30
Bo Gan
4c112650bb lib: sbi: abstract out insn decoding to unify mem fault handlers
This patch abstracts out the instruction decoding part of misaligned ld/st
fault handlers, so it can be reused by ld/st access fault handlers.
Also Added lb/lbu/sb decoding. (previously unreachable by misaligned fault)

sbi_trap_emulate_load/store is now the common handler which takes a `emu`
parameter that is responsible for emulating the misaligned or access fault.
The `emu` callback is expected to fixup the fault, and based on the return
code of `emu`, sbi_trap_emulate_load/store will:

  r/wlen => the fixup is successful and regs/mepc needs to be updated.
  0      => the fixup is successful, but regs/mepc should be left untouched
            (this is usually used if `emu` does `sbi_trap_redirect`)
  -err   => failed, sbi_trap_error will be called

For now, load/store access faults are blindly redirected. It will be
enhanced in the following patches.

Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:50:39 +05:30
Bo Gan
9221fe58d1 lib: sbi: change prototype of sbi_misaligned_load/store_handler
This simplifies both handlers such that when the handler needs to
redirect the original trap, it's readily available.

Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:48:00 +05:30
Bo Gan
a17600c186 lib: sbi: change prototype of sbi_trap_redirect
sbi_trap_redirect now uses const pointer to `trap`.
This ensures the caller that we never change `trap` in sbi_trap_redirect.

Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:36:39 +05:30
Bo Gan
2471cf2e6c include: sbi: rename sbi_misaligned_ldst.h to sbi_trap_ldst.h
Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:36:35 +05:30
Bo Gan
c0a63205f8 lib: sbi: rename sbi_misaligned_ldst.c to sbi_trap_ldst.c
Signed-off-by: Bo Gan <ganboing@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-11 10:36:29 +05:30
Qingyu Shang
e11025c52d lib: sbi: Add initial domain context management support
The domain context management component in OpenSBI provides basic CPU
context management routines for existing OpenSBI domain. As domain
extension, it was initially designed to facilitate the suspension
and resumption of domains, enabling secure domains to efficiently
share CPU resources.

The patch also provides an addition to the OpenSBI domain to provide
updates on hart-domain assignment and declarations of contexts within
the domain.

Signed-off-by: Qingyu Shang <2931013282@sjtu.edu.cn>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Tested-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-10 10:26:42 +05:30
Ivan Orlov
87d8fe7865 lib: tests: Add sbi_console test
Add the test suite covering some of the functions from
lib/sbi/sbi_console.c: putc, puts and printf. The test covers a variety
of format specifiers for printf and different strings and characters for
putc and puts.

In order to do that, the test "mocks" the sbi_console_device structure
by setting the 'console_dev' variable to the virtual console.

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2024-03-10 10:12:52 +05:30
Ivan Orlov
e5f53fdea3 lib: tests: Add a test for sbi_bitmap
Add test suite covering all of the functions from lib/sbi/sbi_bitmap.c:
__bitmap_and, __bitmap_or and __bitmap_xor.

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2024-03-10 10:12:39 +05:30
Ivan Orlov
874fcefdf5 lib: Add SBIUnit testing macros and functions
This patch introduces all of the SBIUnit macros and functions which
can be used during the test development process. Also, it defines
the 'run_all_tests' function, which is being called during the
'init_coldboot' right after printing the boot hart information.

Also, add the CONFIG_SBIUNIT Kconfig entry in order to be able to
turn the tests on and off. When the CONFIG_SBIUNIT is disabled,
the tests and all related code is excluded completely on the
compilation stage.

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2024-03-10 10:05:28 +05:30
Ivan Orlov
b9e4de0641 docs: Add documentation about tests and SBIUnit
This patch contains the documentation for SBIUnit. It describes:

- What is SBIUnit
- Simple test writing scenario
- How we can cover static functions
- How we can "mock" structures in order to test the functions which
operate on them
- SBIUnit API Reference

Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2024-03-10 09:58:57 +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
187397fd65 firmware: fw_dynamic.S: Remove _bad_dynamic_info
_bad_dynamic_info is same as _start_hang, so remove it.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-09 18:08:58 +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
Nylon Chen
748bef1f9d lib: sbi_misaligned_ldst: Add handling of C.LHU/C.LH and C.SH
Added exception handling for compressed instructions C.LHU, C.LH, and
C.SH from the zcb extension to the sbi_misaligned_ldst library.

Signed-off-by: Nylon Chen <nylon.chen@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-05 09:31:52 +05:30
Yu Chien Peter Lin
bc366780c2 platform: andes: Drop andes_pmu_setup()
andes_pmu_setup() [1] was intended to populate event mapping from
hardcoded arrays, however, this increases firmware size and we should
just use PMU DT node [2] instead.

Link: https://lists.infradead.org/pipermail/opensbi/2023-November/006032.html [1]
Link: https://github.com/riscv-software-src/opensbi/blob/v1.4/docs/pmu_support.md#example-3 [2]
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-04 10:20:46 +05:30
Atish Patra
6bb6b61c27 lib: sbi: Add support for smcsrind and smcdeleg
Smcsrind allows generic indirect CSR access mechanism while
Smcdeleg allows delegating hpmcounters in Supervisor mode.

Enable both extensions and set the appropriate bits in mstateen
and menvcfg.

Co-developed-by: Kaiwen Xue <kaiwenxue1@gmail.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-03-04 10:20:41 +05:30
Joshua Yeong
322b598475 lib: sbi_hsm: Restor hart state to stop when fails to start
Hart state should change back to hart stop when hsm_device_hart_start()
or sbi_ipi_raw_send() fails to perform hart start.

Signed-off-by: Joshua Yeong <joshua.yeong@starfivetech.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-24 18:18:34 +05:30
Inochi Amaoto
96a35db63a docs/firmware: document new options for jump and payload firmwares
Adding relocatable address brings new configuration options for jump
and payload firmwares. Describe these new options in documentation.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-24 16:28:42 +05:30
Inochi Amaoto
2cff7f350f platform: Apply relocatable address
Since jump and payload firmware support relocatable address, make
general platform use runtime relocatable address.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-24 16:00:28 +05:30
Inochi Amaoto
f056939d8a firmware: Add relocatable FW_PAYLOAD_FDT_ADDR
The fw_payload.bin has the same issue as described in previous patch.
But only FW_PAYLOAD_FDT_ADDR is affected.

Add FW_PAYLOAD_FDT_OFFSET to identify relocatable payload fdt address.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-24 15:57:59 +05:30
Inochi Amaoto
7227cddcb4 firmware: Add relocatable FW_JUMP_ADDR and FW_JUMP_FDT_ADDR
If FW_PIC=y is defined, the fw_jump.bin will be broken if
FW_TEXT_START is wrong. This is not the desired behavior.

Add two new variables to identify relocatable jump address:
FW_JUMP_OFFSET and FW_JUMP_FDT_ADDR. To keep the existing
ABI, FW_JUMP_ADDR and FW_JUMP_FDT_ADDR is prefered if they
are defined.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-24 15:56:55 +05:30
Nam Cao
741e941cb1 platform: starfive: call starfive_jh7110_inst_init() in pm_reset_init()
The function starfive_jh7110_inst_init() initialize some power
management unit address and clock addresses, needed for the reset
driver. It doesn't do anything else, and also the reset driver doesn't
work without calling this function. Thus, it does not make much sense
that this function is independent from pm_reset_init().

Delete the separate call to starfive_jh7110_inst_init(), and instead
just call this function inside pm_reset_init().

Doing this also fixes another problem: if starfive_jh7110_inst_init()
returns an error code, it gets propagated to final_init() and OpenSBI
hangs. This hang is not necessary, because failures within
starfive_jh7110_inst_init() only mean OpenSBI cannot perform reboot or
shutdown, but the system can still function normally.

Signed-off-by: Nam Cao <namcao@linutronix.de>
Tested-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-22 18:19:01 +05:30
Nam Cao
3edf0447df platform: starfive: return error if needed devices are not present
Jh7110's reset driver needs power management device and clock controller
device to work. Currently, the driver proceed anyway without these
devices, and invalid addresses (jh7110_inst.pmu_reg_base and
jh7110_inst.clk_reg_base) are used during reboot, which causes
unpredictable broken behaviors.

If these devices are not present, return -SBI_ENODEV.

Signed-off-by: Nam Cao <namcao@linutronix.de>
Tested-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-22 18:16:48 +05:30
Nam Cao
80ae0464c1 platform: starfive: rename "stf,axp15060-regulator" -> "x-powers,axp15060"
OpenSBI uses the device tree compatible string "stf,axp15060-regulator"
for the regulator node. However, the string used by U-Boot (and Linux)
is actually "x-powers,axp15060". As OpenSBI gets the device tree from
U-Boot, this causes the regulator device to be undetected, and OpenSBI
does not use this device to perform board reset/shutdown.

Rename this device tree compatible string to match U-Boot (and Linux).

Signed-off-by: Nam Cao <namcao@linutronix.de>
Acked-by: Minda Chen <minda.chen@starfivetech.com>
Tested-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-22 18:12:30 +05:30
Nam Cao
5335340d97 platform: starfive: remove redundant compatibility check in pmic_ops
pmic_ops() is only called if a compatible device is found in device
tree. It is redundant for this function to check the compability again.
Remove this check.

Signed-off-by: Nam Cao <namcao@linutronix.de>
Tested-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-22 18:07:49 +05:30
Nam Cao
4d8569df7b platform: starfive: get I2C offset address from clocks property
The current code gets the I2C offset address using the device tree node
name: it get the I2C device index from the 4th character in the node
name (for example, "i2c5" -> i2c device 5). However, the device tree
node's name in U-Boot is actually just "i2c" without the number, so the
current code cannot be used with the device tree from U-Boot.

Get the I2C offset address from the "clocks" property instead.

Signed-off-by: Nam Cao <namcao@linutronix.de>
Reviewed-by: Minda Chen <minda.chen@starfivetech.com>
Tested-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-22 18:01:51 +05:30
Nam Cao
034af1f85e platform: starfive: correct system clock device tree node
Starfive names the system clock device tree node "starfive,jh7110-clkgen"
in all their git repositories. However, a different name is used in
upstream U-Boot (and also Linux): "starfive,jh7110-syscrg". Since
OpenSBI gets the device tree from U-Boot, this inconsistency leads the
problem that OpenSBI doesn't know the system clock device exists.

Correct this name to keep the consistency.

Signed-off-by: Nam Cao <namcao@linutronix.de>
Acked-by: Minda Chen <minda.chen@starfivetech.com>
Tested-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-22 17:58:17 +05:30
yang.zhang
88273fe19e lib: sbi_pmu: Before using we should ensure PMU init done
If trap earlier before sbi_pmu_init done, some path would call
sbi_pmu_ctr_incr_fw, then it would go wrong:
1. if phs_ptr_offset is zero, then it get a wrong pmu state ptr
2. if phs_ptr_offset is ok, but we didn't call pmu_set_hart_state_ptr
it would be NULL POINT

Of course, the above situation will not occur at present, but it is
reasonable to check before using.

Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-20 16:24:06 +05:30
Cheng Yang
46c8c6582d docs: move documentation of system suspend test.
This patch move documentation of "system-suspend-test" from
docs/domain_support.md to docs/opensbi_config.md

Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-20 16:07:38 +05:30
Cheng Yang
8df836d772 platform: generic: Parse system suspend test from config node.
This patch update generic_domains_init() so that "system-suspend-test"
is parsed from "/chosen/opensbi-config" DT node.

Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-20 16:06:31 +05:30
Cheng Yang
23e7e483ee docs: Add OpenSBI DT configuration guide.
This patch add docs/opensbi_config.md which describes the
"/chosen/opensbi-config" DT node and properties

Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-20 16:05:21 +05:30
Cheng Yang
67ce5a763c platform: generic: Add support for specify coldboot harts in DT
Added support for the generic platform to specify the set of coldboot
hart in DT. If not specified in DT, all harts are allowed to coldboot
as before.

The functions related to sbi_hartmask are not available before coldboot,
so I used bitmap, and added a new bitmap_test() function to test whether
a certain bit of the bitmap is set.

Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-20 15:49:36 +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
Leon M. Busch-George
92e8affb31 firmware: always create dynsym section
With a bare-metal linkers (e.g. riscv64-elf-ld), there exists no
dynsym section. The dynsym section is not used by OpenSBI but
discarding it makes linkers with dynamic library support unhappy.

Signed-off-by: Leon M. Busch-George <leon@georgemail.eu>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-05 16:34:44 +05:30
Leon M. Busch-George
d1dad07cb8 Makefile: check for --exclude-libs
While writing to the dynsym is futile, the --exclude-libs options is not
recognized by all linkers (e.g. riscv64-elf-ld.bfd).

Signed-off-by: Leon M. Busch-George <leon@georgemail.eu>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-05 16:34:44 +05:30
Kalle Wachsmuth
4a76f79ff5 Makefile: don't pass -mstrict-align if not supported
Support for that option will be added in LLVM 18:
23ce536840

Clang 17.0.6, however, will error when passed the
`-mstrict-align` flag.
We should only use the flag if it is supported.

Signed-off-by: Kalle Wachsmuth <kalle.wachsmuth@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Xiang W <wxjstz@126.com>
2024-02-05 16:00:54 +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
Himanshu Chauhan
1ec353d504 lib: sbi: Use mask to check the free bit during trigger allocation
The trigger allocation function uses bit shift instead of mask to check the
mapped status of the triggers. This causes index 0 to be return always. As a
result, the older triggers are overwritten.

Use the mask for MAPPED field in state word to check if the trigger is mapped.

Fixes: 97f234f15 ("lib: sbi: Introduce the SBI debug triggers extension support")
Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-02-05 10:23:01 +05:30
Himanshu Chauhan
bb90a9ebf6 lib: sbi: Print number of debug triggers found
Print the total number of triggers found on the boot hart.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-01-10 10:55:52 +05:30
Himanshu Chauhan
76a2a15c40 lib: sbi: Implement SBI debug trigger extension
This patch adds functions to register ecalls for debug triggers
and handler to handle the debug trigger function IDs.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-01-10 10:55:50 +05:30
Himanshu Chauhan
fa87ec90a0 include: sbi: Add SBI debug trigger extension related defines
This patch adds defines for SBI debug trigger extension and
function IDs to access the extension.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-01-10 10:55:49 +05:30
Himanshu Chauhan
97f234f15c lib: sbi: Introduce the SBI debug triggers extension support
RISC-V Debug specification includes Sdtrig ISA extension
which describes Trigger Module. Triggers can cause
a breakpoint exception or trace action without execution
of a special instruction. They can be used to implement
hardware breakpoints and watchpoints for native debugging.

The SBI Debut Trigger extension (Draft v6) can be found at:
https://lists.riscv.org/g/tech-debug/topic/99825362#1302

This patch is an initial implementation of SBI Debug
Trigger Extension (Draft v6) in OpenSBI.

The following features are supported:
 * mcontrol, mcontrol6 triggers
 * Breakpoint and trace actions

NOTE: Chained triggers are not supported

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-01-10 10:55:42 +05:30
Himanshu Chauhan
40dac6bcfe lib: sbi: Detect support of debug triggers
Detect if debug triggers, sdtrig extension, is supported
by the CPU. The support is detected by access traps and
ISA string parsing.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-01-10 09:43:37 +05:30
Himanshu Chauhan
24997697ae include: sbi: Introduce debug trigger register encodings
This patch introduces Mcontrol and M6 control register
encodings along with macros to manipulate them.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-01-10 09:43:34 +05:30
Himanshu Chauhan
20ca19ab03 include: sbi: Add TINFO debug trigger CSR
Add the missing TINFO debug trigger CSR.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-01-10 09:43:33 +05:30
Himanshu Chauhan
b752099da8 include: sbi: Introduce common endianess conversion macro
Introduce cpu_to_lle and lle_to_cpu macros which invoke
correct word length cpu_to_le<64/32> conversion based on
__riscv_xlen.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2024-01-10 09:43:28 +05:30
Anup Patel
a2b255b889 include: Bump-up version to 1.4
This patch updates OpenSBI version to 1.4 as part of
release preparation.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <anup@brainfault.org>
2023-12-27 12:32:58 +05:30
Anup Patel
bbd065d903 lib: sbi: Detect Zicntr extension only based on traps
OpenSBI uses time CSR if Zicntr extension present which causes
it to crash on an older QEMU because QEMU generates Zicntr in
the ISA string for unleashed machine which only has CYCLE and
INSTRET counters.

Fixes: 776770d2ad ("lib: sbi: Using one array to define the
name of extensions")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Anup Patel <anup@brainfault.org>
2023-12-27 12:25:09 +05:30
Inochi Amaoto
ba29293dc9 lib: utils/timer: mtimer: only use regname for aclint
The parser will fail if the timer is clint timer and has regname
property. As the regname is only meaningful for aclint, it is more
robust to only check regname for aclint timer.

Fixes: 6112d58 ("lib: utils/fdt: Allow to use reg-names when parsing ACLINT")
Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-27 11:57:33 +05:30
Xiang W
63e09ad3f7 lib: sbi: Fix shift bug in sbi_system_reset
There is a problem with judging whether the current hart belongs to
hmask. If cur_hartid minus hbase is greater than BITS_PER_LONG, the
previous hmask will also have a bit cleared incorrectly, which will
cause some harts to lose ipi.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-26 21:28:34 +05:30
Anup Patel
2b80b92f02 lib: sbi: Do not enter OpenSBI with mseccfg.MML == 1
On platforms with Smepmp, the previous booting stage must enter
OpenSBI with mseccfg.MML == 0. This allows OpenSBI to configure
it's own M-mode only regions without depending on the previous
booting stage.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-12-19 15:56:37 +05:30
Anup Patel
5a57e8cd41 lib: sbi: Remove the SBI_ETRAP error code
The SBI_ETRAP error code was introduced only for doing trap
redirection in generic sbi_ecall_handler(). Now the trap
redirection is moved into sbi_ecall_legacy.c and SBI_ETRAP
error code is only used in this source file so let us remove
it.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-12-19 15:56:37 +05:30
Anup Patel
3284bea833 lib: sbi: Allow ecall handlers to directly update register state
Some of the upcoming SBI extensions (such as SSE) will directly
update register state so improve the prototype of ecall handler
to accommodate this. Further, this flexibility allows us to
push the trap redirection from sbi_ecall_handler() to the
sbi_ecall_legacy_handler().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-12-19 15:56:37 +05:30
Anup Patel
cdebae2cc9 lib: utils/irqchip: Add shared MMIO region for PLIC in root domain
On platforms with Smepmp, the MMIO regions accessed by M-mode need
to be explicitly marked with M-mode only read/write or shared (both
(M-mode and S-mode) read/write permission.

If the above is not done then runtime PLIC access from M-mode on
platforms with Smepmp will result in access fault when further
results in CPU hotplug not working.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-12-19 15:56:37 +05:30
Anup Patel
80169b25f8 platform: generic: Fine tune fw_platform_calculate_heap_size()
Let's use SBI_TLB_INFO_SIZE instead of hard-coded 0x40 in
fw_platform_calculate_heap_size() to fine tune the heap size
required for per-hart TLB fifos.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-12-19 15:56:37 +05:30
Anup Patel
416ceb3cd7 lib: sbi_tlb: Reduce size of struct sbi_tlb_info
Let us reduce the size of struct sbi_tlb_info by doing the
following:
1) Change the data type of asid and vmid fields to uint16_t
2) Replace local_fn() function pointer with an enum

Based on the above, the size of struct sbi_tlb_info is reduced
by 16 bytes on RV64 and 4 bytes on RV32.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-12-19 15:56:37 +05:30
Yong-Xuan Wang
3daac8fb87 lib: sbi: Detect extensions from the ISA string in DT
Enable access to some extensions through menvcfg and show them in "Boot
HART ISA Extensions" if they are present in the device tree.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-19 15:39:17 +05:30
Yong-Xuan Wang
776770d2ad lib: sbi: Using one array to define the name of extensions
Define an array sbi_hart_ext to map extension ID and name , and use it
for ISA parsing and printing out the supported extensions.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-19 14:14:22 +05:30
Yong-Xuan Wang
056fe6f85d lib: sbi: Refactor the code for enable extensions in menvfg CSR
Use 1 variable to store the value of menvcfg.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-19 13:54:33 +05:30
Yong-Xuan Wang
2c8be566f3 lib: sbi: Improve the code of privilege mode and extensions detection
We can enhance the code by creating 2 unified interface with macro  for
privilege mode and extensions detection, which relies on supported
privilege modes and CSRs.

Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-19 13:46:02 +05:30
Xiang W
925ce14622 lib: sbi: Simplify the initialization of root_hmask in sbi_domain_init
The original code has multiple conversions between hartid and
hartindex. Can call sbi_hartmask_set_hartindex directly to
avoid conversion.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-18 19:51:45 +05:30
Samuel Holland
2707250495 lib: sbi_ipi: Drop unnecessary ipi_process check
sbi_ipi_event_create() disallows registering an IPI event with a NULL
.process callback, so the function pointer will never be NULL here.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-12-18 19:26:35 +05:30
Samuel Holland
446fa65eb5 lib: sbi_ipi: Process self-IPIs in sbi_ipi_send()
An IPI sent to the local hart can be processed directly instead of
triggering the IPI device. This is more efficient, and it avoids a
deadlock when the .sync callback is defined. Since interrupts are
disabled while handling an ecall, the IPI would not get delivered
until the next mret, but sbi_ipi_sync() is called before then.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-12-18 19:26:33 +05:30
Samuel Holland
a894187e28 lib: sbi_ipi: Do not ignore errors from sbi_ipi_send()
Currently, failures in sbi_ipi_send() are silently ignored, which makes
them difficult to debug. Instead, abort sending the IPI and pass back
the error, but still synchronize any IPIs already sent.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Anup Patel <anup@brainfault.org>
2023-12-18 19:26:11 +05:30
Samuel Holland
35cba92655 lib: sbi_tlb: Check tlb_range_flush_limit only once per request
The tlb_update() callback is called for each destination hart.
Move the size check earlier, so it is executed only once.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-11 10:41:48 +05:30
Inochi Amaoto
6112d584d4 lib: utils/fdt: Allow to use reg-names when parsing ACLINT
Currently, the fdt_parse_aclint_node() follows a fixed order to parse
ACLINT timer. This may cause the undesirable result when the ACLINT
device does not support mtime without adding an empty entry for it in
the DT.

To be robust, make fdt_parse_aclint_node() support "reg-names" property,
so it can parse the DT in an order independent way. For compatibility,
fdt_parse_aclint_node() only use "reg-names" when parsing ACLINT timer,
and will fallback to the old way if "reg-names" property is not found.

Link: https://lore.kernel.org/all/20231114-skedaddle-precinct-66c8897227bb@squawk/
Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup patel <anup@brainfault.org>
2023-12-11 10:35:32 +05:30
Xiang W
a2e254e881 lib: sbi: skip wait_for_coldboot when coolboot done
When warmboot via HSM, coolboot has been completed and
wait_for_coldboot can be skipped to speed up.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-11 09:36:57 +05:30
Inochi Amaoto
87aa3069d1 platform: recalculate heap size to support new tlb entry number
Previous patch introduced a change that using hart count as the default
number of tlb entries in the fifo. This makes the default tlb fifo size
grow in square with the number of harts. So the default heap size is
not enough to allocate tlb fifo when the hart count is big.

Fixes: 52fd64b ("platform: Uses hart count as the default size of tlb info")
Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-11 09:23:24 +05:30
Nick Hu
a25fc74699 lib: sbi_hsm: Put the resume_pending hart in the interruptible hart mask
Current interruptible hart mask doesn't include the hart which HSM state
is SBI_HSM_STATE_RESUME_PENDING. So when there is a request to send an
IPI to the hart which is in the resume process, this hart would miss the
IPI forever. Put the SBI_HSM_STATE_RESUME_PENDING hart in the
interruptible hart mask to fix the issue.

Signed-off-by: Nick Hu <nick.hu@sifive.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-10 13:24:13 +05:30
Matt Waltz
06968103dc firmware: fix section types
These sections are only intended to hold data, and should not be executable.

Signed-off-by: Matt Waltz <matthewwaltzis@gmail.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-09 14:26:58 +05:30
Atish Patra
11a0ba5d4b lib: sbi_pmu: Fix the counter info function
The counter info should only return valid hardware counters for the ones
set in the counter mask. Otherwise, it will report incorrect number of
hardware counters to the supervisor if the platform has discontiguous
counters.

Fixes: c744ed77b1 ("lib: sbi_pmu: Enable noncontigous hpm event and counters")
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-08 22:50:23 +05:30
Atish Patra
ee725174ba lib: sbi_pmu: Add PMU snapshot definitions
OpenSBI doesn't support SBI PMU snapshot yet as there is not much benefit
unless the multiple counters overflow at the same time.

Just add the definition and return not supported error at this moment. The
default returned error is also not supported. Thus, no functional change
intended.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
2023-12-08 22:50:21 +05:30
Samuel Holland
93da66b7d4 lib: sbi_hart: Store PMP granularity as log base 2
This minimizes the need to call log2roundup() to recover the log value.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-08 22:43:12 +05:30
Xiang W
07419ec84b lib: sbi: Prevent redundant sbi_ipi_process
Multiple harts may try to send IPI to a particular target hart A
in which case the send_ipi() should be called only when the old
value of the hart A ipi_type is zero.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-08 17:07:03 +05:30
Anup Patel
88398696c8 lib: sbi: Replace __atomic_op_bit_ord with __atomic intrinsics
Simplify atomic-related bit operations through __atomic intrinsics.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-08 14:06:40 +05:30
Xiang W
11bf49b444 lib: sbi: Fix __atomic_op_bit_ord and comments
The original code returns the value of the word before modification.
When modifying the upper 32 bits under RV64, the value returned via
int return will have no meaning. Corrected to return the value of the
bit. And modify the function description.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-08 13:47:31 +05:30
Xiang W
6b9a849482 lib: sbi: Remove xchg/cmpxchg implemented via lr/sc
lr/sc is part of the A extension. If the A extension is not supported,
lr/sc cannot be used. So remove xchg/cmpxchg.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-08 10:54:35 +05:30
Yu Chien Peter Lin
d162009612 docs: pmu: Add Andes PMU node example
Add PMU node example for event index to counter index mapping
and selector value translation of Andes' CPUs.

Currently, there are 4 HPM counters that can be used to monitor
all of the events for each hart.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Locus Wei-Han Chen <locus84@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
2023-12-06 18:21:25 +05:30
Yu Chien Peter Lin
e19d419f15 lib: utils: fdt_pmu: Do not iterate over the fdt_pmu_evt_select table
The valid entry count is tracking by hw_event_count so there
is no need to check the whole table.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 18:17:08 +05:30
Yu Chien Peter Lin
0308f93dc4 lib: utils: fdt_pmu: Make the fdt_pmu_evt_select table global variable
To allow platform override pmu_init() filling the translation table
fdt_pmu_evt_select[] when PMU node doesn't provide such information,
we need to share the table and its entry counter with other .c file.

We also define the structures of PMU property in fdt_helper.h, so we
can initialize the mappings in arrays.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 18:15:41 +05:30
Yu Chien Peter Lin
009ae4e602 platform: andes: Factor out is_andes() helper
We will need is_andes(45) in the following patch,
so factor out the code that parses marchid to make
it reusable for checking any Andes CPU variants.

Also improves the comment in ae350_hart_start().

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 18:03:12 +05:30
Yu Chien Peter Lin
0b3262efc6 lib: utils: fdt_fixup: Allow preserving PMU properties
Add a Kconfig option to control PMU fixup, so the next
stage software can dump the PMU node including event
mapping information for debugging purposes.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 17:59:44 +05:30
Yu Chien Peter Lin
535c661d87 platform: rzfive: Enable Andes PMU for RZ/Five
Enable Andes PMU extension support for RZ/Five.
We also staticize renesas_rzfive_early_init() as
it is not used outside of this unit.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 17:57:28 +05:30
Yu Chien Peter Lin
2e50c24399 platform: andes: Enable Andes PMU for AE350
Enable Andes PMU extension support for AE350 platforms.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 17:55:55 +05:30
Yu Chien Peter Lin
1b9e743c3d platform: andes: Add Andes custom PMU support
Before the ratification of Sscofpmf, the Andes PMU extension
was designed to support the sampling and filtering with hardware
performance counters (zihpm), it works with the current SBI PMU
extension and Linux SBI PMU driver.

We implement 1) the PMU device callbacks that update the
corresponding bits on custom CSRs, 2) extentions_init() to detect
the hardware support of Andes PMU and initialize the per-hart
PMU related CSR, and 3) pmu_init() to register PMU device and
populate event mappings.

Also define a andes_pmu_setup() function which is in preparation
for adding default PMU mappings in andes_hpm.h

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 17:53:45 +05:30
Yu Chien Peter Lin
effd89aa05 platform: generic: Introduce pmu_init() platform override
Add pmu_init() platform override, which will be used to register
PMU device and populate event mappings.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 17:49:59 +05:30
Yu Chien Peter Lin
51ec60c9ea platform: include: andes45: Add PMU related CSR defines
Add CSR definitions for Andes PMU extension.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
2023-12-06 17:31:36 +05:30
Yu Chien Peter Lin
a48f2cfd94 sbi: sbi_pmu: Add hw_counter_filter_mode() to pmu device
Add support for custom PMU extensions to set inhibit bits
on custom CSRs by introducing the PMU device callback
hw_counter_filter_mode(). This allows the perf tool to
restrict event counting under a specified privileged
mode by appending a modifier, e.g. perf record -e event:k
to count events only happening in kernel mode.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 17:30:01 +05:30
Yu Chien Peter Lin
090fa99d7c lib: sbi: Add XAndesPMU in hart extensions
Add the custom extension to hart extension list.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 17:27:22 +05:30
Yu Chien Peter Lin
291403f6f2 sbi: sbi_pmu: Improve sbi_pmu_init() error handling
This patch makes the following changes:

- As sbi_platform_pmu_init() returns a negative error code on
  failure, let sbi_pmu_init() print out the error code with
  sbi_dprintf().

- In order to distinguish the SBI_EFAIL error returned by
  sbi_pmu_add_*_counter_map(), return SBI_ENOENT to indicate
  that fdt_pmu_setup() failed to locate "riscv,pmu" node, and
  generic_pmu_init() ignores such case.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2023-12-06 17:24:38 +05:30
Leo Yu-Chi Liang
bd74931d79 lib: ipi: Adjust Andes PLICSW to single-bit-per-hart scheme
The old scheme doesn't allow sending hart0 self-IPI as the
corresponding bit on pending register is hardwired to 0, this
could lead to unhandle IPIs on SMP systems, esp. on single-core.

Furthermore, the limitation of old scheme is 8-core, instead of
reserving source hart information, we assign bit (x + 1) as the
enable and pending bit of hartx, this also expands the bootable
hart number.

The following diagram shows the enable bits of the new scheme
on 32-core Andes platform.

   Pending regs: 0x1000  x---0---0---0---0------0---0
Pending hart ID:             0   1   2   3 ... 30  31
   Interrupt ID:         0   1   2   3   4 ... 31  32
                         |   |   |   |   |      |   |
    Enable regs: 0x2000  x---1---0---0---0-...--0---0---> hart0
                         |   |   |   |   |      |   |
                 0x2080  x---0---1---0---0-...--0---0---> hart1
                         |   |   |   |   |      |   |
                 0x2100  x---0---0---1---0-...--0---0---> hart2
                         |   |   |   |   |      |   |
                 0x2180  x---0---0---0---1-...--0---0---> hart3
                         .   .   .   .   .      .   .
                         .   .   .   .   .      .   .
                         .   .   .   .   .      .   .
                 0x2f00  x---0---0---0---0-...--1---0---> hart30
                         |   |   |   |   |      |   |
                 0x2f80  x---0---0---0---0-...--0---1---> hart31
                         <-------- word 0 -------><--- word 1 --->

To send IPI to hart0, for example, another hart (including hart0
itself) will set bit 1 of first word on the pending register.

We also fix indentation in andes_plicsw.h along with this patch.

Fixes: ce7c490719 ("lib: utils/ipi: Add Andes fdt ipi driver support")
Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Randolph <randolph@andestech.com>
Reported-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Link: https://lists.infradead.org/pipermail/opensbi/2023-October/005665.html
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-12-06 17:23:27 +05:30
Anup Patel
b70d6285f0 lib: sbi: Allow relaxed MMIO writes in device ipi_clear() callback
Currently, there are no barriers before or after the ipi_clear()
device callback which forces ipi_clear() device callback to always
use non-relaxed MMIO writes.

Instead of above, we use wmb() in after the ipi_clear() device
callback which pairs with the wmb() done before the ipi_send()
device callback. This also allows device ipi_clear() callback
to use relaxed MMIO writes.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reported-by: Bo Gan <ganboing@gmail.com>
2023-11-26 18:45:08 +05:30
Anup Patel
f520256d03 lib: sbi: Allow relaxed MMIO writes in device ipi_send() callback
Currently, we have a smp_wmb() between atomic_raw_set_bit() and
ipi_send() device callback whereas the MMIO writes done by the
device ipi_send() callback will also include a barrier.

We can avoid unnecessary/redundant barriers described above by
allowing relaxed MMIO writes in device ipi_send() callback. To
achieve this, we simply use  wmb() instead of smp_wmb() before
calling device ipi_send().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reported-by: Bo Gan <ganboing@gmail.com>
2023-11-26 18:45:06 +05:30
Anup Patel
791704cd09 lib: utils/irqchip: Avoid redundant writes to APLIC CLRIE register
Each APLIC CLRIE register allows disabling 32 interrupt sources at
a time by writing -1 so no need to write CLRIE register separately
for each interrupt source.

Fixes: 99792653de ("lib: utils/irqchip: Add APLIC initialization library")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2023-11-24 12:48:41 +05:30
Heinrich Schuchardt
574b9c8ec2 lib: sbi_pmu: avoid buffer overflow
total_ctrs is bounded by

    SBI_PMU_FW_CTR_MAX + SBI_PMU_HW_CTR_MAX) == 48

which exceeds BITS_PER_LONG on 32 bit systems.

Iterating over the bits of &cmask results in a buffer overflow when looking
for a bit >= BITS_PER_LONG.

Adjust the iterators in sbi_pmu_ctr_start() and sbi_pmu_ctr_stop()
accordingly.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-22 20:55:22 +05:30
Anup Patel
16bb930533 lib: sbi: Fix PMP granularity handling in sbi_hart_map_saddr()
The sbi_hart_map_saddr() must create PMP mapping of size greater
than or equal to PMP granularity otherwise PMP mapping does not
work when size parameter less than sbi_hart_pmp_granularity(scratch).

Fixes: 6e44ef686a ("lib: sbi: Add functions to map/unmap shared memory")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
2023-11-22 20:42:24 +05:30
Xiang W
dc0bb19bd2 lib: utils/serial: remove semihosting_putc
For some debuggers that do not implement SYSWRITEC and SYSREADC
operations, we have to use SYSWRITE and SYSREAD.

Instead of implementing semihosting_putc() using SYSWRITE, let us
simply remove semihosting_putc() because console_putc/console_puts
are now interchangeable.

Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-17 16:03:24 +05:30
Xiang W
3aaed4fadf lib: sbi: Make console_puts/console_putc interchangeable
console_puts/console_putc should replace each other, but the previous
sbi_putc can only use console_putc. This patch addresses this problem.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-17 16:03:21 +05:30
Xiang W
6602e11de3 lib: sbi: change sbi_hart_features.extensions as an array
In the future there may be a lot of ISA extensions, a 'long' may not
be able to accommodate, changed to an array for the future.

Addresses-Coverity-ID: 1568357 Out-of-bounds access
Fixes: 6259b2ec2d ("lib: utils/fdt: Fix fdt_parse_isa_extensions()
implementation")
Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-17 13:23:49 +05:30
Heinrich Schuchardt
6e5b0cfb45 lib: sbi: enable seed access in S-mode
If ISA extension Zkr is available, set

    mseccfg.sseed=1
    mseccfg.useed=0

This enables access to the seed CSR in S-mode but not in U-mode.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-17 12:26:22 +05:30
Heinrich Schuchardt
efcac338bd lib: sbi: Add Zkr in hart extensions
- Add Zkr as extension in sbi_hart_extensions enum
- Return "zkr" string for Zkr extension from sbi_hart_extension_id2string

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-17 12:04:18 +05:30
Heinrich Schuchardt
280f7ae627 include: sbi: macros for mseccfg.sseed and .useed
Define macros to access the sseed and the useed bit in the machine
security configuration register (mseccfg).

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-17 12:03:59 +05:30
Inochi Amaoto
2bfdb9e5c2 platform: generic: Add Sophgo sg2042 platform support
Add Sophgo sg2042 soc support

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 21:22:27 +05:30
Inochi Amaoto
3b03cdd60c lib: sbi: Add regions merging when sanitizing domain region
As the domain will reject a new memory region which has a sub-regions
already in the domain, even the new region is bigger and has the same
flags. This problem can be solved by relaxing region restriction and
rechecking when adding and sanitizing domains.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 21:03:26 +05:30
Inochi Amaoto
5b2f55d65a lib: sbi: separate the swap operation of domain region
Swapping domain region is a common operation when sorting domain region,
so separate it as a function to make code clean.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 20:58:56 +05:30
Inochi Amaoto
98bc25f181 lib: utils/ipi: mswi: add separate T-Head C9xx CLINT mswi compatible
Like the mtimer of T-HEAD C9xx clint, the mswi also needs new compatible
string to avoid misuse.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Link: https://lore.kernel.org/linux-riscv/1f6b82a1864477a51db33d3f295889ff985b497b.1696433229.git.unicorn_wang@outlook.com/
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 16:55:28 +05:30
Inochi Amaoto
accafb13d4 lib: utils/timer: mtimer: add separate T-Head C9xx CLINT mtimer compatible
T-HEAD allows soc vendor to map the mtimer and mswi of C9xx clint on
different address, which may cause a misuse if use the same compatible
string, add a new timer compatible string to avoid this.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Link: https://lore.kernel.org/linux-riscv/6e48cbe5e60f9ada2fd1fe58e803e127f1a678e5.1696433229.git.unicorn_wang@outlook.com/
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 16:53:48 +05:30
Inochi Amaoto
896d2c99e2 lib: utils/timer: Allow ACLINT MTIMER driver to setup quirks
The quirks checking will cause ACLINT step into a CLINT code path, this
is not expected when ACLINT needs custom quirks.

Add a new quirk to identify custom ACLINT, and apply the general quirks
after applying CLINT specific quirks.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 16:50:42 +05:30
Guo Ren
d1e0f7f25b utils/reset: Remove fdt_reset_thead
In the past, we used fdt_reset_thead to help customers with prototype
verification. However, with the emergence of the Big-little SoC system,
it can no longer meet the demand. Therefore, we use zero_stage_boot
instead of fdt_reset_thead. It cleans up the opensbi code and ends the
disputation of reset_sample's dts.

This patch removes the fdt_reset_thead component and updates the related
doc.

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:25:23 +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
Chen Pei
07f2ccd990 lib: utils/serial: Optimize semihosting_putc implementation
For some debuggers that do not implement SYSWRITEC and SYSREADC
operations, we can use SYSWRITE and SYSREAD instead like the
implementation of semihosting_getc().

Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 11:36:44 +05:30
Inochi Amaoto
52fd64b82c platform: Uses hart count as the default size of tlb info
For platform with high number of harts, it is better to auto detect a
suitable number of entries in tlb fifo. Since allocating tlb entry for
all online harts can reduce the wait time significantly, using the
number of the online harts can make most platforms happy. This auto
detection can avoid most duplicate code for setting tlb fifo size.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Acked-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 09:53:45 +05:30
Inochi Amaoto
88ae718d36 platform: generic: thead: improve tlb flush errata
Flushing the tlb entries can solve the thead tlb problem, but flushing
it by address will miss something and lead to a exception in some rare
cases, and this is more common for sg2042.

To solve this problem, flush the tlb entries by asid in the custom trap
handler to ensure it is refreshed.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 09:42:12 +05:30
Samuel Holland
a140a4e862 lib: sbi: Correctly limit flushes to a single ASID/VMID
Per the SBI specification, the effects of these functions are limited to
a specific ASID and/or VMID. This applies even when flushing the entire
address space.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-16 09:21:47 +05:30
Inochi Amaoto
3e21b96003 platform: generic: thead: initialize PMU by default in thead generic platform
Since all the SoC with thead c9xx cores need this initialization at now,
initialize the c9xx pmu in the thead generic platform by default.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-14 21:53:52 +05:30
Inochi Amaoto
492d9b153d platform: generic: thead: separate implement of T-HEAD c9xx errata
Separate the implement of T-HEAD c9xx errata to allow any platform
with bug related to c9xx cores can use it.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-14 21:53:50 +05:30
Inochi Amaoto
8e941e7fe3 platform: generic: thead: separate implement of T-HEAD c9xx pmu
Separate the implement of T-HEAD c9xx pmu to allow any platform with
c9xx cores can use it.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-14 21:53:45 +05:30
Inochi Amaoto
c1a6987447 platform: generic: thead: move to thead c9xx header to vendor specific postion
The CSR encoding for t-head c9xx cores is shared across all the
platforms with these cores. So move header thead_c9xx.h to the
thead subdir.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Acked-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-14 21:53:42 +05:30
Heinrich Schuchardt
5d0ed1bfb8 lib: sbi: simplify sanitize_domain()
Since commit 112daa2e64 ("lib: sbi: Maximize the use of HART index in
sbi_domain") the platform parameter is unused.

Fixes: 112daa2e64 ("lib: sbi: Maximize the use of HART index in sbi_domain")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-11-14 17:57:54 +05:30
Anup Patel
cbdd869739 include: sbi: Change spec version to 2.0
Now that SBI v2.0 specification is frozen, we change spec version
implemented by OpenSBI to v2.0.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-10-19 17:21:17 +05:30
Amanieu d'Antras
ec0559eb31 lib: sbi_misaligned_ldst: Fix handling of C.SWSP and C.SDSP
Unlike C.LWSP/C.LDSP, these encodings can be used with the zero
register, so checking that the rs2 field is non-zero is unnecessary.

Additionally, the previous check was incorrect since it was checking
the immediate field of the instruction instead of the rs2 field.

Signed-off-by: Amanieu d'Antras <amanieu@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-09 13:53:20 +05:30
Yangjie Zhang
3632f2b5c4 lib: sbi: Add support for mconfigptr
RISC-V privileged specification v1.12 introduced the mconfigptr CSR
which will hold the physical address of a configuration data
structure.

Signed-off-by: Yangjie Zhang <jay1273062855@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 17:58:42 +05:30
Yangjie Zhang
e8114c6ae2 docs: platform: update platform_requirements.md
"Zicsr" isa extension has been separated from "I" extension.
This patch add the isa requirement of "Zicsr" extension in
platform requirements documentation.

Signed-off-by: Yangjie Zhang <jay1273062855@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 17:58:09 +05:30
Heinrich Schuchardt
d891caeae9 gpio/starfive: redundant readl() call
In starfive_gpio_direction_output() readl() is called twice to read the
gpio direction register. The result of the first read is discarded.

Remove the redundant read.

Fixes: 908be1b85c ("gpio/starfive: add gpio driver and support gpio reset")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 17:29:09 +05:30
Heinrich Schuchardt
f831b93357 lib: sbi_pmu: check for index overflows
sbi_pmu_ctr_cfg_match() receives data from a lower privilege level mode.
We must catch maliciously wrong values.

We already check against total_ctrs. But we do not check that total_ctrs is
less than SBI_PMU_HW_CTR_MAX + SBI_PMU_FW_CTR_MAX.

Check that the number of hardware counters is in the valid range.

Addresses-Coverity-ID: 1566114 Out-of-bounds write
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2023-10-06 17:29:07 +05:30
Heinrich Schuchardt
942aca232e lib: utils: Simplify SET_ISA_EXT_MAP()
The define is hard to read. The continue statement does not do what was
intended.

* Remove do {} while (false);
* Change the name to set_multi_letter_ext
  - Other local macros are lower case too.
  - Refer to the fact that this is only used for multi-letter extensions.

Addresses-Coverity-ID: 1568359 Unexpected control flow
Fixes: d72f5f1747 ("lib: utils: Add detection of Smepmp from ISA string in FDT")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 17:28:52 +05:30
Heinrich Schuchardt
9da30f6105 lib: utils/fdt: simplify dt_parse_isa_extensions
hart_exts == NULL can only occur if offset and node address lead to an
overflow resulting in exactly NULL. As we don't catch other values of
overflow it does not make sense to treat this one as special.

Addresses-Coverity-ID: 1568355 Logically dead code
Addresses-Coverity-ID: 1568358 Logically dead code
Fixes: 6259b2ec2d ("lib: utils/fdt: Fix fdt_parse_isa_extensions() implementation")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 17:06:13 +05:30
Heinrich Schuchardt
8197c2f1ec lib: sbi: fix sbi_domain_get_assigned_hartmask()
'1' is a 32 bit integer. When shifting it by more than 31 bits it becomes
zero and we get an incorrect return value.

Addresses-Coverity-ID: 1568356 Bad bit shift operation
Fixes: 296e70d69d ("lib: sbi: Extend sbi_hartmask to support both hartid and hartindex")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 17:06:09 +05:30
Yu Chien Peter Lin
d36709fcaf lib: utils: timer/ipi: Update memregion flags for PLMT and PLICSW
This patch adds unspecified permission flags for the PLICSW region
and updates the permission of the PLMT region.

With this update, both regions will become M-mode only read/write
regions in the root domain.

  Domain0 Region00: 0x00000000f0300000-0x00000000f0300fff M: (I,R,W) S/U: (R,W)
  Domain0 Region01: 0x0000000000040000-0x000000000005ffff M: (R,W) S/U: ()
  Domain0 Region02: 0x0000000000000000-0x000000000003ffff M: (R,X) S/U: ()
> Domain0 Region03: 0x00000000e6000000-0x00000000e60fffff M: (I,R,W) S/U: ()
> Domain0 Region04: 0x00000000e6400000-0x00000000e67fffff M: (I,R,W) S/U: ()
  Domain0 Region05: 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X)

The PMP rules of AE350-AX65 (single-core) w/ Smepmp:

  p/x $pmpcfg0
  $1 = {0x1f9b9b9d9b1e00,
  pmp0cfg = {0x0},
                    L--AAXWR
  pmp1cfg = {0x1e} (00011110), pmpaddr1: 0xf0300000 ~   0xf0300fff  (UART1)
  pmp2cfg = {0x9b} (10011011), pmpaddr2:    0x40000 ~      0x5ffff
  pmp3cfg = {0x9d} (10011101), pmpaddr3:        0x0 ~      0x3ffff
  pmp4cfg = {0x9b} (10011011), pmpaddr4: 0xe6000000 ~   0xe60fffff  (PLMT)
  pmp5cfg = {0x9b} (10011011), pmpaddr5: 0xe6400000 ~   0xe67fffff  (PLICSW)
  pmp6cfg = {0x1f} (00011111), pmpaddr6:        0x0 ~ 0xffffffffff
  pmp7cfg = {0x0 }}

The PMP rules of AE350-AX45MP (qual-core) w/o Smepmp:

  p/x $pmpcfg0
  $1 = {0x1f181818181b,
                     L--AAXWR
  pmp0cfg = {0x1b}, (00011011), pmpaddr0: 0xf0300000 ~  0xf0300fff  (UART1)
  pmp1cfg = {0x18}, (00011000), pmpaddr1:    0x40000 ~     0x5ffff
  pmp2cfg = {0x18}, (00011000), pmpaddr2:        0x0 ~     0x3ffff
  pmp3cfg = {0x18}, (00011000), pmpaddr3: 0xe6000000 ~  0xe60fffff  (PLMT)
  pmp4cfg = {0x18}, (00011000), pmpaddr4: 0xe6400000 ~  0xe67fffff  (PLICSW)
  pmp5cfg = {0x1f}, (00011111), pmpaddr5:        0x0 ~ 0x1ffffffff
  pmp6cfg = {0x0 }}

Note that starting from this patch, we restrict the S/U-mode read
permission to the PLMT region, since we should read the TIME CSR
in a lower privilege mode.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 16:53:26 +05:30
Yu Chien Peter Lin
a12542316c lib: utils/serial: Ensure proper allocation of PMP entries for uart8250
The added memory region should start from the base address.
Otherwise, the range will be shifted by reg_offset and not
able to merge consecutive NAPOT regions in the root domain,
resulting in wasted PMP entries.

Fixes: e8bc1621 ("lib: utils/serial: Add shared regions for
serial drivers")

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 16:53:25 +05:30
Hoa Nguyen
e21901d317 doc: Fix fw_payload.md
The base of .text is defined by `FW_TEXT_START`, not `FW_TEXT_BASE`.

Signed-off-by: Hoa Nguyen <hn@hnpl.org>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 10:07:48 +05:30
Vivian Wang
6ed125a602 Makefile: Add --exclude-libs ALL to avoid .dynsym
Since everything is statically linked, we don't need to expose symbols
for dynamic linking.

For a default build this saves about 2 KiB of useless read only data in
.dynsym, .dynstr, .hash, .gnu.hash sections.

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-06 09:21:24 +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
Vivian Wang
de525ac18d firmware: Remove ALIGN in .rela.dyn in linker script
The .rela.dyn section should be exactly the size of the relocations,
without padding. On RV64, .rela* sections are already aligned and
there's no need for padding. On RV32, this adds padding up to 4 bytes,
which, if present, confuses the relocation loop into processing an extra
entry past the end of .rela*, and it crashes with an invalid memory
access.

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:21 +05:30
Inochi Amaoto
3669153e06 platform: generic: thead: fix stale TLB entries for th1520/sg2042
The TLB entries remain functional all the time once added in T-HEAD th1520
and Sophgo sg2042 (even if the MMU is then disabled afterwards). If there
are some stale TLB entries that contains the address of SBI, it will cause
unexpected memory access and issue a illegal instruction error. To avoid
this, a TLB flush is needed to drop these TLB entries before any memory
access in the trap handler.

To handle this workaroud, add a custom trap handler with executing TLB flush
first in the T-HEAD platform to fix affected socs.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-10-04 18:59:54 +05:30
Anup Patel
b7e9d34edf lib: utils/regmap: Mark syscon region as shared read-write
The syscon region used by OpenSBI should be marked as a shared
read-write region between M-mode and SU-mode.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
2023-09-24 17:14:26 +05:30
Mayuresh Chitale
e8bc1621c6 lib: utils/serial: Add shared regions for serial drivers
The serial driver regions used by OpenSBI should be marked as a shared
read-write regions between M-mode and SU-mode as those are accessed
by earlycon and the corresponding tty serial drivers running in 'S' mode.
When the smepmp extension is enabled, PMP entries for these shared regions
will get programmed.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-09-24 17:04:41 +05:30
Anup Patel
73aea28264 lib: sbi: Populate M-only Smepmp entries before setting mseccfg.MML
Based on sections 4.c and 4.d in Ch.2 of the Smepmp spec the PMP entries
must be programmed as below:
1. Program M-only entries
2. Enable mseccfg.MML
3. Program shared-region entries
4. Program SU-only entries

Co-developed-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-09-24 16:45:15 +05:30
Anup Patel
2b51a9dd9c lib: sbi: Fix pmp_flags for Smepmp read-only shared region
The Smepmp read-only shared region must have pmpcfg.L, pmpcfg.R,
pmpcfg.W, and pmpcfg.X bits set so sbi_hart_get_smepmp_flags()
must return pmp_flags accordingly.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
2023-09-24 16:40:52 +05:30
Anup Patel
5240d312d3 lib: sbi: Don't clear mseccfg.MML bit in sbi_hart_smepmp_configure()
The mseccfg.MML bit is a sticky bit which remains unchanged once set
so no need to clear it in sbi_hart_smepmp_configure().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
2023-09-24 16:28:16 +05:30
Anup Patel
bff27c1fb4 lib: sbi: Factor-out Smepmp configuration as separate function
Let us factor-out Smepmp configuaration as separate function so
that code is more readable.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
2023-09-24 16:27:40 +05:30
Mayuresh Chitale
b8fb96eceb include: sbi_domain: Fix permission test macros
The macros to test permissions must perform an exact match of all the
bits in the input with the desired permission bits. Otherwise, the check
returns false positives in those cases where only some of the desired
permissions are set in the input.

Fixes: 6c202c5 ("include: sbi: Add Smepmp specific access flags for PMP
entries")
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-09-24 16:27:02 +05:30
Anup Patel
9560fb38fe include: sbi: Remove sbi_hartmask_for_each_hart() macro
The sbi_hartmask_for_each_hart() macro is slow and has only one user
so let us completely remove the sbi_hartmask_for_each_hart() macro.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-09-24 11:48:21 +05:30
Anup Patel
112daa2e64 lib: sbi: Maximize the use of HART index in sbi_domain
Let us maximize the use of HART index in sbi_domain because hartindex
based hartmask access and sbi_scratch lookup is faster.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-09-24 11:48:17 +05:30
Anup Patel
22d6ff8675 lib: sbi: Remove sbi_scratch_last_hartid() macro
The sbi_scratch_last_hartid() macro is not of much use on platforms
with really sparse hartids so let us replace use of this macro with
other approaches.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-09-24 11:41:54 +05:30
Anup Patel
78c667b6fc lib: sbi: Prefer hartindex over hartid in IPI framework
Let us prefer hartindex over hartid in IPI framework which in-turn
forces IPI users to also prefer hartindex.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-09-24 11:39:38 +05:30
Anup Patel
e632cd7c81 lib: sbi: Use sbi_scratch_last_hartindex() in remote TLB managment
The sbi_hartid_to_scratch() involves translating hartid to hartindex
which is expensive so let's use sbi_hartindex_to_scratch() instead.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-09-24 11:39:35 +05:30
Xiang W
296e70d69d lib: sbi: Extend sbi_hartmask to support both hartid and hartindex
Currently, the sbi_hartmask is indexed by hartid which puts a
limit on hartid to be less than SBI_HARTMASK_MAX_BITS.

We extend the sbi_hartmask implementation to use hartindex and
support updating sbi_hartmask using hartid. This removes the
limit on hartid and existing code works largely unmodified.

Signed-off-by: Xiang W <wxjstz@126.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-09-24 11:39:32 +05:30
Anup Patel
e6125c3c4f lib: sbi: Remove sbi_platform_hart_index/invalid() functions
The hartid to hartindex mapping is now tracked in sbi_scratch so we
don't need sbi_platform_hart_index() and sbi_platform_hart_invalid()
functions hence let us remove them.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-09-24 11:39:30 +05:30
Anup Patel
d1e4dff45b lib: sbi: Introduce HART index in sbi_scratch
We introduce HART index and related helper functions in sbi_scratch
where HART index is contiguous and each HART index maps to a physical
HART id such that 0 <= HART index and HART index < SBI_HARTMASK_MAX_BITS.

The HART index to HART id mapping follows the index2id mapping provided
by the platform. If the platform does not provide index2id mapping then
identity mapping is assumed.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-09-24 11:39:21 +05:30
Greentime Hu
130e65dd9d lib: sbi: Implement SET_FS_DIRTY() to make sure the mstatus FS dirty is set
We found the mstatus.FS status is not set correctly after the SET_F64_REG()
and SET_F32_REG(). We should set mstatus.FS dirty after we emulate the FPU
instructions.

Co-developed-by: Roy Lin <roy.lin@sifive.com>
Signed-off-by: Roy Lin <roy.lin@sifive.com>
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-09-22 11:17:26 +05:30
Xiang W
5bd969477f lib: sbi: alloc tlb fifo by sbi_malloc
If the system is defined from tlb_fifo_num_entries, the scratch may be
too small to hold the fifo, so it is alloc through the heap.

Signed-off-by: Xiang W <wxjstz@126.com>
Signed-off-by: Xing Xiaoguang <xiaoguang.xing@sophgo.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-09-10 11:46:44 +05:30
Xiang W
cacfba32cc platform: Allow platforms to specify the size of tlb fifo
For some platforms with a particularly high number of harts, if the
tlb fifo is too small, it case harts to wait. Platforms should be
allowed to specify the size of the tlb fifo.

Signed-off-by: Xiang W <wxjstz@126.com>
Signed-off-by: Xing Xiaoguang <xiaoguang.xing@sophgo.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-09-10 11:21:05 +05:30
Inochi Amaoto
901d3d7bff lib: sbi_pmu: keep overflow interrupt of stopped hpm counter disabled
After the hardware hpm counter is stopped, it should not raise any new
interrupt as it is already stopped. So add the hw_counter_disable_irq
callback to allow the custom pmu device to control this behavior.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Samuel Holland <samuel@sholland.org>
2023-09-10 11:05:01 +05:30
Inochi Amaoto
c9a296d0ed platform: generic: allwinner: fix OF process for T-HEAD c9xx pmu
T-HEAD c9xx pmu needs to clear OV bits of MCOUNTEROF in any condition
to avoid unnecessary OF interrupts.

In addition, the S-mode SCOUNTEROF only have OF bit set when the related
bits of MCOUNTERWEN is set, so also configure MCOUNTERWEN to allow kernel
to access valid SCOUNTEROF.

Signed-off-by: Haijiao Liu <haijiao.liu@sophgo.com>
Co-authored-by: Inochi Amaoto <inochiama@outlook.com>
Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Samuel Holland <samuel@sholland.org>
2023-09-10 11:04:59 +05:30
Inochi Amaoto
664692f507 lib: sbi_pmu: ensure update hpm counter before starting counting
When detecting features of PMU, the hpm counter may be written to some
value, this will cause some unexpected behavior in some cases. So ensure
the hpm counter is updated before starting the counter and the related
interrupt.

Signed-off-by: Haijiao Liu <haijiao.liu@sophgo.com>
Co-authored-by: Inochi Amaoto <inochiama@outlook.com>
Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Samuel Holland <samuel@sholland.org>
2023-09-10 11:04:57 +05:30
Xiang W
b20bd479ef lib: sbi: improve the definition of SBI_IPI_EVENT_MAX
The previous definition had the assumption that the machine word length
is equal to the word length of LONG. Remove this assumption and add a
static check to prevent errors in subsequent modifications.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-09-06 17:06:12 +05:30
Inochi Amaoto
a9cffd6532 firmware: payload: test: Change to SBI v2.0 DBCN ecalls
As the the "Console Putchar" extension is already legacy and may
be removed in the furture. So replace it with the SBI v2.0 "DBCN"
extension.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-09-06 16:50:50 +05:30
Inochi Amaoto
ee1f83ca84 lib: sbi_pmu: remove mhpm_count field in hart feature
After supporting noncontigous hpm event and counters in opensbi, the
number of hpm counters can be calculated by the mhpm_mask. So this field
is unnecessary and can be removed to save some space.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel  <anup@brainfault.org>
2023-08-22 13:26:09 +05:30
Inochi Amaoto
e7e73aa532 platform: generic: allwinner: correct mhpmevent count
Only the CSR mhpmevent 3-9,13-17 of D1 have valid function, so change
the mhpm_mask to a valid value to avoid invalid usage.

Due to the openc906 pmu code
https://github.com/T-head-Semi/openc906/blob/main/C906_RTL_FACTORY/gen_rtl/pmu/rtl/aq_hpcp_top.v

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Anup Patel  <anup@brainfault.org>
2023-08-22 13:26:05 +05:30
Andrew Jones
7aabeee93e Makefile: Fix grep warning
grep (at least my version, grep-3.8-3.fc38.x86_64) warns with
"grep: warning: stray \ before -". Fix the warning by making
the command line input to grep less ambiguous.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel  <anup@brainfault.org>
2023-08-22 13:26:03 +05:30
Kaiwen Xue
c104c60912 lib: sbi: Add support for smcntrpmf
This adds the support for ISA extension smcntrpmf. When some inhibit flags
are set by a lower privilege mode for new CSRs added by smcntrpmf, OpenSBI
sets the appropriate values correspondingly.

Signed-off-by: Kaiwen Xue <kaiwenx@andrew.cmu.edu>
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2023-08-18 14:50:38 +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
Kaiwen Xue
f46a5643bc lib: sbi: Fix typo for finding fixed event counter
Cycle and instructions are hardware events instead of firmware ones. Fix
the typo in the name of this function.

Signed-off-by: Kaiwen Xue <kaiwenx@andrew.cmu.edu>
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
Reviewed-by: Anup patel <anup@brainfault.org>
2023-08-06 10:22:58 +05:30
Anup Patel
6259b2ec2d lib: utils/fdt: Fix fdt_parse_isa_extensions() implementation
Currently, the fdt_parse_isa_extensions() tries to parse the ISA
string once for each HART. This ISA string parsing can fail for
secondary HARTs if the FDT memory is already overwritten by the
supervisor OS.

To tackle this issue, we improve the fdt_parse_isa_extensions()
implementation to pre-parse ISA string for all HARTs during
cold boot.

Fixes: d72f5f1747 ("lib: utils: Add detection of Smepmp from ISA
string in FDT")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-By: Mayuresh Chitale<mchitale@ventanamicro.com>
2023-08-06 10:18:51 +05:30
Mayuresh Chitale
c744ed77b1 lib: sbi_pmu: Enable noncontigous hpm event and counters
Platforms may implement hpm events/counters non contiguously but the current
implementation assumes them to be always contigous. Add a bitmap that
captures the hpm events/counters as implemented in the hardware and use
it to set the max limit of hardware counters visible to the OS. Counters
not implemented in the hardware can't be used by the OS because those
wont be described in the DT.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-08-06 10:09:25 +05:30
Inochi Amaoto
f536e0b02e gitignore: allow gitignore to ignore most dot file
Nowadays, most of the editor use files or directories begin with dot to
store some settings. So let git ignore these files and directories to
reduce potential mistakes.

Add dot match to ignore any editor file and there are two exceptions:
- .gitignore
- .clang-format

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-08-06 10:07:57 +05:30
Anup Patel
c2e602707d lib: utils/reset: Remove SiFive Test reset driver
The functionality of SiFive Test reset driver is easily available
through Syscon reset driver so let us remove the SiFive Test driver.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-07-31 14:09:24 +05:30
Anup Patel
4a344a9b4c lib: utils/reset: Add syscon based reboot and poweroff
Let us have common FDT based reset driver for syscon reboot and
poweroff. The device tree bindings for syscon reboot and poweroff
are already available in the Linux kernel sources.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-31 14:09:21 +05:30
Anup Patel
f21d8f7d59 lib: utils/regmap: Add simple FDT based syscon regmap driver
Let us add a simple FDT based system regmap driver which follows the
device tree bindings already defined in the Linux kernel.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-31 14:09:13 +05:30
Anup Patel
8e97275d97 lib: utils/regmap: Add simple FDT based regmap framework
We add a simple FDT based regmap framework which is built on top of
generic regmap library. The phandle of FDT regmap DT node is treated
as unique regmap ID. The FDT based regmap drivers will be probed
on-demand from fdt_regmap_get_by_phandle() and fdt_regmap_get()
called by the regmap client drivers.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-31 14:09:10 +05:30
Anup Patel
14a35b0e0e lib: utils/regmap: Add generic regmap access library
We add generic regmap access library which is independent of
hardware description format (FDT or ACPI). The OpenSBI platform
support or regmap drivers can register regmap instances which
can be discovered by different regmap clients based on the
unique ID of regmap instances.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-31 14:09:08 +05:30
Anup Patel
44c5151293 include: sbi_utils: Remove driver pointer from struct i2c_adapter
The "driver" pointer in struct i2c_adapter is not used anywhere
so let us remove it.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-31 14:09:06 +05:30
Xiang W
5e20d25f19 include: sbi: fix CSR define of mseccfg
Because the CSR names in the spec are mseccfg and mseccfgh. Remove
CSR_MSECCFG_LOWER and CSR_MSECCFG_UPPER and directly define
CSR_MSECCFG and CSR_MSECCFGH.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-31 11:51:49 +05:30
Andrew Jones
e05a9cfefc lib: sbi: Update system suspend to spec
commit 68e66106120f ("SUSP: Add SBI_ERR_DENIED") of the SBI spec adds
a new error code, SBI_ERR_DENIED, which is returned when entry criteria
has not be meant. Update the system suspend implementation to return
this error when it has detected that not all harts are in the STOPPED
state.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-31 11:45:11 +05:30
Heinrich Schuchardt
0e2111e12c libfdt: fix SPDX license identifiers
License identifiers should be machine readable.

According to the SPDX v2.3.0 specification annex E parentheses are not
used in the SPDX identifier field when specifying multiple licenses [1].

[1] https://spdx.github.io/spdx-spec/v2.3/using-SPDX-short-identifiers-in-source-files/

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-31 11:40:49 +05:30
Himanshu Chauhan
0ad866067d lib: sbi: Map/Unmap debug console shared memory buffers
With Smepmp enabled, it is necessary for shared memory from
S/U mode to be mapped/unmapped before and after read/write
of the memory region. This patch maps the debug console
shared memory before accessing it.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-13 12:44:22 +05:30
Himanshu Chauhan
6e44ef686a lib: sbi: Add functions to map/unmap shared memory
When Smepmp is enabled, M-mode will need to map/unmap the
shared memory before it can read/write to it. This patch
adds functions to create dynamic short-lived mappings.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-13 12:44:02 +05:30
Himanshu Chauhan
5dd8db5b10 lib: sbi: Add support for Smepmp
- If Smepmp is enabled, the access flags of an entry are determined based on
  truth table defined in Smepmp.
- First PMP entry (index 0) is reserved.
- Existing boot PMP entries start from index 1.
- Since enabling Smepmp revokes the access privileges of the M-mode software
  on S/U-mode region, first PMP entry is used to map/unmap the shared memory
  between M and S/U-mode. This allows a temporary access window for the M-mode
  software to read/write to S/U-mode memory region.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-13 12:42:09 +05:30
Himanshu Chauhan
f3fdd041ac lib: sbi: Change the order of PMP initialization
Configure PMP at last when all other initializations have been done.
Because if SMEPMP is detected, M-mode access to the S/U space will be
rescinded.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-13 12:42:06 +05:30
Himanshu Chauhan
4a42a2347c lib: sbi: Grant SU R/W/X permissions to whole memory
Since pmp entries have implicit priority on index, previous entries will
deny access to SU on M-mode region. Also, M-mode will not have access to
SU region while previous entries will allow access to M-mode regions.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-13 12:27:50 +05:30
Himanshu Chauhan
d72f5f1747 lib: utils: Add detection of Smepmp from ISA string in FDT
- Add function to parse ISA string in FDT.
- Set Smepmp feature bit in extensions if "smepmp" string is found in ISA string.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-13 12:12:58 +05:30
Himanshu Chauhan
cbcfc7b10c lib: sbi: Add smepmp in hart extensions
- Add Smepmp as extension in sbi_hart_extensions enum
- Return "smepmp" string for Smepmp extension from sbi_hart_extension_id2string

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-13 12:12:16 +05:30
Himanshu Chauhan
6c202c5efd include: sbi: Add Smepmp specific access flags for PMP entries
Smepmp specification defines a truth table based on which the access is allowed to
different modes. This patch adds different flags based on this truth table.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-13 12:11:10 +05:30
Himanshu Chauhan
1c099c4f36 lib: sbi: Add functions to manipulate PMP entries
- Add a function to disable a given PMP entry.
- Add a function to check if a given entry is disabled.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-13 12:10:39 +05:30
Himanshu Chauhan
c3b98c610b include: sbi: Add macro definitions for mseccfg CSR
- Add macros for Machine Security Configuration (mseccfg) CSR
- Add macros to access/manipulate bits in msecfg CSR

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-13 12:09:34 +05:30
Anup Patel
ea6533ada8 lib: utils/gpio: Fix RV32 compile error for designware GPIO driver
Currently, we see following compile error in the designeware GPIO driver
for RV32 systems:

lib/utils/gpio/fdt_gpio_designware.c:115:20: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
  115 |         chip->dr = (void *)addr + (bank * 0xc);
      |                    ^
lib/utils/gpio/fdt_gpio_designware.c:116:21: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
  116 |         chip->ext = (void *)addr + (bank * 4) + 0x50;

We fix the above error using an explicit type-cast to 'unsigned long'.

Fixes: 7828eebaaa ("gpio/desginware: add Synopsys DesignWare APB GPIO support")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-12 11:22:03 +05:30
Xiang W
a73982d737 lib: sbi: Fix missing '\0' when buffer szie equal 1
Fix special case: sbi_snprintf(out, out_len, ...) when out_len equal
1, The previous code will not fill the buffer with any char.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 10:37:43 +05:30
Xiang W
ff43168137 lib: sbi: Fix timing of clearing tbuf
A single scan of the format char may add multiple characters to the
tbuf, causing a buffer overflow. You should check if tbuf is full in
printc so that it does not cause a buffer overflow.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 10:37:16 +05:30
Xiang W
cc89fa7b54 lib: sbi: Fix printc
Because *out needs to reserve a byte to hold '\0', no more characters
should be added to the buffer when *out has one byte left, and the
buffer size *out_len should not be modified. this patch prevents
the correction of *out_len when *out_len is 1.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 10:02:27 +05:30
Xiang W
3b6fcddceb lib: sbi: Simplify prints
When doing width = width - strlen(string) in prints there is no need
to consider the case that witdh may be less than 0. This is because
the code to do filling needs to be executed under the condition that
width > 0.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 10:02:06 +05:30
Xiang W
c6ee5ae5a4 lib: sbi: Fix printi
Fix two bug:
> printf("%#08x", 0x123); /* print 0000x123 */
> printf("%#x", 0); /* print 0x0 */

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 10:01:43 +05:30
Xiang W
fe0828142f lib: sbi: print add 'o' type
Add o type for print to print octal numbers

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 09:59:22 +05:30
Xiang W
05cbb6e908 lib: sbi: implifying the parameters of printi
The information of sg/b/letbase can be obtained by the type character,
simplifying the parameter by passing the type directly.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 09:58:52 +05:30
Xiang W
458fa74266 lib: sbi: Add ' ' '\'' flags for print
The space flag is used to add a space before positive numbers, and
apostrophe is used to print the thousand separator. Add code to
ignore these two flags

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 09:58:00 +05:30
Xiang W
40dac06e3c lib: sbi: Add '+' flags for print
Adds + flags for print, prefixing positive numbers with + when this
flags is present

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 09:57:48 +05:30
Xiang W
35ef182690 lib: sbi: print not fill '0' when left-aligned
Left alignment and padding '0' should not exist at the same time,
this patch skips padding.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 09:48:49 +05:30
Xiang W
6053917626 lib: sbi: Fix how print gets flags
The flags for print should be able to appear in any order. The
previous code required the order to be fixed.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-12 09:39:38 +05:30
Ley Foon Tan
976895c57e lib: sbi: Fix Priv spec version for [m|s]counteren and mcountinhibit CSRs
Fix Priv spec version typo in commit d4b563c881 ("lib: sbi: Remove MCOUNTEREN
and SCOUNTEREN hart features").

At least Priv spec v1.11 is required for [m|s]counteren and mcountinhibit CSRs.

Fixes: d4b563c881 ("lib: sbi: Remove MCOUNTEREN and SCOUNTEREN hart features")
Signed-off-by: Ley Foon Tan <leyfoon.tan@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-09 11:08:35 +05:30
Anup Patel
5359fc6955 lib: sbi: Rename hart_pmu_get_allowed_bits() function
The hart_pmu_get_allowed_bits() function detects implemented bits
of mhpm counters so let us rename this function accordingly.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-09 11:06:30 +05:30
Anup Patel
72b9c8ff89 lib: sbi: Alphabetically sort HART ISA extensions
Let us follow alphabetical order for HART ISA extension so that
it is simpler to maintain.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-09 11:06:28 +05:30
Anup Patel
669089c5f2 lib: sbi: Add Zihpm as a HART ISA extension
Recently ratified Zihpm ISA extension covers all [m]hpm* CSRs
so we add Zihpm as a HART ISA extension in OpenSBI.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-09 11:06:26 +05:30
Anup Patel
1a398d9faa lib: sbi: Add Zicntr as a HART ISA extension
Recently ratified Zicntr ISA extension covers cycle, time and
instret CSRs so we replace the "time" ISA extension with "zicntr"
ISA extension in OpenSBI.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-09 11:06:24 +05:30
Anup Patel
c6a35733b7 lib: utils: Fix sbi_hartid_to_scratch() usage in ACLINT drivers
The cold_init() functions of ACLINT drivers should skip the HART
if sbi_hartid_to_scratch() returns NULL because we might be dealing
with a HART that is disabled in the device tree.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-07-09 11:04:57 +05:30
Ben Dooks
7828eebaaa gpio/desginware: add Synopsys DesignWare APB GPIO support
Add a driver for the Synopsys DesignWare APB GPIO IP block found in many
SoCs.

Signed-off-by: Ben Dooks <ben.dooks@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-07 10:04:59 +05:30
Heinrich Schuchardt
eb736a5118 lib: sbi_pmu: Avoid out of bounds access
On a misconfigured system we could access phs->active_events[] out of
bounds. Check that num_hw_ctrs is less or equal SBI_PMU_HW_CTR_MAX.

Addresses-Coverity-ID: 1566113 ("Out-of-bounds read")
Addresses-Coverity-ID: 1566114 ("Out-of-bounds write")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-05 09:29:24 +05:30
Gianluca Guida
0907de38db lib: sbi: fix comment indent
Use tabs rather than spaces.

Signed-off-by: Gianluca Guida <gianluca@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-07-05 09:25:32 +05:30
Anup Patel
2552799a1d include: Bump-up version to 1.3
This patch updates OpenSBI version to 1.3 as part of
release preparation.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-06-23 11:01:49 +05:30
Gianluca Guida
8bd666a25b lib: sbi: check A2 register in ecall_dbcn_handler.
Do not ignore register A2 (high bits of physical address) in the dbcn
handler (RV64).

Signed-off-by: Gianluca Guida <gianluca@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-06-23 08:46:07 +05:30
Guo Ren
27c957a43b lib: reset: Move fdt_reset_init into generic_early_init
The fdt_reset_thead driver needs to modify the __reset_thead_csr_stub
text region for the secondary harts booting. After that, the
sbi_hart_pmp_configure may lock down the text region with M_READABLE &
M_EXECUTABLE attributes in the future. Currently, the M_READABLE &
M_EXECUtABLE have no effect on m-mode, the L-bit in pmpcfg csr is
useless for the current opensbi scenario. See:

Priv-isa-spec 3.7.1.2. Locking and Privilege Mode
When the L bit is clear, any M-mode access matching the PMP entry will
succeed; the R/W/X permissions apply only to S and U modes.

That's why current fdt_reset_thead could still work well after commit:
230278dcf1 ("lib: sbi: Add separate entries for firmware RX and RW
regions"). So this patch fixes up a fake bug for the M-mode permission
setting of the future.

Fixes: 230278dcf1 ("lib: sbi: Add separate entries for firmware RX and RW regions")
Link: http://lists.infradead.org/pipermail/opensbi/2023-June/005176.html
Reported-by: Jessica Clarke <jrtc27@jrtc27.com>
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-06-21 11:12:42 +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
Alexandre Ghiti
8153b2622b platform/lib: Set no-map attribute on all PMP regions
This reverts commit 6966ad0abe ("platform/lib: Allow the OS to map the
regions that are protected by PMP").

It was thought at the time of this commit that allowing the kernel to map
PMP protected regions was safe but it is actually not: for example, the
hibernation process will try to access any linear mapping page and then
will fault on such mapped PMP regions [1]. Another issue is that the
device tree specification [2] states that a !no-map region must be
declared as EfiBootServicesData/Code in the EFI memory map which would make
the PMP protected regions reclaimable by the kernel. And to circumvent
this, RISC-V edk2 diverges from the DT specification to declare those
regions as EfiReserved.

The no-map attribute was removed to allow the kernel to use hugepages
larger than 2MB to map the linear mapping to improve the performance but
actually a recent talk from Mike Rapoport [3] stated that the
performance benefit was marginal.

For all those reasons, let's mark all the PMP protected regions as "no-map".

[1] https://lore.kernel.org/linux-riscv/CAAYs2=gQvkhTeioMmqRDVGjdtNF_vhB+vm_1dHJxPNi75YDQ_Q@mail.gmail.com/
[2] "3.5.4 /reserved-memory and UEFI" https://github.com/devicetree-org/devicetree-specification/releases/download/v0.4-rc1/devicetree-specification-v0.4-rc1.pdf
[3] https://lwn.net/Articles/931406/

Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-06-15 18:27:17 +05:30
Anup Patel
932be2cde1 README.md: Improve project copyright information
Over-time a lot of organizations and individuals have contributed to
the OpenSBI project so let us add copyright RISC-V International to
respect the contributions from all RISC-V members.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-14 11:26:06 +05:30
Anup Patel
524feec7b7 docs: Add OpenSBI logo and use it in the top-level README.md
We do have an official OpenSBI logo which was designed few months ago
and was also approved by RISC-V International. Lets add this logo
under docs and also use it in the top-level README.md

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-14 11:26:04 +05:30
Anup Patel
355796c5bc lib: utils/irqchip: Use scratch space to save per-HART IMSIC pointer
Instead of using a global array indexed by hartid, we should use
scratch space to save per-HART IMSIC pointer and IMSIC file number.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-06 16:01:14 +05:30
Anup Patel
1df52fa7e8 lib: utils/irqchip: Don't check hartid in imsic_update_hartid_table()
The imsic_map_hartid_to_data() already checks hartid before using
so we don't need to check in imsic_update_hartid_table().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 16:51:07 +05:30
Anup Patel
b3594ac1d1 lib: utils/irqchip: Use scratch space to save per-HART PLIC pointer
Instead of using a global array indexed by hartid, we should use
scratch space to save per-HART PLIC pointer and PLIC context numbers.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 16:50:56 +05:30
Anup Patel
f0516beae0 lib: utils/timer: Use scratch space to save per-HART MTIMER pointer
Instead of using a global array indexed by hartid, we should use
scratch space to save per-HART MTIMER pointer.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 16:46:50 +05:30
Anup Patel
acbd8fce9e lib: utils/ipi: Use scratch space to save per-HART MSWI pointer
Instead of using a global array indexed by hartid, we should use
scratch space to save per-HART MSWI pointer.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 16:02:59 +05:30
Anup Patel
3c1c972cb6 lib: utils/fdt: Use heap in FDT domain parsing
Let's use heap allocation in FDT domain parsing instead of using
a fixed size global array.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:59:35 +05:30
Anup Patel
7e5636ac37 lib: utils/timer: Use heap in ACLINT MTIMER driver
Let's use heap allocation in ACLINT MTIMER driver instead of using
a fixed size global array.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:58:42 +05:30
Anup Patel
30137166c6 lib: utils/irqchip: Use heap in PLIC, APLIC and IMSIC drivers
Let's use heap allocation in PLIC, APLIC, and IMSIC irqchip drivers
instead of using a fixed size global array.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:57:58 +05:30
Anup Patel
5a8cfcdf19 lib: utils/ipi: Use heap in ACLINT MSWI driver
Let's use heap allocation in ACLINT MSWI driver instead of using
a fixed size global array.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:55:56 +05:30
Anup Patel
903e88caaf lib: utils/i2c: Use heap in DesignWare and SiFive I2C drivers
Let's use heap allocation in DesignWare and SiFive I2C drivers
instead of using a fixed size global array.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:55:45 +05:30
Anup Patel
fa5ad2e6f9 lib: utils/gpio: Use heap in SiFive and StartFive GPIO drivers
Let's use heap allocation in SiFive and Starfive GPIO drivers
instead of using a fixed size global array.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:55:29 +05:30
Anup Patel
66daafe3ba lib: sbi: Use scratch space to save per-HART domain pointer
Instead of using a global array indexed by hartid, we should use
scratch space to save per-HART domain pointer.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:55:21 +05:30
Anup Patel
ef4542dc13 lib: sbi: Use heap for root domain creation
Let's use heap allocation in root domain creation instead of using
a fixed size global array.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:50:33 +05:30
Anup Patel
bbff53fe3b lib: sbi_pmu: Use heap for per-HART PMU state
Instead of using a global array for per-HART PMU state, we should
use heap to on-demand allocate per-HART PMU state when the HART
is initialized in cold boot or warm boot path.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:48:43 +05:30
Anup Patel
2a04f70373 lib: sbi: Print scratch size and usage at boot time
The scratch space being a scarce resource so let us print it's
size and usage at boot time.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:46:22 +05:30
Anup Patel
40d36a6673 lib: sbi: Introduce simple heap allocator
We provide simple heap allocator to manage the heap space provided
by OpenSBI firmware and platform.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-06-05 15:46:09 +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
Anup Patel
aad7a37705 include: sbi_scratch: Add helper macros to access data type
Reading and writing a data type in scratch space is a very common
use-case so let us add related helper macros in sbi_scratch.h.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-06-05 15:42:50 +05:30
Andrew Jones
bdde2ecd27 lib: sbi: Align system suspend errors with spec
The spec says sbi_system_suspend() will return SBI_ERR_INVALID_PARAM
when "sleep_type is reserved or is platform-specific and unimplemented"
and SBI_ERR_NOT_SUPPORTED when sleep_type "is not reserved and is
implemented, but the platform does not support it due to one or more
missing dependencies." Ensure SBI_ERR_INVALID_PARAM is returned for
reserved sleep types and that the system suspend driver can choose
which of the two error types to return itself by returning an error
from its check function rather than a boolean.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-06-04 15:18:40 +05:30
Heinrich Schuchardt
df75e09956 lib: utils/ipi: buffer overrun aclint_mswi_cold_init
The parameter checks in aclint_mswi_cold_init() don't guard against a
buffer overrun.

mswi_hartid2data is defined as an array of SBI_HARTMASK_MAX_BITS entries.
The current check allows

    mswi->hart_count = ACLINT_MSWI_MAX_HARTS
    mswi->first_hartid = SBI_HARTMASK_MAX_BITS - 1.

With these values mswi_hartid2data will be accessed at index

    SBI_HARTMASK_MAX_BITS + SBI_HARTMASK_MAX_BITS - 2.

We have to check the sum of mswi->first_hartid and mswi->hart_count.

Furthermore mswi->hart_count = 0 would not make much sense.

Addresses-Coverity-ID: 1529705 ("Out-of-bounds write")
Fixes: 5a049fe1d6 ("lib: utils/ipi: Add ACLINT MSWI library")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-06-04 15:13:50 +05:30
Xiang W
122f2260b3 lib: utils: Improve fdt_timer
Remove dummy driver. Optimize fdt_timer_cold_init to exit the
loop early.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-26 12:47:22 +05:30
Xiang W
9a0bdd0c84 lib: utils: Improve fdt_ipi
Remove dummy driver. Optimize fdt_ipi_cold_init to exit the loop
early.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-26 12:43:25 +05:30
Xiang W
264d0be1fd lib: utils: Improve fdt_serial_init
A final check of all DT nodes does not necessarily find a match, so
SBI_ENODEV needs to be returned. Optimize removal of current_driver.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-26 12:37:25 +05:30
Xiang W
8b99a7f7d8 lib: sbi: Fix return of sbi_console_init
console is not a required peripheral. So it should return success when
the console does not exist.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-26 12:36:54 +05:30
Filip Filmar
d4c46e0ff1 Makefile: Dereference symlinks on install
Adds the `-L` flag (follow symlinks) to the `cp` commands used to
install `libsbi.a` and `include/sbi/*`.

This should make no difference in regular compilation. However,
it does make a difference when compiling with bazel.  Namely,
bazel's sandboxing will turn all the source files into symlinks.
After installation with `cp` the destination files will be
symlinks pointing to the sandbox symlinks. As the sandbox files
are removed when compilation ends, the just-copied symlinks
become dangling symlinks.

The resulting include files will be
unusable due to the dangling symlink issues. Adding `-L` when
copying ensures that the files obtained by executing the `install`
targets are always dereferenced to files, rather than symlinks,
eliminating this issue.

Signed-off-by: Filip Filmar <fmil@google.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-22 08:52:57 +05:30
Andrew Jones
33f1722f2b lib: sbi: Document sbi_ecall_extension members
With the introduction of the register_extensions callback the
range members (extid_start and extid_end) may now change and it
has become a bit subtle as to when a probe function should be
implemented. Document all the members and their relationship to
the register_extensions callback.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-21 16:54:02 +05:30
Andrew Jones
c3e31cbf36 lib: sbi: Remove 0/1 probe implementations
When a probe implementation just returns zero for not available and
one for available then we don't need it, as the extension won't be
registered at all if it would return zero and the Base extension
probe function will already set out_val to 1 if not probe function
is implemented. Currently all probe functions only return zero or
one, so remove them all.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-21 16:54:00 +05:30
Xiang W
767b5fc418 lib: sbi: Optimize probe of srst/susp
No need to do a fully comprehensive count, just find a supported reset
or suspend type

Signed-off-by: Xiang W <wxjstz@126.com>
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-21 16:53:38 +05:30
Andrew Jones
8b952d4fcd lib: sbi: Only register available extensions
When an extension implements a probe function it means there's a
chance that the extension is not available. Use this function in the
register_extensions callback to determine if the extension should be
registered at all. Where the probe implementation is simple, just
open code the check.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-21 16:53:02 +05:30
Andrew Jones
042f0c3ea2 lib: sbi: pmu: Remove unnecessary probe function
The absence of a probe implementation means that the extension is
always available. Remove the implementation for the PMU extension,
which does no checking, and indeed even has a comment saying it's
always available.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-21 16:30:29 +05:30
Andrew Jones
e307ba7d46 lib: sbi: Narrow vendor extension range
The vendor extension ID range is large, but at runtime at most
a single ID will be available. Narrow the range in the
register_extensions callback. After narrowing, we no longer
need to check that the extension ID is correct in the other
callbacks, as those callbacks will never be invoked with
anything other than the single ID.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-21 16:29:46 +05:30
Andrew Jones
f58c14090f lib: sbi: Introduce register_extensions extension callback
Rather than registering all extensions on their behalf in
sbi_ecall_init(), introduce another extension callback and
invoke that instead. For now, implement each callback by
simply registering the extension, which means this patch
has no intended functional change. In later patches, extension
callbacks will be modified to choose when to register and to
possibly narrow the extension ID range prior to registering.
When an extension range needs to remove IDs, leaving gaps, then
multiple invocations of sbi_ecall_register_extension() may be
used. In summary, later patches for current extensions and the
introductions of future extensions will use the new callback to
ensure that only valid extension IDs from the initial range,
which are also available, will be registered.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-21 16:27:38 +05:30
Xiang W
dc1c7db05e lib: sbi: Simplify BITS_PER_LONG definition
No need to use #elif ladder when defining BITS_PER_LONG.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-11 12:56:56 +05:30
Xiang W
6bc02dede8 lib: sbi: Simplify sbi_ipi_process remove goto
Simplify sbi_ipi_process() by removing goto statement.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-11 12:46:42 +05:30
Xiang W
4e3353057a lib: sbi: Remove unnecessary semicolon
We have redundant semicolon at quite a few places so let's remove it.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-05-11 12:31:34 +05:30
Tan En De
7919530308 lib: sbi: Add debug print when sbi_pmu_init fails
Since sbi_pmu_init is called after sbi_console_init,
the sbi_printf can be called when sbi_pmu_init fails.

Signed-off-by: Tan En De <ende.tan@starfivetech.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2023-04-20 14:19:44 +05:30
Anup Patel
f5dfd99139 lib: sbi: Don't check SBI error range for legacy console getchar
The legacy console getchar SBI call returns character value in
the sbiret.error field so the "SBI_SUCCESS < ret" check in
sbi_ecall_handler() results in unwanted error prints for the
legacy console getchar SBI call. Let's suppress these unwanted
error prints.

Fixes: 67b2a40892 ("lib: sbi: sbi_ecall: Check the range of
SBI error")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-04-17 09:48:13 +05:30
Alexandre Ghiti
674e0199b2 lib: sbi: Fix counter index calculation for SBI_PMU_CFG_FLAG_SKIP_MATCH
As per the SBI specification, we should "unconditionally select the first
counter from the set of counters specified by the counter_idx_base and
counter_idx_mask", so implement this behaviour.

Suggested-by: Atish Patra <atishp@atishpatra.org>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2023-04-17 09:26:28 +05:30
Alexandre Ghiti
bdb3c42bca lib: sbi: Do not clear active_events for cycle/instret when stopping
Those events are enabled by default and should not be reset afterwards
since when using SBI_PMU_CFG_FLAG_SKIP_MATCH, it leads to unaccessible
counters after the first use.

Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2023-04-17 09:26:26 +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
Lad Prabhakar
eeab500a65 platform: generic: andes/renesas: Add SBI EXT to check for enabling IOCP errata
I/O Coherence Port (IOCP) provides an AXI interface for connecting
external non-caching masters, such as DMA controllers. The accesses
from IOCP are coherent with D-Caches and L2 Cache.

IOCP is a specification option and is disabled on the Renesas RZ/Five
SoC (which is based on Andes AX45MP core) due to this reason IP blocks
using DMA will fail.

As a workaround for SoCs with IOCP disabled CMO needs to be handled by
software. Firstly OpenSBI configures the memory region as
"Memory, Non-cacheable, Bufferable" and passes this region as a global
shared dma pool as a DT node. With DMA_GLOBAL_POOL enabled all DMA
allocations happen from this region and synchronization callbacks are
implemented to synchronize when doing DMA transactions.

SBI_EXT_ANDES_IOCP_SW_WORKAROUND checks if the IOCP errata should be
applied to handle cache management.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
2023-04-14 17:35:04 +05:30
Xiang W
bf40e07f6f lib: sbi: Optimize sbi_tlb queue waiting
When tlb_fifo is full, it will wait and affect the ipi update to
other harts. This patch is optimized.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-04-14 13:45:30 +05:30
Xiang W
80078ab088 sbi: tlb: Simplify to tlb_process_count/tlb_process function
tlb_process_count is only used when count=1, so refactor to
tlb_process_once and add the return value to be reused in
tlb_process

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-04-13 13:49:57 +05:30
Xiang W
24dde46b8d lib: sbi: Optimize sbi_ipi
The original sbi_ipi will be processed by hart by hart, after optimization,
send ipi first and finally wait together.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-04-13 12:44:50 +05:30
Xiang W
66fa925353 lib: sbi: Optimize sbi_tlb
Originally, the process and sync of sbi_tlb need to wait for each other.
Evasion by atomic addition and subtraction.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-04-13 12:37:55 +05:30
Heinrich Schuchardt
2868f26131 lib: utils: fdt_fixup: avoid buffer overrun
fdt_reserved_memory_fixup() uses filtered_order[PMP_COUNT]. The index
must not reach PMP_COUNT.

Fixes: 199189bd1c ("lib: utils: Mark only the largest region as reserved in FDT")
Addresses-Coverity-ID: 1536994 ("Out-of-bounds write")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-04-07 11:22:25 +05:30
Gabriel Somlo
ee016a7bb0 docs: Correct FW_JUMP_FDT_ADDR calculation example
When using `PLATFORM=generic` defaults, the kernel is loaded at
`FW_JUMP_ADDR`, and the FDT is loaded at `FW_JUMP_FDT_ADDR.

Therefore, the maximum kernel size before `FW_JUMP_FDT_ADDR` must
be increased is `$(( FW_JUMP_FDT_ADDR - FW_JUMP_ADDR ))`.

The example calculation assumes `rv64`, and is wrong to boot
(off by 0x200000). Fix it and update it for the general case.

Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-04-07 11:16:05 +05:30
Yu Chien Peter Lin
edc9914392 lib: sbi_pmu: Align the event type offset as per SBI specification
The bits encoded in event_idx[19:16] indicate the event type, with
an offset of 16 instead of 20.

Fixes: 13d40f21d5 ("lib: sbi: Add PMU support")
Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-04-07 10:06:59 +05:30
Sunil V L
91767d093b lib: sbi: Print the CPPC device name
If CPPC device is registered by the platform, print its name.

Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-04-07 09:36:42 +05:30
Sunil V L
33caae8069 lib: sbi: Implement SBI CPPC extension
Implement SBI CPPC extension. This extension is only available when
OpenSBI platform provides a CPPC device to generic library.

Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-04-07 09:36:01 +05:30
Sunil V L
45ba2b203c include: Add defines for SBI CPPC extension
Add SBI CPPC extension related defines to the
SBI ecall interface header.

Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-04-07 09:35:06 +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
Anup Patel
30b9e7ee14 lib: sbi_hsm: Fix sbi_hsm_hart_start() for platform with hart hotplug
It possible that a platform supports hart hotplug (i.e. both hart_start
and hart_stop callbacks available) and all harts are start simultaneously
at platform boot-time. In this situation, the sbi_hsm_hart_start() will
call hsm_device_hart_start() for secondary harts at platform boot-time
which will fail because secondary harts were already started.

To fix above, we call hsm_device_hart_start() from sbi_hsm_hart_start()
only when entry_count is same as init_count for the secondary hart.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-04-06 18:48:19 +05:30
Anup Patel
f64dfcd2b5 lib: sbi: Introduce sbi_entry_count() function
We introduce sbi_entry_count() function which counts the number
of times a HART enters OpenSBI via cold-boot or warm-boot path.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-04-06 18:48:15 +05:30
Xiang W
73ab11dfb0 lib: sbi: Fix how to check whether the domain contains fw_region
Because firmware is split into rw/rx segments, it cannot be recorded
by a root_fw_region. This problem is solved by adding a flag
fw_region_inited to sbi_domain.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-04-06 16:14:35 +05:30
Xiang W
ed88a63b90 lib: sbi_scratch: Optimize the alignment code for alloc size
Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-04-06 16:00:45 +05:30
Evgenii Shatokhin
c6a092cd80 lib: sbi: Clear IPIs before init_warm_startup in non-boot harts
Since commit 50d4fde1c5 ("lib: Remove redundant sbi_platform_ipi_clear()
calls"), the IPI sent from the boot hart in wake_coldboot_harts() is not
cleared in the secondary harts until they reach sbi_ipi_init(). However,
sbi_hsm_init() and sbi_hsm_hart_wait() are called earlier, so a secondary
hart might enter sbi_hsm_hart_wait() with an already pending IPI.

sbi_hsm_hart_wait() makes sure the hart leaves the loop only when it is
actually ready, so a pending unrelated IPI should not cause safety issues.
However, it might be inefficient on certain hardware, because it prevents
"wfi" from stalling the hart even if the hardware supports this, making the
hart needlessly spin in a "busy-wait" loop.

This behaviour can be observed, for example, in a QEMU VM (QEMU 7.2.0) with
"-machine virt" running a Linux guest. Inserting delays in
sbi_hsm_hart_start() allows reproducing the issue more reliably.

The comment in wait_for_coldboot() suggests that the initial IPI is needed
in the warm resume path, so let us clear it before init_warm_startup()
only.

To do this, sbi_ipi_raw_clear() was created similar to sbi_ipi_raw_send().

Signed-off-by: Evgenii Shatokhin <e.shatokhin@yadro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-10 14:13:40 +05:30
Evgenii Shatokhin
e8e9ed3790 lib: sbi: Set the state of a hart to START_PENDING after the hart is ready
When a boot hart executes sbi_hsm_hart_start() to start a secondary hart,
next_arg1, next_addr and next_mode for the latter are stored in the scratch
area after the state has been set to SBI_HSM_STATE_START_PENDING.

The secondary hart waits in the loop with wfi() in sbi_hsm_hart_wait() at
that time. However, "wfi" instruction is not guaranteed to wait for an
interrupt to be received by the hart, it is just a hint for the CPU.
According to RISC-V Privileged Architectures spec. v20211203, even an
implementation of "wfi" as "nop" is legal.

So, the secondary might leave the loop in sbi_hsm_hart_wait() as soon as
its state has been set to SBI_HSM_STATE_START_PENDING, even if it got no
IPI or it got an IPI unrelated to sbi_hsm_hart_start(). This could lead to
the following race condition when booting Linux, for example:

  Boot hart (#0)                        Secondary hart (#1)
  runs Linux startup code               waits in sbi_hsm_hart_wait()

  sbi_ecall(SBI_EXT_HSM,
            SBI_EXT_HSM_HART_START,
            ...)
  enters sbi_hsm_hart_start()
  sets state of hart #1 to START_PENDING
                                        leaves sbi_hsm_hart_wait()
                                        runs to the end of init_warmboot()
                                        returns to scratch->next_addr
                                        (next_addr can be garbage here)

  sets next_addr, etc. for hart #1
  (no good: hart #1 has already left)

  sends IPI to hart #1
  (no good either)

If this happens, the secondary hart jumps to a wrong next_addr at the end
of init_warmboot(), which leads to a system hang or crash.

To reproduce the issue more reliably, one could add a delay in
sbi_hsm_hart_start() after setting the hart's state but before sending
IPI to that hart:

    hstate = atomic_cmpxchg(&hdata->state, SBI_HSM_STATE_STOPPED,
                            SBI_HSM_STATE_START_PENDING);
    ...
  + sbi_timer_mdelay(10);
    init_count = sbi_init_count(hartid);
    rscratch->next_arg1 = arg1;
    rscratch->next_addr = saddr;

The issue can be reproduced, for example, in a QEMU VM with '-machine virt'
and 2 or more CPUs, with Linux as the guest OS.

This patch moves writing of next_arg1, next_addr and next_mode for the
secondary hart before setting its state to SBI_HSM_STATE_START_PENDING.

In theory, it is possible that two or more harts enter sbi_hsm_hart_start()
for the same target hart simultaneously. To make sure the current hart has
exclusive access to the scratch area of the target hart at that point, a
per-hart 'start_ticket' is used. It is initially 0. The current hart tries
to acquire the ticket first (set it to 1) at the beginning of
sbi_hsm_hart_start() and only proceeds if it has successfully acquired it.

The target hart reads next_addr, etc., and then the releases the ticket
(sets it to 0) before calling sbi_hart_switch_mode(). This way, even if
some other hart manages to enter sbi_hsm_hart_start() after the ticket has
been released but before the target hart jumps to next_addr, it will not
cause problems.

atomic_cmpxchg() already has "acquire" semantics, among other things, so
no additional barriers are needed in hsm_start_ticket_acquire(). No hart
can perform or observe the update of *rscratch before setting of
'start_ticket' to 1.

atomic_write() only imposes ordering of writes, so an explicit barrier is
needed in hsm_start_ticket_release() to ensure its "release" semantics.
This guarantees that reads of scratch->next_addr, etc., in
sbi_hsm_hart_start_finish() cannot happen after 'start_ticket' has been
released.

Signed-off-by: Evgenii Shatokhin <e.shatokhin@yadro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-10 14:12:43 +05:30
Evgenii Shatokhin
d56049e299 lib: sbi: Refactor the calls to sbi_hart_switch_mode()
Move them into sbi_hsm_hart_start_finish() and sbi_hsm_hart_resume_finish()
to make them easier to manage.

This will be used by subsequent patches.

Suggested-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Evgenii Shatokhin <e.shatokhin@yadro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-10 14:00:36 +05:30
Mayuresh Chitale
c631a7da27 lib: sbi_pmu: Add hartid parameter PMU device ops
Platform specific firmware event handler may leverage the hartid to program
per hart specific registers for a given counter.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-10 14:00:33 +05:30
Mayuresh Chitale
57d3aa3b0d lib: sbi_pmu: Introduce fw_counter_write_value API
Add fw_counter_write_value API for platform specific firmware events
which separates setting the counter's initial value from starting the
counter. This is required so that the fw_event_data array can be reused
to save the event data received.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-10 14:00:30 +05:30
Mayuresh Chitale
641d2e9f38 lib: sbi_pmu: Use dedicated event code for platform firmware events
For all platform specific firmware event operations use the dedicated
event code (0xFFFF) when matching against the input firmware event.
Furthermore save the real platform specific firmware event code received as
the event data for future use.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-10 14:00:28 +05:30
Mayuresh Chitale
b51ddffcc0 lib: sbi_pmu: Update sbi_pmu dev ops
Update fw_event_validate_code, fw_counter_match_code and fw_counter_start
ops which used a 32 bit event code to use the 64 bit event data instead.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-10 14:00:26 +05:30
Mayuresh Chitale
548e4b4b28 lib: sbi_pmu: Rename fw_counter_value
Rename and reuse fw_counter_value array to save both the counter values
for the SBI firmware events and event data for the SBI platform specific
firmware events.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-03-10 14:00:24 +05:30
Mayuresh Chitale
60c358e677 lib: sbi_pmu: Reserve space for implementation specific firmware events
We reserve space for SBI implementation specific custom firmware
events which can be used by M-mode firmwares and HS-mode hypervisors
for their own use. This reserved space is intentionally large to
ensure that SBI implementation has enough space to accommodate
platform specific firmware events as well.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-10 14:00:22 +05:30
Mayuresh Chitale
51951d9e9a lib: sbi_pmu: Implement sbi_pmu_counter_fw_read_hi
To support 64 bit firmware counters on RV32 systems, we implement
sbi_pmu_counter_fw_read_hi() which returns the upper 32 bits of
the firmware counter value. On RV64 (or higher) systems, this
function will always return zero.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-10 14:00:07 +05:30
Mayuresh Chitale
1fe8dc9955 lib: sbi_pmu: add callback for counter width
This patch adds a callback to fetch the number of bits implemented for a
custom firmware counter. If the callback fails or is not implemented then
width defaults to 63.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-10 13:46:52 +05:30
Mayuresh Chitale
506144f398 lib: serial: Cadence: Enable compatibility for cdns,uart-r1p8
The Cadence driver does not use the RX byte status feature and hence can
be advertised to be compatible with cdns,uart-r1p8 as well.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-09 21:12:35 +05:30
Minda Chen
568ea49490 platform: starfive: add PMIC power ops in JH7110 visionfive2 board
add reboot and poweroff support. The whole reboot and shutdown
pm op includes shutdown jh7110 pmu device power domain
and access on board pmic register through I2C.

Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-09 21:11:20 +05:30
Minda Chen
e9d08bd99c lib: utils/i2c: Add minimal StarFive jh7110 I2C driver
Starfive JH7110 I2C IP is synopsys designware.
Minimum StarFIve I2C driver to read/send bytes over I2C bus.

This allows querying information and perform operation of onboard PMIC,
as well as power-off and reset.

Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-09 21:00:57 +05:30
Bin Meng
4b28afc98b make: Add a command line option for debugging OpenSBI
Add a new make command line option "make DEBUG=1" to prevent compiler
optimizations using -O2.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-01 09:23:17 +05:30
minda.chen
908be1b85c gpio/starfive: add gpio driver and support gpio reset
Add gpio driver and gpio reset function in Starfive
JH7110 SOC platform.

Signed-off-by: minda.chen <minda.chen@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-03-01 08:59:33 +05:30
Andrew Jones
5ccebf0a7e platform: generic: Add system suspend test
When the system-suspend-test property is present in the domain config
node as shown below, implement system suspend with a simple 5 second
delay followed by a WFI. This allows testing system suspend when the
low-level firmware doesn't support it.

  / {
    chosen {
      opensbi-domains {
          compatible = "opensbi,domain,config";
          system-suspend-test;
      };

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:50:51 +05:30
Andrew Jones
37558dccbe docs: Correct opensbi-domain property name
Replace the commas with dashes to correct the name.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:49:07 +05:30
Andrew Jones
7c964e279c lib: sbi: Implement system suspend
Fill the implementation of the system suspend ecall. A platform
implementation of the suspend callbacks is still required for this
to do anything.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:47:35 +05:30
Andrew Jones
c9917b6108 lib: sbi: Add system_suspend_allowed domain property
Only privileged domains should be allowed to suspend the entire
system. Give the root domain this property by default and allow
other domains to be given the property by specifying it in the
DT.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:45:28 +05:30
Andrew Jones
73623a0aca lib: sbi: Add system suspend skeleton
Add the SUSP extension probe and ecall support, but for now the
system suspend function is just a stub.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:43:52 +05:30
Andrew Jones
8a40306371 lib: sbi_hsm: Export some functions
A coming patch can make use of a few internal hsm functions if
we export them.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:40:21 +05:30
Andrew Jones
07673fc063 lib: sbi_hsm: Remove unnecessary include
Also remove a superfluous semicolon and add a blank line.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:38:55 +05:30
Andrew Jones
b1ae6ef33b lib: sbi_hsm: Move misplaced comment
While non-retentive suspend is not allowed for M-mode, the comment
at the top of sbi_hsm_hart_suspend() implied suspend wasn't allowed
for M-mode at all. Move the comment above the mode check which is
inside a suspend type is non-retentive check.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:38:00 +05:30
Andrew Jones
c88e039ec2 lib: sbi_hsm: Ensure errors are consistent with spec
HSM functions define when SBI_ERR_INVALID_PARAM should be returned.
Ensure it's not used for reasons that don't meet the definitions by
using the catch-all code, SBI_ERR_FAILED, for those reasons instead.
Also, in one case sbi_hart_suspend() may have returned SBI_ERR_DENIED,
which isn't defined for that function at all. Use SBI_ERR_FAILED for
that case too.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:36:58 +05:30
Andrew Jones
40f16a81d3 lib: sbi_hsm: Don't try to restore state on failed change
When a state change fails there's no need to restore the original
state as it remains the same.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:35:47 +05:30
Andrew Jones
1364d5adb2 lib: sbi_hsm: Factor out invalid state detection
Remove some redundant code by creating an invalid state detection
macro.

No functional change intended.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 19:34:41 +05:30
Bin Meng
17b3776c81 docs: domain_support: Update the DT example
commit 3e2f573e70 ("lib: utils: Disallow non-root domains from adding M-mode regions")
added access permission check in __fdt_parse_region(). With the
existing DT example in the doc OpenSBI won't boot anymore.

Let's update the DT example so that it can work out of the box.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 13:50:27 +05:30
Bin Meng
bc06ff65bf lib: utils/fdt/fdt_domain: Simplify region access permission check
The region access permission check in __fdt_parse_region() can be
simplified as masking SBI_DOMAIN_MEMREGION_{M,SU}_ACCESS_MASK is
enough.

While we are here, update the confusing comments to match the codes.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 13:49:21 +05:30
Bin Meng
5a75f5309c lib: sbi/sbi_domain: cosmetic style fixes
Minor updates to the comments for language and style fixes.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 12:26:26 +05:30
Yu Chien Peter Lin
67b2a40892 lib: sbi: sbi_ecall: Check the range of SBI error
We should also check if the return error code is greater than 0
(SBI_SUCCESS), as this is an invalid error.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 11:46:08 +05:30
Lad Prabhakar
2491242282 platform: generic: renesas: rzfive: Configure the PMA region
On the Renesas RZ/Five SoC by default we want to configure 128MiB of memory
ranging from 0x58000000 as a non-cacheable + bufferable region in the PMA
and populate this region as PMA reserve DT node with shared DMA pool and
no-map flags set so that Linux drivers requesting any DMA'able memory go
through this region.

PMA node passed to the above stack:

        reserved-memory {
            #address-cells = <2>;
            #size-cells = <2>;
            ranges;

            pma_resv0@58000000 {
                compatible = "shared-dma-pool";
                reg = <0x0 0x58000000 0x0 0x08000000>;
                no-map;
                linux,dma-default;
            };
        };

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 11:36:06 +05:30
Lad Prabhakar
c10095132a platform: generic: renesas: rzfive: Add support to configure the PMA
I/O Coherence Port (IOCP) provides an AXI interface for connecting
external non-caching masters, such as DMA controllers. The accesses
from IOCP are coherent with D-Caches and L2 Cache.

IOCP is a specification option and is disabled on the Renesas RZ/Five
SoC due to this reason IP blocks using DMA will fail.

The Andes AX45MP core has a Programmable Physical Memory Attributes (PMA)
block that allows dynamic adjustment of memory attributes in the runtime.
It contains a configurable amount of PMA entries implemented as CSR
registers to control the attributes of memory locations in interest.
Below are the memory attributes supported:
* Device, Non-bufferable
* Device, bufferable
* Memory, Non-cacheable, Non-bufferable
* Memory, Non-cacheable, Bufferable
* Memory, Write-back, No-allocate
* Memory, Write-back, Read-allocate
* Memory, Write-back, Write-allocate
* Memory, Write-back, Read and Write-allocate

More info about PMA (section 10.3):
Link: http://www.andestech.com/wp-content/uploads/AX45MP-1C-Rev.-5.0.0-Datasheet.pdf

As a workaround for SoCs with IOCP disabled CMO needs to be handled by
software. Firstly OpenSBI configures the memory region as
"Memory, Non-cacheable, Bufferable" and passes this region as a global
shared dma pool as a DT node. With DMA_GLOBAL_POOL enabled all DMA
allocations happen from this region and synchronization callbacks are
implemented to synchronize when doing DMA transactions.

Example PMA region passed as a DT node from OpenSBI:
    reserved-memory {
        #address-cells = <2>;
        #size-cells = <2>;
        ranges;

        pma_resv0@58000000 {
            compatible = "shared-dma-pool";
            reg = <0x0 0x58000000 0x0 0x08000000>;
            no-map;
            linux,dma-default;
        };
    };

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 11:35:01 +05:30
Anup Patel
31b82e0d50 include: sbi: Remove extid parameter from vendor_ext_provider() callback
The extid parameter of vendor_ext_provider() is redundant so let us
remove it.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-02-27 11:26:37 +05:30
Anup Patel
81adc62f45 lib: sbi: Align SBI vendor extension id with mvendorid CSR
As-per the SBI specification, the lower 24bits of the SBI vendor
extension id is same as lower 24bits of the mvendorid CSR.

We update the SBI vendor extension id checking based on above.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-02-27 11:26:35 +05:30
Nylon Chen
30ea8069f4 lib: sbi_hart: Enable hcontext and scontext
According to the description in "riscv-state-enable[0]", to access
h/scontext in S-Mode, we need to enable the 57th bit.

If it is not enabled, an "illegal instruction" error will occur.

Link: a28bfae443/content.adoc [0]

Signed-off-by: Nylon Chen <nylon.chen@sifive.com>
Reviewed-by: Zong Li <zong.li@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 11:22:11 +05:30
Shengyu Qu
4f2be40102 docs: fix typo in fw.md
In docs/firmware/fw.md, there's a configuration parameter called
FW_TEXT_ADDR, which actually should be FW_TEXT_START, so fix it.

Signed-off-by: Shengyu Qu <wiagn233@outlook.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 10:54:42 +05:30
Xiang W
6861ee996c lib: utils: fdt_fixup: Fix compile error
When building with GCC-10 or older versions, it throws the following
error:

 CC-DEP    platform/generic/lib/utils/fdt/fdt_fixup.dep
 CC        platform/generic/lib/utils/fdt/fdt_fixup.o
lib/utils/fdt/fdt_fixup.c: In function 'fdt_reserved_memory_fixup':
lib/utils/fdt/fdt_fixup.c:376:2: error: label at end of compound statement
  376 |  next_entry:
      |  ^~~~~~~~~~

Remove the goto statement.

Resolves: https://github.com/riscv-software-src/opensbi/issues/288

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2023-02-27 10:49:09 +05:30
Bin Meng
99d09b601e include: fdt/fdt_helper: Change fdt_get_address() to return root.next_arg1
In sbi_domain_finalize(), when locating the coldboot hart's domain,
the coldboot hart's scratch->arg1 will be overwritten by the domain
configuration. However scratch->arg1 holds the FDT address of the
coldboot hart, and is still being accessed by fdt_get_address() in
later boot process. scratch->arg1 could then contain completely
garbage and lead to a crash.

To fix this, we change fdt_get_address() to return root domain's
next_arg1 as the FDT pointer.

Resolves: https://github.com/riscv-software-src/opensbi/issues/281
Fixes: b1678af210 ("lib: sbi: Add initial domain support")
Reported-by: Marouene Boubakri <marouene.boubakri@nxp.com>
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 10:04:03 +05:30
Bin Meng
745aaecc64 platform: generic/andes: Fix ae350.c header dependency
The code calls various macros from riscv_asm.h which is not directly
included. Fix such dependency.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 10:02:29 +05:30
Bin Meng
aafcc90a87 platform: generic/allwinner: Fix sun20i-d1.c header dependency
The code calls various macros from riscv_asm.h and sbi_scratch.h
which are not directly included. Fix such dependency.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 10:00:15 +05:30
Bin Meng
321293c644 lib: utils/fdt: Fix fdt_pmu.c header dependency
The code calls sbi_scratch_thishart_ptr() from sbi_scratch.h which
is not directly included. Fix such dependency.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-27 09:59:01 +05:30
Anup Patel
65c2190b47 lib: sbi: Speed-up sbi_printf() and friends using nputs()
The sbi_printf() is slow for semihosting because it prints one
character at a time. To speed-up sbi_printf() for semihosting,
we use a temporary buffer and nputs().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-02-10 10:30:18 +05:30
Anup Patel
29285aead0 lib: utils/serial: Implement console_puts() for semihosting
We implement console_puts() for semihosting serial driver to speed-up
semihosting based prints.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-02-10 10:04:59 +05:30
Anup Patel
c43903c4ea lib: sbi: Add console_puts() callback in the console device
We add console_puts() callback in the console device which allows
console drivers (such as semihosting) to implement a specialized
way to output character string.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-02-10 10:04:41 +05:30
Anup Patel
5a41a3884f lib: sbi: Implement SBI debug console extension
We implement SBI debug console extension as one of the replacement
SBI extensions. This extension is only available when OpenSBI platform
provides a console device to generic library.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2023-02-10 09:55:18 +05:30
Anup Patel
eab48c33a1 lib: sbi: Add sbi_domain_check_addr_range() function
We add sbi_domain_check_addr_range() helper function to check
whether a given address range is accessible under a particular
domain.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-02-10 09:14:58 +05:30
Anup Patel
4e0572f57b lib: sbi: Add sbi_ngets() function
We add new sbi_ngets() which help us read characters into a
physical memory location.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2023-02-09 22:30:06 +05:30
Anup Patel
0ee3a86fed lib: sbi: Add sbi_nputs() function
We add new sbi_nputs() which help us print a fixed number of characters
from a physical memory location.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-02-09 22:29:24 +05:30
Anup Patel
e3bf1afcc5 include: Add defines for SBI debug console extension
We add SBI debug console extension related defines to the
SBI ecall interface header.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Xiang W <wxjstz@126.com>
2023-02-09 22:21:24 +05:30
Anup Patel
aa5dafcb5b include: sbi: Fix BSWAPx() macros for big-endian host
The BSWAPx() macros won't do any swapping for big-endian host
because the EXTRACT_BYTE() macro will pickup bytes in reverse
order. Also, the EXTRACT_BYTE() will generate compile error
for constants.

To fix this, we get remove the EXTRACT_BYTE() macro and re-write
BSWAPx() using simple mask and shift operations.

Fixes: 09b34d8cca ("include: Add support for byteorder/endianness
conversion")
Reported-by: Samuel Holland <samuel@sholland.org>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-02-09 09:31:10 +05:30
Rahul Pathak
b224ddb41f include: types: Add typedefs for endianness
If any variable/memory-location follows certain
endianness then its important to annotate it properly
so that proper conversion can be done before read/write
from that variable/memory.

Also, use these new typedefs in libfdt_env.h for deriving
its own custom fdtX_t types

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-08 18:24:13 +05:30
Rahul Pathak
680bea02bf lib: utils/fdt: Use byteorder conversion functions in libfdt_env.h
FDT follows big-endian and CPU can be little or big
endian as per the implementation.
libfdt_env.h defines function for conversion between
fdt and cpu byteorder according to the endianness.

Currently, libfdt_env.h defines custom byte swapping
macros and then undefines them. Instead, use the generic
endianness conversion functions

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-08 18:17:42 +05:30
Rahul Pathak
09b34d8cca include: Add support for byteorder/endianness conversion
Define macros general byteorder conversion
Define functions for endianness conversion
from general byteorder conversion macros

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-08 18:10:39 +05:30
Jessica Clarke
642f3de9b9 Makefile: Add missing .dep files for fw_*.elf.ld
Since we don't currently create these, changes to fw_base.ldS do not
cause the preprocessed fw_*.elf.ld files to be rebuilt, and thus
incremental builds can end up failing with missing symbols if crossing
the recent commits that introduced _fw_rw_offset and then replaced it
with _fw_rw_start.

Reported-by: Ben Dooks <ben.dooks@sifive.com>
Signed-off-by: Jessica Clarke <jrtc27@jrtc27.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-08 16:36:55 +05:30
Andrew Jones
66b0e23a0c lib: sbi: Ensure domidx_to_domain_table is null-terminated
sbi_domain_for_each() requires domidx_to_domain_table[] to be
null-terminated. Allocate one extra element which will always
be null.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-08 13:42:45 +05:30
Himanshu Chauhan
199189bd1c lib: utils: Mark only the largest region as reserved in FDT
In commit 230278dcf, RX and RW regions were marked separately.
When the RW region grows (e.g. with more harts) and it isn't a
power-of-two, sbi_domain_memregion_init will upgrade the region
to the next power-of-two. This will make RX and RW both start
at the same base address, like so (with 64 harts):
Domain0 Region01 : 0x0000000080000000-0x000000008001ffff M: (R,X) S/U: ()
Domain0 Region02 : 0x0000000080000000-0x00000000800fffff M: (R,W) S/U: ()

This doesn't break the permission enforcement because of static
priorities in PMP but makes the kernel complain about the regions
overlapping each other. Like so:
[    0.000000] OF: reserved mem: OVERLAP DETECTED!
[    0.000000] mmode_resv0@80000000 (0x0000000080000000--0x0000000080020000) \
	overlaps with mmode_resv1@80000000 (0x0000000080000000--0x0000000080100000)

To fix this warning, among the multiple regions having same base
address but different sizes, add only the largest region as reserved
region during fdt fixup.

Fixes: 230278dcf (lib: sbi: Add separate entries for firmware RX and RW regions)
Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-02-08 11:13:19 +05:30
Nick Hu
84d15f4f52 lib: sbi_hsm: Use csr_set to restore the MIP
If we use the csr_write to restore the MIP, we may clear the SEIP.
In generic behavior of QEMU, if the pending bits of PLIC are set and we
clear the SEIP, the QEMU may not set it back immediately. It may cause
the interrupts won't be handled anymore until the new interrupts arrived
and QEMU set the bits back.

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:21 +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
Samuel Holland
c45992cc2b platform: generic: allwinner: Advertise nonretentive suspend
Add D1's nonretentive suspend state to the devicetree so S-mode software
knows about it and can use it.

Latency and power measurements were taken on an Allwinner Nezha board:
 - Entry latency was measured from the beginning of sbi_ecall_handler()
   to before the call to wfi() in sun20i_d1_hart_suspend().
 - Exit latency was measured from the beginning of sbi_init() to before
   the call to sbi_hart_switch_mode() in init_warmboot().
 - There was a 17.5 mW benefit from non-retentive suspend compared to
   WFI, with a 170 mW cost during the 107 us entry/exit period. This
   provides a break-even point around 1040 us. Residency includes entry
   latency, so round this up to 1100 us.
 - The hardware power sequence latency (after the WFI) is assumed to be
   negligible, so set the wakeup latency to the exit latency.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2023-01-24 17:30:21 +05:30
Samuel Holland
33bf917460 lib: utils: Add fdt_add_cpu_idle_states() helper function
Since the availability and latency properties of CPU idle states depend
on the specific SBI HSM implementation, it is appropriate that the idle
states are added to the devicetree at runtime by that implementation.

This helper function adds a platform-provided array of idle states to
the devicetree, following the SBI idle state binding.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2023-01-24 17:30:21 +05:30
Lad Prabhakar
dea0922f86 platform: renesas/rzfive: Configure Local memory regions as part of root domain
Renesas RZ/Five RISC-V SoC has Instruction local memory and Data local
memory (ILM & DLM) mapped between region 0x30000 - 0x4FFFF. When a
virtual address falls within this range, the MMU doesn't trigger a page
fault; it assumes the virtual address is a physical address which can
cause undesired behaviours for statically linked applications/libraries.

To avoid this, add the ILM/DLM memory regions to the root domain region
of the PMPU with permissions set to 0x0 for S/U modes so that any access
to these regions gets blocked and for M-mode we grant full access (R/W/X).

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-23 11:29:03 +05:30
Himanshu Chauhan
230278dcf1 lib: sbi: Add separate entries for firmware RX and RW regions
Add two entries for firmware in the root domain:

1. TEXT: fw_start to _fw_rw_offset with RX permissions
2. DATA: _fw_rw_offset to fw_size with RW permissions

These permissions are still not enforced from M-mode but lay
the ground work for enforcing them for M-mode. SU-mode don't
have any access to these regions.

Sample output:
 Domain0 Region01  : 0x0000000080000000-0x000000008001ffff M: (R,X) S/U: ()
 Domain0 Region02  : 0x0000000080020000-0x000000008003ffff M: (R,W) S/U: ()

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-23 10:34:18 +05:30
Himanshu Chauhan
b666760bfa lib: sbi: Print the RW section offset
Print the RW section offset when firmware base and size is
being printed.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-23 10:06:14 +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
Himanshu Chauhan
2f40a99c9e firmware: Move dynsym and reladyn sections to RX section
Currently, the dynsym and reladyn sections are under RW data.
They are moved to the Read-only/Executable region.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-23 10:06:14 +05:30
Himanshu Chauhan
fefa548803 firmware: Split RO/RX and RW sections
Split the RO/RX and RW sections so that they can have
independent pmp entries with required permissions. The
split size is ensured to be a power-of-2 as required by
pmp.

_fw_rw_offset symbol marks the beginning of the data
section.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-23 10:06:14 +05:30
Mayuresh Chitale
a990309fa3 lib: utils: Fix reserved memory node for firmware memory
The commit 9e0ba090 introduced more fine grained permissions for memory
regions and did not update the fdt_reserved_memory_fixup() function. As
a result, the fdt_reserved_memory_fixup continued to use the older coarse
permissions which causes the reserved memory node to be not inserted
into the DT.

To fix the above issue, we correct the flags used for memory region
permission checks in the fdt_reserved_memory_fixup() function.

Fixes: 9e0ba090 ("include: sbi: Fine grain the permissions for M and SU modes")
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-22 17:49:10 +05:30
Yu Chien Peter Lin
7aaeeab9e7 lib: reset/fdt_reset_atcwdt200: Use defined macros and function in atcsmu.h
Reuse the smu related macros and function in atcsmu.h.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-22 17:33:13 +05:30
Yu Chien Peter Lin
787296ae92 platform: andes/ae350: Implement hart hotplug using HSM extension
Add hart_start() and hart_stop() callbacks for the multi-core ae350
platform, it utilizes the ATCSMU to put the harts into power-gated
deep sleep mode. The programming sequence is stated as below:

1. Set the wakeup events to PCSm_WE
2. Set the sleep command to PCSm_CTL
3. Set the reset vector to HARTm_RESET_VECTOR_{LO|HI}
4. Write back and invalidate D-cache by executing the CCTL command L1D_WBINVAL_ALL
5. Disable I/D-cache by clearing mcache_ctl.{I|D}C_EN
6. Disable D-cache coherency by clearing mcache_ctl_.DC_COHEN
7. Wait for mcache_ctl.DC_COHSTA to be cleared to ensure the previous step is completed
8. Execute WFI

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-22 17:33:03 +05:30
Yu Chien Peter Lin
9c4eb3521e lib: utils: atcsmu: Add Andes System Management Unit support
This patch adds atcsmu support for Andes AE350 platforms. The SMU
provides system management capabilities, including clock, reset
and power control based on power domain partitions.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-22 17:32:50 +05:30
Yu Chien Peter Lin
b1818ee244 include: types: add always inline compiler attribute
Provide __always_inline to sbi_types header.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-22 17:32:35 +05:30
Yu Chien Peter Lin
8ecbe6d3fb lib: sbi_hsm: handle failure when hart_stop returns SBI_ENOTSUPP
Make use of generic warm-boot path when platform hart_stop callback
returns SBI_ENOTSUPP, in case certain hart can not turn off its
power domain, or it detects some error occured in power management
unit, it can fall through warm-boot flow and wait for interrupt in
sbi_hsm_hart_wait().

Also improves comment in sbi_hsm_hart_wait().

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-22 17:32:09 +05:30
Yu Chien Peter Lin
ce2a834c98 docs: generic.md: fix typo of andes-ae350
Fix hyperlink due to the typo.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-22 17:31:54 +05:30
Samuel Holland
da5594bf85 platform: generic: allwinner: Fix PLIC array bounds
The two referenced commits passed incorrect bounds to the PLIC save/
restore functions, causing out-of-bounds memory access. The functions
expect "num" to be the 1-based number of interrupt sources, equivalent
to the "riscv,ndev" devicetree property. Thus, "num" must be strictly
smaller than the 0-based size of the array storing the register values.

However, the referenced commits incorrectly passed in the unmodified
size of the array as "num". Fix this by reducing PLIC_SOURCES (matching
"riscv,ndev" on this platform), while keeping the same array sizes.

Addresses-Coverity-ID: 1530251 ("Out-of-bounds access")
Addresses-Coverity-ID: 1530252 ("Out-of-bounds access")
Fixes: 8509e46ca6 ("lib: utils/irqchip: plic: Ensure no out-of-bound access in priority save/restore helpers")
Fixes: 9a2eeb4aae ("lib: utils/irqchip: plic: Ensure no out-of-bound access in context save/restore helpers")
Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-13 17:39:42 +05:30
Himanshu Chauhan
001106d19b docs: Update domain's region permissions and requirements
Updated the various permissions bits available for domains
defined in DT node and restrictions on them.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-01-09 18:04:30 +05:30
Himanshu Chauhan
59a08cd7d6 lib: utils: Add M-mode {R/W} flags to the MMIO regions
Add the M-mode readable/writable flags to mmio regions
of various drivers.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-01-09 18:04:28 +05:30
Himanshu Chauhan
3e2f573e70 lib: utils: Disallow non-root domains from adding M-mode regions
The M-mode regions can only be added to the root domain. The non-root
domains shouldn't be able to add them from FDT.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-01-09 18:04:25 +05:30
Himanshu Chauhan
20646e0184 lib: utils: Use SU-{R/W/X} flags for region permissions during parsing
Use the newer SU-{R/W/X} flags for checking and assigning region
permissions.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-01-09 18:04:23 +05:30
Himanshu Chauhan
44f736c96e lib: sbi: Modify the boot time region flag prints
With the finer permission semantics, the region access
permissions must be displayed separately for M and SU mode.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-01-09 18:04:19 +05:30
Himanshu Chauhan
1ac14f10f6 lib: sbi: Use finer permission sematics to decide on PMP bits
Use the fine grained permission bits to decide if the region
permissions are to be enforced on all modes. Also use the new
permission bits for deciding on R/W/X bits in pmpcfg register.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-01-09 18:04:17 +05:30
Himanshu Chauhan
22dbdb3d60 lib: sbi: Add permissions for the firmware start till end
Change the zero flag to M-mode R/W/X flag for the firmware
region.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-01-09 18:04:14 +05:30
Himanshu Chauhan
aace1e145d lib: sbi: Use finer permission semantics for address validation
Use the fine grained permisssion semantics for address validation
of a given region.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-01-09 18:04:12 +05:30
Himanshu Chauhan
9e0ba09076 include: sbi: Fine grain the permissions for M and SU modes
Split the permissions for M-mode and SU-mode. This would
help if different sections of OpenSBI need to be given
different permissions and if M-mode has different permisssions
than the SU-mode over a region.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
2023-01-09 18:04:10 +05:30
Bin Meng
9e397e3960 docs: domain_support: Use capital letter for privilege modes
The RISC-V convention for the privilege mode is capital letter, like
'M-mode', instead of 'm-mode'.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-09 16:54:29 +05:30
Bin Meng
6997552ea2 lib: sbi_hsm: Rename 'priv' argument to 'arg1'
'priv' argument of sbi_hsm_hart_start() and sbi_hsm_hart_suspend()
may mislead people to think it stands for 'privilege mode', but it
is not. Change it to 'arg1' to clearly indicate the a1 register.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Samuel Holland <samuel@sholland.org>
Tested-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-09 16:52:34 +05:30
Wei Liang Lim
8020df8733 generic/starfive: Add Starfive JH7110 platform implementation
Add Starfive JH7110 platform implementation

Signed-off-by: Wei Liang Lim <weiliang.lim@starfivetech.com>
Reviewed-by: Chee Hong Ang <cheehong.ang@starfivetech.com>
Reviewed-by: Jun Liang Tan <junliang.tan@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-07 16:00:22 +05:30
Wei Liang Lim
cb7e7c3325 platform: generic: Allow platform_override to perform firmware init
We add a generic platform override callback to allow platform specific firmware init.

Signed-off-by: Wei Liang Lim <weiliang.lim@starfivetech.com>
Reviewed-by: Chee Hong Ang <cheehong.ang@starfivetech.com>
Reviewed-by: Jun Liang Tan <junliang.tan@starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-07 15:58:54 +05:30
Anup Patel
6957ae0e91 platform: generic: Allow platform_override to select cold boot HART
We add a generic platform override callback to allow platform specific
selection of cold boot HART.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-01-07 15:58:52 +05:30
Anup Patel
f14595a7cf lib: sbi: Allow platform to influence cold boot HART selection
We add an optional cold_boot_allowed() platform callback which allows
platform support to decide which HARTs can do cold boot initialization.

If this platform callback is not available then any HART can do cold
boot initialization.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2023-01-07 15:58:49 +05:30
Bin Meng
65638f8d6b lib: utils/sys: Allow custom HTIF base address for RV32
commit 6dde43584f ("lib: utils/sys: Extend HTIF library to allow custom base address")
forgot to update do_tohost_fromhost() codes for RV32, which still
accesses the HTIF registers using the ELF symbol address directly.

Fixes: 6dde43584f ("lib: utils/sys: Extend HTIF library to allow custom base address")
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2023-01-06 18:01:36 +05:30
Rahul Pathak
6509127ad6 Makefile: Remove -N ldflag to prevent linker RWX warning
-N option coalesce all sections into single LOAD segment which causes
data and other sections to have executable permission causing warning
with new binutils ld 2.39.
New ld emits warning when any segment have all three permissions RWX.

ld.bfd: warning: test.elf has a LOAD segment with RWX permissions
ld.bfd: warning: fw_dynamic.elf has a LOAD segment with RWX permissions
ld.bfd: warning: fw_jump.elf has a LOAD segment with RWX permissions
ld.bfd: warning: fw_payload.elf has a LOAD segment with RWX permissions

This option was added in below commit -
commit: eeab92f242 ("Makefile: Convert to a more standard format")

Removing -N option allows to have text and rodata into one LOAD
segment and other sections into separate LOAD segment which prevents
RWX permissions on single LOAD segment. Here X == E

Current
 LOAD           0x0000000000000120 0x0000000080000000 0x0000000080000000
                 0x000000000001d4d0 0x0000000000032ed8  RWE    0x10

-N removed
  LOAD           0x0000000000001000 0x0000000080000000 0x0000000080000000
                 0x00000000000198cc 0x00000000000198cc  R E    0x1000
  LOAD           0x000000000001b000 0x000000008001a000 0x000000008001a000
                 0x00000000000034d0 0x0000000000018ed8  RW     0x1000

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Samuel Holland <samuel@sholland.org>
2023-01-06 17:51:15 +05:30
Bin Meng
440fa818fb treewide: Replace TRUE/FALSE with true/false
C language standard uses true/false for the boolean type.
Let's switch to that for better language compatibility.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Samuel Holland <samuel@sholland.org>
Tested-by: Samuel Holland <samuel@sholland.org>
2023-01-06 17:26:35 +05:30
Anup Patel
6b5188ca14 include: Bump-up version to 1.2
This patch updates OpenSBI version to 1.2 as part of
release preparation.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2022-12-24 11:36:49 +05:30
Atish Patra
d5d12a91d1 docs: pmu: Update the pmu doc with removal of mcountinhbit restriction
Since commit b28f070, it is possible for platforms to run perf monitoring
even if mcountinhibit is not supported. Sampling still won't be possible
though as it requires sscofpmf extension.

Update the docs to remove the restriction.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-24 11:07:14 +05:30
Conor Dooley
0412460baf docs: pmu: update a reference to a deprecated property name
event-to-mhpmevent was deprecated and replaced by
riscv,event-to-mhpmevent, but a reference remains to the old name.
Replace it with the new one.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-24 11:06:04 +05:30
Conor Dooley
391ec85875 docs: pmu: fix binding example
The first PMU binding example does not terminate properties with a ;,
which is invalid. Noticed while converting the binding to yaml.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-24 11:05:09 +05:30
Icenowy Zheng
b848d8763a lib: utils/timer: mtimer: add T-Head C9xx CLINT compatible
As we already added the quirk for lacking mtime register to MTIMER
driver, add T-Head C9xx CLINT compatible to it and wire the quirk.

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-17 11:01:06 +05:30
Icenowy Zheng
ca7810aecd lib: utils/timer: mtimer: add a quirk for lacking mtime register
T-Head developers surely have a different understanding of time CSR and
CLINT's mtime register with SiFive ones, that they did not implement
the mtime register at all -- as shown in openC906 source code, their
time CSR value is just exposed at the top of their processor IP block
and expects an external continous counter, which makes it not
overrideable, and thus mtime register is not implemented, even not for
reading. However, if CLINTEE is not enabled in T-Head's MXSTATUS
extended CSR, these systems still rely on the mtimecmp registers to
generate timer interrupts. This makes it necessary to implement T-Head
C9xx CLINT support in OpenSBI MTIMER driver, which skips implementing
reading mtime register and falls back to default code that reads time
CSR.

Add a quirk into MTIMER driver, which represents a mtime register is
lacking and time CSR value should be used instead.

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-17 11:01:03 +05:30
Icenowy Zheng
a8ee82cd8c lib: utils/ipi: mswi: add T-Head C9xx CLINT compatible
Althoug the MTIMER part of a C9xx CLINT differs from a SiFive one, the
MSWI part is compliant.

Add T-Head C9xx CLINT compatible string to fdt_ipi_mswi code, sharing
the same codepath with SiFive CLINT.

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-17 11:01:00 +05:30
Bin Meng
9a2eeb4aae lib: utils/irqchip: plic: Ensure no out-of-bound access in context save/restore helpers
Currently the context save/restore helpers writes/reads the provided
array using an index whose maximum value is determined by PLIC, which
potentially may disagree with the caller to these helpers.

Add a parameter to ask the caller to provide the size limit of the
array to ensure no out-of-bound access happens.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-17 09:03:30 +05:30
Bin Meng
fabbc00668 lib: utils/irqchip: plic: Fix the off-by-one error in context save/restore helpers
plic->num_src holds the number of interrupt sources without interrupt
source 0 but the interrupt enable register includes a bit for the
interrupt source 0 in the first word.

Fixes: 415ecf28f7 ("lib: irqchip/plic: Add context save/restore helpers")
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Samuel Holland <samuel@sholland.org>
2022-12-17 09:02:40 +05:30
Bin Meng
91c8a7d5ce lib: utils/irqchip: plic: Fix the off-by-one error in plic_context_init()
The number of interrupt enable register in words was once correct,
but was wrongly changed to have an off-by-one error since
commit 8c362e7d06 ("lib: irqchip/plic: Factor out a context init function").

Fixes: 8c362e7d06 ("lib: irqchip/plic: Factor out a context init function")
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Samuel Holland <samuel@sholland.org>
2022-12-17 09:00:35 +05:30
Bin Meng
8509e46ca6 lib: utils/irqchip: plic: Ensure no out-of-bound access in priority save/restore helpers
Currently the priority save/restore helpers writes/reads the provided
array using an index whose maximum value is determined by PLIC, which
potentially may disagree with the caller to these helpers.

Add a parameter to ask the caller to provide the size limit of the
array to ensure no out-of-bound access happens.

Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-17 09:00:29 +05:30
Bin Meng
34da6638ad lib: utils/irqchip: plic: Fix the off-by-one error in priority save/restore helpers
Interrupt source 0 is reserved. Hence the irq should start from 1.

Fixes: 2b79b694a8 ("lib: irqchip/plic: Add priority save/restore helpers")
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-17 08:42:21 +05:30
Lad Prabhakar
7a3354ac15 docs: platform: Add documentation for Renesas RZ/Five SoC
This patch adds documentation to build Renesas RZ/Five (R9A07G043F) SoC.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-12 18:51:10 +05:30
Lad Prabhakar
8b1617d13a platform: generic: Add Renesas RZ/Five initial support
This commit provides basic support for the Renesas RZ/Five
(R9A07G043F) SoC.

The RZ/Five microprocessor includes a single RISC-V CPU Core (Andes AX45MP)
1.0 GHz, 16-bit DDR3L/DDR4 interface. Supported interfaces include:
- Gigabit Ethernet 2ch
- CAN interface (CAN-FD) 2ch
- USB 2.0 interface 2ch
- SD interface 2ch
- AD converter 2ch

Useful links:
-------------
Links: https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rz-mpus/rzfive-risc-v-general-purpose-microprocessors-risc-v-cpu-core-andes-ax45mp-single-10-ghz-2ch-gigabit-ethernet
Links: http://www.andestech.com/en/products-solutions/andescore-processors/riscv-ax45mp/

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-12 18:50:56 +05:30
Lad Prabhakar
684090272a lib: utils/irqchip: Add compatible string for Andestech NCEPLIC100
Add compatible string for Andestech NCEPLIC100 found on Renesas RZ/Five SoC
which is equipped with AX45MP AndesCore.

While at it drop the comma after the sentinel as it does not make sense to
have a comma after a sentinel, as any new elements must be added before the
sentinel.

dts example (Single-core AX45MP):

    soc: soc {
          ....
          plic: interrupt-controller@12c00000 {
              compatible = "renesas,r9a07g043-plic", "andestech,nceplic100";
              #interrupt-cells = <2>;
              #address-cells = <0>;
              riscv,ndev = <511>;
              interrupt-controller;
              reg = <0x0 0x12c00000 0 0x400000>;
              clocks = <&cpg CPG_MOD R9A07G043_NCEPLIC_ACLK>;
              power-domains = <&cpg>;
              resets = <&cpg R9A07G043_NCEPLIC_ARESETN>;
              interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9>;
          };
          ....
    };

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2022-12-12 18:50:46 +05:30
Lad Prabhakar
0021b43737 lib: utils: serial: Add FDT driver for Renesas SCIF
Add FDT driver for Renesas SCIF.

    dts example:

    soc: soc {
          ....
            scif0: serial@1004b800 {
                    compatible = "renesas,scif-r9a07g043",
                                 "renesas,scif-r9a07g044";
                    reg = <0 0x1004b800 0 0x400>;
                    interrupts = <412 IRQ_TYPE_LEVEL_HIGH>,
                                 <414 IRQ_TYPE_LEVEL_HIGH>,
                                 <415 IRQ_TYPE_LEVEL_HIGH>,
                                 <413 IRQ_TYPE_LEVEL_HIGH>,
                                 <416 IRQ_TYPE_LEVEL_HIGH>,
                                 <416 IRQ_TYPE_LEVEL_HIGH>;
                    interrupt-names = "eri", "rxi", "txi",
                                      "bri", "dri", "tei";
                    clocks = <&cpg CPG_MOD R9A07G043_SCIF0_CLK_PCK>;
                    clock-names = "fck";
                    power-domains = <&cpg>;
                    resets = <&cpg R9A07G043_SCIF0_RST_SYSTEM_N>;
                    status = "disabled";
            };
          ....
    };

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-12 18:50:35 +05:30
Lad Prabhakar
64e8b9f72e lib: utils: serial: Add Renesas SCIF driver
Add Renesas SCIF driver.

Based on a patch in the BSP by Takeki Hamada
<takeki.hamada.ak@bp.renesas.com>
Link: https://github.com/renesas-rz/rz_opensbi/commits/work/OpenSBI-PMA

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-12 18:50:26 +05:30
Himanshu Chauhan
506928a1be scripts: use env to invoke bash
Not all systems have bash at a fixed location like /bin/bash.
FreeBSD, for example, would typically have it at /usr/local/bin/bash.
When building OpenSBI on freebsd system, the build breaks.

Its advisable to use: #!/usr/bin/env bash

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-10 22:00:27 +05:30
Himanshu Chauhan
cb568b9b29 lib: sbi: Synchronize PMP settings with virtual memory system
As per section 3.7.2 of RISC-V Privileged Specification,
PMP settings must be synchronized with the virtual memory
system after PMP settings have been written.

Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-09 14:17:56 +05:30
Heinrich Schuchardt
7b087781c2 lib: fix irqchip_plic_update_hartid_table
After determining cpu_offset we have to check this value.

Addresses-Coverity-ID: 1529706 ("Logically dead code")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-09 11:27:28 +05:30
Heinrich Schuchardt
c2be21432c lib: fix __fdt_parse_region()
If fdt_getprop() returns NULL, this indicates an error. In this case lenp
is set to an error code. But even if lenp = 0 we should not continue.

If fdt_getprop() returns a wider value than we expect this is a separate
error condition.

In both cases the device-tree is invalid.

Addresses-Coverity-ID: 1529703 ("Dereference after null check")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-09 11:26:39 +05:30
Heinrich Schuchardt
8b00be6927 lib: fix is_region_valid()
For 'reg->order == __riscv_xlen' the term 'BIT(reg->order)' is undefined.

Addresses-Coverity-ID: 1529706 ("Bad bit shift operation")
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-09 11:25:27 +05:30
Lad Prabhakar
ed8b8f5254 platform: generic: Make use of fdt_match_node()
It makes sense to use fdt_match_node() instead of fdt_find_match()
in fw_platform_lookup_special() as we already have the start offset
to search from.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-09 11:13:00 +05:30
Sergey Matyukevich
e1a0cb062a gitignore: add vim swap files
Update .gitignore for vim swap files.

Signed-off-by: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-05 17:57:30 +05:30
Lad Prabhakar
e9775120f5 lib: utils: Add fdt_fixup_node() helper function
Add a helper function fdt_fixup_node() based on the compatible string.
This will avoid code duplication for every new node fixup being added.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-05 17:54:45 +05:30
Yu Chien Peter Lin
4640d041d3 scripts/create-binary-archive.sh: remove andes/ae350 build directory
The andes-specific files have been moved to generic platform so we
can drop this line.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-05 17:33:03 +05:30
Yu Chien Peter Lin
d3fcff77a1 docs: andes-ae350.md: fix watchdog nodename in dts example
The example should use watchdog as nodename instead of wdt.
This is defined in watchdog common schemas:
https://github.com/torvalds/linux/blob/v6.0/Documentation/devicetree/bindings/watchdog/watchdog.yaml#L19

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-05 17:32:16 +05:30
Yu Chien Peter Lin
6cd4b9b223 docs: platform: Update AE350 and generic platform documentation
Update compile option and platform compatible string for AE350 and
add it to the generic platform list.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-05 17:30:55 +05:30
Yu Chien Peter Lin
a36d455182 platform: generic/andes: Enable generic platform support for AE350
We move andes directory to platform/generic as the necessary fdt
drivers are available, the users can enable the console, timer, ipi,
irqchip and reset devices by adding device tree nodes stated in the
docs/platform/andes-ae350.md.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-05 17:24:32 +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
Heinrich Schuchardt
ad2ac29263 lib: fix fdt_parse_aclint_node()
After determining cpu_offset we have to check this variable and not
cpu_intc_offset.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2022-12-05 10:37:38 +05:30
Heinrich Schuchardt
1f6866e015 lib: simplify fdt_translate_address()
Don't assign a value to offset which is never used.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2022-12-05 10:36:41 +05:30
Heinrich Schuchardt
5daa0ef087 lib: fix fdt_parse_plicsw_node()
cpu_offset and cpu_intc_offset must be int to detect failed invocations of
fdt_node_offset_by_phandle() or fdt_parent_offset().

After determining cpu_offset we have to check this value and not
cpu_intc_offset.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2022-12-05 10:35:36 +05:30
Heinrich Schuchardt
e9bc7f1757 lib: fix fdt_parse_plmt_node()
cpu_offset, cpu_intc_offset must be int to discover failed invocations of
fdt_node_offset_by_phandle() or fdt_parent_offset().

After determining cpu_offset we have to check this value and not
cpu_intc_offset.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2022-12-05 10:33:42 +05:30
Heinrich Schuchardt
cc54184619 lib: simplify fdt_parse_plicsw_node()
We should not check !plicsw_base || !size twice.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2022-12-05 10:31:01 +05:30
Heinrich Schuchardt
f8eec91de8 lib: simplify fdt_parse_plmt_node()
We should not check !plmt_base || !plmt_size twice.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2022-12-05 10:10:48 +05:30
Xiang W
fc82e84329 lib: sbi: Fix is_region_valid()
When order is equal to __riscv_xlen, the shift operation will not perform
any operation, which will cause reg->base & (BIT(reg->order) - 1) to always
be 0, and the condition has not been established.

This patch fixes this bug.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-04 21:52:52 +05:30
Xiang W
74e20293c4 lib: sbi: Simplified mmio match checking
We simplify the mmio flag matching in sbi_domain_check_addr().

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-04 21:16:45 +05:30
Alejandro Cabrera Aldaya
49b0e355e6 Makefile: bugfix for handling platform paths
If the path where this repo is located contains the platform name on
it, the original Makefile replaced its occurrences from the path making
it an invalid path. This commit prevents this behavior replacing only
the last part of the path as intended.

Signed-off-by: Alejandro Cabrera Aldaya <aldaya@gmail.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-04 21:02:33 +05:30
KaDiWa
ba32021683 Makefile: replace echo with printf for compatibility
I don't know why but `echo -n` didn't work for me. macOS supports
the `-n` option but it doesn't work in the makefile. What it does
instead is it literally writes `-n` to the file and then also
leaves a newline at the end.

I'm using GNU Make 4.4 (`gmake` from Homebrew).

Signed-off-by: KaDiWa <kalle.wachsmuth@gmail.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-04 20:41:30 +05:30
Xiang W
9a740f5c46 platform: generic/allwinner: Remove ghostly type cast
Corrected the same parameter of writel_relaxed in sun20i_d1_riscv_cfg_init
to be u32 for a while and u64 for a while.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-12-04 20:38:46 +05:30
Leizheng Zhang
1b0d71bb9f platform: generic/allwinner: Remove unused header files
Remove "#include <sbi/sbi_console.h>"

Signed-off-by: Leizheng Zhang <zhangleizheng@eswincomputing.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Xiang W <wxjstz@126.com>
2022-11-22 11:46:19 +05:30
Leizheng Zhang
8e63716c1c firmware: payloads: Optimize usage of "ALIGN"
Delete the redundant "ALIGN" and adjust the position of "ALIGN"

Signed-off-by: Leizheng Zhang <zhangleizheng@eswincomputing.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2022-11-22 11:20:11 +05:30
Vivian Wang
14f5c4cb4d lib: sbi_ecall: Split up sbi_ecall_replace
Split up sbi_ecall_replace so that each extension is in its individual
file.

Also reorganize the corresponding section in lib/sbi/objects.mk so
that it is grouped by extension, now that the object file targets are
split up.

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-11-15 16:44:03 +05:30
Anup Patel
7b29264f11 lib: utils/serial: Fix semihosting compile error using LLVM
We fix the following semihosting compile error observed using LLVM:
lib/utils/serial/semihosting.c:158:12: error: result of comparison of constant -1 with expression of type 'char' is always true [-Werror,-Wtautological-constant-out-of-range-compare]
                ret = ch > -1 ? ch : -1;
                      ~~ ^ ~~

Fixes: 7f09fba86e ("lib: utils/serial: add semihosting support")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Bin Meng <bmeng@tinylab.org>
2022-11-15 16:38:41 +05:30
zhangdongdong
8e9966c1a7 docs: fix some typos
Corrected the typos of some documents in the 'docs' folder.

Signed-off-by: zhangdongdong <zhangdongdong@eswincomputing.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-11-14 22:21:31 +05:30
Xiang W
21ba418f1a lib: utils/fdt: Simplified code
Simplified fdt_parse_xxx_uart_node which direct call
fdt_parse_uart_node_common.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-11-14 22:07:36 +05:30
Xiang W
85cf56c159 lib: utils/fdt: Remove redundant code
uart->reg_offset and uart->reg_io_width are only used on uart8250 and
not required on other platforms. Remove for sifive and gaisler.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-11-14 22:02:33 +05:30
Vivian Wang
22f38ee6c6 lib: sbi_ecall: Add Kconfig option for each extension
For each SBI extension, we:

- Add a Kconfig option for it
- Add the extension to sbi_ecall_exts only if the extension is enabled
- Add the corresponding sbi_ecall_* object file only if the extension is
  enabled

Special cases are as follows:

- The legacy extensions are lumped together as one 'big' extension, as
  has always been the case in OpenSBI code.
- The platform-defined vendor extensions are regarded as one extension.
- The Base extension cannot be disabled.
- sbi_ecall_replace implements multiple extensions, so it's not easy to
  avoid linking it in. Enable it always, and use #ifdef to
  disable/enable individual extensions.

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 11:01:33 +05:30
Vivian Wang
56bed1a0fe lib: sbi_ecall: Generate extensions list with carray
Instead of hard-coding the list of extensions in C code, use carray to
generate the list of extensions.

Using carray makes adding and removing extensions slightly cleaner. This
also paves the way for using Kconfig to disable unneeded extensions.

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 11:00:30 +05:30
Vivian Wang
9d54f431e8 Makefile: Add rules for carray sources in lib/sbi
Add back the missing rules needed to build carray files in lib/sbi. This
allows future usage of carray in lib/sbi.

Fixes: de80e9337d ("Makefile: Compile lib/utils sources separately for each platform")
Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:59:26 +05:30
Yangjie Zhang
51acd4956a docs/firmware: update the document
Since
commit 9c07c513aa ("firmware:Remove FW_PAYLOAD_FDT_PATH compile-time option"),
the section where FDT would be embedded in has changed from *.text* to *.rodata*,
but some places in fw_payload.md and fw.md are still *.text*.
This patch updates the document.

Signed-off-by: Yangjie Zhang <pyjmstr@gmail.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:49:39 +05:30
Tan En De
0fee0bf826 Makefile: Add cscope support
Add cscope support so that running `make cscope` will generate/update
cscope files used for source code browsing, while running `make
distclean` will remove the cscope files.

Also add entry in .gitignore to ignore generated cscope files.

Signed-off-by: Tan En De <ende.tan@linux.starfivetech.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
2022-10-23 10:47:40 +05:30
Yu Chien Peter Lin
d682a0afa1 docs: andes-ae350.md: Update ae350 documentation for fdt driver support
We update ae350 documentation to add details about platform device tree.
The nodes and their properties must be provided to properly initialize
data of underlying hardware and access their mmio registers.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:35:45 +05:30
Yu Chien Peter Lin
c8683c57f6 platform: andes/ae350: Add AE350 domain support
Add domains_init platform hook for Andes AE350, users can add domain
description in device tree and select FDT domain support in Kconfig
to achieve system-level partitioning.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:35:00 +05:30
Yu Chien Peter Lin
ce7c490719 lib: utils/ipi: Add Andes fdt ipi driver support
Move Andes PLICSW ipi device to fdt ipi framework, this patch is based
on Leo's modified IPI scheme on PLICSW.

Current IPI scheme uses bit 0 of pending reigster on PLICSW to send IPI
from hart 0 to hart 7, but bit 0 needs to be hardwired to 0 according
to spec. After some investigation, self-IPI seems to be seldom or never
used, so we re-order the IPI scheme to support 8 core platforms.

dts example (Quad-core AX45MP):

  plicsw: interrupt-controller@e6400000 {
          compatible = "andestech,plicsw";
          reg = <0x00000000 0xe6400000 0x00000000 0x00400000>;
          interrupts-extended = <&CPU0_intc 3
                                 &CPU1_intc 3
                                 &CPU2_intc 3
                                 &CPU3_intc 3>;
          interrupt-controller;
          #address-cells = <2>;
          #interrupt-cells = <2>;
  };

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:31:01 +05:30
Yu Chien Peter Lin
6f3258e671 platform: andes/ae350: Add fw_platform_init for platform initialization
This patch adds fw_platform_init() to initialize ae350 platform.name
and platform.hart_count by parsing device tree.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:30:21 +05:30
Yu Chien Peter Lin
127a3f2ab4 platform: andes/ae350: Use fdt irqchip driver
Andes PLIC is compatible with plic driver. The PLIC base address and
number of source can be obtained by parsing the device tree.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:29:58 +05:30
Yu Chien Peter Lin
8234fc1bdf lib: utils/reset: Add Andes fdt reset driver support
Add ATCWDT200 as reset device of AE350 platform, this driver requires
SMU to program the reset vector registers before triggering WDT software
restart signal.

dts example:

  smu@f0100000 {
    compatible = "andestech,atcsmu";
    reg = <0x00000000 0xf0100000 0x00000000 0x00001000>;
  };

  wdt: wdt@f0500000 {
    compatible = "andestech,atcwdt200";
    reg = <0x00000000 0xf0500000 0x00000000 0x00001000>;
    interrupts = <3 4>;
    interrupt-parent = <&plic0>;
    clock-frequency = <15000000>;
  };

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:29:23 +05:30
Yu Chien Peter Lin
ef9f02e7fb lib: utils/timer: Add Andes fdt timer support
Since we can get the PLMT base address and timer frequency from
device tree, move plmt timer device to fdt timer framework.

dts example (Quad-core AX45MP):

  cpus {
      ...
      timebase-frequency = <0x3938700>;
      ...
  }
  soc {
      ...
      plmt0@e6000000 {
          compatible = "andestech,plmt0";
          reg = <0x00 0xe6000000 0x00 0x100000>;
          interrupts-extended = <&cpu0_intc 0x07
                                 &cpu1_intc 0x07
                                 &cpu2_intc 0x07
                                 &cpu3_intc 0x07>;
      };
      ...
  }

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:26:39 +05:30
Yu Chien Peter Lin
88f58a3694 platform: andes/ae350: Use fdt serial driver
Andes UART is compatible with uart8250 driver. We can use
fdt_serial_init() as platform console init hook.

dts example:

  serial0: serial@f0300000 {
    compatible = "andestech,uart16550", "ns16550a";
    reg = <0x00000000 0xf0300000 0x00000000 0x00001000>;
    interrupts = <9 4>;
    interrupt-parent = <&plic0>;
    clock-frequency = <19660800>;
    current-speed = <38400>;
    reg-shift = <2>;
    reg-offset = <32>;
    reg-io-width = <4>;
    no-loopback-test = <1>;
  };

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:26:06 +05:30
Yu Chien Peter Lin
9899b59beb platform: andes/ae350: Use kconfig to set platform version and default name
This patch makes andes platform name and version can be set in
menuconfig interface.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:25:13 +05:30
Yu Chien Peter Lin
bd7ef41398 platform: andes/ae350: Remove enabling cache from an350_final_init
The boot-time cache operations have been handled by U-boot SPL, so we
can drop duplicate code.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:23:13 +05:30
Yu Chien Peter Lin
dcdaf30274 lib: sbi: Add sbi_domain_root_add_memrange() API
This patch generalizes the logic to add a memory range with desired
alignment and flags of consecutive regions to the root domain.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:21:21 +05:30
Yu Chien Peter Lin
60b78fee92 include: sbi: Fix grammar in comment
Fix minor grammar issue in function description.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:20:04 +05:30
Yu Chien Peter Lin
11d14ae7f2 lib: sbi: Fix typo in comment
%s/is is/is

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:19:28 +05:30
Yu Chien Peter Lin
98aa12738d include: sbi: Fix typo in comment
%s/Priviledge/Privilege

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-23 10:17:22 +05:30
Heiko Stuebner
b6e520b2a8 platform: generic: allwinner: add support for c9xx pmu
With the T-HEAD C9XX cores being designed before or during ratification
of the SSCOFPMF extension, they implement a PMU extension that behaves
very similar but not equal to it by providing overflow interrupts though
in a slightly different registers format.

The sun20i-d1 is using this core. So implement the necessary overrides
to allow its pmu to be used via the standard sbi-pmu extension.

For now it's also the only soc using this core, so keep the additional
code in the d1-space for now.

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2022-10-13 09:52:09 +05:30
Heiko Stuebner
2f63f2465c platform: generic: add extensions_init handler and platform-override
Init of non-standard extensions is a platform-specific thing,
so allow generic platforms to do this via a platform-override.

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2022-10-13 09:52:06 +05:30
Heiko Stuebner
4f2acb53e2 lib: sbi_platform: expose hart_features to extension_init callback
The platform-specific extension_init callback is supposed to
set specific things for the platform opensbi is running on.

So it's also the right place to override specific hart_features
if needed - when it's know that autodetection has provided
wrong results for example.

Suggested-by: Atish Patra <atishp@atishpatra.org>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2022-10-13 09:52:05 +05:30
Heiko Stuebner
c316fa38c2 lib: sbi_hart: move hart_features struct to a public location
Platforms may need to override auto-detected hart features
in their override functions. So move the hart_features
struct to the sbi_hart.h header allowing us to pass it over
to platform-handlers.

Suggested-by: Atish Patra <atishp@atishpatra.org>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2022-10-13 09:52:03 +05:30
Heiko Stuebner
e54cb3298b lib: sbi_pmu: move pmu irq information into pmu itself
Don't spread checking for pmu extensions through the code
but instead introduce a sbi-pmu function that other code can
call to get the correct information about the existence of the
pmu interrupt.

Add a sbi_pmu_device override function to allow overridung this
bit as well if needed.

Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
2022-10-13 09:52:01 +05:30
zhangdongdong
3f3d401d2d docs: Fix some typos
We fix few typos in documentation.

Signed-off-by: zhangdongdong <zhangdongdong@eswincomputing.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-13 09:28:54 +05:30
Nylon.Chen
7105c189f6 docs/firmware: Update FW_JUMP documentation
Add a tip for OpenSBI's FW_JUMP which helps
users avoid overwriting the kernel.

Signed-off-by: Nylon Chen <nylon.chen@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-10-13 09:25:15 +05:30
Kautuk Consul
7f09fba86e lib: utils/serial: add semihosting support
We add RISC-V semihosting based serial console for JTAG based early
debugging.

The RISC-V semihosting specification is available at:
https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Signed-off-by: Kautuk Consul <kconsul@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-09-13 18:24:42 +05:30
Rahul Pathak
49372f2691 lib: sbi: Fix sbi_strnlen wrong count decrement
count(maxlen) should not be decremented here

Fixes: 1901e8a287 ("platform: Add minimal libc support.")
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-09-13 17:17:10 +05:30
Anup Patel
8ce486a781 lib: utils/fdt: Fix DT parsing in fdt_pmu_setup()
This patch does following fixes in fdt_pmu_setup():
1) If any of the event mapping DT property is absent or too small
   then don't skip parsing of other DT properties.
2) Return failure if sbi_pmu_add_hw_event_counter_map() fails.
3) Return failure if sbi_pmu_add_raw_event_counter_map() fails.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-09-13 17:15:58 +05:30
Vivian Wang
46e744ab67 lib: sbi_misaligned_ldst: Set GVA if not emulating
If a particular misaligned load or store cannot be emulated at all, for
the redirected trap, trap.gva is set to 0, but it should be the same as
mstatus[h].GVA of the original trap. Fix this so that if the trap is
destined for HS-mode, hstatus.GVA is then set correctly.

Fixes: 1c4ce74f51 ("lib: sbi: Set gva when creating sbi_trap_info")
Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-09-13 16:43:07 +05:30
Vivian Wang
37a0d83b6d lib: sbi_trap: Add helper to get GVA in sbi_trap_regs
The GVA bit is in mstatus on RV64, and in mstatush in RV32. Refactor
code handling this in sbi_trap_handler into a helper function to extract
GVA from sbi_trap_regs, so that future code accessing GVA can be
XLEN-agnostic.

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-09-13 16:42:59 +05:30
Nikita Shubin
19664f6757 docs: pmu: extend bindings example for Unmatched
Extend example for Unmatched board to provide SBI PMU bindings
for generalized and cache event's where they are applicable.

Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-09-13 16:42:10 +05:30
Nikita Shubin
d32b0a92db docs: pmu: fix Unmatched example typo
bitmap for MHPMCOUNTERx should be 0x18 and not 0x0c, we check
against SBI_PMU_FIXED_CTR_MASK which assumes than first 3 bits are
dedicated to mcycle, mtime and minstret, u74 has 2 hardware counters.

Reported-by: Zhang Xin <zhangxin.xa@gmail.com>
Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-09-13 16:42:03 +05:30
Anup Patel
5019fd124b include: sbi: Reduce includes in sbi_pmu.h
The sbi_pmu.h should only include minimal required headers whereas
sbi_pmu.c should include all required headers.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-09-01 16:53:28 +05:30
Anup Patel
ee69f8eeb3 lib: sbi: Print platform PMU device at boot-time
Let us print the platform PMU device name at the boot-time so that users
know whether the underlying platform has custom per-HART PMU operations.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-09-01 16:53:25 +05:30
Anup Patel
d10c1f4acd lib: sbi_pmu: Add custom PMU device operations
We extend SBI PMU implementation to allow custom PMU device operations
which a platform can use for platform specific quirks.

The custom PMU device operations added by this patch include:
1) Operations to allow a platform implement custom firmware events.
   These custom firmware events can be SBI vendor extension related
   events or platform specific per-HART events are not possible to
   count through HPM CSRs.
2) Operations to allow a platform implement custom way for enabling
   (or disabling) an overflow interrupt (e.g. T-Head C9xx).

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-09-01 16:53:22 +05:30
Anup Patel
c9b388d578 lib: sbi_pmu: Simplify FW counters to reduce memory usage
Currently, we have 32 elements (i.e. SBI_PMU_FW_EVENT_MAX) array of
"struct sbi_pmu_fw_event" for each of 128 possible HARTs
(i.e. SBI_HARTMASK_MAX_BITS).

To reduce memory usage of OpenSBI, we update FW counter implementation
as follows:
1) Remove SBI_PMU_FW_EVENT_MAX
2) Remove "struct sbi_pmu_fw_event"
3) Create per-HART bitmap of XLEN bits to track FW counters
   which are started on each HART
4) Create per-HART uint64_t array to track values of FW
   counters on each HART.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-09-01 16:53:20 +05:30
Anup Patel
e238459fab lib: sbi_pmu: Firmware counters are always 64 bits wide
As-per SBI specification, all firmware counters are always 64 bits
wide so let us update the SBI PMU implementation to reflect this fact.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-09-01 16:53:18 +05:30
Anup Patel
1664d0efce lib: sbi_pmu: Replace sbi_pmu_ctr_read() with sbi_pmu_ctr_fw_read()
The "read a firmware counter" SBI call should only work for firmware
counters so let us replace sbi_pmu_ctr_read() with sbi_pmu_ctr_fw_read()
which works only on firmware counters.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-09-01 16:53:16 +05:30
Anup Patel
a90cf6b186 lib: sbi_pmu: Remove "event_idx" member from struct sbi_pmu_fw_event
The "event_idx" member of struct sbi_pmu_fw_event is not used
anywhere so let us remove it.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-09-01 16:53:14 +05:30
Rahul Pathak
622cc5f014 include: Remove sideleg and sedeleg
sideleg and sedeleg csrs are not part of riscv isa spec
anymore, these csrs were part of N extension which
is removed from the riscv isa specification.

These commits removed all traces of these csrs from
riscv spec (https://github.com/riscv/riscv-isa-manual) -

commit f8d27f805b65 ("Remove or downgrade more references to N extension (#674)")
commit b6cade07034d ("Remove N extension chapter for now")

Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-09-01 15:37:22 +05:30
Jun Liang Tan
cbaa9b0333 lib: utils: serial: Add Cadence UART driver
Add Cadence UART driver

Signed-off-by: Jun Liang Tan <junliang.tan@linux.starfivetech.com>
Signed-off-by: Wei Liang Lim <weiliang.lim@linux.starfivetech.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-08-23 08:40:17 +05:30
Anup Patel
adf44b51ba lib: sbi: Use the official extension name for AIA M-mode CSRs
The arch review of AIA spec is completed and we now have official
extension names for AIA: Smaia (M-mode AIA CSRs) and Ssaia (S-mode
AIA CSRs).

Refer, section 1.6 of the latest AIA v0.3.1 stable specification at
https://github.com/riscv/riscv-aia/releases/download/0.3.1-draft.32/riscv-interrupts-032.pdf)

Based on above, we update generic library to use "Smaia" extension
name for AIA M-mode CSRs.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-08-22 09:01:33 +05:30
Rahul Pathak
111afc1230 lib: sbi_illegal_insn: Fix FENCE.TSO emulation infinite trap loop
In case of missing "FENCE.TSO" instruction implementation,
opensbi can emulate the "FENCE.TSO" with "FENCE RW,RW", but
mepc was not incremented to continue from the next instruction
causing infinite trap.

Fixes: cb8271c8 ("lib: sbi_illegal_insn: Add emulation for fence.tso")
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Samuel Holland <samuel@sholland.org>
2022-08-22 08:57:23 +05:30
Vivian Wang
a69eb6cc65 lib: sbi_trap: Set hstatus.GVA when going to HS-mode
The privileged spec specifies that on a trap to HS-mode, hstatus.GVA
should be set to 1 if stval is written with a guest virtual address, and
to 0 otherwise. Implement this by setting hstatus.GVA to trap->gva when
redirecting traps to HS-mode.

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-08-22 08:50:23 +05:30
Vivian Wang
5a0ca098f1 lib: sbi_trap: Set hypervisor CSRs for HS-mode
The hypervisor CSRs hstatus, htval, htinst should always be set if the
trap is to be taken in HS-mode, regardless of which mode it came from.

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-08-22 08:50:04 +05:30
Vivian Wang
1c4ce74f51 lib: sbi: Set gva when creating sbi_trap_info
In some cases the sbi_trap_info argument passed to sbi_trap_redirect is
created from scratch by filling its fields. Since we previously added a
gva field to struct sbi_trap_info, initialize gva in these cases also.

Suggested-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-08-22 08:49:49 +05:30
Vivian Wang
1fbe7778c9 lib: sbi_trap: Save mstatus[h].GVA in trap->gva
The machine mode GVA field is available if the hypervisor extension is
implemented, and indicates if mtval is a guest virtual address. Add a
gva field to sbi_trap_info for this, and in __sbi_expected_trap_hext,
save mstatus[h].GVA to it, so that gva indicates if tval is a guest
virtual address. If the hypervisor extension is not implemented, always
set gva to 0.

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-08-22 08:49:39 +05:30
Vivian Wang
9529e360df include: Add mstatus[h].GVA encodings
The machine mode GVA field is in mstatus for RV64 and mstatush for RV32,
and is available if the hypervisor extension is available. If an
exception occurs, we may need to redirect the trap to HS-mode, in which
case, hstatus.GVA should be set to same as the machine mode GVA bit.

Add MSTATUS_GVA for RV64, MSTATUSH_GVA for RV32, and their SHIFT
encodings. The SHIFT index is helpful in assembly code, since field
extraction can be implemented in only one register. In pseudocode:

- For RV32: gva = (mstatus >> MSTATUS_GVA_SHIFT) & 1;
- For RV64: gva = (mstatush >> MSTATUSH_GVA_SHIFT) & 1;

Signed-off-by: Vivian Wang <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-08-22 08:49:29 +05:30
Anup Patel
a6a85579b6 Makefile: Fix typo related to object.mk
The "object.mk" name referred in top-level makefile should be
"objects.mk".

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:34:43 +05:30
Anup Patel
0723bab8fe docs: Update documentation for kconfig support
We update all documentation files to:
1) Remove references to platform specific config.mk file since it is
   has been removed.
2) Add details about platform specific configs/defconfig and Kconfig
   files mandatory for each platform.
3) Add required packages in top-level README.md
4) Fix typo releated to object.mk in docs/platform/platform.md

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:34:31 +05:30
Anup Patel
eccb9df5cf platform: Remove redundant config.mk from all platforms
The options defined in config.mk can be specified in objects.mk of each
platform so let us remove config.mk from all platforms.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:34:25 +05:30
Anup Patel
bc317a378f platform: generic: Use kconfig to set platform version and default name
The generic platform version and default name should be set based
on kconfig options so that users can override it.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:34:20 +05:30
Anup Patel
d514a8f0dc platform: generic: Use kconfig for enabling/disabling overrides
We update generic platform to use kconfig for enabling/disabling
platform overrides. We also enable all platform overrides in generic
platform defconfig.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:34:14 +05:30
Anup Patel
68d7b85ec7 lib: utils/fdt: Use kconfig for enabling/disabling
We update FDT support makefile to use kconfig for enabling/disabling.
To avoid compilation errors, we also enable FDT for each platform.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:34:08 +05:30
Anup Patel
5616aa4f4a lib: utils/gpio: Use kconfig for enabling/disabling drivers
We update gpio drivers makefile to use kconfig for enabling/disabling
drivers. To avoid compile errors, we also enable appropriate gpio
drivers for each platform.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:34:02 +05:30
Anup Patel
b126ce4a8f lib: utils/i2c: Use kconfig for enabling/disabling drivers
We update i2c drivers makefile to use kconfig for enabling/disabling
drivers. To avoid compile errors, we also enable appropriate i2c
drivers for each platform.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:33:57 +05:30
Anup Patel
0b1cf2f645 lib: utils/irqchip: Use kconfig for enabling/disabling drivers
We update irqchip drivers makefile to use kconfig for enabling/disabling
drivers. To avoid compile errors, we also enable appropriate irqchip
drivers for each platform.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:33:52 +05:30
Anup Patel
76af9d40da lib: utils/ipi: Use kconfig for enabling/disabling drivers
We update ipi drivers makefile to use kconfig for enabling/disabling
drivers. To avoid compile errors, we also enable appropriate ipi
drivers for each platform.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:33:45 +05:30
Anup Patel
013dbb3a60 lib: utils/timer: Use kconfig for enabling/disabling drivers
We update timer drivers makefile to use kconfig for enabling/disabling
drivers. To avoid compile errors, we also enable appropriate timer
drivers for each platform.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:33:37 +05:30
Anup Patel
3e76a607b5 lib: utils/sys: Use kconfig for enabling/disabling drivers
We update system drivers makefile to use kconfig for enabling/disabling
drivers. To avoid compile errors, we also enable appropriate system
drivers for each platform.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:33:31 +05:30
Anup Patel
2adc94b466 lib: utils/reset: Use kconfig for enabling/disabling drivers
We update reset drivers makefile to use kconfig for enabling/disabling
drivers. To avoid compile errors, we also enable appropriate reset
drivers for each platform.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:33:26 +05:30
Anup Patel
26bbff5f76 lib: utils/serial: Use kconfig for enabling/disabling drivers
We update serial drivers makefile to use kconfig for enabling/disabling
drivers. To avoid compile errors, we also enable appropriate serial
drivers for each platform.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:33:21 +05:30
Anup Patel
de80e9337d Makefile: Compile lib/utils sources separately for each platform
Currently, if same build directory is used to compile two different
platforms then lib/utils objects are shared for these platforms.

We will be having platform specific configs to enable/disable drivers
in lib/utils and select compile time options for lib/utils sources.
This means lib/utils sources will now be compiled in a platform
specific way.

To tackle above, we update top-level Makefile as follows:
1) Don't create libsbiutils.a anymore because this can't be shared
   between platforms.
2) Compile lib/utils sources separately for each platform.
3) Add comments showing which make rules are for lib/sbi, lib/utils,
   firmware, and platform sources.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:33:14 +05:30
Anup Patel
662e631cce Makefile: Add initial kconfig support for each platform
We extend the top-level makefile to allow kconfig based configuration
for each platform where each platform has it's own set of configs with
"defconfig" being the default config.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:33:09 +05:30
Anup Patel
422f0e0486 scripts: Add Kconfiglib v14.1.0 under scripts directory
We adopt Kconfiglib v14.1.0 sources under scripts directory so that
top-level OpenSBI makefile can directly use Kconfiglib scripts without
expecting users to install a particular version of Kconfiglib on their
build system.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Tested-by: Andrew Jones <ajones@ventanamicro.com>
Acked-by: Atish Patra <atishp@rivosinc.com>
Tested-by: Atish Patra <atishp@rivosinc.com>
2022-08-08 09:33:03 +05:30
dramforever
b9edf49b67 lib: sbi: Fix printf handling of long long
Read long long arguments directly using va_arg. Remove original hack for
RV32 that read a long long arg as two long args.

This un-breaks the case on RV64 where e.g. the long long is followed by
an odd number of ints:

    sbi_printf("%d %lld", (int) 1, (long long) 2LL);

Also remove the acnt variable, which is now unused.

Signed-off-by: dramforever <dramforever@live.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-30 11:55:51 +05:30
Andrew Jones
f27203525a lib: utils/serial: Ensure baudrate is non-zero before using
RISC-V doesn't generate exceptions on divide-by-zero, but the result,
all bits set, is not likely what people expect either. In all cases
where we divide by baudrate there's a chance it's zero (when the DT
it came from is "bad"). To avoid difficult to debug situations, leave
baudrate dependent registers alone when baudrate is zero, as, also in
all cases, it appears we can skip initialization of those registers
and still [hopefully] have a functioning UART.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-30 11:39:42 +05:30
Andrew Jones
7198e1d06f lib: serial: Clean up coding style in sifive-uart.c
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-30 11:39:19 +05:30
Andrew Jones
7d28d3be50 lib: utils/serial: Initialize platform_uart_data to zero
While it doesn't look like there are any current cases of using
uninitialized data, let's zero all the UART data members to be
safe. Zero may not actually be better than a random number in
some cases, so all structure members should still be validated
before use, but at least zero is usually easier to debug than
some random stack garbage...

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-30 11:39:10 +05:30
Andrew Jones
8e86b23db9 lib: utils/fdt: Factor out common uart node code
Factor out the common code used by the fdt UART node parsers,
allowing us to drop duplicate code.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-30 11:39:01 +05:30
Atish Patra
11c0008862 lib: sbi: Fix fw_event_map initialization
fw_event_map represents array of firmware events. It should initialized
for maximum number of firmware events not counters.

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-30 11:28:36 +05:30
Atish Patra
860a376817 lib: sbi: Fix possible buffer overrun in counter validation
The active_events array is accessed with counter ID passed from the supervisor
software before the counter ID bound check. This may cause a buffer overrun
if a supervisor passes an invalid counter ID.

Fix this by moving the access part after the bound check.

Reported-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-30 11:25:48 +05:30
Atish Patra
83db3af5f9 lib: sbi: Add the bound check for events during config match
Currently, there is no sanity check for firmware event code. We don't see
any issue as Linux kernel driver does a bound check on firmware events
already. However, OpenSBI can't assume sane supervisor mode software
always. Thus, an invalid event idx can cause a buffer overflow error.
For hardware events, the match will fail for invalid event code anyways.
However, a search is unecessary if event code is invalid.

Add a event ID validation function to solve the issue.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-30 11:22:50 +05:30
Atish Patra
1545afd342 lib: sbi: Fix counter index sanity check
The current implementation computes the possible counter range
by doing a left shift of counter base. However, this may overflow depending
on the counter base value. In case of overflow, the highest counter id
may be computed incorrectly. As per the SBI specification, the respective
function should return an error if any of the counter is not valid.

Fix the counter index check by avoiding left shifting while doing the
sanity checks. Without the shift, the implementation just iterates
over the counter mask and computes the correct counter index by adding
the base to it.

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-30 11:09:18 +05:30
Andrew Jones
88b790f129 lib: sbi: Fix sbi_snprintf
printc would happily write to 'out' even when 'out_len' was zero,
potentially overflowing buffers. Rework printc to not do that and
also ensure the null byte is written at the last position when
necessary, as stated in the snprintf man page. Also, panic if
sprintf or snprintf are called with NULL output strings (except
the special case of snprintf having a NULL output string and
a zero output size, allowing it to be used to get the number of
characters that would have been written). Finally, rename a
goto label which clashed with 'out'.

Fixes: 9e8ff05cb6 ("Initial commit.")
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-30 11:02:07 +05:30
Prasanna T
4e21ccacd1 lib: utils/serial: Update Shakti UART based on latest implementation
The age old version of Shakti UART was upgraded long back, but we missed
updating the driver in OpenSBI. The old version of UART is not supported
anymore, hence removed the inline comment which is also outdated now.

Signed-off-by: Prasanna T <ptprasanna@gmail.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2022-07-20 10:06:25 +05:30
gagachang
0374ccf3f1 lib: sbi_hart: Shorten the code to set MPV bit
MPV bit is set when the value of next_virt boolean variable equals
true. Since the value of next_virt is either 0 or 1, we can set
MPV bit without if-else logic.

Signed-off-by: Che-Chia Chang <alvinga@andestech.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-20 10:05:33 +05:30
Ben Dooks
caa5eeacac lib: sbi: add check for ipi device for hsm start
If the ecall SBI_EXT_HSM_HART_START is called it might try to wake the
secondary hart using sbi_ipi_raw_send() to send an IPI to the hart.
This can fail if there is no IPI device but no error is returned from
sbi_ipi_raw_send() so the ecall returns as if the action completed and
the caller continues without noticing (in the case of Linux it just hangs
waiting for the secondary hart to become active)

Fix this by changing sbi_ipi_raw_send() to return and error, and if an
error is returned, then return it via SBI_EXT_HSM_HART_START call.

Signed-off-by: Ben Dooks <ben.dooks@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-11 15:46:59 +05:30
Adnan Rahman Chowdhury
994c8cfb29 lib: sbi_timer: Added a conditional wait function which can timeout
Motivation: Suppose a peripheral needs to be configured to transmit
data. There is an SFR bit which indicates that the peripheral is ready
to transmit. The firmware should check the bit and will only transmit
data when the peripheral is ready. When the firmware starts polling the
SFR, the peripheral could be busy transmitting/receiving other data so
the firmware must wait till that completes. Assuming that there is no
other way, the firmware shouldn't wait indefinitely.

The function sbi_timer_waitms_until() will constantly check whether a
certain condition is satisfied, or timeout occurs. It can be used for
the cases when a timeout is required.

Signed-off-by: Adnan Rahman Chowdhury <adnan.chowdhury@sifive.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-07-08 14:51:24 +05:30
Anup Patel
4489876e93 include: Bump-up version to 1.1
This patch updates OpenSBI version to 1.1 as part of
release preparation.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
2022-06-25 09:12:10 +05:30
Sergey Matyukevich
3f66465fb6 lib: pmu: allow to use the highest available counter
OpenSBI explicitly assumes that there is no pmu hardware counter with
index 1: hardware uses that bit for TM control. So OpenSBI filters
out that index in sanity checks. However OpenSBI also excludes that
counter when reports total amount of hardware counters to Linux. As
a result, Linux uses incomplete counters mask excluding the highest
available counter.

Return accurate number of counters, update the firmware counter
starting index, fix range checks that include num_hw_ctrs.

The simple test is to make sure that there is no counter multiplexing
in the following command:

$ perf stat -e \
	r8000000000000000,r8000000000000001,r8000000000000002,r8000000000000003, \
	r8000000000000004,r8000000000000005,r8000000000000006,r8000000000000007, \
	r8000000000000008,r8000000000000009,r800000000000000a,r800000000000000b, \
	r800000000000000c,r800000000000000d,r800000000000000e,r800000000000000f  \
	ls

Note that 16 firmware events with 16 counters won't require multiplexing.

Signed-off-by: Sergey Matyukevich <geomatsi@gmail.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-06-25 08:44:20 +05:30
Anup Patel
c6fdbcf83f include: sbi: Change spec version to 1.0
Now that SBI v1.0 specification is ratified, we change spec verion
implemented by OpenSBI to v1.0.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-06-24 08:54:59 +05:30
Samuel Holland
6f1fe98c2f lib: utils/timer: Remove Allwinner D1 CLINT compatibles
The allwinner,sun20i-d1-clint compatible string is not documented in any
official binding, so it should not be used by drivers.

The MSWI in the D1 CLINT is compatible with the ACLINT specification, so
it can take advantage of generic driver support. However, that is only
possible if the MSWI and MTIMER are split into separate DT nodes. This
means the final binding for this device is likely to be incompatible
with what is implemented here.

Remove this compatible string from the driver to prevent it from
appearing in a stable version and causing future issues.

Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-06-22 10:55:37 +05:30
Jan Remes
d76a196bfc lib: irqchip/plic: fix typo in plic_warm_irqchip_init
The second invocation of plic_context_init() incorrectly calls the
function with m_cntx_id instead of s_cntx_id. This breaks systems which
only have 1 external interrupt per hart.

Fixes: 8c362e7 ("lib: irqchip/plic: Factor out a context init function")
Signed-off-by: Jan Remes <jan.remes@codasip.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Samuel Holland <samuel@sholland.org>
2022-06-22 10:55:27 +05:30
Samuel Holland
7738345396 lib: utils/timer: Add a separate compatible for the D1 CLINT
The CLINT in the Allwinner D1 SoC apparently does not support 64-bit
MMIO access. A property was added to support this quirk (and that
property was copied to the ACLINT MTIMER code). However, since this
difference in behavior makes the D1 CLINT incompatible with the SiFive
CLINT's programming interface, a better solution is to use a separate
compatible string.

Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-06-21 09:20:59 +05:30
Anup Patel
c6530012d4 lib: utils: Remove CSRs that set/clear an IMSIC interrupt file bits
Based on architecture review committee feedback, the [m|s|vs]seteienum,
[m|s|vs]clreienum, [m|s|vs]seteipnum, and [m|s|vs]clreipnum CSRs are
removed in the latest AIA draft v0.3.0 specification.
(Refer, https://github.com/riscv/riscv-aia/releases/tag/0.3.0-draft.31)

These CSRs were mostly for software convenience and software can always
use [m|s|vs]iselect and [m|s|vs]ireg CSRs to update the IMSIC interrupt
file bits.

We update the IMSIC programming as-per above to match the latest AIA
draft specification.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-06-21 08:44:45 +05:30
dramforever
a07402ac9c lib: sbi: Fix tval and tinst for sbi_get_insn()
We should not change trap->tval to mepc because mtval already points to
the faulting portion of the emulated instruction fetch, which is also
what stval is expected to be.

In addition, htinst is only allowed to be zero for instruction access
faults or page faults, and is only allowed to be zero or a
psuedoinstruction for instruction guest-page faults. Fix trap->tinst for
these cases.

Signed-off-by: dramforever <dramforever@live.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-06-21 08:31:56 +05:30
dramforever
187127fb89 lib: sbi: Fixup tinst for exceptions in sbi_misaligned_*()
If there is an exception while emulating a misaligned load/store, fixup
uptrap.tinst before redirecting. Otherwise, HS-mode software may receive
an htinst describing the lbu/sb instruction that faulted during
emulation[1].

[1]: https://github.com/riscv-software-src/opensbi/issues/258

Signed-off-by: dramforever <dramforever@live.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-06-21 08:31:14 +05:30
dramforever
551c70c040 include: sbi: Add mtinst/htinst psuedoinstructions
Add psuedoinstruction encodings written to mtinst/htinst for faults
caused by implicit memory access for VS-stage address translation

Signed-off-by: dramforever <dramforever@live.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-06-21 08:31:04 +05:30
Samuel Holland
9dc5ec5c51 platform: Add HSM implementation for Allwinner D1
Allwinner D1 contains a "PPU" power domain controller which can
automatically power down/up the CPU power domain. This power domain
includes the C906 core along with its CLINT and PLIC.

This HSM implementation supports non-retentive hart suspend by:
  1) Saving/restoring state that is lost during hart suspend,
  2) Performing cache maintenance before/after hart suspend,
  3) Configuring wakeup sources before hart suspend, and
  4) Asking the PPU to power down the hart when it enters WFI.

Since this HSM implementation is for a single-core SoC, it does not need
to worry about concurrency or saving multiple instances of state.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2022-06-13 11:59:09 +05:30
Samuel Holland
5e5675874c lib: utils/irqchip: Add wrapper for T-HEAD PLIC delegation
The delegation bit is lost along with the rest of the PLIC state when
the CPU power domain in the Allwinner D1 is powered down, so the PLIC
needs to be re-delegated to S-mode during the hart resume path.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2022-06-13 11:54:06 +05:30
Samuel Holland
69be3dff9d lib: utils/irqchip: Add FDT wrappers for PLIC save/restore functions
These functions save/restore the state of the PLIC associated with the
current hart. The context save/restore functions only manipulate a
single context, since most likely the M-mode context is unused and does
not need to be saved.

Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-06-13 11:54:06 +05:30
Samuel Holland
2b79b694a8 lib: irqchip/plic: Add priority save/restore helpers
These can be used by platform code to save the PLIC priority state, if
it would otherwise be lost during non-retentive suspend. The platform
is responsible for allocating all necessary storage.

As a space optimization, store the saved priority values as 8-bit
integers, since that is large enough to hold any priority value on the
relevant platforms.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2022-06-13 11:54:06 +05:30
Samuel Holland
415ecf28f7 lib: irqchip/plic: Add context save/restore helpers
These can be used by platform code to save the PLIC context state, if
it would otherwise be lost during non-retentive suspend. The platform
is responsible for allocating all necessary storage.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2022-06-13 11:54:06 +05:30
Samuel Holland
8c362e7d06 lib: irqchip/plic: Factor out a context init function
This simplifies both the callers and the callees by removing duplicated
code and consolidating the error handling. It also fixes two bugs in the
process:
  1) ie_words was one too large when plic->num_src was a multiple of 32.
  2) plic_set_ie takes a 32-bit mask, not a Boolean value, so the FPGA
     platforms previously only enabled one out of every 32 interrupts.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2022-06-13 11:54:06 +05:30
Samuel Holland
2ea7799d56 lib: irqchip/plic: Constify plic_data pointers
None of the functions modify the passed-in plic_data, so mark it const.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2022-06-13 11:54:06 +05:30
Samuel Holland
79e42eb2d6 lib: sbi_hsm: Assume a consistent resume address
The suspend code needs to know the resume address for two reasons:
  1) Programming some hardware register or management firmware. Here we
     assume the hardware/firmware maintains its state between suspends,
     so it only needs to be programmed once at startup.
  2) When a non-retentive suspend request ends up being retentive, due
     to lack of hardware support, pending interrupt, or for some other
     reason. However, the behavior here is not platform-dependent, and
     this can be handled in the generic hart suspend function.

Since neither situation requires the platform-level suspend function to
know the resume address, stop passing it to that function. Instead,
handle the non-retentive to retentive situation generically.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2022-06-13 11:54:06 +05:30
Samuel Holland
b20ed9febe lib: sbi_hsm: Call a device hook during hart resume
Non-retentive suspend states may require platform-specific actions
during resume. For example, firmware may need to save and restore the
values of custom CSRs. Add a hook to support this.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2022-06-13 11:54:06 +05:30
Mayuresh Chitale
ce1d6188a2 platform: generic: add overrides for vendor extensions
Allow the vendor_ext_check and vendor_ext_provider APIs of the
generic platform to be overridden by other platforms

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-06-13 11:17:38 +05:30
dramforever
adc3388d76 lib: sbi_trap: Redirect exception based on hedeleg
HS-mode software can choose what exceptions to delegate to VS-mode using
the hedeleg CSR. Synthetic VS/VU-mode exceptions should also honor
hedeleg. They should be redirected to VS-mode if and only if delegated
by HS-mode.

Signed-off-by: dramforever <dramforever@live.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-06-13 11:02:49 +05:30
Samuel Holland
cb8271c8e4 lib: sbi_illegal_insn: Add emulation for fence.tso
While OpenC906 appears to properly decode `fence.tso` as a fence
instruction[1], the version of the C906 taped out in the Allwinner D1
does not, and raises illegal instruction.

Handle this errata by emulating `fence.tso` as `fence rw, rw`.

[1]: https://github.com/T-head-Semi/openc906/blob/30827e7f/C906_RTL_FACTORY/gen_rtl/idu/rtl/aq_idu_id_decd.v#L2097

Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-06-01 17:20:20 +05:30
Samuel Holland
ff65bfec4e lib: sbi_illegal_insn: Constify illegal_insn_table
This table does not need to be modified at runtime.

Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-05-30 10:54:31 +05:30
Samuel Holland
295e5f3c69 lib: sbi_timer: Drop unnecessary get_platform_ticks wrapper
The device's timer_value callback is already the right prototype to use
for the get_time_val function pointer.

Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-05-30 10:43:03 +05:30
Samuel Holland
fab0379bb6 lib: utils/fdt: Require match data to be const
Match data stores hardware attributes which do not change at runtime, so
it does not need to be mutable. Make it const.

Reviewed-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
2022-05-30 10:32:35 +05:30
Xiang W
f067bb84cf lib: sbi: fix system_opcode_insn
If the csr's operation comes from M mode, it should not be forwarded
to low-privilege processing, this patch fixes this problem.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-05-30 10:22:13 +05:30
Jan Remes
1bc67db80c lib: utils/fdt: rename fdt_parse_max_hart_id
The function returns the highest hart-id of the harts actually used in
the system (enabled). Change the name to reflect this fact.

Signed-off-by: Jan Remes <jan.remes@codasip.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-05-14 10:18:12 +05:30
Jan Remes
575bb4e8ca platform: generic: check if CPU node is enabled
Ignore CPU nodes in FDT which are not enabled.

Signed-off-by: Jan Remes <jan.remes@codasip.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-05-14 10:17:33 +05:30
Jan Remes
616da52e18 lib: utils: check if CPU node is enabled
Ignore CPU nodes in FDT that are not enabled.

Signed-off-by: Jan Remes <jan.remes@codasip.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-05-14 10:16:50 +05:30
Jan Remes
90a9dd2b22 lib: utils/fdt: introduce fdt_node_is_enabled()
If an FDT node contains a "status" property and this property is not
"ok" or "okay", this node should be ignored. Introduce a function that
checks this.

Signed-off-by: Jan Remes <jan.remes@codasip.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-05-14 10:16:24 +05:30
Jan Remes
851c14d455 lib: utils/irqchip: fix typo when checking for CPU node
Fix typo in irqchip_imsic_update_hartid_table() when checking for CPU
node.

Signed-off-by: Jan Remes <jan.remes@codasip.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
2022-05-13 09:58:54 +05:30
Anup Patel
9a7a677d5f platform: generic: Move Sifive platform overrides into own directory
Let us move SiFive platform overrides for FU540 and FU740 into a separate
directory so better maintainability. Other SoC vendors can also create
their own directory under platform/generic.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:27:23 +05:30
Anup Patel
a3a3c60b66 platform: generic: Generate platform override module list at compile-time
Instead of having platform override module list hard-coded in the C source,
we generate it using carray.sh at compile-time.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:27:18 +05:30
Anup Patel
4eacd8229b lib: utils/gpio: Generate FDT gpio driver list at compile-time
Instead of having FDT gpio driver list hard-coded in the C source,
we generate it using carray.sh at compile-time.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:27:12 +05:30
Anup Patel
998ed43fde lib: utils/i2c: Generate FDT i2c adapter driver list at compile-time
Instead of having FDT i2c adapter driver list hard-coded in the C source,
we generate it using carray.sh at compile-time.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:26:45 +05:30
Anup Patel
4ee0c57969 lib: utils/ipi: Generate FDT ipi driver list at compile-time
Instead of having FDT ipi driver list hard-coded in the C source,
we generate it using carray.sh at compile-time.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:26:35 +05:30
Anup Patel
3a69d12fc3 lib: utils/irqchip: Generate FDT irqchip driver list at compile-time
Instead of having FDT irqchip driver list hard-coded in the C source,
we generate it using carray.sh at compile-time.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:26:27 +05:30
Anup Patel
bfeb305e0f lib: utils/timer: Generate FDT timer driver list at compile-time
Instead of having FDT timer driver list hard-coded in the C source,
we generate it using carray.sh at compile-time.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:26:20 +05:30
Anup Patel
1e62705adc lib: utils/serial: Generate FDT serial driver list at compile-time
Instead of having FDT serial driver list hard-coded in the C source,
we generate it using carray.sh at compile-time.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:26:13 +05:30
Anup Patel
73cf511914 lib: utils/reset: Generate FDT reset driver list at compile-time
Instead of having FDT reset driver list hard-coded in the C source,
we generate it using carray.sh at compile-time.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:26:06 +05:30
Anup Patel
7fb474b9dd Makefile: Add support for generating C array at compile time
Generating C array at compile time based on details provided by
objects.mk is a very useful feature which will help us compile
only a subset of drivers or modules.

We add a bash script (carray.sh) which takes array details and
object/variable list from command-line to generate a C source
containing array of object/variable pointers. We also extend
top-level makefile to use carray.sh whenever specified through
objects.mk.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:26:00 +05:30
Anup Patel
f726f2dc01 Makefile: Allow generated C source to be anywhere in build directory
The generated C source could be anywhere within build directory so
let us update the make rule to comple generated C source accordingly.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-13 09:25:50 +05:30
Anup Patel
023f0ad2d9 lib: sbi_platform: Add callback to populate HART extensions
We add platform specific extensions_init() callback which allows
platforms to populate HART extensions for each HART. For example,
the generic platform can populate HART extensions from HART ISA
string described in DeviceTree.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 10:17:28 +05:30
Anup Patel
994ace30f7 lib: sbi: Add sbi_hart_update_extension() function
We add sbi_hart_update_extension() function which allow platforms
to enable/disable hart extensions.

Signed-off-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 10:17:25 +05:30
Anup Patel
be4903ae00 lib: sbi: Detect hart features only once for each hart
Currently, the hart_detect_features() is called everytime a hart
is stopped and started again which is unnecessary work.

We update hart_detect_features() to detect hart features only
once for each hart.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 10:17:22 +05:30
Anup Patel
cad6c91045 lib: sbi: Convert hart features into hart extensions
Since past few years, we have been using "hart features" in OpenSBI
to represent all optionalities and multi-letter extensions defined
by the RISC-V specifications.

The RISC-V profiles specification has taken a different approach and
started assigning extension names for all optionalities which did not
have any extension name previously.
(Refer, https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc)

Inspired from the RISC-V profiles specification, we convert OpenSBI
hart features into hart extensions. Going forward, we align the
extension naming with RISC-V profiles specification. Currently, only
"time CSR" and "AIA CSR" have not been assigned extension name but
for everything else we have a name.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 10:16:30 +05:30
Anup Patel
a6ab94fdbf lib: sbi: Fix AIA feature detection
The AIA feature detection uses unnecessary goto which is not need
and AIA case in sbi_hart_feature_id2string() does not break. This
patch fixes both issues in AIA feature detection.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 10:06:57 +05:30
Anup Patel
97a17c2e5c lib: sbi: Remove MENVCFG hart feature
If a hart implements privileged spec v1.12 (or higher) then we can
safely assume that menvcfg CSR is present and we don't need MENVCFG
as a hart feature.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 10:06:19 +05:30
Anup Patel
dbc3d8f0ef lib: sbi: Remove MCOUNTINHIBT hart feature
If a hart implements privileged spec v1.11 (or higher) then we can
safely assume that mcountinhibit CSR is present and we don't need
MCOUNTINHIBT as a hart feature.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 10:05:37 +05:30
Anup Patel
d4b563c881 lib: sbi: Remove MCOUNTEREN and SCOUNTEREN hart features
If a hart implements privileged spec v1.10 (or higher) then we can
safely assume that [m|s]counteren CSR are present and we don't need
MCOUNTEREN and SCOUNTEREN as hart features.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 10:04:54 +05:30
Anup Patel
5b8b377178 lib: sbi: Update the name of ISA string printed at boot time
The ISA string printed at boot time is not the complete ISA string
representing all single letter and multi-letter extensions rather
it is base ISA string derived from misa CSR so let us update the
boot print accordingly.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 10:03:24 +05:30
Anup Patel
5a6be99cc5 lib: sbi: Remove 's' and 'u' from misa_string() output
Both 's' and 'u' are not treated as ISA extensions since these are
privilege modes so let's remove it from misa_string() output.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 10:02:28 +05:30
Anup Patel
1a754bb365 lib: sbi: Detect and print privileged spec version
It is possible to guess privileged spec versions based on the CSRs
that where introduced in different privileged spec versions. In
future, if we are not able guess privileged spec version then we
can have platform provide it.

We add privileged spec version as per-hart feature and try to guess
it based on presence of mcounteren, mcountinhibit, and menvcfg CSRs.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-05-07 09:49:54 +05:30
Atish Patra
b0c9df514b lib: sbi: Fix mhpmeventh access for rv32 in absence of sscofpmf
MHPMEVENT3H-31H are defined in sscofpmf extension. Thus, they should be
accessed only if sscofpmf is present.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-05-07 09:40:59 +05:30
Jun Liang Tan
e576b3e620 include: sbi: Define SBI_PMU_HW_EVENT_MAX to 256
Increase maximum number of PMU hardware events that can be mapped
by OpenSBI to 256

Signed-off-by: Jun Liang Tan <junliang.tan@linux.starfivetech.com>
Signed-off-by: Wei Liang Lim <weiliang.lim@linux.starfivetech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-05-07 09:37:42 +05:30
Anup Patel
474a9d4555 lib: sbi: Fix mstatus_init() for RV32 when Sscofpmf is not available
The mhpmevent3h to mhpmevent31h CSRs are available on RV32 only when
Sscofpmf extension is available so mstatus_init() should set this
CSRs only when Sscofpmf extension is available.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-04-28 19:39:01 +05:30
Atish Patra
d62f6da062 lib: sbi: Implement Sstc extension
Recently, Sstc extension was ratified. It defines stimecmp which allows
the supervisor mode to directly update the timecmp value without the
need of the SBI call. The hardware also can inject the S-mode timer
interrupt direclty to the supervisor without going through the M-mode.
To maintain backward compatibility with the older software, SBI call
now uses stimecmp directly if the hardware supports.

Implement the Sstc extension.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-04-28 11:45:21 +05:30
Atish Patra
4035ae94be docs: pmu: Improve the PMU DT bindings
The current DT binding description is misleading and confusing. Clarify
the text and provide more examples.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-04-28 11:40:15 +05:30
Dmitry Dunaev
9cd95e13bb lib: sbi/hart: preserve csr validation value
The OpenSBI hart init function hart_detect_features() try to read
important CSRs but reasign the last read value to the variable that
initially contains write probe value. So for series of CSRs (like
PMPADDRx) the second CSR probe value will became the initial value of
first probing CSR. To avoid of this issue the CSR read value should be
saved in different variable. In this configuration the count of PMP
will detect rightly if any PMPADDR is hardwired to zero.

Signed-off-by: Dmitry Dunaev <dunaich@mail.ru>
Signed-off-by: Anup Patel <anup@brainfault.org>
2022-04-17 14:43:08 +05:30
Vincent Chen
c1e47d0c3f include: correct the definition of MSTATUS_VS
Accordind to the RISC-V privileged specification, the VS filed is
mstatus[10:9] instead of mstatus[24:23]. Modify the MSTATUS_VS
to the correct value.

Reported-by: I-Cheng Cheng <i-cheng.cheng@sifive.com>
Signed-off-by: Vincent Chen <vincent.chen@sifive.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-04-17 14:30:19 +05:30
Zong Li
5c5cbb53a4 lib: utils/serial: support 'reg-offset' property
reg-offset property is used for offset to apply to the mapbase
from the start of the registers in 8250 UART. In Linux kernel,
it has been handled in 8250 UART driver.

dt-bindings:
<linux>/Documentation/devicetree/bindings/serial/8250.yaml

Signed-off-by: Zong Li <zong.li@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-04-17 13:57:48 +05:30
Mayuresh Chitale
3383d6a4d1 lib: irqchip/imsic: configure mstateen
When mstateen registers are implemented, the AIA related
configurations need to be done in mstateen for the IMSIC
initialization to succeed.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-04-11 08:34:17 +05:30
Mayuresh Chitale
d44568a0f2 lib: sbi: Detect Smstateen CSRs at boot-time
Extend HART feature detection to discover Smstateen CSRs at boot-time
and configure mstateen envcfg bit depending on availability of
menvcfg CSR.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-04-11 08:34:10 +05:30
Mayuresh Chitale
499601a4ff lib: sbi: Add Smstateen extension defines
Smstateen extension provides a mechanism to plug potential
covert channels which are opened by extensions that add to
processor state that may not get context-switched.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-04-11 08:34:02 +05:30
Anup Patel
794986f87f lib: sbi: Enable Svpbmt extension in the menvcfg CSR
The menvcfg.PBMTE bit is read-only zero when Svpbmt extension is not
available so we try to enable menvcfg.PBMTE bit irrespective whether
Svpbmt is available or not.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2022-04-05 08:53:11 +05:30
Anup Patel
47d676570d lib: sbi: Enable Zicbo[m|z] extensions in the menvcfg CSR
The bits to configure/enable Zicbo[m|z] extensions in the menvcfg
CSR are WARL. We try to enable these bits irrespective whether
these extensions are available or not because writes to these
bits will be ignored if these extensions are not available.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2022-04-05 08:51:40 +05:30
Atish Patra
31fecad46d lib: sbi: Detect menvcfg CSR at boot time
We add the menvcfg CSR as a HART feature and detect it at boot time
using traping mechanism.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2022-04-05 08:50:48 +05:30
Anup Patel
722f80d8e9 include: Add defines for [m|h|s]envcfg CSRs
The latest RISC-V privileged specification introduces xenvcfg CSRs
to enable/disable certain features/extensions for lower privilege
modes. This patch adds defines for these new [m|h|s]envcfg CSRs.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
2022-04-05 08:50:17 +05:30
Xiang W
7924a0b220 include: Use static asserts for FW_DYNAMIC_INFO_xxx_OFFSET defines
Add static detection to prevent the modification of struct fw_dynamic_info
from forgetting the modification of FW_DYNAMIC_INFO_xxx_OFFSET

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-03-27 09:44:58 +05:30
Xiang W
1b42d3ace3 include: Use static asserts for SBI_SCRATCH_xxx_OFFSET defines
Add static detection to prevent the modification of struct sbi_scratch
from forgetting the modification of SBI_SCRATCH_xxx_OFFSET

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-03-27 09:44:54 +05:30
Xiang W
555bdb1cf3 include: Use static asserts for SBI_PLATFORM_xxx_OFFSET defines
Add static detection to prevent the modification of struct sbi_platform
from forgetting the modification of SBI_PLATFORM_xxx_OFFSET

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-03-27 09:07:44 +05:30
Xiang W
d552fc8d36 lib: Add error messages via conditional compilation for the future
On 128-bit machines, sbi_load_xx/sbi_store_xx needs to be improved.
Through this conditional compile, the corresponding implementation
can be prompted to be added.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-03-27 08:54:12 +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
Xiang W
2dfbd3c0e2 lib: pmp_set/pmp_get moved errors from runtime to compile time
pmp_set/pmp_get calculates the location of the CSR register separately
through conditional compilation. In the case of non-32-bit and 64-bit,
we can report an error directly through #error without putting it at
runtime

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-03-27 08:52:19 +05:30
Alistair Francis
4998a712b2 lib: utils: serial: Initial commit of xlnx-uartlite
Initial commit of the xlnx-uartlite device and FDT support. This was
tested by running OpenSBI on a modified QEMU virt machine using the
xlnx-uartlite for serial.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-02-28 09:50:09 +05:30
Anup Patel
f3f4604c19 lib: sbi: Add a simple external interrupt handling framework
Currently, the external interrupt handling is scattered between
sbi_init and sbi_trap. This patch moves all external interrupt
handling into a simple framework called sbi_irqchip.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-28 09:43:12 +05:30
Nikita Shubin
f2ccf2f783 lib: sbi: verbose sbi_domain_root_add_memregion
Be more verbose on region confict, print addresses in conflict.

Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-02-15 20:59:38 +05:30
Nikita Shubin
3a69cc1487 lib: sbi: fix typo in is_region_subset
Fix typo in is_region_subset, regB_end should be calculated from regB.

Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
Reviewed-by: Dong Du <Dd_nirvana@sjtu.edu.cn>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-02-15 20:58:04 +05:30
Anup Patel
8e2ef4f7af lib: utils: Disable appropriate APLIC DT nodes in fdt_fixups()
We should disable APLIC DT nodes in fdt_fixups() which are not
accessible to the next booting stage based on currently assigned
domain.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:39:15 +05:30
Anup Patel
34612193af lib: utils/irqchip: Add FDT based driver for APLIC
We add simple FDT irqchip driver for APLIC so that generic platform (and
other FDT based platforms) can utilize common APLIC initialization library.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:39:01 +05:30
Anup Patel
99792653de lib: utils/irqchip: Add APLIC initialization library
We add simple APLIC initialization library which is independent of
hardware description format (FDT or ACPI). This APLIC initialization
library can be used by custom OpenSBI platform support to setup
APLIC domains.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:37:55 +05:30
Anup Patel
7127aaaaf7 lib: utils: Disable appropriate IMSIC DT nodes in fdt_fixups()
We should disable IMSIC DT nodes in fdt_fixups() which are not
accessible to the next booting stage based on currently assigned
domain.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:37:27 +05:30
Anup Patel
811da5c541 lib: utils/irqchip: Add FDT based driver for IMSIC
We add simple FDT irqchip driver for IMSIC so that generic platform
(and other FDT based platforms) can utilize common IMIC library.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:37:05 +05:30
Anup Patel
9f73669959 lib: utils/irqchip: Add IMSIC library
We add simple IMSIC library which is independent of hardware description
format (FDT or ACPI). This IMSIC library can be used by custom OpenSBI
platform support to setup IMSIC for external interrupts.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:36:24 +05:30
Anup Patel
55e79f823d lib: sbi: Enable mie.MEIE bit for IPIs based on external interrupts.
We can have IPIs based on external interrupts provided by devices
such as AIA IMSIC so we should enable mie.MEIE bit at appropriate
places in generic library.

Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:35:45 +05:30
Anup Patel
10509405b2 include: sbi: Introduce nascent_init() platform callback
We introduce nascent_init() platform callback which will allow
platforms to do very early initialization of platform specific
per-HART CSRs and per-HART devices.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:34:24 +05:30
Anup Patel
5f56314618 lib: utils/irqchip: Allow multiple FDT irqchip drivers
We can have multiple FDT irqchip drivers to be probed when a RISC-V
system has different types of interrupt controller in a hierarchy.

This will be certainly the case when a RISC-V system has both
RISC-V AIA IMSIC and RISC-V AIA APLIC implemented.

We extend simple FDT irqchip framework to allow multiple FDT
irqchip drivers to be used for same RISC-V platform.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:34:08 +05:30
Anup Patel
222132f48c lib: sbi: Add sbi_trap_set_external_irqfn() API
This patch adds sbi_trap_set_external_irqfn() API which can be used by
OpenSBI platform code to set a callback function for external interrupts.
The RISC-V AIA IMSIC driver will use this API to implement inter-processor
interrupts on-top-of MSIs.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:33:55 +05:30
Anup Patel
65b4c7c01e lib: sbi: Use AIA CSRs for local interrupts when available
We should use AIA CSRs to process local interrupts whenever AIA
is available.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:33:31 +05:30
Anup Patel
8f96070067 lib: sbi: Detect AIA CSRs at boot-time
We extend HART feature detection to discover AIA CSRs at boot-time.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:32:42 +05:30
Anup Patel
01250d0044 include: sbi: Add AIA related CSR defines
The RISC-V AIA specification improves handling of per-HART local
interrupts in a backward compatible manner. This patch adds defines
for the new RISC-V AIA CSRs.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-02-15 20:32:07 +05:30
Jakub Luzny
ce4c0188d9 lib: utils/serial: Round UART8250 baud rate divisor to nearest integer
Previously, it was rounded down and that gives suboptimal results when
non-standard clock sources or baud rates are used.

Signed-off-by: Jakub Luzny <jakub.luzny@codasip.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-02-04 11:16:29 +05:30
Petro Karashchenko
6ad8917b7e lib: fix compilation when strings.h is included
In a systems that provide strings.h and it is included
together with sbi_bitops.h the compilation error appears.
The ffs() and fls() are provided by strings.h

Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-02-04 11:04:19 +05:30
Aurelien Jarno
5d53b55aa7 Makefile: fix build with binutils 2.38
From version 2.38, binutils default to ISA spec version 20191213. This
means that the csr read/write (csrr*/csrw*) instructions and fence.i
instruction has separated from the `I` extension, become two standalone
extensions: Zicsr and Zifencei. As the kernel uses those instruction,
this causes the following build failure:

 CC        lib/sbi/sbi_tlb.o
<<BUILDDIR>>/lib/sbi/sbi_tlb.c: Assembler messages:
<<BUILDDIR>>/lib/sbi/sbi_tlb.c:190: Error: unrecognized opcode `fence.i'
make: *** [Makefile:431: <<BUILDDIR>>/build/lib/sbi/sbi_tlb.o] Error 1

The fix is to specify those extensions explicitly in -march. However as
older binutils version do not support this, we first need to detect
that.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Alexandre Ghiti <alexandre.ghiti@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-02-04 10:47:24 +05:30
Atish Patra
a26dc609df lib: sbi: Disable interrupt and inhibit counting in M-mode during init
Currently, the mhpmevent CSRs are untouched during hart init during
cold/warm boot. Ideally, we should clear out all the bits except
overflow and MINH bit. That is required to disable overflow
interrupt and inhibit counting in M-mode to avoid any spurious
interrupts before perf start.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-02-04 10:10:28 +05:30
Atish Patra
3b7c204dca lib: sbi: Disable interrupt during config matching
PMU overflow interrupt should be disabled durinig initial configuration of
counters. They should be enabled while starting counters.

Fixes: 730f01bb41 ("lib: sbi: Support sscofpmf extension in OpenSBI")
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-02-04 10:08:57 +05:30
Atish Patra
632f59392b lib: sbi: Map only the counters enabled in hardware
The counter mapping in DT may be incorrect if all the counters specified
in the mapping are actually not physically present in the hardware.
OpenSBI should only keep a mapping of counters enabled in hardware and
defined in DT. This assume that all the programmable hpmcounters are
consecutive as it doesn't make sense to build a system with sparse
hpmcounters.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-02-04 10:07:07 +05:30
Jukka Laitinen
5d025eb235 lib: fix pointer of type 'void *' used in arithmetic
Using "void *" in arithmetic causes errors with strict compiler settings:
"error: pointer of type 'void *' used in arithmetic [-Werror=pointer-arith]"

Avoid these by calculating on "char *" where 1-byte data size is assumed.

Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
Reviewed-by: Dong Du <Dd_nirvana@sjtu.edu.cn>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-01-21 21:58:12 +05:30
Aurelien Jarno
fb688d9e9d platform: sifive_fu740: fix reset when watchdog is running
When the watchdog is running the HiFive Unmatched board does not reboot
properly and shuts down itself a few seconds after reboot, in the early
stages of the u-boot loading. On a Linux kernel this happens when the
da9063_wdt module is loaded. This does not happen if the module is
unloaded before reboot or if the watchdog module is loaded with
"stop_on_reboot=1".

Fix that by stopping the watchdog before attempting to reset the board.
This is done by zeroing the TWDSCALE field of CONTROL_D register, unless
it was already set to 0.

Reported-by: Tianon Gravi <tianon@debian.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Nikita Shubin <n.shubin@yadro.com>
Tested-by: Nikita Shubin <n.shubin@yadro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
2022-01-21 21:44:57 +05:30
Aurelien Jarno
8257262dbf platform: sifive_fu740: do not use a global in da9063_reset/shutdown
da9063_reset() and da9063_shutdown() take the chip address in argument
(like similar functions), but in practice use the da9063 global struct
instead. Fix that.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Nikita Shubin <n.shubin@yadro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Xiang W <wxjstz@126.com>
2022-01-21 21:41:33 +05:30
Anup Patel
6dde43584f lib: utils/sys: Extend HTIF library to allow custom base address
Some of RISC-V emulators provide HTIF at fixed base address so for
such emulators users have to hard-code HTIF base address in the
linker script.

To address this problem, we let users optionally provide fixed HTIF
base address via platform support (or device tree).

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Dong Du <Dd_nirvana@sjtu.edu.cn>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
2022-01-11 18:17:49 +05:30
Anup Patel
5b9960379f lib: utils/ipi: Fix size check in aclint_mswi_cold_init()
Currently, the ACLINT MSWI size check is forcing size to be at least
0x4000. This is inappropriate check because most systems will never
utilize full 16KB for a single ACLINT MSWI device so instead we should
check that ACLINT MSWI size is enough for on the associated HARTs.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Dong Du <Dd_nirvana@sjtu.edu.cn>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
2022-01-11 18:17:07 +05:30
426 changed files with 41594 additions and 6587 deletions

21
.editorconfig Normal file
View File

@@ -0,0 +1,21 @@
# SPDX-License-Identifier: GPL-2.0-only
# See here for more information about the format and editor support:
# https://editorconfig.org/
root = true
[{*.{c,dts,h,lds,ldS,mk,s,S},Kconfig,Makefile,Makefile.*}]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = tab
indent_size = 8
[*.py]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4

26
.github/workflows/repo-lockdown.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: 'Repo Lockdown'
on:
pull_request_target:
types: opened
permissions:
pull-requests: write
jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/repo-lockdown@v4
with:
pr-comment: |
We have mailing list based patch review so it would be great if you can send these patchs to OpenSBI mailing list.
You need to join OpenSBI mailing list using following link
http://lists.infradead.org/mailman/listinfo/opensbi
Make sure you use "git send-email" to send the patches.
Thanks for your contribution to OpenSBI project.
lock-pr: true
close-pr: true

11
.gitignore vendored
View File

@@ -1,3 +1,12 @@
# ignore anything begin with dot
.*
# exceptions we need even begin with dot
!.clang-format
!.gitignore
!.github
!.editorconfig
# Object files
*.o
*.a
@@ -9,3 +18,5 @@ install/
# Development friendly files
tags
cscope*
*~

25
Kconfig Normal file
View File

@@ -0,0 +1,25 @@
# SPDX-License-Identifier: BSD-2-Clause
mainmenu "OpenSBI $(OPENSBI_PLATFORM) Configuration"
config OPENSBI_SRC_DIR
string
option env="OPENSBI_SRC_DIR"
config OPENSBI_PLATFORM
string
option env="OPENSBI_PLATFORM"
config OPENSBI_PLATFORM_SRC_DIR
string
option env="OPENSBI_PLATFORM_SRC_DIR"
menu "Platform Options"
source "$(OPENSBI_PLATFORM_SRC_DIR)/Kconfig"
endmenu
source "$(OPENSBI_SRC_DIR)/lib/sbi/Kconfig"
source "$(OPENSBI_SRC_DIR)/lib/utils/Kconfig"
source "$(OPENSBI_SRC_DIR)/firmware/Kconfig"

274
Makefile
View File

@@ -47,11 +47,14 @@ ifdef PLATFORM_DIR
platform_parent_dir=$(platform_dir_path)
else
PLATFORM=$(shell basename $(platform_dir_path))
platform_parent_dir=$(subst $(PLATFORM),,$(platform_dir_path))
platform_parent_dir=$(shell realpath ${platform_dir_path}/..)
endif
else
platform_parent_dir=$(src_dir)/platform
endif
ifndef PLATFORM_DEFCONFIG
PLATFORM_DEFCONFIG=defconfig
endif
# Check if verbosity is ON for build process
CMD_PREFIX_DEFAULT := @
@@ -70,17 +73,47 @@ export libsbi_dir=$(CURDIR)/lib/sbi
export libsbiutils_dir=$(CURDIR)/lib/utils
export firmware_dir=$(CURDIR)/firmware
# Setup variables for kconfig
ifdef PLATFORM
export PYTHONDONTWRITEBYTECODE=1
export KCONFIG_DIR=$(platform_build_dir)/kconfig
export KCONFIG_AUTOLIST=$(KCONFIG_DIR)/auto.list
export KCONFIG_AUTOHEADER=$(KCONFIG_DIR)/autoconf.h
export KCONFIG_AUTOCONFIG=$(KCONFIG_DIR)/auto.conf
export KCONFIG_AUTOCMD=$(KCONFIG_DIR)/auto.conf.cmd
export KCONFIG_CONFIG=$(KCONFIG_DIR)/.config
# Additional exports for include paths in Kconfig files
export OPENSBI_SRC_DIR=$(src_dir)
export OPENSBI_PLATFORM=$(PLATFORM)
export OPENSBI_PLATFORM_SRC_DIR=$(platform_src_dir)
endif
# Find library version
OPENSBI_VERSION_MAJOR=`grep "define OPENSBI_VERSION_MAJOR" $(include_dir)/sbi/sbi_version.h | sed 's/.*MAJOR.*\([0-9][0-9]*\)/\1/'`
OPENSBI_VERSION_MINOR=`grep "define OPENSBI_VERSION_MINOR" $(include_dir)/sbi/sbi_version.h | sed 's/.*MINOR.*\([0-9][0-9]*\)/\1/'`
OPENSBI_VERSION_GIT=$(shell if [ -d $(src_dir)/.git ]; then git describe 2> /dev/null; fi)
OPENSBI_VERSION_GIT=
# Detect 'git' presence before issuing 'git' commands
GIT_AVAIL := $(shell command -v git 2> /dev/null)
ifneq ($(GIT_AVAIL),)
GIT_DIR := $(shell git rev-parse --git-dir 2> /dev/null)
ifneq ($(GIT_DIR),)
OPENSBI_VERSION_GIT := $(shell if [ -d $(GIT_DIR) ]; then git describe 2> /dev/null; fi)
endif
endif
# Setup compilation commands
ifneq ($(LLVM),)
CC = clang
AR = llvm-ar
LD = ld.lld
OBJCOPY = llvm-objcopy
ifneq ($(filter %/,$(LLVM)),)
LLVM_PREFIX := $(LLVM)
else ifneq ($(filter -%,$(LLVM)),)
LLVM_SUFFIX := $(LLVM)
endif
CC = $(LLVM_PREFIX)clang$(LLVM_SUFFIX)
AR = $(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX)
LD = $(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX)
OBJCOPY = $(LLVM_PREFIX)llvm-objcopy$(LLVM_SUFFIX)
else
ifdef CROSS_COMPILE
CC = $(CROSS_COMPILE)gcc
@@ -147,11 +180,32 @@ else
USE_LD_FLAG = -fuse-ld=bfd
endif
REPRODUCIBLE ?= n
ifeq ($(REPRODUCIBLE),y)
REPRODUCIBLE_FLAGS += -ffile-prefix-map=$(src_dir)=
endif
# Check whether the linker supports creating PIEs
OPENSBI_LD_PIE := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) $(USE_LD_FLAG) -fPIE -nostdlib -Wl,-pie -x c /dev/null -o /dev/null >/dev/null 2>&1 && echo y || echo n)
# Check whether the linker supports --exclude-libs
OPENSBI_LD_EXCLUDE_LIBS := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) $(USE_LD_FLAG) "-Wl,--exclude-libs,ALL" -x c /dev/null -o /dev/null >/dev/null 2>&1 && echo y || echo n)
# Check whether the compiler supports -m(no-)save-restore
CC_SUPPORT_SAVE_RESTORE := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -mno-save-restore -x c /dev/null -o /dev/null 2>&1 | grep "\-save\-restore" >/dev/null && echo n || echo y)
CC_SUPPORT_SAVE_RESTORE := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -mno-save-restore -x c /dev/null -o /dev/null 2>&1 | grep -e "-save-restore" >/dev/null && echo n || echo y)
# Check whether the compiler supports -m(no-)strict-align
CC_SUPPORT_STRICT_ALIGN := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -mstrict-align -x c /dev/null -o /dev/null 2>&1 | grep -e "-mstrict-align" -e "-mno-unaligned-access" >/dev/null && echo n || echo y)
# Check whether the assembler and the compiler support the Zicsr and Zifencei extensions
CC_SUPPORT_ZICSR_ZIFENCEI := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -march=rv$(OPENSBI_CC_XLEN)imafd_zicsr_zifencei -x c /dev/null -o /dev/null 2>&1 | grep -e "zicsr" -e "zifencei" > /dev/null && echo n || echo y)
# Check whether the assembler and the compiler support the Vector extension
CC_SUPPORT_VECTOR := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -march=rv$(OPENSBI_CC_XLEN)gv -dM -E -x c /dev/null 2>&1 | grep -q riscv.*vector && echo y || echo n)
ifneq ($(OPENSBI_LD_PIE),y)
$(error Your linker does not support creating PIEs, opensbi requires this.)
endif
# Build Info:
# OPENSBI_BUILD_TIME_STAMP -- the compilation time stamp
@@ -159,16 +213,18 @@ CC_SUPPORT_SAVE_RESTORE := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib
BUILD_INFO ?= n
ifeq ($(BUILD_INFO),y)
OPENSBI_BUILD_DATE_FMT = +%Y-%m-%d %H:%M:%S %z
ifndef OPENSBI_BUILD_TIME_STAMP
ifdef SOURCE_DATE_EPOCH
OPENSBI_BUILD_TIME_STAMP ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" \
OPENSBI_BUILD_TIME_STAMP := $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" \
"$(OPENSBI_BUILD_DATE_FMT)" 2>/dev/null || \
date -u -r "$(SOURCE_DATE_EPOCH)" \
"$(OPENSBI_BUILD_DATE_FMT)" 2>/dev/null || \
date -u "$(OPENSBI_BUILD_DATE_FMT)")
else
OPENSBI_BUILD_TIME_STAMP ?= $(shell date "$(OPENSBI_BUILD_DATE_FMT)")
OPENSBI_BUILD_TIME_STAMP := $(shell date "$(OPENSBI_BUILD_DATE_FMT)")
endif
OPENSBI_BUILD_COMPILER_VERSION=$(shell $(CC) -v 2>&1 | grep ' version ' | \
endif
OPENSBI_BUILD_COMPILER_VERSION := $(shell $(CC) -v 2>&1 | grep ' version ' | \
sed 's/[[:space:]]*$$//')
endif
@@ -180,12 +236,42 @@ libsbi-object-mks=$(shell if [ -d $(libsbi_dir) ]; then find $(libsbi_dir) -inam
libsbiutils-object-mks=$(shell if [ -d $(libsbiutils_dir) ]; then find $(libsbiutils_dir) -iname "objects.mk" | sort -r; fi)
firmware-object-mks=$(shell if [ -d $(firmware_dir) ]; then find $(firmware_dir) -iname "objects.mk" | sort -r; fi)
# Include platform specifig config.mk
# The "make all" rule should always be first rule
.PHONY: all
all:
# Include platform specific .config
ifdef PLATFORM
include $(platform_src_dir)/config.mk
.PHONY: menuconfig
menuconfig: $(platform_src_dir)/Kconfig $(src_dir)/Kconfig
$(CMD_PREFIX)mkdir -p $(KCONFIG_DIR)
$(CMD_PREFIX)$(src_dir)/scripts/Kconfiglib/menuconfig.py $(src_dir)/Kconfig
.PHONY: savedefconfig
savedefconfig: $(platform_src_dir)/Kconfig $(src_dir)/Kconfig
$(CMD_PREFIX)mkdir -p $(KCONFIG_DIR)
$(CMD_PREFIX)$(src_dir)/scripts/Kconfiglib/savedefconfig.py --kconfig $(src_dir)/Kconfig --out $(KCONFIG_DIR)/defconfig
$(KCONFIG_CONFIG): $(platform_src_dir)/configs/$(PLATFORM_DEFCONFIG)
$(CMD_PREFIX)mkdir -p $(KCONFIG_DIR)
$(CMD_PREFIX)$(src_dir)/scripts/Kconfiglib/defconfig.py --kconfig $(src_dir)/Kconfig $(platform_src_dir)/configs/$(PLATFORM_DEFCONFIG)
$(KCONFIG_AUTOCONFIG): $(KCONFIG_CONFIG)
$(CMD_PREFIX)$(src_dir)/scripts/Kconfiglib/genconfig.py --header-path $(KCONFIG_AUTOHEADER) --sync-deps $(KCONFIG_DIR) --file-list $(KCONFIG_AUTOLIST) $(src_dir)/Kconfig
$(KCONFIG_AUTOHEADER): $(KCONFIG_AUTOCONFIG);
$(KCONFIG_AUTOLIST): $(KCONFIG_AUTOCONFIG);
$(KCONFIG_AUTOCMD): $(KCONFIG_AUTOLIST)
$(CMD_PREFIX)printf "%s: " $(KCONFIG_CONFIG) > $(KCONFIG_AUTOCMD)
$(CMD_PREFIX)cat $(KCONFIG_AUTOLIST) | tr '\n' ' ' >> $(KCONFIG_AUTOCMD)
include $(KCONFIG_AUTOCONFIG)
include $(KCONFIG_AUTOCMD)
endif
# Include all object.mk files
# Include all objects.mk files
ifdef PLATFORM
include $(platform-object-mks)
endif
@@ -195,8 +281,8 @@ include $(firmware-object-mks)
# Setup list of objects
libsbi-objs-path-y=$(foreach obj,$(libsbi-objs-y),$(build_dir)/lib/sbi/$(obj))
libsbiutils-objs-path-y=$(foreach obj,$(libsbiutils-objs-y),$(build_dir)/lib/utils/$(obj))
ifdef PLATFORM
libsbiutils-objs-path-y=$(foreach obj,$(libsbiutils-objs-y),$(platform_build_dir)/lib/utils/$(obj))
platform-objs-path-y=$(foreach obj,$(platform-objs-y),$(platform_build_dir)/$(obj))
firmware-bins-path-y=$(foreach bin,$(firmware-bins-y),$(platform_build_dir)/firmware/$(bin))
endif
@@ -208,6 +294,7 @@ deps-y=$(platform-objs-path-y:.o=.dep)
deps-y+=$(libsbi-objs-path-y:.o=.dep)
deps-y+=$(libsbiutils-objs-path-y:.o=.dep)
deps-y+=$(firmware-objs-path-y:.o=.dep)
deps-y+=$(firmware-elfs-path-y:=.dep)
# Setup platform ABI, ISA and Code Model
ifndef PLATFORM_RISCV_ABI
@@ -223,7 +310,10 @@ ifndef PLATFORM_RISCV_ABI
endif
ifndef PLATFORM_RISCV_ISA
ifneq ($(PLATFORM_RISCV_TOOLCHAIN_DEFAULT), 1)
PLATFORM_RISCV_ISA = rv$(PLATFORM_RISCV_XLEN)imafdc
PLATFORM_RISCV_ISA := rv$(PLATFORM_RISCV_XLEN)imafdc
ifeq ($(CC_SUPPORT_ZICSR_ZIFENCEI), y)
PLATFORM_RISCV_ISA := $(PLATFORM_RISCV_ISA)_zicsr_zifencei
endif
else
PLATFORM_RISCV_ISA = $(OPENSBI_CC_ISA)
endif
@@ -273,22 +363,34 @@ ifeq ($(BUILD_INFO),y)
GENFLAGS += -DOPENSBI_BUILD_TIME_STAMP="\"$(OPENSBI_BUILD_TIME_STAMP)\""
GENFLAGS += -DOPENSBI_BUILD_COMPILER_VERSION="\"$(OPENSBI_BUILD_COMPILER_VERSION)\""
endif
GENFLAGS += -include $(include_dir)/sbi/sbi_visibility.h
ifdef PLATFORM
GENFLAGS += -include $(KCONFIG_AUTOHEADER)
endif
GENFLAGS += $(libsbiutils-genflags-y)
GENFLAGS += $(platform-genflags-y)
GENFLAGS += $(firmware-genflags-y)
CFLAGS = -g -Wall -Werror -ffreestanding -nostdlib -fno-stack-protector -fno-strict-aliasing -O2
CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls -mstrict-align
# enable -m(no-)save-restore option by CC_SUPPORT_SAVE_RESTORE
CFLAGS = -g -Wall -Werror -ffreestanding -nostdlib -fno-stack-protector -fno-strict-aliasing -ffunction-sections -fdata-sections
CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables
CFLAGS += $(REPRODUCIBLE_FLAGS)
# Optionally supported flags
ifeq ($(CC_SUPPORT_VECTOR),y)
CFLAGS += -DOPENSBI_CC_SUPPORT_VECTOR
endif
ifeq ($(CC_SUPPORT_SAVE_RESTORE),y)
CFLAGS += -mno-save-restore
endif
ifeq ($(CC_SUPPORT_STRICT_ALIGN),y)
CFLAGS += -mstrict-align
endif
CFLAGS += -mabi=$(PLATFORM_RISCV_ABI) -march=$(PLATFORM_RISCV_ISA)
CFLAGS += -mcmodel=$(PLATFORM_RISCV_CODE_MODEL)
CFLAGS += $(RELAX_FLAG)
CFLAGS += $(GENFLAGS)
CFLAGS += $(platform-cflags-y)
CFLAGS += -fno-pie -no-pie
CFLAGS += -fPIE -pie
CFLAGS += $(firmware-cflags-y)
CPPFLAGS += $(GENFLAGS)
@@ -296,11 +398,16 @@ CPPFLAGS += $(platform-cppflags-y)
CPPFLAGS += $(firmware-cppflags-y)
ASFLAGS = -g -Wall -nostdlib
ASFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls -mstrict-align
# enable -m(no-)save-restore option by CC_SUPPORT_SAVE_RESTORE
ASFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
ASFLAGS += -fPIE
ASFLAGS += $(REPRODUCIBLE_FLAGS)
# Optionally supported flags
ifeq ($(CC_SUPPORT_SAVE_RESTORE),y)
ASFLAGS += -mno-save-restore
endif
ifeq ($(CC_SUPPORT_STRICT_ALIGN),y)
ASFLAGS += -mstrict-align
endif
ASFLAGS += -mabi=$(PLATFORM_RISCV_ABI) -march=$(PLATFORM_RISCV_ISA)
ASFLAGS += -mcmodel=$(PLATFORM_RISCV_CODE_MODEL)
ASFLAGS += $(RELAX_FLAG)
@@ -316,7 +423,12 @@ ASFLAGS += $(firmware-asflags-y)
ARFLAGS = rcs
ELFFLAGS += $(USE_LD_FLAG)
ELFFLAGS += -Wl,--build-id=none -Wl,-N
ELFFLAGS += -Wl,--gc-sections
ifeq ($(OPENSBI_LD_EXCLUDE_LIBS),y)
ELFFLAGS += -Wl,--exclude-libs,ALL
endif
ELFFLAGS += -Wl,--build-id=none
ELFFLAGS += -Wl,--no-dynamic-linker -Wl,-pie
ELFFLAGS += $(platform-ldflags-y)
ELFFLAGS += $(firmware-ldflags-y)
@@ -330,6 +442,13 @@ MERGEFLAGS += -m elf$(PLATFORM_RISCV_XLEN)lriscv
DTSCPPFLAGS = $(CPPFLAGS) -nostdinc -nostdlib -fno-builtin -D__DTS__ -x assembler-with-cpp
ifneq ($(DEBUG),)
CFLAGS += -O0
ELFFLAGS += -Wl,--print-gc-sections
else
CFLAGS += -O2
endif
# Setup functions for compilation
define dynamic_flags
-I$(shell dirname $(2)) -D__OBJNAME__=$(subst -,_,$(shell basename $(1) .o))
@@ -342,10 +461,10 @@ merge_deps = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
cat $(2) > $(1)
copy_file = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
echo " COPY $(subst $(build_dir)/,,$(1))"; \
cp -f $(2) $(1)
cp -L -f $(2) $(1)
inst_file = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
echo " INSTALL $(subst $(install_root_dir)/,,$(1))"; \
cp -f $(2) $(1)
cp -L -f $(2) $(1)
inst_file_list = $(CMD_PREFIX)if [ ! -z "$(4)" ]; then \
mkdir -p $(1)/$(3); \
for file in $(4) ; do \
@@ -354,12 +473,17 @@ inst_file_list = $(CMD_PREFIX)if [ ! -z "$(4)" ]; then \
dest_dir=`dirname $$dest_file`; \
echo " INSTALL "$(3)"/"`echo $$rel_file`; \
mkdir -p $$dest_dir; \
cp -f $$file $$dest_file; \
cp -L -f $$file $$dest_file; \
done \
fi
inst_header_dir = $(CMD_PREFIX)mkdir -p $(1); \
echo " INSTALL $(subst $(install_root_dir)/,,$(1))"; \
cp -rf $(2) $(1)
cp -L -rf $(2) $(1)
compile_cpp_dep = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
echo " CPP-DEP $(subst $(build_dir)/,,$(1))"; \
printf %s `dirname $(1)`/ > $(1) && \
$(CC) $(CPPFLAGS) -x c -MM $(3) \
-MT `basename $(1:.dep=$(2))` >> $(1) || rm -f $(1)
compile_cpp = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
echo " CPP $(subst $(build_dir)/,,$(1))"; \
$(CPP) $(CPPFLAGS) -x c $(2) | grep -v "\#" > $(1)
@@ -397,66 +521,73 @@ compile_d2c = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
$(if $($(2)-varprefix-$(3)),$(eval D2C_NAME_PREFIX := $($(2)-varprefix-$(3))),$(eval D2C_NAME_PREFIX := $(5))) \
$(if $($(2)-padding-$(3)),$(eval D2C_PADDING_BYTES := $($(2)-padding-$(3))),$(eval D2C_PADDING_BYTES := 0)) \
$(src_dir)/scripts/d2c.sh -i $(6) -a $(D2C_ALIGN_BYTES) -p $(D2C_NAME_PREFIX) -t $(D2C_PADDING_BYTES) > $(1)
compile_carray = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
echo " CARRAY $(subst $(build_dir)/,,$(1))"; \
$(eval CARRAY_VAR_LIST := $(carray-$(subst .carray.c,,$(shell basename $(1)))-y)) \
$(src_dir)/scripts/carray.sh -i $(2) -l "$(CARRAY_VAR_LIST)" > $(1) || rm $(1)
compile_gen_dep = $(CMD_PREFIX)mkdir -p `dirname $(1)`; \
echo " GEN-DEP $(subst $(build_dir)/,,$(1))"; \
echo "$(1:.dep=$(2)): $(3)" >> $(1)
targets-y = $(build_dir)/lib/libsbi.a
targets-y += $(build_dir)/lib/libsbiutils.a
ifdef PLATFORM
targets-y += $(platform_build_dir)/lib/libplatsbi.a
endif
targets-y += $(firmware-bins-path-y)
# Default rule "make" should always be first rule
# The default "make all" rule
.PHONY: all
all: $(targets-y)
# Preserve all intermediate files
.SECONDARY:
# Rules for lib/sbi sources
$(build_dir)/lib/libsbi.a: $(libsbi-objs-path-y)
$(call compile_ar,$@,$^)
$(build_dir)/lib/libsbiutils.a: $(libsbi-objs-path-y) $(libsbiutils-objs-path-y)
$(call compile_ar,$@,$^)
$(platform_build_dir)/lib/libplatsbi.a: $(libsbi-objs-path-y) $(libsbiutils-objs-path-y) $(platform-objs-path-y)
$(call compile_ar,$@,$^)
$(build_dir)/%.dep: $(src_dir)/%.c
$(build_dir)/%.dep: $(src_dir)/%.carray $(KCONFIG_AUTOHEADER)
$(call compile_gen_dep,$@,.c,$< $(KCONFIG_AUTOHEADER))
$(call compile_gen_dep,$@,.o,$(@:.dep=.c))
$(build_dir)/%.carray.c: $(src_dir)/%.carray $(src_dir)/scripts/carray.sh
$(call compile_carray,$@,$<)
$(build_dir)/%.dep: $(src_dir)/%.c $(KCONFIG_AUTOHEADER)
$(call compile_cc_dep,$@,$<)
$(build_dir)/%.o: $(src_dir)/%.c
$(call compile_cc,$@,$<)
$(build_dir)/%.o: $(build_dir)/%.c
$(call compile_cc,$@,$<)
ifeq ($(BUILD_INFO),y)
$(build_dir)/lib/sbi/sbi_init.o: $(libsbi_dir)/sbi_init.c FORCE
$(call compile_cc,$@,$<)
endif
$(build_dir)/%.dep: $(src_dir)/%.S
$(build_dir)/%.dep: $(src_dir)/%.S $(KCONFIG_AUTOHEADER)
$(call compile_as_dep,$@,$<)
$(build_dir)/%.o: $(src_dir)/%.S
$(call compile_as,$@,$<)
$(platform_build_dir)/%.bin: $(platform_build_dir)/%.elf
$(call compile_objcopy,$@,$<)
# Rules for platform sources
$(platform_build_dir)/%.dep: $(platform_src_dir)/%.carray $(KCONFIG_AUTOHEADER)
$(call compile_gen_dep,$@,.c,$< $(KCONFIG_AUTOHEADER))
$(call compile_gen_dep,$@,.o,$(@:.dep=.c))
$(platform_build_dir)/%.elf: $(platform_build_dir)/%.o $(platform_build_dir)/%.elf.ld $(platform_build_dir)/lib/libplatsbi.a
$(call compile_elf,$@,$@.ld,$< $(platform_build_dir)/lib/libplatsbi.a)
$(platform_build_dir)/%.carray.c: $(platform_src_dir)/%.carray $(src_dir)/scripts/carray.sh
$(call compile_carray,$@,$<)
$(platform_build_dir)/%.ld: $(src_dir)/%.ldS
$(call compile_cpp,$@,$<)
$(platform_build_dir)/%.dep: $(platform_src_dir)/%.c
$(platform_build_dir)/%.dep: $(platform_src_dir)/%.c $(KCONFIG_AUTOHEADER)
$(call compile_cc_dep,$@,$<)
$(platform_build_dir)/%.o: $(platform_src_dir)/%.c
$(call compile_cc,$@,$<)
$(platform_build_dir)/%.o: $(platform_build_dir)/%.c
$(platform_build_dir)/%.o: $(platform_src_dir)/%.c $(KCONFIG_AUTOHEADER)
$(call compile_cc,$@,$<)
$(platform_build_dir)/%.dep: $(platform_src_dir)/%.S
@@ -465,8 +596,8 @@ $(platform_build_dir)/%.dep: $(platform_src_dir)/%.S
$(platform_build_dir)/%.o: $(platform_src_dir)/%.S
$(call compile_as,$@,$<)
$(platform_build_dir)/%.dep: $(platform_src_dir)/%.dts
$(call compile_gen_dep,$@,.dtb,$<)
$(platform_build_dir)/%.dep: $(platform_src_dir)/%.dts $(KCONFIG_AUTOHEADER)
$(call compile_gen_dep,$@,.dtb,$< $(KCONFIG_AUTOHEADER))
$(call compile_gen_dep,$@,.c,$(@:.dep=.dtb))
$(call compile_gen_dep,$@,.o,$(@:.dep=.c))
@@ -476,13 +607,33 @@ $(platform_build_dir)/%.c: $(platform_build_dir)/%.dtb
$(platform_build_dir)/%.dtb: $(platform_src_dir)/%.dts
$(call compile_dts,$@,$<)
$(platform_build_dir)/%.dep: $(src_dir)/%.c
# Rules for lib/utils and firmware sources
$(platform_build_dir)/%.bin: $(platform_build_dir)/%.elf
$(call compile_objcopy,$@,$<)
$(platform_build_dir)/%.elf: $(platform_build_dir)/%.o $(platform_build_dir)/%.elf.ld $(platform_build_dir)/lib/libplatsbi.a
$(call compile_elf,$@,$@.ld,$< $(platform_build_dir)/lib/libplatsbi.a)
$(platform_build_dir)/%.dep: $(src_dir)/%.ldS $(KCONFIG_AUTOHEADER)
$(call compile_cpp_dep,$@,.ld,$<)
$(platform_build_dir)/%.ld: $(src_dir)/%.ldS
$(call compile_cpp,$@,$<)
$(platform_build_dir)/%.dep: $(src_dir)/%.carray $(KCONFIG_AUTOHEADER)
$(call compile_gen_dep,$@,.c,$< $(KCONFIG_AUTOHEADER))
$(call compile_gen_dep,$@,.o,$(@:.dep=.c))
$(platform_build_dir)/%.carray.c: $(src_dir)/%.carray $(src_dir)/scripts/carray.sh
$(call compile_carray,$@,$<)
$(platform_build_dir)/%.dep: $(src_dir)/%.c $(KCONFIG_AUTOHEADER)
$(call compile_cc_dep,$@,$<)
$(platform_build_dir)/%.o: $(src_dir)/%.c
$(call compile_cc,$@,$<)
$(platform_build_dir)/%.dep: $(src_dir)/%.S
$(platform_build_dir)/%.dep: $(src_dir)/%.S $(KCONFIG_AUTOHEADER)
$(call compile_as_dep,$@,$<)
$(platform_build_dir)/%.o: $(src_dir)/%.S
@@ -526,7 +677,6 @@ endif
endif
install_targets-y = install_libsbi
install_targets-y += install_libsbiutils
ifdef PLATFORM
install_targets-y += install_libplatsbi
install_targets-y += install_firmwares
@@ -541,17 +691,12 @@ install_libsbi: $(build_dir)/lib/libsbi.a
$(call inst_header_dir,$(install_root_dir)/$(install_include_path),$(include_dir)/sbi)
$(call inst_file,$(install_root_dir)/$(install_lib_path)/libsbi.a,$(build_dir)/lib/libsbi.a)
.PHONY: install_libsbiutils
install_libsbiutils: $(build_dir)/lib/libsbiutils.a
$(call inst_header_dir,$(install_root_dir)/$(install_include_path),$(include_dir)/sbi_utils)
$(call inst_file,$(install_root_dir)/$(install_lib_path)/libsbiutils.a,$(build_dir)/lib/libsbiutils.a)
.PHONY: install_libplatsbi
install_libplatsbi: $(platform_build_dir)/lib/libplatsbi.a $(build_dir)/lib/libsbi.a $(build_dir)/lib/libsbiutils.a
install_libplatsbi: $(platform_build_dir)/lib/libplatsbi.a $(build_dir)/lib/libsbi.a
$(call inst_file,$(install_root_dir)/$(install_lib_path)/opensbi/$(platform_subdir)/lib/libplatsbi.a,$(platform_build_dir)/lib/libplatsbi.a)
.PHONY: install_firmwares
install_firmwares: $(platform_build_dir)/lib/libplatsbi.a $(build_dir)/lib/libsbi.a $(build_dir)/lib/libsbiutils.a $(firmware-bins-path-y)
install_firmwares: $(platform_build_dir)/lib/libplatsbi.a $(build_dir)/lib/libsbi.a $(firmware-bins-path-y)
$(call inst_file_list,$(install_root_dir),$(build_dir),$(install_firmware_path)/$(platform_subdir)/firmware,$(firmware-elfs-path-y))
$(call inst_file_list,$(install_root_dir),$(build_dir),$(install_firmware_path)/$(platform_subdir)/firmware,$(firmware-bins-path-y))
@@ -559,12 +704,25 @@ install_firmwares: $(platform_build_dir)/lib/libplatsbi.a $(build_dir)/lib/libsb
install_docs: $(build_dir)/docs/latex/refman.pdf
$(call inst_file,$(install_root_dir)/$(install_docs_path)/refman.pdf,$(build_dir)/docs/latex/refman.pdf)
.PHONY: cscope
cscope:
$(CMD_PREFIX)find \
"$(src_dir)/firmware" \
"$(src_dir)/include" \
"$(src_dir)/lib" \
"$(platform_src_dir)" \
-name "*.[chS]" -print > cscope.files
$(CMD_PREFIX)echo "$(KCONFIG_AUTOHEADER)" >> cscope.files
$(CMD_PREFIX)cscope -bkq -i cscope.files -f cscope.out
# Rule for "make clean"
.PHONY: clean
clean:
$(CMD_PREFIX)mkdir -p $(build_dir)
$(if $(V), @echo " RM $(build_dir)/*.o")
$(CMD_PREFIX)find $(build_dir) -type f -name "*.o" -exec rm -rf {} +
$(if $(V), @echo " RM $(build_dir)/*.carray.c")
$(CMD_PREFIX)find $(build_dir) -type f -name "*.carray.c" -exec rm -rf {} +
$(if $(V), @echo " RM $(build_dir)/*.a")
$(CMD_PREFIX)find $(build_dir) -type f -name "*.a" -exec rm -rf {} +
$(if $(V), @echo " RM $(build_dir)/*.elf")
@@ -588,6 +746,8 @@ ifeq ($(install_root_dir),$(install_root_dir_default)/usr)
$(if $(V), @echo " RM $(install_root_dir_default)")
$(CMD_PREFIX)rm -rf $(install_root_dir_default)
endif
$(if $(V), @echo " RM $(src_dir)/cscope*")
$(CMD_PREFIX)rm -f $(src_dir)/cscope*
.PHONY: FORCE
FORCE:

View File

@@ -1,11 +1,15 @@
RISC-V Open Source Supervisor Binary Interface (OpenSBI)
========================================================
![RISC-V OpenSBI](docs/riscv_opensbi_logo_final_color.png)
Copyright and License
---------------------
The OpenSBI project is copyright (c) 2019 Western Digital Corporation
or its affiliates and other contributors.
The OpenSBI project is:
* Copyright (c) 2019 Western Digital Corporation or its affiliates
* Copyright (c) 2023 RISC-V International
It is distributed under the terms of the BSD 2-clause license
("Simplified BSD License" or "FreeBSD License", SPDX: *BSD-2-Clause*).
@@ -92,10 +96,10 @@ N.B. Any S-mode boot loader (i.e. U-Boot) doesn't need to support HSM extension,
as it doesn't need to boot all the harts. The operating system should be
capable enough to bring up all other non-booting harts using HSM extension.
Required Toolchain
------------------
Required Toolchain and Packages
-------------------------------
OpenSBI can be compiled natively or cross-compiled on a x86 host. For
OpenSBI can be compiled natively or cross-compiled on a host machine. For
cross-compilation, you can build your own toolchain, download a prebuilt one
from the [Bootlin toolchain repository] or install a distribution-provided
toolchain; if you opt to use LLVM/Clang, most distribution toolchains will
@@ -104,16 +108,20 @@ LLVM/Clang toolchain due to LLVM's ability to support multiple backends in the
same binary, so is often an easy way to obtain a working cross-compilation
toolchain.
Basically, we prefer toolchains with Position Independent Executable (PIE)
support like *riscv64-linux-gnu-gcc*, *riscv64-unknown-freebsd-gcc*, or
*Clang/LLVM* as they generate PIE firmware images that can run at arbitrary
address with appropriate alignment. If a bare-metal GNU toolchain (e.g.
*riscv64-unknown-elf-gcc*) is used, static linked firmware images are
generated instead. *Clang/LLVM* can still generate PIE images if a bare-metal
triple is used (e.g. *-target riscv64-unknown-elf*).
Toolchains with Position Independent Executable (PIE) support like
*riscv64-linux-gnu-gcc*, *riscv64-unknown-freebsd-gcc*, or *Clang/LLVM* are
required in order to generate PIE firmware images that can run at arbitrary
address with appropriate alignment. Bare-metal GNU toolchains (e.g.
*riscv64-unknown-elf-gcc*) cannot be used. *Clang/LLVM* can still generate PIE
images if a bare-metal triple is used (e.g. *-target riscv64-unknown-elf*).
Please note that only a 64-bit version of the toolchain is available in
the Bootlin toolchain repository for now.
In addition to a toolchain, OpenSBI also requires the following packages on
the host:
1. device-tree-compiler: The device tree compiler for compiling device
tree sources (DTS files).
2. python3: The python 3.0 (or compatible) language support for various
scripts.
Building and Installing the OpenSBI Platform-Independent Library
----------------------------------------------------------------
@@ -196,6 +204,19 @@ top-level make command line. These options, such as *PLATFORM_<xyz>* or
*docs/platform/<platform_name>.md* files and
*docs/firmware/<firmware_name>.md* files.
All OpenSBI platforms support Kconfig style build-time configuration. Users
can change the build-time configuration of a platform using a graphical
interface as follows:
```
make PLATFORM=<platform_subdir> menuconfig
```
Alternately, an OpenSBI platform can have multiple default configurations
and users can select a custom default configuration as follows:
```
make PLATFORM=<platform_subdir> PLATFORM_DEFCONFIG=<platform_custom_defconfig>
```
Building 32-bit / 64-bit OpenSBI Images
---------------------------------------
By default, building OpenSBI generates 32-bit or 64-bit images based on the
@@ -231,6 +252,18 @@ option with:
make LLVM=1
```
To build with a specific version of LLVM, a path to a directory containing the
LLVM tools can be provided:
```
make LLVM=/path/to/llvm/
```
If you have versioned llvm tools you would like to use, such as `clang-17`, the LLVM variable can
be set as:
```
make LLVM=-17
```
When using Clang, *CROSS_COMPILE* often does not need to be defined unless
using GNU binutils with prefixed binary names. *PLATFORM_RISCV_XLEN* will be
used to infer a default triple to pass to Clang, so if *PLATFORM_RISCV_XLEN*
@@ -251,8 +284,7 @@ document.
NOTE: Using Clang with a `riscv*-linux-gnu` GNU binutils linker has been seen
to produce broken binaries with missing relocations; it is therefore currently
recommended that this combination be avoided or *FW_PIC=n* be used to disable
building OpenSBI as a position-independent binary.
recommended that this combination be avoided.
Building with timestamp and compiler info
-----------------------------------------
@@ -277,6 +309,19 @@ NOTE: Using `BUILD_INFO=y` without specifying SOURCE_DATE_EPOCH will violate
purpose, and should NOT be used in a product which follows "reproducible
builds".
Building with optimization off for debugging
--------------------------------------------
When debugging OpenSBI, we may want to turn off the compiler optimization and
make debugging produce the expected results for a better debugging experience.
To build with optimization off we can just simply add `DEBUG=1`, like:
```
make DEBUG=1
```
This definition is ONLY for development and debug purpose, and should NOT be
used in a product build.
Contributing to OpenSBI
-----------------------

View File

@@ -1,17 +1,15 @@
OpenSBI Contribution Guideline
==============================
All contributions to OpenSBI can be sent in the following ways:
1. Email patches to the OpenSBI mailing list at `opensbi@lists.infradead.org`
2. GitHub Pull Requests (PRs) to the [OpenSBI main repository]
All contributions to OpenSBI must be sent via email patches to the OpenSBI
mailing list at `opensbi@lists.infradead.org`
To join the OpenSBI mailing list, please visit the [OpenSBI infradead page].
The OpenSBI maintainers prefer patches via the OpenSBI mailing list
(option 1 above) so that they are visible to a wider audience. All
accepted patches on the OpenSBI mailing list will be taken by any of
the OpenSBI maintainers and merged into the [OpenSBI main repository]
using GitHub PRs.
The mailing list based patch approach is preferred over github PRs so that they
are visible to a wider audience. All accepted patches on the OpenSBI mailing
list will be taken by one of the OpenSBI maintainers and merged into the
[OpenSBI main repository].
All contributed work must follow the following rules:
1. OpenSBI code should be written in accordance to the [Linux coding style].
@@ -29,13 +27,10 @@ and "top:".
5. Maintainers should use "Rebase and Merge" when using GitHub to merge pull
requests to avoid creating unnecessary merge commits.
6. Maintainers should avoid creating branches directly in the main
riscv/opensbi repository. Instead prefer using a fork of the riscv/opensbi main
riscv/opensbi repository. Instead, prefer using a fork of the riscv/opensbi main
repository and branches within that fork to create pull requests.
7. A maintainer cannot merge his own pull requests in the riscv/opensbi main
repository.
8. A pull request must get at least one review from a maintainer.
9. A pull request must spend at least 24 hours in review to allow for other
developers to review.
-----------------------------------------------------------------------

View File

@@ -2,7 +2,7 @@ OpenSBI Domain Support
======================
An OpenSBI domain is a system-level partition (subset) of underlying hardware
having it's own memory regions (RAM and MMIO devices) and HARTs. The OpenSBI
having its own memory regions (RAM and MMIO devices) and HARTs. The OpenSBI
will try to achieve secure isolation between domains using RISC-V platform
features such as PMP, ePMP, IOPMP, SiFive Shield, etc.
@@ -15,7 +15,7 @@ Important entities which help implement OpenSBI domain support are:
Each HART of a RISC-V platform must have an OpenSBI domain assigned to it.
The OpenSBI platform support is responsible for populating domains and
providing HART id to domain mapping. The OpenSBI domain support will by
default assign **the ROOT domain** to all HARTs of a RISC-V platform so
default assign **the ROOT domain** to all HARTs of a RISC-V platform, so
it is not mandatory for the OpenSBI platform support to populate domains.
Domain Memory Region
@@ -29,7 +29,7 @@ OpenSBI and has following details:
* **base** - The base address of a memory region is **2 ^ order**
aligned start address
* **flags** - The flags of a memory region represent memory type (i.e.
RAM or MMIO) and allowed accesses (i.e. READ, WRITE, EXECUTE, etc)
RAM or MMIO) and allowed accesses (i.e. READ, WRITE, EXECUTE, etc.)
Domain Instance
---------------
@@ -52,6 +52,7 @@ has following details:
* **next_mode** - Privilege mode of the next booting stage for this
domain. This can be either S-mode or U-mode.
* **system_reset_allowed** - Is domain allowed to reset the system?
* **system_suspend_allowed** - Is domain allowed to suspend the system?
The memory regions represented by **regions** in **struct sbi_domain** have
following additional constraints to align with RISC-V PMP requirements:
@@ -91,6 +92,7 @@ following manner:
* **next_mode** - Next booting stage mode in coldboot HART scratch space
is the next mode for the ROOT domain
* **system_reset_allowed** - The ROOT domain is allowed to reset the system
* **system_suspend_allowed** - The ROOT domain is allowed to suspend the system
Domain Effects
--------------
@@ -160,17 +162,23 @@ The DT properties of a domain instance DT node are as follows:
* **regions** (Optional) - The list of domain memory region DT node phandle
and access permissions for the domain instance. Each list entry is a pair
of DT node phandle and access permissions. The access permissions are
represented as a 32bit bitmask having bits: **readable** (BIT[0]),
**writeable** (BIT[1]), **executable** (BIT[2]), and **m-mode** (BIT[3]).
represented as a 32bit bitmask having bits: **M readable** (BIT[0]),
**M writeable** (BIT[1]), **M executable** (BIT[2]), **SU readable**
(BIT[3]), **SU writable** (BIT[4]), and **SU executable** (BIT[5]).
The enforce permission bit (BIT[6]), if set, will lock the permissions
in the PMP. This will enforce the permissions on M-mode as well which
otherwise will have unrestricted access. This bit must be used with
caution because no changes can be made to a PMP entry once its locked
until the hart is reset.
Any region of a domain defined in DT node cannot have only M-bits set
in access permissions i.e. it cannot be an m-mode only accessible region.
* **boot-hart** (Optional) - The DT node phandle of the HART booting the
domain instance. If coldboot HART is assigned to the domain instance then
this DT property is ignored and the coldboot HART is assumed to be the
boot HART of the domain instance.
* **next-arg1** (Optional) - The 64 bit next booting stage arg1 for the
domain instance. If this DT property is not available and coldboot HART
is not assigned to the domain instance then **0x0** is used as default
value. If this DT property is not available and coldboot HART is assigned
to the domain instance then **next booting stage arg1 of coldboot HART**
is not assigned to the domain instance then **next booting stage arg1 of coldboot HART**
is used as default value.
* **next-addr** (Optional) - The 64 bit next booting stage address for the
domain instance. If this DT property is not available and coldboot HART
@@ -180,13 +188,15 @@ The DT properties of a domain instance DT node are as follows:
is used as default value.
* **next-mode** (Optional) - The 32 bit next booting stage mode for the
domain instance. The possible values of this DT property are: **0x1**
(s-mode), and **0x0** (u-mode). If this DT property is not available
(S-mode), and **0x0** (U-mode). If this DT property is not available
and coldboot HART is not assigned to the domain instance then **0x1**
is used as default value. If this DT property is not available and
coldboot HART is assigned to the domain instance then **next booting
stage mode of coldboot HART** is used as default value.
* **system-reset-allowed** (Optional) - A boolean flag representing
whether the domain instance is allowed to do system reset.
* **system-suspend-allowed** (Optional) - A boolean flag representing
whether the domain instance is allowed to do system suspend.
### Assigning HART To Domain Instance
@@ -195,9 +205,9 @@ platform support can provide the HART to domain instance assignment using
platform specific callback.
The HART to domain instance assignment can be parsed from the device tree
using optional DT property **opensbi,domain** in each CPU DT node. The
value of DT property **opensbi,domain** is the DT phandle of the domain
instance DT node. If **opensbi,domain** DT property is not specified then
using optional DT property **opensbi-domain** in each CPU DT node. The
value of DT property **opensbi-domain** is the DT phandle of the domain
instance DT node. If **opensbi-domain** DT property is not specified then
corresponding HART is assigned to **the ROOT domain**.
### Domain Configuration Only Accessible to OpenSBI
@@ -246,18 +256,19 @@ be done:
tdomain: trusted-domain {
compatible = "opensbi,domain,instance";
possible-harts = <&cpu0>;
regions = <&tmem 0x7>, <&tuart 0x7>;
regions = <&tmem 0x3f>, <&tuart 0x3f>;
boot-hart = <&cpu0>;
next-arg1 = <0x0 0x0>;
next-addr = <0x0 0x80100000>;
next-mode = <0x0>;
system-reset-allowed;
system-suspend-allowed;
};
udomain: untrusted-domain {
compatible = "opensbi,domain,instance";
possible-harts = <&cpu1 &cpu2 &cpu3 &cpu4>;
regions = <&tmem 0x0>, <&tuart 0x0>, <&allmem 0x7>;
regions = <&tmem 0x0>, <&tuart 0x0>, <&allmem 0x3f>;
};
};
};

View File

@@ -796,6 +796,8 @@ INPUT = @@SRC_DIR@@/README.md \
@@SRC_DIR@@/docs/platform_requirements.md \
@@SRC_DIR@@/docs/library_usage.md \
@@SRC_DIR@@/docs/domain_support.md \
@@SRC_DIR@@/docs/opensbi_config.md \
@@SRC_DIR@@/docs/writing_tests.md \
@@SRC_DIR@@/docs/firmware \
@@SRC_DIR@@/docs/platform \
@@SRC_DIR@@/include \

View File

@@ -53,7 +53,7 @@ the booting stage to follow OpenSBI firmware.
A *FW_PAYLOAD* firmware is also useful for cases where the booting stage prior
to OpenSBI firmware does not pass a *flattened device tree (FDT file)*. In such
case, a *FW_PAYLOAD* firmware allows embedding a flattened device tree in the
.text section of the final firmware.
.rodata section of the final firmware.
Firmware Configuration and Compilation
--------------------------------------
@@ -61,20 +61,15 @@ Firmware Configuration and Compilation
All firmware types support the following common compile time configuration
parameters:
* **FW_TEXT_ADDR** - Defines the execution address of the OpenSBI firmware.
This configuration parameter is mandatory.
* **FW_TEXT_START** - Defines the compile time address of the OpenSBI
firmware. This configuration parameter is optional and assumed to be
`0` if not specified.
* **FW_FDT_PATH** - Path to an external flattened device tree binary file to
be embedded in the *.rodata* section of the final firmware. If this option
is not provided then the firmware will expect the FDT to be passed as an
argument by the prior booting stage.
* **FW_FDT_PADDING** - Optional zero bytes padding to the embedded flattened
device tree binary file specified by **FW_FDT_PATH** option.
* **FW_PIC** - "FW_PIC=y" generates position independent executable firmware
images. OpenSBI can run at arbitrary address with appropriate alignment.
Therefore, the original relocation mechanism ("FW_PIC=n") will be skipped.
In other words, OpenSBI will directly run at the load address without any
code movement. This option requires a toolchain with PIE support, and it
is on by default.
Additionally, each firmware type as a set of type specific configuration
parameters. Detailed information for each firmware type can be found in the

View File

@@ -20,7 +20,7 @@ the booting stage binary to follow OpenSBI firmware.
A platform can enable *FW_DYNAMIC* firmware using any of the following methods.
1. Specifying `FW_DYNAMIC=y` on the top level `make` command line.
2. Specifying `FW_DYNAMIC=y` in the target platform *config.mk* configuration
2. Specifying `FW_DYNAMIC=y` in the target platform *objects.mk* configuration
file.
The compiled *FW_DYNAMIC* firmware ELF file is named *fw_dynamic.elf*. It's
@@ -31,6 +31,6 @@ directory.
*FW_DYNAMIC* Firmware Configuration Options
-------------------------------------------
The *FW_DYNAMIC* firmware does not requires any platform specific configuration
The *FW_DYNAMIC* firmware does not require any platform specific configuration
parameters because all required information is passed by previous booting stage
at runtime via *struct fw_dynamic_info*.

View File

@@ -15,7 +15,7 @@ and the booting stage binary to follow the OpenSBI firmware.
A platform *FW_JUMP* firmware can be enabled by any of the following methods:
1. Specifying `FW_JUMP=y` on the top level `make` command line.
2. Specifying `FW_JUMP=y` in the target platform *config.mk* configuration file.
2. Specifying `FW_JUMP=y` in the target platform *objects.mk* configuration file.
The compiled *FW_JUMP* firmware ELF file is named *fw_jump.elf*. Its expanded
image file is *fw_jump.bin*. Both files are created in the platform-specific
@@ -26,14 +26,19 @@ build directory under the *build/platform/<platform_subdir>/firmware* directory.
To operate correctly, a *FW_JUMP* firmware requires some configuration
parameters to be defined using either the top level `make` command line or the
target platform *config.mk* configuration file. The possible parameters are as
target platform *objects.mk* configuration file. The possible parameters are as
follows:
* **FW_JUMP_ADDR** - Address of the entry point of the booting stage to be
executed following OpenSBI firmware. This address generally corresponds
exactly to the address where this next booting stage was loaded. This is a
mandatory parameter. Compilation errors will result from not defining this
address.
exactly to the address where this next booting stage was loaded.
At least one of *FW_JUMP_ADDR* and *FW_JUMP_OFFSET* (see below) should be
defined. Compilation errors will result from not defining one of them.
* **FW_JUMP_OFFSET** - Address offset from the opensbi load address where the
entry point of the next booting stage is located. This offset is used as
relocatable address of the next booting stage entry point. If *FW_JUMP_ADDR*
is also defined, the firmware will prefer *FW_JUMP_ADDR*.
* **FW_JUMP_FDT_ADDR** - Address where the *flattened device tree (FDT file)*
passed by the prior booting stage will be placed in memory before executing
@@ -41,6 +46,28 @@ follows:
provided, then the OpenSBI firmware will pass the FDT address passed by the
previous booting stage to the next booting stage.
When using the default *FW_JUMP_FDT_ADDR* with *PLATFORM=generic*, you must
ensure *FW_JUMP_FDT_ADDR* is set high enough to avoid overwriting the kernel.
You can use the following method (e.g., using bash or zsh):
```
${CROSS_COMPILE}objdump -h $KERNEL_ELF | sort -k 5,5 | awk -n '
/^ +[0-9]+ / {addr="0x"$3; size="0x"$5; printf "0x""%x\n",addr+size}' |
(( `tail -1` > (FW_JUMP_FDT_ADDR - FW_JUMP_ADDR) )) &&
echo fdt overlaps kernel, increase FW_JUMP_FDT_ADDR
${LLVM}objdump -h --show-lma $KERNEL_ELF | sort -k 5,5 | awk -n '
/^ +[0-9]+ / {addr="0x"$3; size="0x"$5; printf "0x""%x\n",addr+size}' |
(( `tail -1` > (FW_JUMP_FDT_ADDR - FW_JUMP_ADDR) )) &&
echo fdt overlaps kernel, increase FW_JUMP_FDT_ADDR
```
* **FW_JUMP_FDT_OFFSET** - Address offset from the opensbi load address where
the FDT will be passed to the next booting stage. This offset is used
as relocatable address of the FDT passed to the next booting stage. If
*FW_JUMP_FDT_ADDR* is also defined, the firmware will prefer
*FW_JUMP_FDT_ADDR*.
*FW_JUMP* Example
-----------------

View File

@@ -12,7 +12,7 @@ firmware and the booting stage to follow OpenSBI firmware.
A *FW_PAYLOAD* firmware is also useful for cases where the booting stage prior
to the OpenSBI firmware does not pass a *flattened device tree (FDT file)*. In
such a case, a *FW_PAYLOAD* firmware allows embedding a flattened device tree
in the .text section of the final firmware.
in the .rodata section of the final firmware.
Enabling *FW_PAYLOAD* compilation
---------------------------------
@@ -20,10 +20,10 @@ Enabling *FW_PAYLOAD* compilation
The *FW_PAYLOAD* firmware can be enabled by any of the following methods:
1. Specifying `FW_PAYLOAD=y` on the top level `make` command line.
2. Specifying `FW_PAYLOAD=y` in the target platform *config.mk* configuration
2. Specifying `FW_PAYLOAD=y` in the target platform *objects.mk* configuration
file.
The compiled *FW_PAYLOAD* firmware ELF file is named *fw_jump.elf*. Its
The compiled *FW_PAYLOAD* firmware ELF file is named *fw_payload.elf*. Its
expanded image file is *fw_payload.bin*. Both files are created in the
platform-specific build directory under the
*build/platform/<platform_subdir>/firmware* directory.
@@ -33,11 +33,11 @@ Configuration Options
A *FW_PAYLOAD* firmware is built according to configuration parameters and
options. These configuration parameters can be defined using either the top
level `make` command line or the target platform *config.mk* configuration
level `make` command line or the target platform *objects.mk* configuration
file. The parameters currently defined are as follows:
* **FW_PAYLOAD_OFFSET** - Offset from *FW_TEXT_BASE* where the payload binary
will be linked in the final *FW_PAYLOAD* firmware binary image. This
* **FW_PAYLOAD_OFFSET** - Offset from the opensbi load address where the payload
binary will be linked in the final *FW_PAYLOAD* firmware binary image. This
configuration parameter is mandatory if *FW_PAYLOAD_ALIGN* is not defined.
Compilation errors will result from an incorrect definition of
*FW_PAYLOAD_OFFSET* or of *FW_PAYLOAD_ALIGN*, or if neither of these
@@ -62,6 +62,11 @@ file. The parameters currently defined are as follows:
firmware will pass the FDT address passed by the previous booting stage
to the next booting stage.
* **FW_PAYLOAD_FDT_OFFSET** - Address offset from the opensbi load address where
the FDT will be passed to the next booting stage. This offset is used as
relocatable address of the FDT passed to the next booting stage. If
*FW_PAYLOAD_FDT_ADDR* is also defined, the firmware will prefer *FW_PAYLOAD_FDT_ADDR*.
*FW_PAYLOAD* Example
--------------------

View File

@@ -8,11 +8,7 @@ OpenSBI provides two types of static libraries:
hooks for the execution of this interface must be provided by the firmware or
bootloader linking with this library. This library is installed as
*<install_directory>/lib/libsbi.a*
2. *libsbiutils.a* - A static library that will contain all common code required
by any platform supported in OpenSBI. It will be built by default and included
in libplatsbi.a. This library is installed as
*<install_directory>/lib/libsbiutils.a*.
3. *libplatsbi.a* - An example platform-specific static library integrating
2. *libplatsbi.a* - An example platform-specific static library integrating
*libsbi.a* with platform-specific hooks. This library is available only for
the platforms supported by OpenSBI. This library is installed as
*<install_directory>/platform/<platform_subdir>/lib/libplatsbi.a*
@@ -77,7 +73,7 @@ firmware drivers based on the external firmware architecture.
**OPENSBI_EXTERNAL_SBI_TYPES** identifier is introduced to *sbi_types.h* for selecting
external header file during the build preprocess in order to define OpensSBI data types
based on external firmware data type binding.
For example, *bool* is declared as *int* in sbi_types.h. However in EDK2 build system,
For example, *bool* is declared as *int* in sbi_types.h. However, in EDK2 build system,
*bool* is declared as *BOOLEAN* which is defined as *unsigned char* data type.
External firmware can define **OPENSBI_EXTERNAL_SBI_TYPES** in CFLAGS and specify it to the

91
docs/opensbi_config.md Normal file
View File

@@ -0,0 +1,91 @@
OpenSBI Device Tree Configuration Guideline
==================================
Some configurations of OpenSBI's Generic Platform can be described
in the **device tree (DT) blob** (or flattened device tree) passed
to the OpenSBI firmwares by the previous booting stage. OpenSBI will
parse and use these configurations during the boot phase, but delete
them from the device tree at the end of cold boot.
### OpenSBI Configuration Node
All nodes related to OpenSBI configuration should be under the OpenSBI
configuration DT node. The **/chosen** DT node is the preferred parent
of the OpenSBI configuration DT node.
The DT properties of a domain configuration DT node are as follows:
* **compatible** (Mandatory) - The compatible string of the OpenSBI
configuration. This DT property should have value *"opensbi,config"*
* **cold-boot-harts** (Optional) - If a platform lacks an override
cold_boot_allowed() mechanism, this DT property specifies that a
set of harts is permitted to perform a cold boot. Otherwise, all
harts are allowed to cold boot.
* **heap-size** (Optional) - When present, the specified value is used
as the size of the heap in bytes.
* **system-suspend-test** (Optional) - When present, enable a system
suspend test implementation which simply waits five seconds and issues a WFI.
The OpenSBI Configuration Node will be deleted at the end of cold boot
(replace the node (subtree) with nop tags).
### Example
```text
chosen {
opensbi-config {
compatible = "opensbi,config";
cold-boot-harts = <&cpu1 &cpu2 &cpu3 &cpu4>;
heap-size = <0x400000>;
system-suspend-test;
};
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <10000000>;
cpu0: cpu@0 {
device_type = "cpu";
reg = <0x00>;
compatible = "riscv";
...
};
cpu1: cpu@1 {
device_type = "cpu";
reg = <0x01>;
compatible = "riscv";
...
};
cpu2: cpu@2 {
device_type = "cpu";
reg = <0x02>;
compatible = "riscv";
...
};
cpu3: cpu@3 {
device_type = "cpu";
reg = <0x03>;
compatible = "riscv";
...
};
cpu4: cpu@4 {
device_type = "cpu";
reg = <0x04>;
compatible = "riscv";
...
};
};
uart1: serial@10011000 {
...
};
```

View File

@@ -8,7 +8,7 @@ AHB/APB IPs suites a majority embedded systems, and the verified platform serves
as a starting point to jump start SoC designs.
To build platform specific library and firmwares, provide the
*PLATFORM=andes/ae350* parameter to the top level make command.
*PLATFORM=generic* parameter to the top level `make` command.
Platform Options
----------------
@@ -18,13 +18,190 @@ The Andes AE350 platform does not have any platform-specific options.
Building Andes AE350 Platform
-----------------------------
To use Linux v5.2 should be used to build Andes AE350 OpenSBI binaries by using
the compile time option FW_FDT_PATH.
AE350's dts is included in https://github.com/andestech/linux/tree/ast-v3_2_0-release-public
AE350's dts is included in https://github.com/andestech/linux/tree/RISCV-Linux-5.4-ast-v5_1_0-branch
**Linux Kernel Payload**
```
make PLATFORM=andes/ae350 FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image FW_FDT_PATH=<ae350.dtb path>
make PLATFORM=generic FW_PAYLOAD_PATH=<linux_build_directory>/arch/riscv/boot/Image FW_FDT_PATH=<ae350.dtb path>
```
DTS Example: (Quad-core AX45MP)
-------------------------------
```
compatible = "andestech,ae350";
cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <60000000>;
CPU0: cpu@0 {
device_type = "cpu";
reg = <0>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdc";
riscv,priv-major = <1>;
riscv,priv-minor = <10>;
mmu-type = "riscv,sv48";
clock-frequency = <60000000>;
i-cache-size = <0x8000>;
i-cache-sets = <256>;
i-cache-line-size = <64>;
i-cache-block-size = <64>;
d-cache-size = <0x8000>;
d-cache-sets = <128>;
d-cache-line-size = <64>;
d-cache-block-size = <64>;
next-level-cache = <&L2>;
CPU0_intc: interrupt-controller {
#interrupt-cells = <1>;
interrupt-controller;
compatible = "riscv,cpu-intc";
};
};
CPU1: cpu@1 {
device_type = "cpu";
reg = <1>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdc";
riscv,priv-major = <1>;
riscv,priv-minor = <10>;
mmu-type = "riscv,sv48";
clock-frequency = <60000000>;
i-cache-size = <0x8000>;
i-cache-sets = <256>;
i-cache-line-size = <64>;
i-cache-block-size = <64>;
d-cache-size = <0x8000>;
d-cache-sets = <128>;
d-cache-line-size = <64>;
d-cache-block-size = <64>;
next-level-cache = <&L2>;
CPU1_intc: interrupt-controller {
#interrupt-cells = <1>;
interrupt-controller;
compatible = "riscv,cpu-intc";
};
};
CPU2: cpu@2 {
device_type = "cpu";
reg = <2>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdc";
riscv,priv-major = <1>;
riscv,priv-minor = <10>;
mmu-type = "riscv,sv48";
clock-frequency = <60000000>;
i-cache-size = <0x8000>;
i-cache-sets = <256>;
i-cache-line-size = <64>;
i-cache-block-size = <64>;
d-cache-size = <0x8000>;
d-cache-sets = <128>;
d-cache-line-size = <64>;
d-cache-block-size = <64>;
next-level-cache = <&L2>;
CPU2_intc: interrupt-controller {
#interrupt-cells = <1>;
interrupt-controller;
compatible = "riscv,cpu-intc";
};
};
CPU3: cpu@3 {
device_type = "cpu";
reg = <3>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdc";
riscv,priv-major = <1>;
riscv,priv-minor = <10>;
mmu-type = "riscv,sv48";
clock-frequency = <60000000>;
i-cache-size = <0x8000>;
i-cache-sets = <256>;
i-cache-line-size = <64>;
i-cache-block-size = <64>;
d-cache-size = <0x8000>;
d-cache-sets = <128>;
d-cache-line-size = <64>;
d-cache-block-size = <64>;
next-level-cache = <&L2>;
CPU3_intc: interrupt-controller {
#interrupt-cells = <1>;
interrupt-controller;
compatible = "riscv,cpu-intc";
};
};
};
soc {
#address-cells = <2>;
#size-cells = <2>;
compatible = "andestech,riscv-ae350-soc", "simple-bus";
ranges;
plic0: interrupt-controller@e4000000 {
compatible = "riscv,plic0";
reg = <0x00000000 0xe4000000 0x00000000 0x02000000>;
interrupts-extended = < &CPU0_intc 11 &CPU0_intc 9
&CPU1_intc 11 &CPU1_intc 9
&CPU2_intc 11 &CPU2_intc 9
&CPU3_intc 11 &CPU3_intc 9 >;
interrupt-controller;
#address-cells = <2>;
#interrupt-cells = <2>;
riscv,ndev = <71>;
};
plicsw: interrupt-controller@e6400000 {
compatible = "andestech,plicsw";
reg = <0x00000000 0xe6400000 0x00000000 0x00400000>;
interrupts-extended = < &CPU0_intc 3
&CPU1_intc 3
&CPU2_intc 3
&CPU3_intc 3 >;
interrupt-controller;
#address-cells = <2>;
#interrupt-cells = <2>;
};
plmt0: plmt0@e6000000 {
compatible = "andestech,plmt0";
reg = <0x00000000 0xe6000000 0x00000000 0x00100000>;
interrupts-extended = < &CPU0_intc 7
&CPU1_intc 7
&CPU2_intc 7
&CPU3_intc 7 >;
};
wdt: watchdog@f0500000 {
compatible = "andestech,atcwdt200";
reg = <0x00000000 0xf0500000 0x00000000 0x00001000>;
interrupts = <3 4>;
interrupt-parent = <&plic0>;
clock-frequency = <15000000>;
};
serial0: serial@f0300000 {
compatible = "andestech,uart16550", "ns16550a";
reg = <0x00000000 0xf0300000 0x00000000 0x00001000>;
interrupts = <9 4>;
interrupt-parent = <&plic0>;
clock-frequency = <19660800>;
current-speed = <38400>;
reg-shift = <2>;
reg-offset = <32>;
reg-io-width = <4>;
no-loopback-test = <1>;
};
smu: smu@f0100000 {
compatible = "andestech,atcsmu";
reg = <0x00000000 0xf0100000 0x00000000 0x00001000>;
};
};
```

View File

@@ -7,7 +7,7 @@ Linux.
The FPGA SoC currently contains the following peripherals:
- DDR3 memory controller
- SPI controller to conncet to an SDCard
- SPI controller to connect to an SDCard
- Ethernet controller
- JTAG port (see debugging section below)
- Bootrom containing zero stage bootloader and device tree.

View File

@@ -9,10 +9,9 @@ boards.
By default, the generic FDT platform makes following assumptions:
1. platform FW_TEXT_START is 0x80000000
2. platform features are default
3. platform stack size is default
4. platform has no quirks or work-arounds
1. platform features are default
2. platform stack size is default
3. platform has no quirks or work-arounds
The above assumptions (except 1) can be overridden by adding special platform
callbacks which will be called based on FDT root node compatible string.
@@ -33,10 +32,6 @@ Users of the generic FDT platform will have to ensure that:
To build the platform-specific library and firmware images, provide the
*PLATFORM=generic* parameter to the top level `make` command.
For custom FW_TEXT_START, we can build the platform-specific library and
firmware images by passing *PLATFORM=generic FW_TEXT_START=<custom_text_start>*
parameter to the top level `make` command.
Platform Options
----------------
@@ -45,13 +40,17 @@ The *Generic* platform does not have any platform-specific options.
RISC-V Platforms Using Generic Platform
---------------------------------------
* **Andes AE350 Platform** (*[andes-ae350.md]*)
* **QEMU RISC-V Virt Machine** (*[qemu_virt.md]*)
* **Renesas RZ/Five SoC** (*[renesas-rzfive.md]*)
* **Shakti C-class SoC Platform** (*[shakti_cclass.md]*)
* **SiFive HiFive Unleashed** (*[sifive_fu540.md]*)
* **Spike** (*[spike.md]*)
* **T-HEAD C9xx series Processors** (*[thead-c9xx.md]*)
[andes-ae350.md]: andes-ae350.md
[qemu_virt.md]: qemu_virt.md
[renesas-rzfive.md]: renesas-rzfive.md
[shakti_cclass.md]: shakti_cclass.md
[sifive_fu540.md]: sifive_fu540.md
[spike.md]: spike.md

View File

@@ -39,11 +39,15 @@ OpenSBI currently supports the following virtual and hardware platforms:
processor based SOCs. More details on this platform can be found in the
file *[shakti_cclass.md]*.
* **Renesas RZ/Five SoC**: Platform support for Renesas RZ/Five (R9A07G043F) SoC
used on the Renesas RZ/Five SMARC EVK board. More details on this platform can
be found in the file *[renesas-rzfive.md]*.
The code for these supported platforms can be used as example to implement
support for other platforms. The *platform/template* directory also provides
template files for implementing support for a new platform. The *object.mk*,
*config.mk* and *platform.c* template files provides enough comments to
facilitate the implementation.
template files for implementing support for a new platform. The *objects.mk*,
*Kconfig*, *configs/defconfig* and *platform.c* template files provides enough
comments to facilitate the implementation.
[generic.md]: generic.md
[qemu_virt.md]: qemu_virt.md
@@ -54,3 +58,4 @@ facilitate the implementation.
[spike.md]: spike.md
[fpga-openpiton.md]: fpga-openpiton.md
[shakti_cclass.md]: shakti_cclass.md
[renesas-rzfive.md]: renesas-rzfive.md

View File

@@ -56,7 +56,14 @@ qemu-system-riscv64 -M virt -m 256M -nographic \
**Linux Kernel Payload**
Note: We assume that the Linux kernel is compiled using
*arch/riscv/configs/defconfig*.
*arch/riscv/configs/defconfig*. The kernel must be a flattened image (a file
called `Image`) rather than an ELF (`vmlinux`).
Example of building a Linux kernel:
```
make ARCH=riscv CROSS_COMPILE=riscv64-linux- defconfig
make ARCH=riscv CROSS_COMPILE=riscv64-linux- Image
```
Build:
```

View File

@@ -0,0 +1,160 @@
Renesas RZ/Five SoC (R9A07G043F) Platform
=========================================
The RZ/Five microprocessor includes a single RISC-V CPU Core (Andes AX45MP)
1.0 GHz, 16-bit DDR3L/DDR4 interface. Supported interfaces include:
- Memory controller for DDR4-1600 / DDR3L-1333 with 16 bits
- System RAM (RAM of 128 Kbytes (ECC))
- SPI Multi I/O Bus Controller 1ch
- SD Card Host Interface/Multimedia Card Interface (SD/MMC) 2ch
- Serial Sound Interface (SSI) 4ch
- Sampling Rate Converter (SRC) 1ch
- USB2.0 host/function interface 2ch (ch0: Host-Function ch1: Host only)
- Gigabit Ethernet Interface (GbE) 2ch
- Controller Area Network Interface (CAN) 2ch (CAN-FD ISO 11898-1 (CD2014) compliant)
- Multi-function Timer Pulse Unit 3 (MTU3a) 9 ch (16 bits × 8 channels, 32 bits × 1 channel)
- Port Output Enable 3 (POE3)
- Watchdog Timer (WDT) 1ch
- General Timer (GTM) 3ch (32bits)
- I2C Bus Interface (I2C) 4ch
- Serial Communication Interface with FIFO (SCIFA) 5ch
- Serial Communication Interface (SCI) 2ch
- Renesas Serial Peripheral Interface (RSPI) 3ch
- A/D Converter (ADC) 2ch
making it ideal for applications such as entry-class social infrastructure
gateway control and industrial gateway control. More details can be found at
below link [0].
[0] https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rz-mpus/rzfive-general-purpose-microprocessors-risc-v-cpu-core-andes-ax45mp-single-10-ghz-2ch-gigabit-ethernet
To build platform specific library and firmwares, provide the
*PLATFORM=generic* parameter to the top level make command.
Platform Options
----------------
The Renesas RZ/Five platform does not have any platform-specific options.
Building Renesas RZ/Five Platform
---------------------------------
```
make PLATFORM=generic
```
DTS Example: (RZ/Five AX45MP)
-----------------------------
```
compatible = "renesas,r9a07g043f01", "renesas,r9a07g043";
cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <12000000>;
cpu0: cpu@0 {
compatible = "andestech,ax45mp", "riscv";
device_type = "cpu";
reg = <0x0>;
status = "okay";
riscv,isa = "rv64imafdc";
mmu-type = "riscv,sv39";
i-cache-size = <0x8000>;
i-cache-line-size = <0x40>;
d-cache-size = <0x8000>;
d-cache-line-size = <0x40>;
clocks = <&cpg CPG_CORE R9A07G043_CLK_I>;
cpu0_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
};
soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
ranges;
scif0: serial@1004b800 {
compatible = "renesas,scif-r9a07g043",
"renesas,scif-r9a07g044";
reg = <0 0x1004b800 0 0x400>;
interrupts = <412 IRQ_TYPE_LEVEL_HIGH>,
<414 IRQ_TYPE_LEVEL_HIGH>,
<415 IRQ_TYPE_LEVEL_HIGH>,
<413 IRQ_TYPE_LEVEL_HIGH>,
<416 IRQ_TYPE_LEVEL_HIGH>,
<416 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "eri", "rxi", "txi",
"bri", "dri", "tei";
clocks = <&cpg CPG_MOD R9A07G043_SCIF0_CLK_PCK>;
clock-names = "fck";
power-domains = <&cpg>;
resets = <&cpg R9A07G043_SCIF0_RST_SYSTEM_N>;
status = "disabled";
};
cpg: clock-controller@11010000 {
compatible = "renesas,r9a07g043-cpg";
reg = <0 0x11010000 0 0x10000>;
clocks = <&extal_clk>;
clock-names = "extal";
#clock-cells = <2>;
#reset-cells = <1>;
#power-domain-cells = <0>;
};
sysc: system-controller@11020000 {
compatible = "renesas,r9a07g043-sysc";
reg = <0 0x11020000 0 0x10000>;
status = "disabled";
};
pinctrl: pinctrl@11030000 {
compatible = "renesas,r9a07g043-pinctrl";
reg = <0 0x11030000 0 0x10000>;
gpio-controller;
#gpio-cells = <2>;
#interrupt-cells = <2>;
interrupt-controller;
gpio-ranges = <&pinctrl 0 0 152>;
clocks = <&cpg CPG_MOD R9A07G043_GPIO_HCLK>;
power-domains = <&cpg>;
resets = <&cpg R9A07G043_GPIO_RSTN>,
<&cpg R9A07G043_GPIO_PORT_RESETN>,
<&cpg R9A07G043_GPIO_SPARE_RESETN>;
};
plmt0: plmt0@110c0000 {
compatible = "andestech,plmt0", "riscv,plmt0";
reg = <0x0 0x110c0000 0x0 0x10000>;
interrupts-extended = <&cpu0_intc 7>;
};
plic: interrupt-controller@12c00000 {
compatible = "renesas,r9a07g043-plic", "andestech,nceplic100";
#interrupt-cells = <2>;
#address-cells = <0>;
riscv,ndev = <511>;
interrupt-controller;
reg = <0x0 0x12c00000 0x0 0x400000>;
clocks = <&cpg CPG_MOD R9A07G043_NCEPLIC_ACLK>;
power-domains = <&cpg>;
resets = <&cpg R9A07G043_NCEPLIC_ARESETN>;
interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9>;
};
plicsw: interrupt-controller@13000000 {
compatible = "andestech,plicsw";
reg = <0x0 0x13000000 0x0 0x400000>;
interrupts-extended = <&cpu0_intc 3>;
interrupt-controller;
#address-cells = <2>;
#interrupt-cells = <2>;
};
};
```

View File

@@ -150,7 +150,7 @@ If you want to test OpenSBI with QEMU 'sifive_u' machine, please follow the
same instructions above, with the exception of not passing FW_FDT_PATH.
This is because QEMU generates a device tree blob on the fly based on the
command line parameters and it's compatible with the one used in the upstream
command line parameters, and it's compatible with the one used in the upstream
Linux kernel.
When U-Boot v2021.07 (or higher) is used as the payload, as the SiFive FU540

View File

@@ -1,7 +1,7 @@
T-HEAD C9xx Series Processors
=============================
The **C9xx** series processors are high-performance RISC-V architecture
The C9xx series processors are high-performance RISC-V architecture
multi-core processors with AI vector acceleration engine.
For more details, refer [T-HEAD.CN](https://www.t-head.cn/)
@@ -12,187 +12,16 @@ To build the platform-specific library and firmware images, provide the
Platform Options
----------------
The *T-HEAD C9xx* does not have any platform-specific compile options
because it use generic platform.
The T-HEAD C9xx does not have any platform-specific compile options
because it uses generic platform.
```
CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic /usr/bin/make
CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic make
```
The *T-HEAD C9xx* DTB provided to OpenSBI generic firmwares will usually have
"riscv,clint0", "riscv,plic0", "thead,reset-sample" compatible strings.
Here is the simplest boot flow for a fpga prototype:
DTS Example1: (Single core, eg: Allwinner D1 - c906)
----------------------------------------------------
(Jtag gdbinit) -> (zsb) -> (opensbi) -> (linux)
```
cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <3000000>;
cpu@0 {
device_type = "cpu";
reg = <0>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdcv";
mmu-type = "riscv,sv39";
cpu0_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
};
soc {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
ranges;
clint0: clint@14000000 {
compatible = "riscv,clint0";
interrupts-extended = <
&cpu0_intc 3 &cpu0_intc 7
>;
reg = <0x0 0x14000000 0x0 0x04000000>;
clint,has-no-64bit-mmio;
};
intc: interrupt-controller@10000000 {
#interrupt-cells = <1>;
compatible = "allwinner,sun20i-d1-plic",
"thead,c900-plic";
interrupt-controller;
interrupts-extended = <
&cpu0_intc 0xffffffff &cpu0_intc 9
>;
reg = <0x0 0x10000000 0x0 0x04000000>;
reg-names = "control";
riscv,max-priority = <7>;
riscv,ndev = <200>;
};
}
```
DTS Example2: (Multi cores with soc reset-regs)
-----------------------------------------------
```
cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <3000000>;
cpu@0 {
device_type = "cpu";
reg = <0>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imafdc";
mmu-type = "riscv,sv39";
cpu0_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
cpu@1 {
device_type = "cpu";
reg = <1>;
status = "fail";
compatible = "riscv";
riscv,isa = "rv64imafdc";
mmu-type = "riscv,sv39";
cpu1_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
cpu@2 {
device_type = "cpu";
reg = <2>;
status = "fail";
compatible = "riscv";
riscv,isa = "rv64imafdc";
mmu-type = "riscv,sv39";
cpu2_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
cpu@3 {
device_type = "cpu";
reg = <3>;
status = "fail";
compatible = "riscv";
riscv,isa = "rv64imafdc";
mmu-type = "riscv,sv39";
cpu3_intc: interrupt-controller {
#interrupt-cells = <1>;
compatible = "riscv,cpu-intc";
interrupt-controller;
};
};
};
soc {
#address-cells = <2>;
#size-cells = <2>;
compatible = "simple-bus";
ranges;
reset: reset-sample {
compatible = "thead,reset-sample";
entry-reg = <0xff 0xff019050>;
entry-cnt = <4>;
control-reg = <0xff 0xff015004>;
control-val = <0x1c>;
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc>;
};
clint0: clint@ffdc000000 {
compatible = "riscv,clint0";
interrupts-extended = <
&cpu0_intc 3 &cpu0_intc 7
&cpu1_intc 3 &cpu1_intc 7
&cpu2_intc 3 &cpu2_intc 7
&cpu3_intc 3 &cpu3_intc 7
&cpu4_intc 3 &cpu4_intc 7
>;
reg = <0xff 0xdc000000 0x0 0x04000000>;
clint,has-no-64bit-mmio;
};
intc: interrupt-controller@ffd8000000 {
#interrupt-cells = <1>;
compatible = "thead,c900-plic";
interrupt-controller;
interrupts-extended = <
&cpu0_intc 0xffffffff &cpu0_intc 9
&cpu1_intc 0xffffffff &cpu1_intc 9
&cpu2_intc 0xffffffff &cpu2_intc 9
&cpu3_intc 0xffffffff &cpu3_intc 9
>;
reg = <0xff 0xd8000000 0x0 0x04000000>;
reg-names = "control";
riscv,max-priority = <7>;
riscv,ndev = <80>;
};
}
```
DTS Example2: (Multi cores with old reset csrs)
-----------------------------------------------
```
reset: reset-sample {
compatible = "thead,reset-sample";
using-csr-reset;
csr-copy = <0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc
0x3b0 0x3b1 0x3b2 0x3b3
0x3b4 0x3b5 0x3b6 0x3b7
0x3a0>;
};
```
For more details, refer:
[zero stage boot](https://github.com/c-sky/zero_stage_boot)

View File

@@ -28,11 +28,12 @@ Adding support for a new platform
Support for a new platform named *&lt;xyz&gt;* can be added as follows:
1. Create a directory named *&lt;xyz&gt;* under the *platform/* directory.
2. Create a platform configuration file named *config.mk* under the
*platform/&lt;xyz&gt;/* directory. This configuration file will provide
2. Create platform configuration files named *Kconfig* and *configs/defconfig*
under the *platform/&lt;xyz&gt;/* directory. These configuration files will
provide the build time configuration for the sources to be compiled.
3. Create a *platform/&lt;xyz&gt;/objects.mk* file for listing the platform
object files to be compiled. This file also provides platform-specific
compiler flags, and select firmware options.
3. Create a *platform/&lt;xyz&gt;/objects.mk* file for listing the
platform-specific object files to be compiled.
4. Create a *platform/&lt;xyz&gt;/platform.c* file providing a
*struct sbi_platform* instance.

View File

@@ -10,7 +10,7 @@ To handle this, we have two types of RISC-V platform requirements:
2. **Release specific platform requirements** which apply to a OpenSBI
release and later releases
Currently, we don't have any **Release specific platform requirements**
Currently, we don't have any **Release specific platform requirements**,
but such platform requirements will be added in future.
Base Platform Requirements
@@ -18,7 +18,11 @@ Base Platform Requirements
The base RISC-V platform requirements for OpenSBI are as follows:
1. At least rv32ima or rv64ima required on all HARTs
1. At least rv32ima_zicsr or rv64ima_zicsr required on all HARTs
* Users may restrict the usage of atomic instructions to lr/sc
via rv32im_zalrsc_zicsr or rv64im_zalrsc_zicsr if preferred
2. At least one HART should have S-mode support because:
* SBI calls are meant for RISC-V S-mode (Supervisor mode)
@@ -33,7 +37,7 @@ The base RISC-V platform requirements for OpenSBI are as follows:
6. Hardware support for injecting M-mode software interrupts on
a multi-HART platform
The RISC-V extensions not covered by rv32ima or rv64ima are optional
The RISC-V extensions not covered by rv32ima_zicsr or rv64ima_zicsr are optional
for OpenSBI. Although, OpenSBI will detect and handle some of these
optional RISC-V extensions at runtime.

View File

@@ -1,14 +1,11 @@
OpenSBI SBI PMU extension support
==================================
SBI PMU extension supports allow supervisor software to configure/start/stop
any performance counter at anytime. Thus, an user can leverage full
any performance counter at anytime. Thus, a user can leverage full
capability of performance analysis tools such as perf if SBI PMU extension is
enabled. The OpenSBI implementation makes the following assumptions about the
hardware platform.
* MCOUNTINHIBIT CSR must be implemented in the hardware. Otherwise, SBI PMU
extension will not be enabled.
* The platform must provide information about PMU event to counter mapping
via device tree or platform specific hooks. Otherwise, SBI PMU extension will
not be enabled.
@@ -25,7 +22,7 @@ SBI PMU Device Tree Bindings
----------------------------
Platforms may choose to describe PMU event selector and event to counter mapping
values via device tree. The following sections describes the PMU DT node
values via device tree. The following sections describe the PMU DT node
bindings in details.
* **compatible** (Mandatory) - The compatible string of SBI PMU device tree node.
@@ -42,46 +39,171 @@ This property shouldn't encode any raw hardware event.
* **riscv,event-to-mhpmcounters**(Optional) - It represents a MANY-to-MANY
mapping between a range of events and all the MHPMCOUNTERx in a bitmap format
that can be used to monitor these range of events. The information is encoded in
a table format where each row represent a certain range of events and
a table format where each row represents a certain range of events and
corresponding counters. The first column represents starting of the pmu event id
and 2nd column represents the end of the pmu event id. The third column
represent a bitmap of all the MHPMCOUNTERx. This property is mandatory if
event-to-mhpmevent is present. Otherwise, it can be omitted. This property
riscv,event-to-mhpmevent is present. Otherwise, it can be omitted. This property
shouldn't encode any raw event.
* **riscv,raw-event-to-mhpmcounters**(Optional) - It represents an ONE-to-MANY
or MANY-to-MANY mapping between the raw event(s) and all the MHPMCOUNTERx in
a bitmap format that can be used to monitor that raw event, which depends on
how the platform encodes the monitor events. Currently, only the following three
encoding methods are supported, encoding each event as a number, using a bitmap
to encode monitor events, and mixing the previous two methods. The information
is encoded in a table format where each row represent the specific raw event(s).
The first column represents a 64-bit selector value which can indicate an
monitor event ID (encoded by a number) or an event set (encoded by a bitmap).
In case of the latter, the lower bits used to encode a set of events should be
set to zero. The second column is a 64-bit selector mask where any bits used
for event encoding will be cleared. If a platform directly encodes each raw PMU
event as a unique ID, the value of select_mask will be 0xffffffff_ffffffff.
The third column represent a bitmap of all the MHPMCOUNTERx that can be used for
monitoring the specified event(s).
a bitmap format that can be used to monitor that raw event. The encoding of the
raw events are platform specific. The information is encoded in a table format
where each row represents the specific raw event(s). The first column is a 64bit
match value where the invariant bits of range of events are set. The second
column is a 64 bit mask that will have all the variant bits of the range of
events cleared. All other bits should be set in the mask.
The third column is a 32bit value to represent bitmap of all MHPMCOUNTERx that
can monitor these set of event(s).
If a platform directly encodes each raw PMU event as a unique ID, the value of
select_mask must be 0xffffffff_ffffffff.
*Note:* A platform may choose to provide the mapping between event & counters
via platform hooks rather than the device tree.
### Example
### Example 1
```
pmu {
compatible = "riscv,pmu";
interrupts = <0x100>;
interrupt-parent = <&plic>
riscv,event-to-mhpmevent = <0x0000B 0x0000 0x0001>,
riscv,event-to-mhpmevent = <0x0000B 0x0000 0x0001>;
riscv,event-to-mhpmcounters = <0x00001 0x00001 0x00000001>,
<0x00002 0x00002 0x00000004>,
<0x00003 0x0000A 0x00000ff8>,
<0x10000 0x10033 0x000ff000>,
riscv,raw-event-to-mhpmcounters = <0x0000 0x0002 0xffffffff 0xffffffff 0x00000f8>,
<0xffffffff 0xfffffff0 0xffffffff 0xfffffff0 0x00000ff0>,
<0x10000 0x10033 0x000ff000>;
/* For event ID 0x0002 */
riscv,raw-event-to-mhpmcounters = <0x0000 0x0002 0xffffffff 0xffffffff 0x00000f8>,
/* For event ID 0-15 */
<0x0 0x0 0xffffffff 0xfffffff0 0x00000ff0>,
/* For event ID 0xffffffff0000000f - 0xffffffff000000ff */
<0xffffffff 0xf 0xffffffff 0xffffff0f 0x00000ff0>;
};
```
### Example 2
```
/*
* For HiFive Unmatched board. The encodings can be found here
* https://sifive.cdn.prismic.io/sifive/1a82e600-1f93-4f41-b2d8-86ed8b16acba_fu740-c000-manual-v1p6.pdf
* This example also binds standard SBI PMU hardware id's to U74 PMU event codes, U74 uses bitfield for
* events encoding, so several U74 events can be bound to single perf id.
* See SBI PMU hardware id's in include/sbi/sbi_ecall_interface.h
*/
pmu {
compatible = "riscv,pmu";
riscv,event-to-mhpmevent =
/* SBI_PMU_HW_CACHE_REFERENCES -> Instruction cache/ITIM busy | Data cache/DTIM busy */
<0x00003 0x00000000 0x1801>,
/* SBI_PMU_HW_CACHE_MISSES -> Instruction cache miss | Data cache miss or memory-mapped I/O access */
<0x00004 0x00000000 0x0302>,
/* SBI_PMU_HW_BRANCH_INSTRUCTIONS -> Conditional branch retired */
<0x00005 0x00000000 0x4000>,
/* SBI_PMU_HW_BRANCH_MISSES -> Branch direction misprediction | Branch/jump target misprediction */
<0x00006 0x00000000 0x6001>,
/* L1D_READ_MISS -> Data cache miss or memory-mapped I/O access */
<0x10001 0x00000000 0x0202>,
/* L1D_WRITE_ACCESS -> Data cache write-back */
<0x10002 0x00000000 0x0402>,
/* L1I_READ_ACCESS -> Instruction cache miss */
<0x10009 0x00000000 0x0102>,
/* LL_READ_MISS -> UTLB miss */
<0x10011 0x00000000 0x2002>,
/* DTLB_READ_MISS -> Data TLB miss */
<0x10019 0x00000000 0x1002>,
/* ITLB_READ_MISS-> Instruction TLB miss */
<0x10021 0x00000000 0x0802>;
riscv,event-to-mhpmcounters = <0x00003 0x00006 0x18>,
<0x10001 0x10002 0x18>,
<0x10009 0x10009 0x18>,
<0x10011 0x10011 0x18>,
<0x10019 0x10019 0x18>,
<0x10021 0x10021 0x18>;
riscv,raw-event-to-mhpmcounters = <0x0 0x0 0xffffffff 0xfc0000ff 0x18>,
<0x0 0x1 0xffffffff 0xfff800ff 0x18>,
<0x0 0x2 0xffffffff 0xffffe0ff 0x18>;
};
```
### Example 3
```
/*
* For Andes 45-series platforms. The encodings can be found in the
* "Machine Performance Monitoring Event Selector" section
* http://www.andestech.com/wp-content/uploads/AX45MP-1C-Rev.-5.0.0-Datasheet.pdf
*/
pmu {
compatible = "riscv,pmu";
riscv,event-to-mhpmevent =
<0x1 0x0000 0x10>, /* CPU_CYCLES -> Cycle count */
<0x2 0x0000 0x20>, /* INSTRUCTIONS -> Retired instruction count */
<0x3 0x0000 0x41>, /* CACHE_REFERENCES -> D-Cache access */
<0x4 0x0000 0x51>, /* CACHE_MISSES -> D-Cache miss */
<0x5 0x0000 0x80>, /* BRANCH_INSTRUCTIONS -> Conditional branch instruction count */
<0x6 0x0000 0x02>, /* BRANCH_MISSES -> Misprediction of conditional branches */
<0x10000 0x0000 0x61>, /* L1D_READ_ACCESS -> D-Cache load access */
<0x10001 0x0000 0x71>, /* L1D_READ_MISS -> D-Cache load miss */
<0x10002 0x0000 0x81>, /* L1D_WRITE_ACCESS -> D-Cache store access */
<0x10003 0x0000 0x91>, /* L1D_WRITE_MISS -> D-Cache store miss */
<0x10008 0x0000 0x21>, /* L1I_READ_ACCESS -> I-Cache access */
<0x10009 0x0000 0x31>; /* L1I_READ_MISS -> I-Cache miss */
riscv,event-to-mhpmcounters = <0x1 0x6 0x78>,
<0x10000 0x10003 0x78>,
<0x10008 0x10009 0x78>;
riscv,raw-event-to-mhpmcounters =
<0x0 0x10 0xffffffff 0xffffffff 0x78>, /* Cycle count */
<0x0 0x20 0xffffffff 0xffffffff 0x78>, /* Retired instruction count */
<0x0 0x30 0xffffffff 0xffffffff 0x78>, /* Integer load instruction count */
<0x0 0x40 0xffffffff 0xffffffff 0x78>, /* Integer store instruction count */
<0x0 0x50 0xffffffff 0xffffffff 0x78>, /* Atomic instruction count */
<0x0 0x60 0xffffffff 0xffffffff 0x78>, /* System instruction count */
<0x0 0x70 0xffffffff 0xffffffff 0x78>, /* Integer computational instruction count */
<0x0 0x80 0xffffffff 0xffffffff 0x78>, /* Conditional branch instruction count */
<0x0 0x90 0xffffffff 0xffffffff 0x78>, /* Taken conditional branch instruction count */
<0x0 0xA0 0xffffffff 0xffffffff 0x78>, /* JAL instruction count */
<0x0 0xB0 0xffffffff 0xffffffff 0x78>, /* JALR instruction count */
<0x0 0xC0 0xffffffff 0xffffffff 0x78>, /* Return instruction count */
<0x0 0xD0 0xffffffff 0xffffffff 0x78>, /* Control transfer instruction count */
<0x0 0xE0 0xffffffff 0xffffffff 0x78>, /* EXEC.IT instruction count */
<0x0 0xF0 0xffffffff 0xffffffff 0x78>, /* Integer multiplication instruction count */
<0x0 0x100 0xffffffff 0xffffffff 0x78>, /* Integer division instruction count */
<0x0 0x110 0xffffffff 0xffffffff 0x78>, /* Floating-point load instruction count */
<0x0 0x120 0xffffffff 0xffffffff 0x78>, /* Floating-point store instruction count */
<0x0 0x130 0xffffffff 0xffffffff 0x78>, /* Floating-point addition/subtraction instruction count */
<0x0 0x140 0xffffffff 0xffffffff 0x78>, /* Floating-point multiplication instruction count */
<0x0 0x150 0xffffffff 0xffffffff 0x78>, /* Floating-point fused multiply-add instruction count */
<0x0 0x160 0xffffffff 0xffffffff 0x78>, /* Floating-point division or square-root instruction count */
<0x0 0x170 0xffffffff 0xffffffff 0x78>, /* Other floating-point instruction count */
<0x0 0x180 0xffffffff 0xffffffff 0x78>, /* Integer multiplication and add/sub instruction count */
<0x0 0x190 0xffffffff 0xffffffff 0x78>, /* Retired operation count */
<0x0 0x01 0xffffffff 0xffffffff 0x78>, /* ILM access */
<0x0 0x11 0xffffffff 0xffffffff 0x78>, /* DLM access */
<0x0 0x21 0xffffffff 0xffffffff 0x78>, /* I-Cache access */
<0x0 0x31 0xffffffff 0xffffffff 0x78>, /* I-Cache miss */
<0x0 0x41 0xffffffff 0xffffffff 0x78>, /* D-Cache access */
<0x0 0x51 0xffffffff 0xffffffff 0x78>, /* D-Cache miss */
<0x0 0x61 0xffffffff 0xffffffff 0x78>, /* D-Cache load access */
<0x0 0x71 0xffffffff 0xffffffff 0x78>, /* D-Cache load miss */
<0x0 0x81 0xffffffff 0xffffffff 0x78>, /* D-Cache store access */
<0x0 0x91 0xffffffff 0xffffffff 0x78>, /* D-Cache store miss */
<0x0 0xA1 0xffffffff 0xffffffff 0x78>, /* D-Cache writeback */
<0x0 0xB1 0xffffffff 0xffffffff 0x78>, /* Cycles waiting for I-Cache fill data */
<0x0 0xC1 0xffffffff 0xffffffff 0x78>, /* Cycles waiting for D-Cache fill data */
<0x0 0xD1 0xffffffff 0xffffffff 0x78>, /* Uncached fetch data access from bus */
<0x0 0xE1 0xffffffff 0xffffffff 0x78>, /* Uncached load data access from bus */
<0x0 0xF1 0xffffffff 0xffffffff 0x78>, /* Cycles waiting for uncached fetch data from bus */
<0x0 0x101 0xffffffff 0xffffffff 0x78>, /* Cycles waiting for uncached load data from bus */
<0x0 0x111 0xffffffff 0xffffffff 0x78>, /* Main ITLB access */
<0x0 0x121 0xffffffff 0xffffffff 0x78>, /* Main ITLB miss */
<0x0 0x131 0xffffffff 0xffffffff 0x78>, /* Main DTLB access */
<0x0 0x141 0xffffffff 0xffffffff 0x78>, /* Main DTLB miss */
<0x0 0x151 0xffffffff 0xffffffff 0x78>, /* Cycles waiting for Main ITLB fill data */
<0x0 0x161 0xffffffff 0xffffffff 0x78>, /* Pipeline stall cycles caused by Main DTLB miss */
<0x0 0x171 0xffffffff 0xffffffff 0x78>, /* Hardware prefetch bus access */
<0x0 0x02 0xffffffff 0xffffffff 0x78>, /* Misprediction of conditional branches */
<0x0 0x12 0xffffffff 0xffffffff 0x78>, /* Misprediction of taken conditional branches */
<0x0 0x22 0xffffffff 0xffffffff 0x78>; /* Misprediction of targets of Return instructions */
};
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

127
docs/writing_tests.md Normal file
View File

@@ -0,0 +1,127 @@
Writing tests for OpenSBI
=========================
SBIUnit
-------
SBIUnit is a set of macros and functions which simplify the test development and
automate the test execution and evaluation. All of the SBIUnit definitions are
in the `include/sbi/sbi_unit_test.h` header file, and implementations are
available in `lib/sbi/tests/sbi_unit_test.c`.
Simple SBIUnit test
-------------------
For instance, we would like to test the following function from
`lib/sbi/sbi_string.c`:
```c
size_t sbi_strlen(const char *str)
{
unsigned long ret = 0;
while (*str != '\0') {
ret++;
str++;
}
return ret;
}
```
which calculates the string length.
Create the file `lib/sbi/tests/sbi_string_test.c` with the following content:
```c
#include <sbi/sbi_unit_test.h>
#include <sbi/sbi_string.h>
static void strlen_test(struct sbiunit_test_case *test)
{
SBIUNIT_EXPECT_EQ(test, sbi_strlen("Hello"), 5);
SBIUNIT_EXPECT_EQ(test, sbi_strlen("Hell\0o"), 4);
}
static struct sbiunit_test_case string_test_cases[] = {
SBIUNIT_TEST_CASE(strlen_test),
SBIUNIT_END_CASE,
};
SBIUNIT_TEST_SUITE(string_test_suite, string_test_cases);
```
Then, add the corresponding Makefile entries to `lib/sbi/tests/objects.mk`:
```lang-makefile
...
carray-sbi_unit_tests-$(CONFIG_SBIUNIT) += string_test_suite
libsbi-objs-$(CONFIG_SBIUNIT) += tests/sbi_string_test.o
```
Now, run `make clean` in order to regenerate the carray-related files.
Recompile OpenSBI with the CONFIG_SBIUNIT option enabled and run it in QEMU.
You will see something like this:
```
# make PLATFORM=generic run
...
# Running SBIUNIT tests #
...
## Running test suite: string_test_suite
[PASSED] strlen_test
1 PASSED / 0 FAILED / 1 TOTAL
```
Now let's try to change this test in the way that it will fail:
```c
- SBIUNIT_EXPECT_EQ(test, sbi_strlen("Hello"), 5);
+ SBIUNIT_EXPECT_EQ(test, sbi_strlen("Hello"), 100);
```
`make all` and `make run` it again:
```
...
# Running SBIUNIT tests #
...
## Running test suite: string_test_suite
[SBIUnit] [.../opensbi/lib/sbi/tests/sbi_string_test.c:6]: strlen_test: Condition "(sbi_strlen("Hello")) == (100)" expected to be true!
[FAILED] strlen_test
0 PASSED / 1 FAILED / 1 TOTAL
```
Covering the static functions / using the static definitions
------------------------------------------------------------
SBIUnit also allows you to test static functions. In order to do so, simply
include your test source in the file you would like to test. Complementing the
example above, just add this to the `lib/sbi/sbi_string.c` file:
```c
#ifdef CONFIG_SBIUNIT
#include "tests/sbi_string_test.c"
#endif
```
In this case you should only add a new carray entry pointing to the test suite
to `lib/sbi/tests/objects.mk`:
```lang-makefile
...
carray-sbi_unit_tests-$(CONFIG_SBIUNIT) += string_test_suite
```
You don't have to compile the `sbi_string_test.o` separately, because the
test code will be included into the `sbi_string` object file.
"Mocking" the structures
------------------------
See the example of structure "mocking" in `lib/sbi/tests/sbi_console_test.c`,
where the sbi_console_device structure was mocked to be used in various
console-related functions in order to test them.
API Reference
-------------
All of the `SBIUNIT_EXPECT_*` macros will cause a test case to fail if the
corresponding conditions are not met, however, the execution of a particular
test case will not be stopped.
All of the `SBIUNIT_ASSERT_*` macros will cause a test case to fail and stop
immediately, triggering a panic.

28
firmware/Kconfig Normal file
View File

@@ -0,0 +1,28 @@
# SPDX-License-Identifier: BSD-2-Clause
menu "Stack Protector Support"
config STACK_PROTECTOR
bool "Stack Protector buffer overflow detection"
default n
help
This option turns on the "stack-protector" compiler feature.
config STACK_PROTECTOR_STRONG
bool "Strong Stack Protector"
depends on STACK_PROTECTOR
default n
help
Turn on the "stack-protector" with "-fstack-protector-strong" option.
Like -fstack-protector but includes additional functions to be
protected.
config STACK_PROTECTOR_ALL
bool "Almighty Stack Protector"
depends on STACK_PROTECTOR
default n
help
Turn on the "stack-protector" with "-fstack-protector-all" option.
Like -fstack-protector except that all functions are protected.
endmenu

View File

@@ -14,8 +14,8 @@
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_trap.h>
#define BOOT_STATUS_RELOCATE_DONE 1
#define BOOT_STATUS_BOOT_HART_DONE 2
#define BOOT_LOTTERY_ACQUIRED 1
#define BOOT_STATUS_BOOT_HART_DONE 1
.macro MOV_3R __d0, __s0, __d1, __s1, __d2, __s2
add \__d0, \__s0, zero
@@ -31,15 +31,14 @@
add \__d4, \__s4, zero
.endm
/*
* If __start_reg <= __check_reg and __check_reg < __end_reg then
* jump to __pass
*/
.macro BRANGE __start_reg, __end_reg, __check_reg, __jump_lable
blt \__check_reg, \__start_reg, 999f
bge \__check_reg, \__end_reg, 999f
j \__jump_lable
999:
.macro CLEAR_MDT tmp
#if __riscv_xlen == 32
li \tmp, MSTATUSH_MDT
csrc CSR_MSTATUSH, \tmp
#else
li \tmp, MSTATUS_MDT
csrc CSR_MSTATUS, \tmp
#endif
.endm
.section .entry, "ax", %progbits
@@ -55,164 +54,48 @@ _start:
li a7, -1
beq a6, a7, _try_lottery
/* Jump to relocation wait loop if we are not boot hart */
bne a0, a6, _wait_relocate_copy_done
bne a0, a6, _wait_for_boot_hart
_try_lottery:
/* Jump to relocation wait loop if we don't get relocation lottery */
lla a6, _relocate_lottery
li a7, 1
amoadd.w a6, a7, (a6)
bnez a6, _wait_relocate_copy_done
lla a6, _boot_lottery
li a7, BOOT_LOTTERY_ACQUIRED
#ifdef __riscv_atomic
amoswap.w a6, a7, (a6)
bnez a6, _wait_for_boot_hart
#elif __riscv_zalrsc
_sc_fail:
lr.w t0, (a6)
sc.w t1, a7, (a6)
bnez t1, _sc_fail
bnez t0, _wait_for_boot_hart
#else
#error "need a or zalrsc"
#endif
/* Save load address */
lla t0, _load_start
lla t1, _fw_start
REG_S t1, 0(t0)
#ifdef FW_PIC
/* relocate the global table content */
lla t0, _link_start
REG_L t0, 0(t0)
/* t1 shall has the address of _fw_start */
sub t2, t1, t0
lla t3, _runtime_offset
REG_S t2, (t3)
lla t0, __rel_dyn_start
lla t1, __rel_dyn_end
li t0, FW_TEXT_START /* link start */
lla t1, _fw_start /* load start */
sub t2, t1, t0 /* load offset */
lla t0, __rela_dyn_start
lla t1, __rela_dyn_end
beq t0, t1, _relocate_done
j 5f
2:
REG_L t5, -(REGBYTES*2)(t0) /* t5 <-- relocation info:type */
REG_L t5, __SIZEOF_LONG__(t0) /* t5 <-- relocation info:type */
li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */
bne t5, t3, 3f
REG_L t3, -(REGBYTES*3)(t0)
REG_L t5, -(REGBYTES)(t0) /* t5 <-- addend */
REG_L t3, 0(t0)
REG_L t5, (__SIZEOF_LONG__ * 2)(t0) /* t5 <-- addend */
add t5, t5, t2
add t3, t3, t2
REG_S t5, 0(t3) /* store runtime address to the GOT entry */
j 5f
3:
lla t4, __dyn_sym_start
4:
REG_L t5, -(REGBYTES*2)(t0) /* t5 <-- relocation info:type */
srli t6, t5, SYM_INDEX /* t6 <--- sym table index */
andi t5, t5, 0xFF /* t5 <--- relocation type */
li t3, RELOC_TYPE
bne t5, t3, 5f
/* address R_RISCV_64 or R_RISCV_32 cases*/
REG_L t3, -(REGBYTES*3)(t0)
li t5, SYM_SIZE
mul t6, t6, t5
add s5, t4, t6
REG_L t6, -(REGBYTES)(t0) /* t0 <-- addend */
REG_L t5, REGBYTES(s5)
add t5, t5, t6
add t5, t5, t2 /* t5 <-- location to fix up in RAM */
add t3, t3, t2 /* t3 <-- location to fix up in RAM */
REG_S t5, 0(t3) /* store runtime address to the variable */
5:
addi t0, t0, (REGBYTES*3)
ble t0, t1, 2b
j _relocate_done
_wait_relocate_copy_done:
j _wait_for_boot_hart
#else
/* Relocate if load address != link address */
_relocate:
lla t0, _link_start
REG_L t0, 0(t0)
lla t1, _link_end
REG_L t1, 0(t1)
lla t2, _load_start
REG_L t2, 0(t2)
sub t3, t1, t0
add t3, t3, t2
beq t0, t2, _relocate_done
lla t4, _relocate_done
sub t4, t4, t2
add t4, t4, t0
blt t2, t0, _relocate_copy_to_upper
_relocate_copy_to_lower:
ble t1, t2, _relocate_copy_to_lower_loop
lla t3, _relocate_lottery
BRANGE t2, t1, t3, _start_hang
lla t3, _boot_status
BRANGE t2, t1, t3, _start_hang
lla t3, _relocate
lla t5, _relocate_done
BRANGE t2, t1, t3, _start_hang
BRANGE t2, t1, t5, _start_hang
BRANGE t3, t5, t2, _start_hang
_relocate_copy_to_lower_loop:
REG_L t3, 0(t2)
REG_S t3, 0(t0)
add t0, t0, __SIZEOF_POINTER__
add t2, t2, __SIZEOF_POINTER__
blt t0, t1, _relocate_copy_to_lower_loop
jr t4
_relocate_copy_to_upper:
ble t3, t0, _relocate_copy_to_upper_loop
lla t2, _relocate_lottery
BRANGE t0, t3, t2, _start_hang
lla t2, _boot_status
BRANGE t0, t3, t2, _start_hang
lla t2, _relocate
lla t5, _relocate_done
BRANGE t0, t3, t2, _start_hang
BRANGE t0, t3, t5, _start_hang
BRANGE t2, t5, t0, _start_hang
_relocate_copy_to_upper_loop:
add t3, t3, -__SIZEOF_POINTER__
add t1, t1, -__SIZEOF_POINTER__
REG_L t2, 0(t3)
REG_S t2, 0(t1)
blt t0, t1, _relocate_copy_to_upper_loop
jr t4
_wait_relocate_copy_done:
lla t0, _fw_start
lla t1, _link_start
REG_L t1, 0(t1)
beq t0, t1, _wait_for_boot_hart
lla t2, _boot_status
lla t3, _wait_for_boot_hart
sub t3, t3, t0
add t3, t3, t1
1:
/* waitting for relocate copy done (_boot_status == 1) */
li t4, BOOT_STATUS_RELOCATE_DONE
REG_L t5, 0(t2)
/* Reduce the bus traffic so that boot hart may proceed faster */
nop
nop
nop
bgt t4, t5, 1b
jr t3
#endif
addi t0, t0, (__SIZEOF_LONG__ * 3)
blt t0, t1, 2b
_relocate_done:
/*
* Mark relocate copy done
* Use _boot_status copy relative to the load address
*/
lla t0, _boot_status
#ifndef FW_PIC
lla t1, _link_start
REG_L t1, 0(t1)
lla t2, _load_start
REG_L t2, 0(t2)
sub t0, t0, t1
add t0, t0, t2
#endif
li t1, BOOT_STATUS_RELOCATE_DONE
REG_S t1, 0(t0)
fence rw, rw
/* At this point we are running from link address */
/* Reset all registers for boot HART */
/* Reset all registers except ra, a0, a1, a2, a3 and a4 for boot HART */
li ra, 0
call _reset_regs
@@ -228,6 +111,14 @@ _bss_zero:
lla s4, _start_hang
csrw CSR_MTVEC, s4
/*
* While at this point, trap handling is rudimentary, if a trap happens,
* it will end up in _start_hang which is enough to hook up a GDB. Clear
* MDT to avoid generating a double trap and thus entering a
* critical-error state.
*/
CLEAR_MDT t0
/* Setup temporary stack */
lla s4, _fw_end
li s5, (SBI_SCRATCH_SIZE * 2)
@@ -257,20 +148,28 @@ _bss_zero:
/* Preload HART details
* s7 -> HART Count
* s8 -> HART Stack Size
* s9 -> Heap Size
* s10 -> Heap Offset
*/
lla a4, platform
#if __riscv_xlen == 64
#if __riscv_xlen > 32
lwu s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
lwu s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
lwu s9, SBI_PLATFORM_HEAP_SIZE_OFFSET(a4)
#else
lw s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
lw s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
lw s9, SBI_PLATFORM_HEAP_SIZE_OFFSET(a4)
#endif
/* Setup scratch space for all the HARTs*/
lla tp, _fw_end
mul a5, s7, s8
add tp, tp, a5
/* Setup heap base address */
lla s10, _fw_start
sub s10, tp, s10
add tp, tp, s9
/* Keep a copy of tp */
add t3, tp, zero
/* Counter */
@@ -285,8 +184,11 @@ _scratch_init:
* t3 -> the firmware end address
* s7 -> HART count
* s8 -> HART stack size
* s9 -> Heap Size
* s10 -> Heap Offset
*/
add tp, t3, zero
sub tp, tp, s9
mul a5, s8, t1
sub tp, tp, a5
li a5, SBI_SCRATCH_SIZE
@@ -298,6 +200,16 @@ _scratch_init:
sub a5, t3, a4
REG_S a4, SBI_SCRATCH_FW_START_OFFSET(tp)
REG_S a5, SBI_SCRATCH_FW_SIZE_OFFSET(tp)
/* Store R/W section's offset in scratch space */
lla a5, _fw_rw_start
sub a5, a5, a4
REG_S a5, SBI_SCRATCH_FW_RW_OFFSET(tp)
/* Store fw_heap_offset and fw_heap_size in scratch space */
REG_S s10, SBI_SCRATCH_FW_HEAP_OFFSET(tp)
REG_S s9, SBI_SCRATCH_FW_HEAP_SIZE_OFFSET(tp)
/* Store next arg1 in scratch space */
MOV_3R s0, a0, s1, a1, s2, a2
call fw_next_arg1
@@ -322,10 +234,8 @@ _scratch_init:
/* Store hartid-to-scratch function address in scratch space */
lla a4, _hartid_to_scratch
REG_S a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp)
/* Store trap-exit function address in scratch space */
lla a4, _trap_exit
REG_S a4, SBI_SCRATCH_TRAP_EXIT_OFFSET(tp)
/* Clear tmp0 in scratch space */
/* Clear trap_context and tmp0 in scratch space */
REG_S zero, SBI_SCRATCH_TRAP_CONTEXT_OFFSET(tp)
REG_S zero, SBI_SCRATCH_TMP0_OFFSET(tp)
/* Store firmware options in scratch space */
MOV_3R s0, a0, s1, a1, s2, a2
@@ -336,6 +246,8 @@ _scratch_init:
#endif
REG_S a0, SBI_SCRATCH_OPTIONS_OFFSET(tp)
MOV_3R a0, s0, a1, s1, a2, s2
/* Store hart index in scratch space */
REG_S t1, SBI_SCRATCH_HARTINDEX_OFFSET(tp)
/* Move to next scratch space */
add t1, t1, t2
blt t1, s7, _scratch_init
@@ -360,30 +272,14 @@ _scratch_init:
beq t1, a1, _fdt_reloc_done
/* t0 = source FDT start address */
add t0, a1, zero
/* t2 = source FDT size in big-endian */
#if __riscv_xlen == 64
lwu t2, 4(t0)
#else
lw t2, 4(t0)
#endif
/* t3 = bit[15:8] of FDT size */
add t3, t2, zero
srli t3, t3, 16
and t3, t3, a4
/* t2 = source FDT size (convert from big-endian) */
lbu t2, 7(t0)
lbu t3, 6(t0)
lbu t4, 5(t0)
lbu t5, 4(t0)
slli t3, t3, 8
/* t4 = bit[23:16] of FDT size */
add t4, t2, zero
srli t4, t4, 8
and t4, t4, a4
slli t4, t4, 16
/* t5 = bit[31:24] of FDT size */
add t5, t2, zero
and t5, t5, a4
slli t5, t5, 24
/* t2 = bit[7:0] of FDT size */
srli t2, t2, 24
and t2, t2, a4
/* t2 = FDT size in little-endian */
or t2, t2, t3
or t2, t2, t4
or t2, t2, t5
@@ -402,33 +298,32 @@ _fdt_reloc_done:
/* mark boot hart done */
li t0, BOOT_STATUS_BOOT_HART_DONE
lla t1, _boot_status
REG_S t0, 0(t1)
fence rw, rw
REG_S t0, 0(t1)
j _start_warm
/* waiting for boot hart to be done (_boot_status == 2) */
/* waiting for boot hart to be done (_boot_status == BOOT_STATUS_BOOT_HART_DONE) */
_wait_for_boot_hart:
li t0, BOOT_STATUS_BOOT_HART_DONE
lla t1, _boot_status
REG_L t1, 0(t1)
/* Reduce the bus traffic so that boot hart may proceed faster */
nop
nop
nop
div t2, t2, zero
div t2, t2, zero
div t2, t2, zero
bne t0, t1, _wait_for_boot_hart
_start_warm:
/* Reset all registers for non-boot HARTs */
/* Reset all registers except ra, a0, a1, a2, a3 and a4 for non-boot HART */
li ra, 0
call _reset_regs
/* Disable and clear all interrupts */
/* Disable all interrupts */
csrw CSR_MIE, zero
csrw CSR_MIP, zero
/* Find HART count and HART stack size */
lla a4, platform
#if __riscv_xlen == 64
#if __riscv_xlen > 32
lwu s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
lwu s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
#else
@@ -444,7 +339,7 @@ _start_warm:
beqz s9, 3f
li a4, 0
1:
#if __riscv_xlen == 64
#if __riscv_xlen > 32
lwu a5, (s9)
#else
lw a5, (s9)
@@ -453,7 +348,6 @@ _start_warm:
add s9, s9, 4
add a4, a4, 1
blt a4, s7, 1b
li a4, -1
2: add s6, a4, zero
3: bge s6, s7, _start_hang
@@ -474,27 +368,16 @@ _start_warm:
/* Setup trap handler */
lla a4, _trap_handler
#if __riscv_xlen == 32
csrr a5, CSR_MISA
srli a5, a5, ('H' - 'A')
andi a5, a5, 0x1
beq a5, zero, _skip_trap_handler_rv32_hyp
lla a4, _trap_handler_rv32_hyp
_skip_trap_handler_rv32_hyp:
#endif
beq a5, zero, _skip_trap_handler_hyp
lla a4, _trap_handler_hyp
_skip_trap_handler_hyp:
csrw CSR_MTVEC, a4
#if __riscv_xlen == 32
/* Override trap exit for H-extension */
csrr a5, CSR_MISA
srli a5, a5, ('H' - 'A')
andi a5, a5, 0x1
beq a5, zero, _skip_trap_exit_rv32_hyp
lla a4, _trap_exit_rv32_hyp
csrr a5, CSR_MSCRATCH
REG_S a4, SBI_SCRATCH_TRAP_EXIT_OFFSET(a5)
_skip_trap_exit_rv32_hyp:
#endif
/* Clear MDT here again for all harts */
CLEAR_MDT t0
/* Initialize SBI runtime */
csrr a0, CSR_MSCRATCH
@@ -505,20 +388,10 @@ _skip_trap_exit_rv32_hyp:
.data
.align 3
#ifdef FW_PIC
_runtime_offset:
RISCV_PTR 0
#endif
_relocate_lottery:
_boot_lottery:
RISCV_PTR 0
_boot_status:
RISCV_PTR 0
_load_start:
RISCV_PTR _fw_start
_link_start:
RISCV_PTR FW_TEXT_START
_link_end:
RISCV_PTR _fw_reloc_end
.section .entry, "ax", %progbits
.align 3
@@ -532,7 +405,7 @@ _hartid_to_scratch:
* t2 -> Temporary
*/
lla t2, platform
#if __riscv_xlen == 64
#if __riscv_xlen > 32
lwu t0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(t2)
lwu t2, SBI_PLATFORM_HART_COUNT_OFFSET(t2)
#else
@@ -616,10 +489,10 @@ memcmp:
xor t0, tp, t0
/* Save original SP on exception stack */
REG_S sp, (SBI_TRAP_REGS_OFFSET(sp) - SBI_TRAP_REGS_SIZE)(t0)
REG_S sp, (SBI_TRAP_REGS_OFFSET(sp) - SBI_TRAP_CONTEXT_SIZE)(t0)
/* Set SP to exception stack and make room for trap registers */
add sp, t0, -(SBI_TRAP_REGS_SIZE)
/* Set SP to exception stack and make room for trap context */
add sp, t0, -(SBI_TRAP_CONTEXT_SIZE)
/* Restore T0 from scratch space */
REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp)
@@ -679,6 +552,35 @@ memcmp:
REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
.endm
.macro TRAP_SAVE_INFO have_mstatush have_h_extension
csrr t0, CSR_MCAUSE
REG_S t0, (SBI_TRAP_REGS_SIZE + SBI_TRAP_INFO_OFFSET(cause))(sp)
csrr t0, CSR_MTVAL
REG_S t0, (SBI_TRAP_REGS_SIZE + SBI_TRAP_INFO_OFFSET(tval))(sp)
.if \have_h_extension
csrr t0, CSR_MTVAL2
REG_S t0, (SBI_TRAP_REGS_SIZE + SBI_TRAP_INFO_OFFSET(tval2))(sp)
csrr t0, CSR_MTINST
REG_S t0, (SBI_TRAP_REGS_SIZE + SBI_TRAP_INFO_OFFSET(tinst))(sp)
.if \have_mstatush
csrr t0, CSR_MSTATUSH
srli t0, t0, MSTATUSH_GVA_SHIFT
.else
csrr t0, CSR_MSTATUS
srli t0, t0, MSTATUS_GVA_SHIFT
.endif
and t0, t0, 0x1
.else
REG_S zero, (SBI_TRAP_REGS_SIZE + SBI_TRAP_INFO_OFFSET(tval2))(sp)
REG_S zero, (SBI_TRAP_REGS_SIZE + SBI_TRAP_INFO_OFFSET(tinst))(sp)
li t0, 0
.endif
REG_S t0, (SBI_TRAP_REGS_SIZE + SBI_TRAP_INFO_OFFSET(gva))(sp)
/* We are ready to take another trap, clear MDT */
CLEAR_MDT t0
.endm
.macro TRAP_CALL_C_ROUTINE
/* Call C routine */
add a0, sp, zero
@@ -719,15 +621,18 @@ memcmp:
.endm
.macro TRAP_RESTORE_MEPC_MSTATUS have_mstatush
/* Restore MEPC and MSTATUS CSRs */
REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(a0)
csrw CSR_MEPC, t0
REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(a0)
csrw CSR_MSTATUS, t0
/*
* Restore MSTATUS and MEPC CSRs starting with MSTATUS/H to set MDT
* flags since we can not take a trap now or MEPC would be cloberred
*/
.if \have_mstatush
REG_L t0, SBI_TRAP_REGS_OFFSET(mstatusH)(a0)
csrw CSR_MSTATUSH, t0
.endif
REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(a0)
csrw CSR_MSTATUS, t0
REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(a0)
csrw CSR_MEPC, t0
.endm
.macro TRAP_RESTORE_A0_T0
@@ -741,7 +646,6 @@ memcmp:
.section .entry, "ax", %progbits
.align 3
.globl _trap_handler
.globl _trap_exit
_trap_handler:
TRAP_SAVE_AND_SETUP_SP_T0
@@ -749,9 +653,10 @@ _trap_handler:
TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0
TRAP_SAVE_INFO 0 0
TRAP_CALL_C_ROUTINE
_trap_exit:
TRAP_RESTORE_GENERAL_REGS_EXCEPT_A0_T0
TRAP_RESTORE_MEPC_MSTATUS 0
@@ -760,29 +665,39 @@ _trap_exit:
mret
#if __riscv_xlen == 32
.section .entry, "ax", %progbits
.align 3
.globl _trap_handler_rv32_hyp
.globl _trap_exit_rv32_hyp
_trap_handler_rv32_hyp:
.globl _trap_handler_hyp
_trap_handler_hyp:
TRAP_SAVE_AND_SETUP_SP_T0
#if __riscv_xlen == 32
TRAP_SAVE_MEPC_MSTATUS 1
#else
TRAP_SAVE_MEPC_MSTATUS 0
#endif
TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0
#if __riscv_xlen == 32
TRAP_SAVE_INFO 1 1
#else
TRAP_SAVE_INFO 0 1
#endif
TRAP_CALL_C_ROUTINE
_trap_exit_rv32_hyp:
TRAP_RESTORE_GENERAL_REGS_EXCEPT_A0_T0
#if __riscv_xlen == 32
TRAP_RESTORE_MEPC_MSTATUS 1
#else
TRAP_RESTORE_MEPC_MSTATUS 0
#endif
TRAP_RESTORE_A0_T0
mret
#endif
.section .entry, "ax", %progbits
.align 3
@@ -791,7 +706,7 @@ _reset_regs:
/* flush the instruction cache */
fence.i
/* Reset all registers except ra, a0, a1 and a2 */
/* Reset all registers except ra, a0, a1, a2, a3 and a4 */
li sp, 0
li gp, 0
li tp, 0
@@ -800,8 +715,6 @@ _reset_regs:
li t2, 0
li s0, 0
li s1, 0
li a3, 0
li a4, 0
li a5, 0
li a6, 0
li a7, 0
@@ -823,6 +736,27 @@ _reset_regs:
ret
.section .rodata
.Lstack_corrupt_msg:
.string "stack smashing detected\n"
/* This will be called when the stack corruption is detected */
.section .text
.align 3
.globl __stack_chk_fail
.type __stack_chk_fail, %function
__stack_chk_fail:
la a0, .Lstack_corrupt_msg
call sbi_panic
/* Initial value of the stack guard variable */
.section .data
.align 3
.globl __stack_chk_guard
.type __stack_chk_guard, %object
__stack_chk_guard:
RISCV_PTR 0x95B5FF5A
#ifdef FW_FDT_PATH
.section .rodata
.align 4

View File

@@ -20,31 +20,52 @@
PROVIDE(_text_start = .);
*(.entry)
*(.text)
*(.text.*)
. = ALIGN(8);
PROVIDE(_text_end = .);
}
. = ALIGN(0x1000); /* Ensure next section is page aligned */
/* End of the code sections */
. = ALIGN(0x1000); /* Ensure next section is page aligned */
/* Beginning of the read-only data sections */
. = ALIGN(0x1000); /* Ensure next section is page aligned */
PROVIDE(_rodata_start = .);
.rodata :
{
PROVIDE(_rodata_start = .);
*(.rodata .rodata.*)
. = ALIGN(8);
PROVIDE(_rodata_end = .);
}
.dynsym :
{
*(.dynsym)
}
. = ALIGN(0x1000); /* Ensure next section is page aligned */
.rela.dyn : {
PROVIDE(__rela_dyn_start = .);
*(.rela*)
PROVIDE(__rela_dyn_end = .);
}
PROVIDE(_rodata_end = .);
/* End of the read-only data sections */
/* Beginning of the read-write data sections */
/*
* PMP regions must be to be power-of-2. RX/RW will have separate
* regions, so ensure that the split is power-of-2.
*/
. = ALIGN(1 << LOG2CEIL((SIZEOF(.rodata) + SIZEOF(.text)
+ SIZEOF(.dynsym) + SIZEOF(.rela.dyn))));
. = ALIGN(0x1000); /* Ensure next section is page aligned */
PROVIDE(_fw_rw_start = .);
/* Beginning of the read-write data sections */
.data :
{
@@ -61,19 +82,6 @@
PROVIDE(_data_end = .);
}
.dynsym : {
PROVIDE(__dyn_sym_start = .);
*(.dynsym)
PROVIDE(__dyn_sym_end = .);
}
.rela.dyn : {
PROVIDE(__rel_dyn_start = .);
*(.rela*)
. = ALIGN(8);
PROVIDE(__rel_dyn_end = .);
}
. = ALIGN(0x1000); /* Ensure next section is page aligned */
.bss :

View File

@@ -11,12 +11,6 @@
#include "fw_base.S"
.section .entry, "ax", %progbits
.align 3
_bad_dynamic_info:
wfi
j _bad_dynamic_info
.section .entry, "ax", %progbits
.align 3
.global fw_boot_hart
@@ -30,10 +24,10 @@ fw_boot_hart:
/* Sanity checks */
li a1, FW_DYNAMIC_INFO_MAGIC_VALUE
REG_L a0, FW_DYNAMIC_INFO_MAGIC_OFFSET(a2)
bne a0, a1, _bad_dynamic_info
bne a0, a1, _start_hang
li a1, FW_DYNAMIC_INFO_VERSION_MAX
REG_L a0, FW_DYNAMIC_INFO_VERSION_OFFSET(a2)
bgt a0, a1, _bad_dynamic_info
bgt a0, a1, _start_hang
/* Read boot HART id */
li a1, FW_DYNAMIC_INFO_VERSION_2
@@ -129,7 +123,7 @@ fw_options:
REG_L a0, (a0)
ret
.section .entry, "ax", %progbits
.section .data
.align 3
_dynamic_next_arg1:
RISCV_PTR 0x0

View File

@@ -46,6 +46,10 @@ fw_save_info:
fw_next_arg1:
#ifdef FW_JUMP_FDT_ADDR
li a0, FW_JUMP_FDT_ADDR
#elif defined(FW_JUMP_FDT_OFFSET)
lla a0, _fw_start
li a1, FW_JUMP_FDT_OFFSET
add a0, a0, a1
#else
add a0, a1, zero
#endif
@@ -59,8 +63,16 @@ fw_next_arg1:
* The next address should be returned in 'a0'.
*/
fw_next_addr:
#ifdef FW_JUMP_ADDR
lla a0, _jump_addr
REG_L a0, (a0)
#elif defined(FW_JUMP_OFFSET)
lla a0, _fw_start
li a1, FW_JUMP_OFFSET
add a0, a0, a1
#else
#error "Must define at least FW_JUMP_ADDR or FW_JUMP_OFFSET"
#endif
ret
.section .entry, "ax", %progbits
@@ -86,11 +98,9 @@ fw_options:
add a0, zero, zero
ret
#ifndef FW_JUMP_ADDR
#error "Must define FW_JUMP_ADDR"
#endif
.section .entry, "ax", %progbits
#ifdef FW_JUMP_ADDR
.section .rodata
.align 3
_jump_addr:
RISCV_PTR FW_JUMP_ADDR
#endif

View File

@@ -46,6 +46,10 @@ fw_save_info:
fw_next_arg1:
#ifdef FW_PAYLOAD_FDT_ADDR
li a0, FW_PAYLOAD_FDT_ADDR
#elif defined(FW_PAYLOAD_FDT_OFFSET)
lla a0, _fw_start
li a1, FW_PAYLOAD_FDT_OFFSET
add a0, a0, a1
#else
add a0, a1, zero
#endif

View File

@@ -13,19 +13,10 @@ firmware-cflags-y +=
firmware-asflags-y +=
firmware-ldflags-y +=
ifndef FW_PIC
FW_PIC := $(OPENSBI_LD_PIE)
endif
ifeq ($(FW_PIC),y)
firmware-genflags-y += -DFW_PIC
firmware-asflags-y += -fpic
firmware-cflags-y += -fPIE -pie
firmware-ldflags-y += -Wl,--no-dynamic-linker -Wl,-pie
endif
ifdef FW_TEXT_START
firmware-genflags-y += -DFW_TEXT_START=$(FW_TEXT_START)
else
firmware-genflags-y += -DFW_TEXT_START=0x0
endif
ifdef FW_FDT_PATH
@@ -38,9 +29,15 @@ endif
firmware-bins-$(FW_DYNAMIC) += fw_dynamic.bin
firmware-bins-$(FW_JUMP) += fw_jump.bin
ifdef FW_JUMP_OFFSET
firmware-genflags-$(FW_JUMP) += -DFW_JUMP_OFFSET=$(FW_JUMP_OFFSET)
endif
ifdef FW_JUMP_ADDR
firmware-genflags-$(FW_JUMP) += -DFW_JUMP_ADDR=$(FW_JUMP_ADDR)
endif
ifdef FW_JUMP_FDT_OFFSET
firmware-genflags-$(FW_JUMP) += -DFW_JUMP_FDT_OFFSET=$(FW_JUMP_FDT_OFFSET)
endif
ifdef FW_JUMP_FDT_ADDR
firmware-genflags-$(FW_JUMP) += -DFW_JUMP_FDT_ADDR=$(FW_JUMP_FDT_ADDR)
endif
@@ -59,6 +56,9 @@ ifdef FW_PAYLOAD_ALIGN
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_ALIGN=$(FW_PAYLOAD_ALIGN)
endif
ifdef FW_PAYLOAD_FDT_OFFSET
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_FDT_OFFSET=$(FW_PAYLOAD_FDT_OFFSET)
endif
ifdef FW_PAYLOAD_FDT_ADDR
firmware-genflags-$(FW_PAYLOAD) += -DFW_PAYLOAD_FDT_ADDR=$(FW_PAYLOAD_FDT_ADDR)
endif
@@ -66,3 +66,12 @@ endif
ifdef FW_OPTIONS
firmware-genflags-y += -DFW_OPTIONS=$(FW_OPTIONS)
endif
ifeq ($(CONFIG_STACK_PROTECTOR),y)
stack-protector-cflags-$(CONFIG_STACK_PROTECTOR) := -fstack-protector
stack-protector-cflags-$(CONFIG_STACK_PROTECTOR_STRONG) := -fstack-protector-strong
stack-protector-cflags-$(CONFIG_STACK_PROTECTOR_ALL) := -fstack-protector-all
else
stack-protector-cflags-y := -fno-stack-protector
endif
firmware-cflags-y += $(stack-protector-cflags-y)

View File

@@ -33,14 +33,12 @@ SECTIONS
PROVIDE(_text_end = .);
}
. = ALIGN(0x1000); /* Ensure next section is page aligned */
/* End of the code sections */
/* Beginning of the read-only data sections */
. = ALIGN(0x1000); /* Ensure next section is page aligned */
/* Beginning of the read-only data sections */
.rodata :
{
PROVIDE(_rodata_start = .);
@@ -51,10 +49,10 @@ SECTIONS
/* End of the read-only data sections */
/* Beginning of the read-write data sections */
. = ALIGN(0x1000); /* Ensure next section is page aligned */
/* Beginning of the read-write data sections */
.data :
{
PROVIDE(_data_start = .);

View File

@@ -30,7 +30,18 @@ _start:
/* Pick one hart to run the main boot sequence */
lla a3, _hart_lottery
li a2, 1
#ifdef __riscv_atomic
amoadd.w a3, a2, (a3)
#elif __riscv_zalrsc
_sc_fail:
lr.w t0, (a3)
addw t1, t0, a2
sc.w t1, t1, (a3)
bnez t1, _sc_fail
move a3, t0
#else
#error "need a or zalrsc"
#endif
bnez a3, _start_hang
/* Save a0 and a1 */
@@ -78,7 +89,7 @@ _start_hang:
wfi
j _start_hang
.section .entry, "ax", %progbits
.section .data
.align 3
_hart_lottery:
RISCV_PTR 0
@@ -86,3 +97,18 @@ _boot_a0:
RISCV_PTR 0
_boot_a1:
RISCV_PTR 0
/* This will be called when the stack corruption is detected */
.section .text
.align 3
.globl __stack_chk_fail
.type __stack_chk_fail, %function
.equ __stack_chk_fail, _start_hang
/* Initial value of the stack guard variable */
.section .data
.align 3
.globl __stack_chk_guard
.type __stack_chk_guard, %object
__stack_chk_guard:
RISCV_PTR 0x95B5FF5A

View File

@@ -8,31 +8,49 @@
*/
#include <sbi/sbi_ecall_interface.h>
#include <sbi/sbi_string.h>
#define SBI_ECALL(__eid, __fid, __a0, __a1, __a2) \
({ \
register unsigned long a0 asm("a0") = (unsigned long)(__a0); \
register unsigned long a1 asm("a1") = (unsigned long)(__a1); \
register unsigned long a2 asm("a2") = (unsigned long)(__a2); \
register unsigned long a6 asm("a6") = (unsigned long)(__fid); \
register unsigned long a7 asm("a7") = (unsigned long)(__eid); \
asm volatile("ecall" \
: "+r"(a0) \
: "r"(a1), "r"(a2), "r"(a6), "r"(a7) \
: "memory"); \
a0; \
})
struct sbiret {
unsigned long error;
unsigned long value;
};
#define SBI_ECALL_0(__eid, __fid) SBI_ECALL(__eid, __fid, 0, 0, 0)
#define SBI_ECALL_1(__eid, __fid, __a0) SBI_ECALL(__eid, __fid, __a0, 0, 0)
#define SBI_ECALL_2(__eid, __fid, __a0, __a1) SBI_ECALL(__eid, __fid, __a0, __a1, 0)
struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
unsigned long arg1, unsigned long arg2,
unsigned long arg3, unsigned long arg4,
unsigned long arg5)
{
struct sbiret ret;
#define sbi_ecall_console_putc(c) SBI_ECALL_1(SBI_EXT_0_1_CONSOLE_PUTCHAR, 0, (c))
register unsigned long a0 asm ("a0") = (unsigned long)(arg0);
register unsigned long a1 asm ("a1") = (unsigned long)(arg1);
register unsigned long a2 asm ("a2") = (unsigned long)(arg2);
register unsigned long a3 asm ("a3") = (unsigned long)(arg3);
register unsigned long a4 asm ("a4") = (unsigned long)(arg4);
register unsigned long a5 asm ("a5") = (unsigned long)(arg5);
register unsigned long a6 asm ("a6") = (unsigned long)(fid);
register unsigned long a7 asm ("a7") = (unsigned long)(ext);
asm volatile ("ecall"
: "+r" (a0), "+r" (a1)
: "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
: "memory");
ret.error = a0;
ret.value = a1;
return ret;
}
static inline void sbi_ecall_console_puts(const char *str)
{
while (str && *str)
sbi_ecall_console_putc(*str++);
sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE,
sbi_strlen(str), (unsigned long)str, 0, 0, 0, 0);
}
static inline void sbi_ecall_shutdown(void)
{
sbi_ecall(SBI_EXT_SRST, SBI_EXT_SRST_RESET,
SBI_SRST_RESET_TYPE_SHUTDOWN, SBI_SRST_RESET_REASON_NONE,
0, 0, 0, 0);
}
#define wfi() \
@@ -43,7 +61,6 @@ static inline void sbi_ecall_console_puts(const char *str)
void test_main(unsigned long a0, unsigned long a1)
{
sbi_ecall_console_puts("\nTest payload running\n");
while (1)
wfi();
sbi_ecall_shutdown();
sbi_ecall_console_puts("sbi_ecall_shutdown failed to execute.\n");
}

View File

@@ -75,6 +75,17 @@ struct fw_dynamic_info {
unsigned long boot_hart;
} __packed;
/**
* Prevent modification of struct fw_dynamic_info from affecting
* FW_DYNAMIC_INFO_xxx_OFFSET
*/
assert_member_offset(struct fw_dynamic_info, magic, FW_DYNAMIC_INFO_MAGIC_OFFSET);
assert_member_offset(struct fw_dynamic_info, version, FW_DYNAMIC_INFO_VERSION_OFFSET);
assert_member_offset(struct fw_dynamic_info, next_addr, FW_DYNAMIC_INFO_NEXT_ADDR_OFFSET);
assert_member_offset(struct fw_dynamic_info, next_mode, FW_DYNAMIC_INFO_NEXT_MODE_OFFSET);
assert_member_offset(struct fw_dynamic_info, options, FW_DYNAMIC_INFO_OPTIONS_OFFSET);
assert_member_offset(struct fw_dynamic_info, boot_hart, FW_DYNAMIC_INFO_BOOT_HART_OFFSET);
#endif
#endif

View File

@@ -101,6 +101,14 @@
__v; \
})
/* Variant of csr_read() that allows the compiler to cache the value. */
#define csr_read_relaxed(csr) \
({ \
register unsigned long __v; \
__asm__ ("csrr %0, " __ASM_STR(csr) : "=r"(__v)); \
__v; \
})
#define csr_write(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
@@ -148,6 +156,26 @@
: "memory"); \
})
#if __riscv_xlen == 64
#define __csrrw64(op, csr, csrh, val) (true ? op(csr, val) : (uint64_t)csrh)
#define __csrr64( op, csr, csrh) (true ? op(csr) : (uint64_t)csrh)
#define __csrw64( op, csr, csrh, val) (true ? op(csr, val) : (uint64_t)csrh)
#elif __riscv_xlen == 32
#define __csrrw64(op, csr, csrh, val) ( op(csr, val) | (uint64_t)op(csrh, val >> 32) << 32)
#define __csrr64( op, csr, csrh) ( op(csr) | (uint64_t)op(csrh) << 32)
#define __csrw64( op, csr, csrh, val) ({ op(csr, val); op(csrh, val >> 32); })
#endif
#define csr_swap64( csr, val) __csrrw64(csr_swap, csr, csr ## H, val)
#define csr_read64( csr) __csrr64 (csr_read, csr, csr ## H)
#define csr_read_relaxed64(csr) __csrr64 (csr_read_relaxed, csr, csr ## H)
#define csr_write64( csr, val) __csrw64 (csr_write, csr, csr ## H, val)
#define csr_read_set64( csr, val) __csrrw64(csr_read_set, csr, csr ## H, val)
#define csr_set64( csr, val) __csrw64 (csr_set, csr, csr ## H, val)
#define csr_clear64( csr, val) __csrw64 (csr_clear, csr, csr ## H, val)
#define csr_read_clear64( csr, val) __csrrw64(csr_read_clear, csr, csr ## H, val)
#define csr_clear64( csr, val) __csrw64 (csr_clear, csr, csr ## H, val)
unsigned long csr_read_num(int csr_num);
void csr_write_num(int csr_num, unsigned long val);
@@ -163,7 +191,7 @@ void csr_write_num(int csr_num, unsigned long val);
} while (0)
/* Get current HART id */
#define current_hartid() ((unsigned int)csr_read(CSR_MHARTID))
#define current_hartid() ((unsigned int)csr_read_relaxed(CSR_MHARTID))
/* determine CPU extension, return non-zero support */
int misa_extension_imp(char ext);
@@ -181,6 +209,12 @@ int misa_xlen(void);
/* Get RISC-V ISA string representation */
void misa_string(int xlen, char *out, unsigned int out_sz);
/* Disable pmp entry at a given index */
int pmp_disable(unsigned int n);
/* Check if the matching field is set */
int is_pmp_entry_mapped(unsigned long entry);
int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
unsigned long log2len);

View File

@@ -39,14 +39,14 @@ unsigned int atomic_raw_xchg_uint(volatile unsigned int *ptr,
unsigned long atomic_raw_xchg_ulong(volatile unsigned long *ptr,
unsigned long newval);
/**
* Set a bit in an atomic variable and return the new value.
* Set a bit in an atomic variable and return the value of bit before modify.
* @nr : Bit to set.
* @atom: atomic variable to modify
*/
int atomic_set_bit(int nr, atomic_t *atom);
/**
* Clear a bit in an atomic variable and return the new value.
* Clear a bit in an atomic variable and return the value of bit before modify.
* @nr : Bit to set.
* @atom: atomic variable to modify
*/
@@ -54,14 +54,14 @@ int atomic_set_bit(int nr, atomic_t *atom);
int atomic_clear_bit(int nr, atomic_t *atom);
/**
* Set a bit in any address and return the new value .
* Set a bit in any address and return the value of bit before modify.
* @nr : Bit to set.
* @addr: Address to modify
*/
int atomic_raw_set_bit(int nr, volatile unsigned long *addr);
/**
* Clear a bit in any address and return the new value .
* Clear a bit in any address and return the value of bit before modify.
* @nr : Bit to set.
* @addr: Address to modify
*/

View File

@@ -40,7 +40,11 @@
#define smp_wmb() RISCV_FENCE(w,w)
/* CPU relax for busy loop */
#define cpu_relax() asm volatile ("" : : : "memory")
#define cpu_relax() \
do { \
unsigned long __t; \
__asm__ __volatile__ ("div %0, %0, zero" : "=r" (__t)); \
} while (0)
/* clang-format on */

249
include/sbi/riscv_dbtr.h Normal file
View File

@@ -0,0 +1,249 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2023 Ventana Micro System, Inc.
*
* Authors:
* Himanshu Chauhan <hchauhan@ventanamicro.com>
*/
#ifndef __RISCV_DBTR_H__
#define __RISCV_DBTR_H__
#define RV_MAX_TRIGGERS 32
enum {
RISCV_DBTR_TRIG_NONE = 0,
RISCV_DBTR_TRIG_LEGACY,
RISCV_DBTR_TRIG_MCONTROL,
RISCV_DBTR_TRIG_ICOUNT,
RISCV_DBTR_TRIG_ITRIGGER,
RISCV_DBTR_TRIG_ETRIGGER,
RISCV_DBTR_TRIG_MCONTROL6,
};
#define RV_DBTR_BIT(_prefix, _name) \
RV_DBTR_##_prefix##_##_name##_BIT
#define RV_DBTR_BIT_MASK(_prefix, _name) \
RV_DBTR_##_prefix##_name##_BIT_MASK
#define RV_DBTR_DECLARE_BIT(_prefix, _name, _val) \
RV_DBTR_BIT(_prefix, _name) = _val
#define RV_DBTR_DECLARE_BIT_MASK(_prefix, _name, _width) \
RV_DBTR_BIT_MASK(_prefix, _name) = \
(((1UL << _width) - 1) << RV_DBTR_BIT(_prefix, _name))
#define CLEAR_DBTR_BIT(_target, _prefix, _bit_name) \
__clear_bit(RV_DBTR_BIT(_prefix, _bit_name), &_target)
#define SET_DBTR_BIT(_target, _prefix, _bit_name) \
__set_bit(RV_DBTR_BIT(_prefix, _bit_name), &_target)
/* Trigger Data 1 */
enum {
RV_DBTR_DECLARE_BIT(TDATA1, DATA, 0),
#if __riscv_xlen == 64
RV_DBTR_DECLARE_BIT(TDATA1, DMODE, 59),
RV_DBTR_DECLARE_BIT(TDATA1, TYPE, 60),
#elif __riscv_xlen == 32
RV_DBTR_DECLARE_BIT(TDATA1, DMODE, 27),
RV_DBTR_DECLARE_BIT(TDATA1, TYPE, 28),
#else
#error "Unknown __riscv_xlen"
#endif
};
enum {
#if __riscv_xlen == 64
RV_DBTR_DECLARE_BIT_MASK(TDATA1, DATA, 59),
#elif __riscv_xlen == 32
RV_DBTR_DECLARE_BIT_MASK(TDATA1, DATA, 27),
#else
#error "Unknown __riscv_xlen"
#endif
RV_DBTR_DECLARE_BIT_MASK(TDATA1, DMODE, 1),
RV_DBTR_DECLARE_BIT_MASK(TDATA1, TYPE, 4),
};
/* MC - Match Control Type Register */
enum {
RV_DBTR_DECLARE_BIT(MC, LOAD, 0),
RV_DBTR_DECLARE_BIT(MC, STORE, 1),
RV_DBTR_DECLARE_BIT(MC, EXEC, 2),
RV_DBTR_DECLARE_BIT(MC, U, 3),
RV_DBTR_DECLARE_BIT(MC, S, 4),
RV_DBTR_DECLARE_BIT(MC, RES2, 5),
RV_DBTR_DECLARE_BIT(MC, M, 6),
RV_DBTR_DECLARE_BIT(MC, MATCH, 7),
RV_DBTR_DECLARE_BIT(MC, CHAIN, 11),
RV_DBTR_DECLARE_BIT(MC, ACTION, 12),
RV_DBTR_DECLARE_BIT(MC, SIZELO, 16),
RV_DBTR_DECLARE_BIT(MC, TIMING, 18),
RV_DBTR_DECLARE_BIT(MC, SELECT, 19),
RV_DBTR_DECLARE_BIT(MC, HIT, 20),
#if __riscv_xlen >= 64
RV_DBTR_DECLARE_BIT(MC, SIZEHI, 21),
#endif
#if __riscv_xlen == 64
RV_DBTR_DECLARE_BIT(MC, MASKMAX, 53),
RV_DBTR_DECLARE_BIT(MC, DMODE, 59),
RV_DBTR_DECLARE_BIT(MC, TYPE, 60),
#elif __riscv_xlen == 32
RV_DBTR_DECLARE_BIT(MC, MASKMAX, 21),
RV_DBTR_DECLARE_BIT(MC, DMODE, 27),
RV_DBTR_DECLARE_BIT(MC, TYPE, 28),
#else
#error "Unknown __riscv_xlen"
#endif
};
enum {
RV_DBTR_DECLARE_BIT_MASK(MC, LOAD, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, STORE, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, EXEC, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, U, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, S, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, RES2, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, M, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, MATCH, 4),
RV_DBTR_DECLARE_BIT_MASK(MC, CHAIN, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, ACTION, 4),
RV_DBTR_DECLARE_BIT_MASK(MC, SIZELO, 2),
RV_DBTR_DECLARE_BIT_MASK(MC, TIMING, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, SELECT, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, HIT, 1),
#if __riscv_xlen >= 64
RV_DBTR_DECLARE_BIT_MASK(MC, SIZEHI, 2),
#endif
RV_DBTR_DECLARE_BIT_MASK(MC, MASKMAX, 6),
RV_DBTR_DECLARE_BIT_MASK(MC, DMODE, 1),
RV_DBTR_DECLARE_BIT_MASK(MC, TYPE, 4),
};
/* MC6 - Match Control 6 Type Register */
enum {
RV_DBTR_DECLARE_BIT(MC6, LOAD, 0),
RV_DBTR_DECLARE_BIT(MC6, STORE, 1),
RV_DBTR_DECLARE_BIT(MC6, EXEC, 2),
RV_DBTR_DECLARE_BIT(MC6, U, 3),
RV_DBTR_DECLARE_BIT(MC6, S, 4),
RV_DBTR_DECLARE_BIT(MC6, RES2, 5),
RV_DBTR_DECLARE_BIT(MC6, M, 6),
RV_DBTR_DECLARE_BIT(MC6, MATCH, 7),
RV_DBTR_DECLARE_BIT(MC6, CHAIN, 11),
RV_DBTR_DECLARE_BIT(MC6, ACTION, 12),
RV_DBTR_DECLARE_BIT(MC6, SIZE, 16),
RV_DBTR_DECLARE_BIT(MC6, TIMING, 20),
RV_DBTR_DECLARE_BIT(MC6, SELECT, 21),
RV_DBTR_DECLARE_BIT(MC6, HIT, 22),
RV_DBTR_DECLARE_BIT(MC6, VU, 23),
RV_DBTR_DECLARE_BIT(MC6, VS, 24),
#if __riscv_xlen == 64
RV_DBTR_DECLARE_BIT(MC6, DMODE, 59),
RV_DBTR_DECLARE_BIT(MC6, TYPE, 60),
#elif __riscv_xlen == 32
RV_DBTR_DECLARE_BIT(MC6, DMODE, 27),
RV_DBTR_DECLARE_BIT(MC6, TYPE, 28),
#else
#error "Unknown __riscv_xlen"
#endif
};
enum {
RV_DBTR_DECLARE_BIT_MASK(MC6, LOAD, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, STORE, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, EXEC, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, U, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, S, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, RES2, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, M, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, MATCH, 4),
RV_DBTR_DECLARE_BIT_MASK(MC6, CHAIN, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, ACTION, 4),
RV_DBTR_DECLARE_BIT_MASK(MC6, SIZE, 4),
RV_DBTR_DECLARE_BIT_MASK(MC6, TIMING, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, SELECT, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, HIT, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, VU, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, VS, 1),
#if __riscv_xlen == 64
RV_DBTR_DECLARE_BIT_MASK(MC6, DMODE, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, TYPE, 4),
#elif __riscv_xlen == 32
RV_DBTR_DECLARE_BIT_MASK(MC6, DMODE, 1),
RV_DBTR_DECLARE_BIT_MASK(MC6, TYPE, 4),
#else
#error "Unknown __riscv_xlen"
#endif
};
#define RV_DBTR_SET_TDATA1_TYPE(_t1, _type) \
do { \
_t1 &= ~RV_DBTR_BIT_MASK(TDATA1, TYPE); \
_t1 |= (((unsigned long)_type \
<< RV_DBTR_BIT(TDATA1, TYPE)) \
& RV_DBTR_BIT_MASK(TDATA1, TYPE)); \
}while (0);
#define RV_DBTR_SET_MC_TYPE(_t1, _type) \
do { \
_t1 &= ~RV_DBTR_BIT_MASK(MC, TYPE); \
_t1 |= (((unsigned long)_type \
<< RV_DBTR_BIT(MC, TYPE)) \
& RV_DBTR_BIT_MASK(MC, TYPE)); \
}while (0);
#define RV_DBTR_SET_MC6_TYPE(_t1, _type) \
do { \
_t1 &= ~RV_DBTR_BIT_MASK(MC6, TYPE); \
_t1 |= (((unsigned long)_type \
<< RV_DBTR_BIT(MC6, TYPE)) \
& RV_DBTR_BIT_MASK(MC6, TYPE)); \
}while (0);
#define RV_DBTR_SET_MC_EXEC(_t1) \
SET_DBTR_BIT(_t1, MC, EXEC)
#define RV_DBTR_SET_MC_LOAD(_t1) \
SET_DBTR_BIT(_t1, MC, LOAD)
#define RV_DBTR_SET_MC_STORE(_t1) \
SET_DBTR_BIT(_t1, MC, STORE)
#define RV_DBTR_SET_MC_SIZELO(_t1, _val) \
do { \
_t1 &= ~RV_DBTR_BIT_MASK(MC, SIZELO); \
_t1 |= ((_val << RV_DBTR_BIT(MC, SIZELO)) \
& RV_DBTR_BIT_MASK(MC, SIZELO)); \
} while(0);
#define RV_DBTR_SET_MC_SIZEHI(_t1, _val) \
do { \
_t1 &= ~RV_DBTR_BIT_MASK(MC, SIZEHI); \
_t1 |= ((_val << RV_DBTR_BIT(MC, SIZEHI)) \
& RV_DBTR_BIT_MASK(MC, SIZEHI)); \
} while(0);
#define RV_DBTR_SET_MC6_EXEC(_t1) \
SET_DBTR_BIT(_t1, MC6, EXEC)
#define RV_DBTR_SET_MC6_LOAD(_t1) \
SET_DBTR_BIT(_t1, MC6, LOAD)
#define RV_DBTR_SET_MC6_STORE(_t1) \
SET_DBTR_BIT(_t1, MC6, STORE)
#define RV_DBTR_SET_MC6_SIZE(_t1, _val) \
do { \
_t1 &= ~RV_DBTR_BIT_MASK(MC6, SIZE); \
_t1 |= ((_val << RV_DBTR_BIT(MC6, SIZE)) \
& RV_DBTR_BIT_MASK(MC6, SIZE)); \
} while(0);
typedef unsigned long riscv_dbtr_tdata1_mcontrol_t;
typedef unsigned long riscv_dbtr_tdata1_mcontrol6_t;
typedef unsigned long riscv_dbtr_tdata1_t;
#endif /* __RISCV_DBTR_H__ */

View File

@@ -1,14 +1,6 @@
#ifndef __RISCV_ELF_H__
#define __RISCV_ELF_H__
#include <sbi/riscv_asm.h>
#define R_RISCV_32 1
#define R_RISCV_64 2
#define R_RISCV_RELATIVE 3
#define RELOC_TYPE __REG_SEL(R_RISCV_64, R_RISCV_32)
#define SYM_INDEX __REG_SEL(0x20, 0x8)
#define SYM_SIZE __REG_SEL(0x18,0x10)
#endif

View File

@@ -25,24 +25,34 @@
#define MSTATUS_MPP (_UL(3) << MSTATUS_MPP_SHIFT)
#define MSTATUS_FS _UL(0x00006000)
#define MSTATUS_XS _UL(0x00018000)
#define MSTATUS_VS _UL(0x01800000)
#define MSTATUS_VS _UL(0x00000600)
#define MSTATUS_MPRV _UL(0x00020000)
#define MSTATUS_SUM _UL(0x00040000)
#define MSTATUS_MXR _UL(0x00080000)
#define MSTATUS_TVM _UL(0x00100000)
#define MSTATUS_TW _UL(0x00200000)
#define MSTATUS_TSR _UL(0x00400000)
#define MSTATUS_SPELP _UL(0x00800000)
#define MSTATUS_SDT _UL(0x01000000)
#define MSTATUS32_SD _UL(0x80000000)
#if __riscv_xlen == 64
#define MSTATUS_UXL _ULL(0x0000000300000000)
#define MSTATUS_SXL _ULL(0x0000000C00000000)
#define MSTATUS_SBE _ULL(0x0000001000000000)
#define MSTATUS_MBE _ULL(0x0000002000000000)
#define MSTATUS_GVA _ULL(0x0000004000000000)
#define MSTATUS_GVA_SHIFT 38
#define MSTATUS_MPV _ULL(0x0000008000000000)
#define MSTATUS_MPELP _ULL(0x0000020000000000)
#define MSTATUS_MDT _ULL(0x0000040000000000)
#else
#define MSTATUSH_SBE _UL(0x00000010)
#define MSTATUSH_MBE _UL(0x00000020)
#define MSTATUSH_GVA _UL(0x00000040)
#define MSTATUSH_GVA_SHIFT 6
#define MSTATUSH_MPV _UL(0x00000080)
#define MSTATUSH_MPELP _UL(0x00000200)
#define MSTATUSH_MDT _UL(0x00000400)
#endif
#define MSTATUS32_SD _UL(0x80000000)
#define MSTATUS64_SD _ULL(0x8000000000000000)
@@ -76,6 +86,10 @@
#define HSTATUS_GVA _UL(0x00000040)
#define HSTATUS_VSBE _UL(0x00000020)
#define MTVEC_MODE _UL(0x00000003)
#define MCAUSE_IRQ_MASK (_UL(1) << (__riscv_xlen - 1))
#define IRQ_S_SOFT 1
#define IRQ_VS_SOFT 2
#define IRQ_M_SOFT 3
@@ -173,6 +187,10 @@
#define HGATP_MODE_SHIFT HGATP32_MODE_SHIFT
#endif
#define TOPI_IID_SHIFT 16
#define TOPI_IID_MASK 0xfff
#define TOPI_IPRIO_MASK 0xff
#if __riscv_xlen == 64
#define MHPMEVENT_OF (_UL(1) << 63)
#define MHPMEVENT_MINH (_UL(1) << 62)
@@ -181,13 +199,14 @@
#define MHPMEVENT_VSINH (_UL(1) << 59)
#define MHPMEVENT_VUINH (_UL(1) << 58)
#else
#define MHPMEVENTH_OF (_UL(1) << 31)
#define MHPMEVENTH_OF (_ULL(1) << 31)
#define MHPMEVENTH_MINH (_ULL(1) << 30)
#define MHPMEVENTH_SINH (_ULL(1) << 29)
#define MHPMEVENTH_UINH (_ULL(1) << 28)
#define MHPMEVENTH_VSINH (_ULL(1) << 27)
#define MHPMEVENTH_VUINH (_ULL(1) << 26)
#define MHPMEVENT_OF (MHPMEVENTH_OF << 32)
#define MHPMEVENT_MINH (MHPMEVENTH_MINH << 32)
#define MHPMEVENT_SINH (MHPMEVENTH_SINH << 32)
#define MHPMEVENT_UINH (MHPMEVENTH_UINH << 32)
@@ -196,7 +215,31 @@
#endif
#define MHPMEVENT_SSCOF_MASK _ULL(0xFFFF000000000000)
#define MHPMEVENT_SSCOF_MASK _ULL(0xFF00000000000000)
#define ENVCFG_STCE (_ULL(1) << 63)
#define ENVCFG_PBMTE (_ULL(1) << 62)
#define ENVCFG_ADUE_SHIFT 61
#define ENVCFG_ADUE (_ULL(1) << ENVCFG_ADUE_SHIFT)
#define ENVCFG_CDE (_ULL(1) << 60)
#define ENVCFG_DTE_SHIFT 59
#define ENVCFG_DTE (_ULL(1) << ENVCFG_DTE_SHIFT)
#define ENVCFG_PMM (_ULL(0x3) << 32)
#define ENVCFG_PMM_PMLEN_0 (_ULL(0x0) << 32)
#define ENVCFG_PMM_PMLEN_7 (_ULL(0x2) << 32)
#define ENVCFG_PMM_PMLEN_16 (_ULL(0x3) << 32)
#define ENVCFG_CBZE (_UL(1) << 7)
#define ENVCFG_CBCFE (_UL(1) << 6)
#define ENVCFG_CBIE_SHIFT 4
#define ENVCFG_CBIE (_UL(0x3) << ENVCFG_CBIE_SHIFT)
#define ENVCFG_CBIE_ILL _UL(0x0)
#define ENVCFG_CBIE_FLUSH _UL(0x1)
#define ENVCFG_CBIE_INV _UL(0x3)
#define ENVCFG_SSE_SHIFT 3
#define ENVCFG_SSE (_UL(1) << ENVCFG_SSE_SHIFT)
#define ENVCFG_LPE_SHIFT 2
#define ENVCFG_LPE (_UL(1) << ENVCFG_LPE_SHIFT)
#define ENVCFG_FIOM _UL(0x1)
/* ===== User-level CSRs ===== */
@@ -204,6 +247,7 @@
#define CSR_USTATUS 0x000
#define CSR_UIE 0x004
#define CSR_UTVEC 0x005
#define CSR_SSP 0x011
/* User Trap Handling (N-extension) */
#define CSR_USCRATCH 0x040
@@ -287,12 +331,16 @@
/* Supervisor Trap Setup */
#define CSR_SSTATUS 0x100
#define CSR_SEDELEG 0x102
#define CSR_SIDELEG 0x103
#define CSR_SIE 0x104
#define CSR_STVEC 0x105
#define CSR_SCOUNTEREN 0x106
/* Supervisor Configuration */
#define CSR_SENVCFG 0x10a
/* Supervisor Conter Inhibit */
#define CSR_SCOUNTINHIBIT 0x120
/* Supervisor Trap Handling */
#define CSR_SSCRATCH 0x140
#define CSR_SEPC 0x141
@@ -300,9 +348,47 @@
#define CSR_STVAL 0x143
#define CSR_SIP 0x144
/* Sstc extension */
#define CSR_STIMECMP 0x14D
#define CSR_STIMECMPH 0x15D
/* Supervisor Protection and Translation */
#define CSR_SATP 0x180
/* Supervisor Indirect Register Alias */
#define CSR_SISELECT 0x150
#define CSR_SIREG 0x151
#define CSR_SIREG2 0x152
#define CSR_SIREG3 0x153
#define CSR_SIREG4 0x155
#define CSR_SIREG5 0x156
#define CSR_SIREG6 0x157
/* Supervisor-Level Interrupts (AIA) */
#define CSR_STOPEI 0x15c
#define CSR_STOPI 0xdb0
/* Supervisor-Level High-Half CSRs (AIA) */
#define CSR_SIEH 0x114
#define CSR_SIPH 0x154
/* Supervisor stateen CSRs */
#define CSR_SSTATEEN0 0x10C
#define CSR_SSTATEEN1 0x10D
#define CSR_SSTATEEN2 0x10E
#define CSR_SSTATEEN3 0x10F
/* Machine-Level Control transfer records CSRs */
#define CSR_MCTRCTL 0x34e
/* Supervisor-Level Control transfer records CSRs */
#define CSR_SCTRCTL 0x14e
#define CSR_SCTRSTATUS 0x14f
#define CSR_SCTRDEPTH 0x15f
/* VS-Level Control transfer records CSRs */
#define CSR_VSCTRCTL 0x24e
/* ===== Hypervisor-level CSRs ===== */
/* Hypervisor Trap Setup (H-extension) */
@@ -313,6 +399,10 @@
#define CSR_HCOUNTEREN 0x606
#define CSR_HGEIE 0x607
/* Hypervisor Configuration */
#define CSR_HENVCFG 0x60a
#define CSR_HENVCFGH 0x61a
/* Hypervisor Trap Handling (H-extension) */
#define CSR_HTVAL 0x643
#define CSR_HIP 0x644
@@ -338,6 +428,44 @@
#define CSR_VSIP 0x244
#define CSR_VSATP 0x280
/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
#define CSR_HVIEN 0x608
#define CSR_HVICTL 0x609
#define CSR_HVIPRIO1 0x646
#define CSR_HVIPRIO2 0x647
/* Virtual Supervisor Indirect Alias */
#define CSR_VSISELECT 0x250
#define CSR_VSIREG 0x251
#define CSR_VSIREG2 0x252
#define CSR_VSIREG3 0x253
#define CSR_VSIREG4 0x255
#define CSR_VSIREG5 0x256
#define CSR_VSIREG6 0x257
/* VS-Level Interrupts (H-extension with AIA) */
#define CSR_VSTOPEI 0x25c
#define CSR_VSTOPI 0xeb0
/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
#define CSR_HIDELEGH 0x613
#define CSR_HVIENH 0x618
#define CSR_HVIPH 0x655
#define CSR_HVIPRIO1H 0x656
#define CSR_HVIPRIO2H 0x657
#define CSR_VSIEH 0x214
#define CSR_VSIPH 0x254
/* Hypervisor stateen CSRs */
#define CSR_HSTATEEN0 0x60C
#define CSR_HSTATEEN0H 0x61C
#define CSR_HSTATEEN1 0x60D
#define CSR_HSTATEEN1H 0x61D
#define CSR_HSTATEEN2 0x60E
#define CSR_HSTATEEN2H 0x61E
#define CSR_HSTATEEN3 0x60F
#define CSR_HSTATEEN3H 0x61F
/* ===== Machine-level CSRs ===== */
/* Machine Information Registers */
@@ -345,6 +473,7 @@
#define CSR_MARCHID 0xf12
#define CSR_MIMPID 0xf13
#define CSR_MHARTID 0xf14
#define CSR_MCONFIGPTR 0xf15
/* Machine Trap Setup */
#define CSR_MSTATUS 0x300
@@ -356,6 +485,10 @@
#define CSR_MCOUNTEREN 0x306
#define CSR_MSTATUSH 0x310
/* Machine Configuration */
#define CSR_MENVCFG 0x30a
#define CSR_MENVCFGH 0x31a
/* Machine Trap Handling */
#define CSR_MSCRATCH 0x340
#define CSR_MEPC 0x341
@@ -513,6 +646,8 @@
/* Machine Counter Setup */
#define CSR_MCOUNTINHIBIT 0x320
#define CSR_MCYCLECFG 0x321
#define CSR_MINSTRETCFG 0x322
#define CSR_MHPMEVENT3 0x323
#define CSR_MHPMEVENT4 0x324
#define CSR_MHPMEVENT5 0x325
@@ -544,6 +679,8 @@
#define CSR_MHPMEVENT31 0x33f
/* For RV32 */
#define CSR_MCYCLECFGH 0x721
#define CSR_MINSTRETCFGH 0x722
#define CSR_MHPMEVENT3H 0x723
#define CSR_MHPMEVENT4H 0x724
#define CSR_MHPMEVENT5H 0x725
@@ -574,6 +711,21 @@
#define CSR_MHPMEVENT30H 0x73e
#define CSR_MHPMEVENT31H 0x73f
/* Machine Security Configuration CSR (mseccfg) */
#define CSR_MSECCFG 0x747
#define CSR_MSECCFGH 0x757
#define MSECCFG_MML_SHIFT (0)
#define MSECCFG_MML (_UL(1) << MSECCFG_MML_SHIFT)
#define MSECCFG_MMWP_SHIFT (1)
#define MSECCFG_MMWP (_UL(1) << MSECCFG_MMWP_SHIFT)
#define MSECCFG_RLB_SHIFT (2)
#define MSECCFG_RLB (_UL(1) << MSECCFG_RLB_SHIFT)
#define MSECCFG_USEED_SHIFT (8)
#define MSECCFG_USEED (_UL(1) << MSECCFG_USEED_SHIFT)
#define MSECCFG_SSEED_SHIFT (9)
#define MSECCFG_SSEED (_UL(1) << MSECCFG_SSEED_SHIFT)
/* Counter Overflow CSR */
#define CSR_SCOUNTOVF 0xda0
@@ -582,6 +734,7 @@
#define CSR_TDATA1 0x7a1
#define CSR_TDATA2 0x7a2
#define CSR_TDATA3 0x7a3
#define CSR_TINFO 0x7a4
/* Debug Mode Registers */
#define CSR_DCSR 0x7b0
@@ -589,6 +742,47 @@
#define CSR_DSCRATCH0 0x7b2
#define CSR_DSCRATCH1 0x7b3
/* Machine Indirect Register Alias */
#define CSR_MISELECT 0x350
#define CSR_MIREG 0x351
#define CSR_MIREG2 0x352
#define CSR_MIREG3 0x353
#define CSR_MIREG4 0x355
#define CSR_MIREG5 0x356
#define CSR_MIREG6 0x357
/* Machine-Level Interrupts (AIA) */
#define CSR_MTOPEI 0x35c
#define CSR_MTOPI 0xfb0
/* Virtual Interrupts for Supervisor Level (AIA) */
#define CSR_MVIEN 0x308
#define CSR_MVIP 0x309
/* Smstateen extension registers */
/* Machine stateen CSRs */
#define CSR_MSTATEEN0 0x30C
#define CSR_MSTATEEN0H 0x31C
#define CSR_MSTATEEN1 0x30D
#define CSR_MSTATEEN1H 0x31D
#define CSR_MSTATEEN2 0x30E
#define CSR_MSTATEEN2H 0x31E
#define CSR_MSTATEEN3 0x30F
#define CSR_MSTATEEN3H 0x31F
/* Machine-Level High-Half CSRs (AIA) */
#define CSR_MIDELEGH 0x313
#define CSR_MIEH 0x314
#define CSR_MVIENH 0x318
#define CSR_MVIPH 0x319
#define CSR_MIPH 0x354
/* Vector extension registers */
#define CSR_VSTART 0x8
#define CSR_VL 0xc20
#define CSR_VTYPE 0xc21
#define CSR_VLENB 0xc22
/* ===== Trap/Exception Causes ===== */
#define CAUSE_MISALIGNED_FETCH 0x0
@@ -606,11 +800,34 @@
#define CAUSE_FETCH_PAGE_FAULT 0xc
#define CAUSE_LOAD_PAGE_FAULT 0xd
#define CAUSE_STORE_PAGE_FAULT 0xf
#define CAUSE_DOUBLE_TRAP 0x10
#define CAUSE_SW_CHECK_EXCP 0x12
#define CAUSE_FETCH_GUEST_PAGE_FAULT 0x14
#define CAUSE_LOAD_GUEST_PAGE_FAULT 0x15
#define CAUSE_VIRTUAL_INST_FAULT 0x16
#define CAUSE_STORE_GUEST_PAGE_FAULT 0x17
/* Common defines for all smstateen */
#define SMSTATEEN_MAX_COUNT 4
#define SMSTATEEN0_CS_SHIFT 0
#define SMSTATEEN0_CS (_ULL(1) << SMSTATEEN0_CS_SHIFT)
#define SMSTATEEN0_FCSR_SHIFT 1
#define SMSTATEEN0_FCSR (_ULL(1) << SMSTATEEN0_FCSR_SHIFT)
#define SMSTATEEN0_CTR_SHIFT 54
#define SMSTATEEN0_CTR (_ULL(1) << SMSTATEEN0_CTR_SHIFT)
#define SMSTATEEN0_CONTEXT_SHIFT 57
#define SMSTATEEN0_CONTEXT (_ULL(1) << SMSTATEEN0_CONTEXT_SHIFT)
#define SMSTATEEN0_IMSIC_SHIFT 58
#define SMSTATEEN0_IMSIC (_ULL(1) << SMSTATEEN0_IMSIC_SHIFT)
#define SMSTATEEN0_AIA_SHIFT 59
#define SMSTATEEN0_AIA (_ULL(1) << SMSTATEEN0_AIA_SHIFT)
#define SMSTATEEN0_SVSLCT_SHIFT 60
#define SMSTATEEN0_SVSLCT (_ULL(1) << SMSTATEEN0_SVSLCT_SHIFT)
#define SMSTATEEN0_HSENVCFG_SHIFT 62
#define SMSTATEEN0_HSENVCFG (_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT)
#define SMSTATEEN_STATEN_SHIFT 63
#define SMSTATEEN_STATEN (_ULL(1) << SMSTATEEN_STATEN_SHIFT)
/* ===== Instruction Encodings ===== */
#define INSN_MATCH_LB 0x3
@@ -683,9 +900,412 @@
#define INSN_MATCH_C_FSWSP 0xe002
#define INSN_MASK_C_FSWSP 0xe003
#define INSN_MATCH_C_LHU 0x8400
#define INSN_MASK_C_LHU 0xfc43
#define INSN_MATCH_C_LH 0x8440
#define INSN_MASK_C_LH 0xfc43
#define INSN_MATCH_C_SH 0x8c00
#define INSN_MASK_C_SH 0xfc43
#define INSN_MASK_WFI 0xffffff00
#define INSN_MATCH_WFI 0x10500000
#define INSN_MASK_FENCE_TSO 0xffffffff
#define INSN_MATCH_FENCE_TSO 0x8330000f
#define INSN_MASK_VECTOR_UNIT_STRIDE 0xfdf0707f
#define INSN_MASK_VECTOR_FAULT_ONLY_FIRST 0xfdf0707f
#define INSN_MASK_VECTOR_STRIDE 0xfc00707f
#define INSN_MASK_VECTOR_WHOLE_REG 0xfff0707f
#define INSN_MASK_VECTOR_INDEXED 0xfc00707f
#define INSN_MATCH_VLUXSEG(n, bits) ((((n) - 1) << 29) | 0x04000007 | \
((bits) == 16 ? 5 : (bits) == 32 ? 6 : 7) << 12)
#define INSN_MATCH_VSUXSEG(n, bits) ((((n) - 1) << 29) | 0x04000027 | \
((bits) == 16 ? 5 : (bits) == 32 ? 6 : 7) << 12)
#define INSN_MATCH_VLOXSEG(n, bits) ((((n) - 1) << 29) | 0x0c000007 | \
((bits) == 16 ? 5 : (bits) == 32 ? 6 : 7) << 12)
#define INSN_MATCH_VSOXSEG(n, bits) ((((n) - 1) << 29) | 0x0c000027 | \
((bits) == 16 ? 5 : (bits) == 32 ? 6 : 7) << 12)
#define INSN_MATCH_VLSSEG(n, bits) ((((n) - 1) << 29) | 0x08000007 | \
((bits) == 16 ? 5 : (bits) == 32 ? 6 : 7) << 12)
#define INSN_MATCH_VSSSEG(n, bits) ((((n) - 1) << 29) | 0x08000027 | \
((bits) == 16 ? 5 : (bits) == 32 ? 6 : 7) << 12)
#define INSN_MATCH_VSSEG(n, bits) ((((n) - 1) << 29) | 0x00004027 | \
((bits) == 16 ? 5 : (bits) == 32 ? 6 : 7) << 12)
#define INSN_MATCH_VLSEG(n, bits) ((((n) - 1) << 29) | 0x00004007 | \
((bits) == 16 ? 5 : (bits) == 32 ? 6 : 7) << 12)
#define INSN_MATCH_VLSEGFF(n, bits) ((((n) - 1) << 29) | 0x1000007 | \
((bits) == 16 ? 5 : (bits) == 32 ? 6 : 7) << 12)
#define INSN_MATCH_VLE16V 0x00005007
#define INSN_MATCH_VLE32V 0x00006007
#define INSN_MATCH_VLE64V 0x00007007
#define INSN_MATCH_VSE16V 0x00005027
#define INSN_MATCH_VSE32V 0x00006027
#define INSN_MATCH_VSE64V 0x00007027
#define INSN_MATCH_VLSE16V 0x08005007
#define INSN_MATCH_VLSE32V 0x08006007
#define INSN_MATCH_VLSE64V 0x08007007
#define INSN_MATCH_VSSE16V 0x08005027
#define INSN_MATCH_VSSE32V 0x08006027
#define INSN_MATCH_VSSE64V 0x08007027
#define INSN_MATCH_VLOXEI16V 0x0c005007
#define INSN_MATCH_VLOXEI32V 0x0c006007
#define INSN_MATCH_VLOXEI64V 0x0c007007
#define INSN_MATCH_VSOXEI16V 0x0c005027
#define INSN_MATCH_VSOXEI32V 0x0c006027
#define INSN_MATCH_VSOXEI64V 0x0c007027
#define INSN_MATCH_VLUXEI16V 0x04005007
#define INSN_MATCH_VLUXEI32V 0x04006007
#define INSN_MATCH_VLUXEI64V 0x04007007
#define INSN_MATCH_VSUXEI16V 0x04005027
#define INSN_MATCH_VSUXEI32V 0x04006027
#define INSN_MATCH_VSUXEI64V 0x04007027
#define INSN_MATCH_VLE16FFV 0x01005007
#define INSN_MATCH_VLE32FFV 0x01006007
#define INSN_MATCH_VLE64FFV 0x01007007
#define INSN_MATCH_VL1RE8V 0x02800007
#define INSN_MATCH_VL1RE16V 0x02805007
#define INSN_MATCH_VL1RE32V 0x02806007
#define INSN_MATCH_VL1RE64V 0x02807007
#define INSN_MATCH_VL2RE8V 0x22800007
#define INSN_MATCH_VL2RE16V 0x22805007
#define INSN_MATCH_VL2RE32V 0x22806007
#define INSN_MATCH_VL2RE64V 0x22807007
#define INSN_MATCH_VL4RE8V 0x62800007
#define INSN_MATCH_VL4RE16V 0x62805007
#define INSN_MATCH_VL4RE32V 0x62806007
#define INSN_MATCH_VL4RE64V 0x62807007
#define INSN_MATCH_VL8RE8V 0xe2800007
#define INSN_MATCH_VL8RE16V 0xe2805007
#define INSN_MATCH_VL8RE32V 0xe2806007
#define INSN_MATCH_VL8RE64V 0xe2807007
#define INSN_MATCH_VS1RV 0x02800027
#define INSN_MATCH_VS2RV 0x22800027
#define INSN_MATCH_VS4RV 0x62800027
#define INSN_MATCH_VS8RV 0xe2800027
#define INSN_OPCODE_MASK 0x7f
#define INSN_OPCODE_VECTOR_LOAD 0x07
#define INSN_OPCODE_VECTOR_STORE 0x27
#define INSN_OPCODE_AMO 0x2f
#define IS_VECTOR_LOAD_STORE(insn) \
((((insn) & INSN_OPCODE_MASK) == INSN_OPCODE_VECTOR_LOAD) || \
(((insn) & INSN_OPCODE_MASK) == INSN_OPCODE_VECTOR_STORE))
#define IS_VECTOR_INSN_MATCH(insn, match, mask) \
(((insn) & (mask)) == ((match) & (mask)))
#define IS_UNIT_STRIDE_MATCH(insn, match) \
IS_VECTOR_INSN_MATCH(insn, match, INSN_MASK_VECTOR_UNIT_STRIDE)
#define IS_STRIDE_MATCH(insn, match) \
IS_VECTOR_INSN_MATCH(insn, match, INSN_MASK_VECTOR_STRIDE)
#define IS_INDEXED_MATCH(insn, match) \
IS_VECTOR_INSN_MATCH(insn, match, INSN_MASK_VECTOR_INDEXED)
#define IS_FAULT_ONLY_FIRST_MATCH(insn, match) \
IS_VECTOR_INSN_MATCH(insn, match, INSN_MASK_VECTOR_FAULT_ONLY_FIRST)
#define IS_WHOLE_REG_MATCH(insn, match) \
IS_VECTOR_INSN_MATCH(insn, match, INSN_MASK_VECTOR_WHOLE_REG)
#define IS_UNIT_STRIDE_LOAD(insn) ( \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLE16V) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLE32V) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLE64V) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(2, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(3, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(4, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(5, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(6, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(7, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(8, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(2, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(3, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(4, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(5, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(6, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(7, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(8, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(2, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(3, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(4, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(5, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(6, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(7, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VLSEG(8, 64)))
#define IS_UNIT_STRIDE_STORE(insn) ( \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSE16V) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSE32V) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSE64V) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(2, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(3, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(4, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(5, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(6, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(7, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(8, 16)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(2, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(3, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(4, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(5, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(6, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(7, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(8, 32)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(2, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(3, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(4, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(5, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(6, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(7, 64)) || \
IS_UNIT_STRIDE_MATCH(insn, INSN_MATCH_VSSEG(8, 64)))
#define IS_STRIDE_LOAD(insn) ( \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSE16V) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSE32V) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSE64V) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(2, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(3, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(4, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(5, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(6, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(7, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(8, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(2, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(3, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(4, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(5, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(6, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(7, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(8, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(2, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(3, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(4, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(5, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(6, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(7, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VLSSEG(8, 64)))
#define IS_STRIDE_STORE(insn) ( \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSE16V) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSE32V) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSE64V) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(2, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(3, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(4, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(5, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(6, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(7, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(8, 16)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(2, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(3, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(4, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(5, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(6, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(7, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(8, 32)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(2, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(3, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(4, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(5, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(6, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(7, 64)) || \
IS_STRIDE_MATCH(insn, INSN_MATCH_VSSSEG(8, 64)))
#define IS_INDEXED_LOAD(insn) ( \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXEI16V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXEI32V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXEI64V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXEI16V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXEI32V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXEI64V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(2, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(3, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(4, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(5, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(6, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(7, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(8, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(2, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(3, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(4, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(5, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(6, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(7, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(8, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(2, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(3, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(4, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(5, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(6, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(7, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLUXSEG(8, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(2, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(3, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(4, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(5, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(6, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(7, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(8, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(2, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(3, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(4, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(5, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(6, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(7, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(8, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(2, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(3, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(4, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(5, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(6, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(7, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VLOXSEG(8, 64)))
#define IS_INDEXED_STORE(insn) ( \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXEI16V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXEI32V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXEI64V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXEI16V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXEI32V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXEI64V) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(2, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(3, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(4, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(5, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(6, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(7, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(8, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(2, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(3, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(4, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(5, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(6, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(7, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(8, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(2, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(3, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(4, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(5, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(6, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(7, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSUXSEG(8, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(2, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(3, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(4, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(5, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(6, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(7, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(8, 16)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(2, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(3, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(4, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(5, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(6, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(7, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(8, 32)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(2, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(3, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(4, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(5, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(6, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(7, 64)) || \
IS_INDEXED_MATCH(insn, INSN_MATCH_VSOXSEG(8, 64)))
#define IS_FAULT_ONLY_FIRST_LOAD(insn) ( \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLE16FFV) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLE32FFV) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLE64FFV) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(2, 16)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(3, 16)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(4, 16)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(5, 16)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(6, 16)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(7, 16)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(8, 16)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(2, 32)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(3, 32)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(4, 32)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(5, 32)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(6, 32)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(7, 32)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(8, 32)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(2, 64)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(3, 64)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(4, 64)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(5, 64)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(6, 64)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(7, 64)) || \
IS_FAULT_ONLY_FIRST_MATCH(insn, INSN_MATCH_VLSEGFF(8, 64)))
#define IS_WHOLE_REG_LOAD(insn) ( \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL1RE8V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL1RE16V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL1RE32V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL1RE64V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL2RE8V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL2RE16V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL2RE32V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL2RE64V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL4RE8V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL4RE16V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL4RE32V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL4RE64V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL8RE8V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL8RE16V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL8RE32V) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VL8RE64V))
#define IS_WHOLE_REG_STORE(insn) ( \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VS1RV) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VS2RV) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VS4RV) || \
IS_WHOLE_REG_MATCH(insn, INSN_MATCH_VS8RV))
#if __riscv_xlen == 64
/* 64-bit read for VS-stage address translation (RV64) */
#define INSN_PSEUDO_VS_LOAD 0x00003000
/* 64-bit write for VS-stage address translation (RV64) */
#define INSN_PSEUDO_VS_STORE 0x00003020
#elif __riscv_xlen == 32
/* 32-bit read for VS-stage address translation (RV32) */
#define INSN_PSEUDO_VS_LOAD 0x00002000
/* 32-bit write for VS-stage address translation (RV32) */
#define INSN_PSEUDO_VS_STORE 0x00002020
#else
#error "Unexpected __riscv_xlen"
#endif
#define MASK_FUNCT3 0x7000
#define SHIFT_FUNCT3 12
#define MASK_RS1 0xf8000
#define MASK_RS2 0x1f00000
#define MASK_RD 0xf80
#define MASK_CSR 0xfff00000
#define SHIFT_CSR 20
#define MASK_AQRL 0x06000000
#define SHIFT_AQRL 25
#define VM_MASK 0x1
#define VIEW_MASK 0x3
#define VSEW_MASK 0x3
#define VLMUL_MASK 0x7
#define VD_MASK 0x1f
#define VS2_MASK 0x1f
#define INSN_16BIT_MASK 0x3
#define INSN_32BIT_MASK 0x1c
@@ -697,13 +1317,12 @@
#define INSN_LEN(insn) (INSN_IS_16BIT(insn) ? 2 : 4)
#if __riscv_xlen == 64
#define LOG_REGBYTES 3
#else
#define LOG_REGBYTES 2
#endif
#define REGBYTES (1 << LOG_REGBYTES)
#define SH_VSEW 3
#define SH_VIEW 12
#define SH_VD 7
#define SH_VS2 20
#define SH_VM 25
#define SH_MEW 28
#define SH_RD 7
#define SH_RS1 15
#define SH_RS2 20
@@ -732,28 +1351,39 @@
#define SHIFT_RIGHT(x, y) \
((y) < 0 ? ((x) << -(y)) : ((x) >> (y)))
#define REG_MASK \
((1 << (5 + LOG_REGBYTES)) - (1 << LOG_REGBYTES))
#define GET_FUNC3(insn) ((insn & MASK_FUNCT3) >> SHIFT_FUNCT3)
#define GET_RM(insn) GET_FUNC3(insn)
#define GET_RS1_NUM(insn) ((insn & MASK_RS1) >> SH_RS1)
#define GET_RS2_NUM(insn) ((insn & MASK_RS2) >> SH_RS2)
#define GET_RS1S_NUM(insn) RVC_RS1S(insn)
#define GET_RS2S_NUM(insn) RVC_RS2S(insn)
#define GET_RS2C_NUM(insn) RVC_RS2(insn)
#define GET_RD_NUM(insn) ((insn & MASK_RD) >> SH_RD)
#define GET_CSR_NUM(insn) ((insn & MASK_CSR) >> SHIFT_CSR)
#define GET_AQRL(insn) ((insn & MASK_AQRL) >> SHIFT_AQRL)
#define REG_OFFSET(insn, pos) \
(SHIFT_RIGHT((insn), (pos) - LOG_REGBYTES) & REG_MASK)
#define REG_PTR(insn, pos, regs) \
(ulong *)((ulong)(regs) + REG_OFFSET(insn, pos))
#define GET_RM(insn) (((insn) >> 12) & 7)
#define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs))
#define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs))
#define GET_RS1S(insn, regs) (*REG_PTR(RVC_RS1S(insn), 0, regs))
#define GET_RS2S(insn, regs) (*REG_PTR(RVC_RS2S(insn), 0, regs))
#define GET_RS2C(insn, regs) (*REG_PTR(insn, SH_RS2C, regs))
#define GET_SP(regs) (*REG_PTR(2, 0, regs))
#define SET_RD(insn, regs, val) (*REG_PTR(insn, SH_RD, regs) = (val))
#define IMM_I(insn) ((s32)(insn) >> 20)
#define IMM_S(insn) (((s32)(insn) >> 25 << 5) | \
(s32)(((insn) >> 7) & 0x1f))
#define MASK_FUNCT3 0x7000
#define IS_MASKED(insn) (((insn >> SH_VM) & VM_MASK) == 0)
#define GET_VD(insn) ((insn >> SH_VD) & VD_MASK)
#define GET_VS2(insn) ((insn >> SH_VS2) & VS2_MASK)
#define GET_VIEW(insn) (((insn) >> SH_VIEW) & VIEW_MASK)
#define GET_MEW(insn) (((insn) >> SH_MEW) & 1)
#define GET_VSEW(vtype) (((vtype) >> SH_VSEW) & VSEW_MASK)
#define GET_VLMUL(vtype) ((vtype) & VLMUL_MASK)
#define GET_LEN(view) (1UL << (view))
#define GET_NF(insn) (1 + ((insn >> 29) & 7))
#define GET_VEMUL(vlmul, view, vsew) ((vlmul + view - vsew) & 7)
#define GET_EMUL(vemul) (1UL << ((vemul) >= 4 ? 0 : (vemul)))
#define CSRRW 1
#define CSRRS 2
#define CSRRC 3
#define CSRRWI 5
#define CSRRSI 6
#define CSRRCI 7
/* clang-format on */

View File

@@ -15,7 +15,6 @@
#include <sbi/sbi_types.h>
#define GET_PRECISION(insn) (((insn) >> 25) & 3)
#define GET_RM(insn) (((insn) >> 12) & 7)
#define PRECISION_S 0
#define PRECISION_D 1
@@ -84,7 +83,7 @@
#define GET_FFLAGS() csr_read(CSR_FFLAGS)
#define SET_FFLAGS(value) csr_write(CSR_FFLAGS, (value))
#define SET_FS_DIRTY() ((void)0)
#define SET_FS_DIRTY(regs) (regs->mstatus |= MSTATUS_FS)
#define GET_F32_RS1(insn, regs) (GET_F32_REG(insn, 15, regs))
#define GET_F32_RS2(insn, regs) (GET_F32_REG(insn, 20, regs))
@@ -93,9 +92,9 @@
#define GET_F64_RS2(insn, regs) (GET_F64_REG(insn, 20, regs))
#define GET_F64_RS3(insn, regs) (GET_F64_REG(insn, 27, regs))
#define SET_F32_RD(insn, regs, val) \
(SET_F32_REG(insn, 7, regs, val), SET_FS_DIRTY())
(SET_F32_REG(insn, 7, regs, val), SET_FS_DIRTY(regs))
#define SET_F64_RD(insn, regs, val) \
(SET_F64_REG(insn, 7, regs, val), SET_FS_DIRTY())
(SET_F64_REG(insn, 7, regs, val), SET_FS_DIRTY(regs))
#define GET_F32_RS2C(insn, regs) (GET_F32_REG(insn, 2, regs))
#define GET_F32_RS2S(insn, regs) (GET_F32_REG(RVC_RS2S(insn), 0, regs))

View File

@@ -62,6 +62,11 @@ static inline void bitmap_zero(unsigned long *dst, int nbits)
}
}
static inline int bitmap_test(unsigned long *bmap, int bit)
{
return __test_bit(bit, bmap);
}
static inline void bitmap_zero_except(unsigned long *dst,
int exception, int nbits)
{
@@ -125,4 +130,17 @@ static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
__bitmap_xor(dst, src1, src2, nbits);
}
static inline int bitmap_weight(const unsigned long *src, int nbits)
{
int i, res = 0;
for (i = 0; i < nbits / BITS_PER_LONG; i++)
res += sbi_popcount(src[i]);
if (nbits % BITS_PER_LONG)
res += sbi_popcount(src[i] & BITMAP_LAST_WORD_MASK(nbits));
return res;
}
#endif

View File

@@ -12,13 +12,9 @@
#include <sbi/sbi_types.h>
#if __SIZEOF_POINTER__ == 8
#define BITS_PER_LONG 64
#elif __SIZEOF_POINTER__ == 4
#define BITS_PER_LONG 32
#else
#error "Unexpected __SIZEOF_POINTER__"
#endif
#define BITS_PER_LONG (8 * __SIZEOF_LONG__)
#define BITS_PER_LONG_LONG 64
#define EXTRACT_FIELD(val, which) \
(((val) & (which)) / ((which) & ~((which)-1)))
@@ -32,52 +28,22 @@
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(bit) ((bit) / BITS_PER_LONG)
#define BIT_WORD_OFFSET(bit) ((bit) & (BITS_PER_LONG - 1))
#define BIT_ALIGN(bit, align) (((bit) + ((align) - 1)) & ~((align) - 1))
#define BIT_ULL(nr) (1ULL << (nr))
#define GENMASK(h, l) \
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
#define GENMASK_ULL(h, l) \
(((~0ULL) - (1ULL << (l)) + 1) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
/**
* ffs - Find first bit set
* @x: the word to search
*
* This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
static inline int ffs(int x)
{
int r = 1;
if (!x)
return 0;
if (!(x & 0xffff)) {
x >>= 16;
r += 16;
}
if (!(x & 0xff)) {
x >>= 8;
r += 8;
}
if (!(x & 0xf)) {
x >>= 4;
r += 4;
}
if (!(x & 3)) {
x >>= 2;
r += 2;
}
if (!(x & 1))
r += 1;
return r;
}
/**
* __ffs - find first bit in word.
* sbi_ffs - find first (less-significant) set bit in a long word.
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static inline int __ffs(unsigned long word)
static inline int sbi_ffs(unsigned long word)
{
int num = 0;
@@ -109,55 +75,20 @@ static inline int __ffs(unsigned long word)
}
/*
* ffz - find first zero in word.
* sbi_ffz - find first zero in word.
* @word: The word to search
*
* Undefined if no zero exists, so code should check against ~0UL first.
*/
#define ffz(x) __ffs(~(x))
#define sbi_ffz(x) sbi_ffs(~(x))
/**
* fls - find last (most-significant) bit set
* @x: the word to search
*
* This is defined the same way as ffs.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
static inline int fls(int x)
{
int r = 32;
if (!x)
return 0;
if (!(x & 0xffff0000u)) {
x <<= 16;
r -= 16;
}
if (!(x & 0xff000000u)) {
x <<= 8;
r -= 8;
}
if (!(x & 0xf0000000u)) {
x <<= 4;
r -= 4;
}
if (!(x & 0xc0000000u)) {
x <<= 2;
r -= 2;
}
if (!(x & 0x80000000u))
r -= 1;
return r;
}
/**
* __fls - find last (most-significant) set bit in a long word
* sbi_fls - find last (most-significant) set bit in a long word
* @word: the word to search
*
* Undefined if no set bit exists, so code should check against 0 first.
*/
static inline unsigned long __fls(unsigned long word)
static inline unsigned long sbi_fls(unsigned long word)
{
int num = BITS_PER_LONG - 1;
@@ -188,6 +119,30 @@ static inline unsigned long __fls(unsigned long word)
return num;
}
/**
* sbi_popcount - find the number of set bit in a long word
* @word: the word to search
*/
static inline unsigned long sbi_popcount(unsigned long word)
{
unsigned long count;
#if BITS_PER_LONG == 64
count = word - ((word >> 1) & 0x5555555555555555ul);
count = (count & 0x3333333333333333ul) + ((count >> 2) & 0x3333333333333333ul);
count = (count + (count >> 4)) & 0x0F0F0F0F0F0F0F0Ful;
count = count + (count >> 8);
count = count + (count >> 16);
return (count + (count >> 32)) & 0x00000000000000FFul;
#else
count = word - ((word >> 1) & 0x55555555);
count = (count & 0x33333333) + ((count >> 2) & 0x33333333);
count = (count + (count >> 4)) & 0x0F0F0F0F;
count = count + (count >> 8);
return (count + (count >> 16)) & 0x000000FF;
#endif
}
#define for_each_set_bit(bit, addr, size) \
for ((bit) = find_first_bit((addr), (size)); \
(bit) < (size); \

View File

@@ -0,0 +1,80 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2023 Ventana Micro Systems Inc.
*/
#ifndef __SBI_BYTEORDER_H__
#define __SBI_BYTEORDER_H__
#ifdef __ASSEMBLER__
# define _conv_cast(type, val) (val)
#else
# include <sbi/sbi_types.h>
# define _conv_cast(type, val) ((type)(val))
#endif
#define __BSWAP16(x) ((((x) & 0x00ff) << 8) | \
(((x) & 0xff00) >> 8))
#define __BSWAP32(x) ((((x) & 0x000000ff) << 24) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0xff000000) >> 24))
#define __BSWAP64(x) ((((x) & 0x00000000000000ffULL) << 56) | \
(((x) & 0x000000000000ff00ULL) << 40) | \
(((x) & 0x0000000000ff0000ULL) << 24) | \
(((x) & 0x00000000ff000000ULL) << 8) | \
(((x) & 0x000000ff00000000ULL) >> 8) | \
(((x) & 0x0000ff0000000000ULL) >> 24) | \
(((x) & 0x00ff000000000000ULL) >> 40) | \
(((x) & 0xff00000000000000ULL) >> 56))
#define BSWAP64(x) ({ uint64_t _sv = (x); __BSWAP64(_sv); })
#define BSWAP32(x) ({ uint32_t _sv = (x); __BSWAP32(_sv); })
#define BSWAP16(x) ({ uint16_t _sv = (x); __BSWAP16(_sv); })
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* CPU(little-endian) */
#define cpu_to_be16(x) _conv_cast(uint16_t, BSWAP16(x))
#define cpu_to_be32(x) _conv_cast(uint32_t, BSWAP32(x))
#define cpu_to_be64(x) _conv_cast(uint64_t, BSWAP64(x))
#define be16_to_cpu(x) _conv_cast(uint16_t, BSWAP16(x))
#define be32_to_cpu(x) _conv_cast(uint32_t, BSWAP32(x))
#define be64_to_cpu(x) _conv_cast(uint64_t, BSWAP64(x))
#define cpu_to_le16(x) _conv_cast(uint16_t, (x))
#define cpu_to_le32(x) _conv_cast(uint32_t, (x))
#define cpu_to_le64(x) _conv_cast(uint64_t, (x))
#define le16_to_cpu(x) _conv_cast(uint16_t, (x))
#define le32_to_cpu(x) _conv_cast(uint32_t, (x))
#define le64_to_cpu(x) _conv_cast(uint64_t, (x))
#else /* CPU(big-endian) */
#define cpu_to_be16(x) _conv_cast(uint16_t, (x))
#define cpu_to_be32(x) _conv_cast(uint32_t, (x))
#define cpu_to_be64(x) _conv_cast(uint64_t, (x))
#define be16_to_cpu(x) _conv_cast(uint16_t, (x))
#define be32_to_cpu(x) _conv_cast(uint32_t, (x))
#define be64_to_cpu(x) _conv_cast(uint64_t, (x))
#define cpu_to_le16(x) _conv_cast(uint16_t, BSWAP16(x))
#define cpu_to_le32(x) _conv_cast(uint32_t, BSWAP32(x))
#define cpu_to_le64(x) _conv_cast(uint64_t, BSWAP64(x))
#define le16_to_cpu(x) _conv_cast(uint16_t, BSWAP16(x))
#define le32_to_cpu(x) _conv_cast(uint32_t, BSWAP32(x))
#define le64_to_cpu(x) _conv_cast(uint64_t, BSWAP64(x))
#endif
#if __riscv_xlen == 64
#define cpu_to_lle cpu_to_le64
#define lle_to_cpu le64_to_cpu
#elif __riscv_xlen == 32
#define cpu_to_lle cpu_to_le32
#define lle_to_cpu le32_to_cpu
#else
#error "Unknown __riscv_xlen"
#endif
#endif /* __SBI_BYTEORDER_H__ */

View File

@@ -19,6 +19,9 @@ struct sbi_console_device {
/** Write a character to the console output */
void (*console_putc)(char ch);
/** Write a character string to the console output */
unsigned long (*console_puts)(const char *str, unsigned long len);
/** Read a character from the console input */
int (*console_getc)(void);
};
@@ -33,8 +36,12 @@ void sbi_putc(char ch);
void sbi_puts(const char *str);
unsigned long sbi_nputs(const char *str, unsigned long len);
void sbi_gets(char *s, int maxwidth, char endchar);
unsigned long sbi_ngets(char *str, unsigned long len);
int __printf(2, 3) sbi_sprintf(char *out, const char *format, ...);
int __printf(3, 4) sbi_snprintf(char *out, u32 out_sz, const char *format, ...);
@@ -51,8 +58,6 @@ void sbi_console_set_device(const struct sbi_console_device *dev);
struct sbi_scratch;
int sbi_console_init(struct sbi_scratch *scratch);
#define SBI_ASSERT(cond, args) do { \
if (unlikely(!(cond))) \
sbi_panic args; \

35
include/sbi/sbi_cppc.h Normal file
View File

@@ -0,0 +1,35 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2023 Ventana Micro Systems Inc.
*
*/
#ifndef __SBI_CPPC_H__
#define __SBI_CPPC_H__
#include <sbi/sbi_types.h>
/** CPPC device */
struct sbi_cppc_device {
/** Name of the CPPC device */
char name[32];
/** probe - returns register width if implemented, 0 otherwise */
int (*cppc_probe)(unsigned long reg);
/** read the cppc register*/
int (*cppc_read)(unsigned long reg, uint64_t *val);
/** write to the cppc register*/
int (*cppc_write)(unsigned long reg, uint64_t val);
};
int sbi_cppc_probe(unsigned long reg);
int sbi_cppc_read(unsigned long reg, uint64_t *val);
int sbi_cppc_write(unsigned long reg, uint64_t val);
const struct sbi_cppc_device *sbi_cppc_get_device(void);
void sbi_cppc_set_device(const struct sbi_cppc_device *dev);
#endif

View File

@@ -18,7 +18,7 @@
({ \
register ulong tinfo asm("a3") = (ulong)trap; \
register ulong ttmp asm("a4"); \
register ulong mtvec = sbi_hart_expected_trap_addr(); \
register ulong mtvec = (ulong)sbi_hart_expected_trap; \
register ulong ret = 0; \
((struct sbi_trap_info *)(trap))->cause = 0; \
asm volatile( \
@@ -37,7 +37,7 @@
({ \
register ulong tinfo asm("a3") = (ulong)trap; \
register ulong ttmp asm("a4"); \
register ulong mtvec = sbi_hart_expected_trap_addr(); \
register ulong mtvec = (ulong)sbi_hart_expected_trap; \
((struct sbi_trap_info *)(trap))->cause = 0; \
asm volatile( \
"add %[ttmp], %[tinfo], zero\n" \

124
include/sbi/sbi_dbtr.h Normal file
View File

@@ -0,0 +1,124 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2023 Ventana Micro Systems, Inc.
*
* Authors:
* Himanshu Chauhan <hchauhan@ventanamicro.com>
*/
#ifndef __SBI_DBTR_H__
#define __SBI_DBTR_H__
#include <sbi/riscv_dbtr.h>
#include <sbi/sbi_types.h>
struct sbi_domain;
enum {
RV_DBTR_DECLARE_BIT(TS, MAPPED, 0), /* trigger mapped to hw trigger */
RV_DBTR_DECLARE_BIT(TS, U, 1),
RV_DBTR_DECLARE_BIT(TS, S, 2),
RV_DBTR_DECLARE_BIT(TS, VU, 3),
RV_DBTR_DECLARE_BIT(TS, VS, 4),
RV_DBTR_DECLARE_BIT(TS, HAVE_TRIG, 5), /* H/w dbtr details available */
RV_DBTR_DECLARE_BIT(TS, HW_IDX, 8), /* Hardware index of trigger */
};
enum {
RV_DBTR_DECLARE_BIT_MASK(TS, MAPPED, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, U, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, S, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, VU, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, VS, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, HAVE_TRIG, 1),
RV_DBTR_DECLARE_BIT_MASK(TS, HW_IDX, (__riscv_xlen-9)),
};
#if __riscv_xlen == 64
#define SBI_DBTR_SHMEM_INVALID_ADDR 0xFFFFFFFFFFFFFFFFUL
#elif __riscv_xlen == 32
#define SBI_DBTR_SHMEM_INVALID_ADDR 0xFFFFFFFFUL
#else
#error "Unexpected __riscv_xlen"
#endif
struct sbi_dbtr_shmem {
unsigned long phys_lo;
unsigned long phys_hi;
};
struct sbi_dbtr_trigger {
unsigned long index;
unsigned long type_mask;
unsigned long state;
unsigned long tdata1;
unsigned long tdata2;
unsigned long tdata3;
};
struct sbi_dbtr_data_msg {
unsigned long tstate;
unsigned long tdata1;
unsigned long tdata2;
unsigned long tdata3;
};
struct sbi_dbtr_id_msg {
unsigned long idx;
};
struct sbi_dbtr_hart_triggers_state {
struct sbi_dbtr_trigger triggers[RV_MAX_TRIGGERS];
struct sbi_dbtr_shmem shmem;
u32 total_trigs;
u32 available_trigs;
u32 hartid;
u32 probed;
};
#define TDATA1_GET_TYPE(_t1) \
EXTRACT_FIELD(_t1, RV_DBTR_BIT_MASK(TDATA1, TYPE))
/* Set the hardware index of trigger in logical trigger state */
#define SET_TRIG_HW_INDEX(_state, _idx) \
do { \
_state &= ~RV_DBTR_BIT_MASK(TS, HW_IDX); \
_state |= (((unsigned long)_idx \
<< RV_DBTR_BIT(TS, HW_IDX)) \
& RV_DBTR_BIT_MASK(TS, HW_IDX)); \
}while (0);
/** SBI shared mem messages layout */
union sbi_dbtr_shmem_entry {
struct sbi_dbtr_data_msg data;
struct sbi_dbtr_id_msg id;
};
#define SBI_DBTR_SHMEM_ALIGN_MASK ((__riscv_xlen / 8) - 1)
/** Initialize debug triggers */
int sbi_dbtr_init(struct sbi_scratch *scratch, bool coldboot);
/** SBI DBTR extension functions */
int sbi_dbtr_supported(void);
int sbi_dbtr_setup_shmem(const struct sbi_domain *dom, unsigned long smode,
unsigned long shmem_phys_lo,
unsigned long shmem_phys_hi);
int sbi_dbtr_num_trig(unsigned long trig_tdata1, unsigned long *out);
int sbi_dbtr_read_trig(unsigned long smode,
unsigned long trig_idx_base, unsigned long trig_count);
int sbi_dbtr_install_trig(unsigned long smode,
unsigned long trig_count, unsigned long *out);
int sbi_dbtr_uninstall_trig(unsigned long trig_idx_base,
unsigned long trig_idx_mask);
int sbi_dbtr_enable_trig(unsigned long trig_idx_base,
unsigned long trig_idx_mask);
int sbi_dbtr_update_trig(unsigned long smode,
unsigned long trig_count);
int sbi_dbtr_disable_trig(unsigned long trig_idx_base,
unsigned long trig_idx_mask);
int sbi_dbtr_get_total_triggers(void);
#endif

View File

@@ -10,8 +10,12 @@
#ifndef __SBI_DOMAIN_H__
#define __SBI_DOMAIN_H__
#include <sbi/riscv_locks.h>
#include <sbi/sbi_list.h>
#include <sbi/sbi_types.h>
#include <sbi/sbi_hartmask.h>
#include <sbi/sbi_domain_context.h>
#include <sbi/sbi_domain_data.h>
struct sbi_scratch;
@@ -36,32 +40,138 @@ struct sbi_domain_memregion {
*/
unsigned long base;
/** Flags representing memory region attributes */
#define SBI_DOMAIN_MEMREGION_READABLE (1UL << 0)
#define SBI_DOMAIN_MEMREGION_WRITEABLE (1UL << 1)
#define SBI_DOMAIN_MEMREGION_EXECUTABLE (1UL << 2)
#define SBI_DOMAIN_MEMREGION_MMODE (1UL << 3)
#define SBI_DOMAIN_MEMREGION_ACCESS_MASK (0xfUL)
#define SBI_DOMAIN_MEMREGION_M_READABLE (1UL << 0)
#define SBI_DOMAIN_MEMREGION_M_WRITABLE (1UL << 1)
#define SBI_DOMAIN_MEMREGION_M_EXECUTABLE (1UL << 2)
#define SBI_DOMAIN_MEMREGION_SU_READABLE (1UL << 3)
#define SBI_DOMAIN_MEMREGION_SU_WRITABLE (1UL << 4)
#define SBI_DOMAIN_MEMREGION_SU_EXECUTABLE (1UL << 5)
#define SBI_DOMAIN_MEMREGION_ACCESS_MASK (0x3fUL)
#define SBI_DOMAIN_MEMREGION_M_ACCESS_MASK (0x7UL)
#define SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK (0x38UL)
#define SBI_DOMAIN_MEMREGION_SU_ACCESS_SHIFT (3)
#define SBI_DOMAIN_MEMREGION_SHARED_RDONLY \
(SBI_DOMAIN_MEMREGION_M_READABLE | \
SBI_DOMAIN_MEMREGION_SU_READABLE)
#define SBI_DOMAIN_MEMREGION_SHARED_SUX_MRX \
(SBI_DOMAIN_MEMREGION_M_READABLE | \
SBI_DOMAIN_MEMREGION_M_EXECUTABLE | \
SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
#define SBI_DOMAIN_MEMREGION_SHARED_SUX_MX \
(SBI_DOMAIN_MEMREGION_M_EXECUTABLE | \
SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
#define SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW \
(SBI_DOMAIN_MEMREGION_M_READABLE | \
SBI_DOMAIN_MEMREGION_M_WRITABLE | \
SBI_DOMAIN_MEMREGION_SU_READABLE| \
SBI_DOMAIN_MEMREGION_SU_WRITABLE)
#define SBI_DOMAIN_MEMREGION_SHARED_SUR_MRW \
(SBI_DOMAIN_MEMREGION_M_READABLE | \
SBI_DOMAIN_MEMREGION_M_WRITABLE | \
SBI_DOMAIN_MEMREGION_SU_READABLE)
/* Shared read-only region between M and SU mode */
#define SBI_DOMAIN_MEMREGION_IS_SUR_MR(__flags) \
((__flags & SBI_DOMAIN_MEMREGION_ACCESS_MASK) == \
SBI_DOMAIN_MEMREGION_SHARED_RDONLY)
/* Shared region: SU execute-only and M read/execute */
#define SBI_DOMAIN_MEMREGION_IS_SUX_MRX(__flags) \
((__flags & SBI_DOMAIN_MEMREGION_ACCESS_MASK) == \
SBI_DOMAIN_MEMREGION_SHARED_SUX_MRX)
/* Shared region: SU and M execute-only */
#define SBI_DOMAIN_MEMREGION_IS_SUX_MX(__flags) \
((__flags & SBI_DOMAIN_MEMREGION_ACCESS_MASK) == \
SBI_DOMAIN_MEMREGION_SHARED_SUX_MX)
/* Shared region: SU and M read/write */
#define SBI_DOMAIN_MEMREGION_IS_SURW_MRW(__flags) \
((__flags & SBI_DOMAIN_MEMREGION_ACCESS_MASK) == \
SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW)
/* Shared region: SU read-only and M read/write */
#define SBI_DOMAIN_MEMREGION_IS_SUR_MRW(__flags) \
((__flags & SBI_DOMAIN_MEMREGION_ACCESS_MASK) == \
SBI_DOMAIN_MEMREGION_SHARED_SUR_MRW)
/*
* Check if region flags match with any of the above
* mentioned shared region type
*/
#define SBI_DOMAIN_MEMREGION_IS_SHARED(_flags) \
(SBI_DOMAIN_MEMREGION_IS_SUR_MR(_flags) || \
SBI_DOMAIN_MEMREGION_IS_SUX_MRX(_flags) || \
SBI_DOMAIN_MEMREGION_IS_SUX_MX(_flags) || \
SBI_DOMAIN_MEMREGION_IS_SURW_MRW(_flags)|| \
SBI_DOMAIN_MEMREGION_IS_SUR_MRW(_flags))
#define SBI_DOMAIN_MEMREGION_M_ONLY_ACCESS(__flags) \
((__flags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK) && \
!(__flags & SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK))
#define SBI_DOMAIN_MEMREGION_SU_ONLY_ACCESS(__flags) \
((__flags & SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK) && \
!(__flags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK))
/** Bit to control if permissions are enforced on all modes */
#define SBI_DOMAIN_MEMREGION_ENF_PERMISSIONS (1UL << 6)
#define SBI_DOMAIN_MEMREGION_M_RWX \
(SBI_DOMAIN_MEMREGION_M_READABLE | \
SBI_DOMAIN_MEMREGION_M_WRITABLE | \
SBI_DOMAIN_MEMREGION_M_EXECUTABLE)
#define SBI_DOMAIN_MEMREGION_SU_RWX \
(SBI_DOMAIN_MEMREGION_SU_READABLE | \
SBI_DOMAIN_MEMREGION_SU_WRITABLE | \
SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
/* Unrestricted M-mode accesses but enfoced on SU-mode */
#define SBI_DOMAIN_MEMREGION_READABLE \
(SBI_DOMAIN_MEMREGION_SU_READABLE | \
SBI_DOMAIN_MEMREGION_M_RWX)
#define SBI_DOMAIN_MEMREGION_WRITEABLE \
(SBI_DOMAIN_MEMREGION_SU_WRITABLE | \
SBI_DOMAIN_MEMREGION_M_RWX)
#define SBI_DOMAIN_MEMREGION_EXECUTABLE \
(SBI_DOMAIN_MEMREGION_SU_EXECUTABLE | \
SBI_DOMAIN_MEMREGION_M_RWX)
/* Enforced accesses across all modes */
#define SBI_DOMAIN_MEMREGION_ENF_READABLE \
(SBI_DOMAIN_MEMREGION_SU_READABLE | \
SBI_DOMAIN_MEMREGION_M_READABLE)
#define SBI_DOMAIN_MEMREGION_ENF_WRITABLE \
(SBI_DOMAIN_MEMREGION_SU_WRITABLE | \
SBI_DOMAIN_MEMREGION_M_WRITABLE)
#define SBI_DOMAIN_MEMREGION_ENF_EXECUTABLE \
(SBI_DOMAIN_MEMREGION_SU_EXECUTABLE | \
SBI_DOMAIN_MEMREGION_M_EXECUTABLE)
#define SBI_DOMAIN_MEMREGION_MMIO (1UL << 31)
unsigned long flags;
};
/** Maximum number of domains */
#define SBI_DOMAIN_MAX_INDEX 32
/** Representation of OpenSBI domain */
struct sbi_domain {
/**
* Logical index of this domain
* Note: This set by sbi_domain_finalize() in the coldboot path
*/
/** Node in linked list of domains */
struct sbi_dlist node;
/** Internal state of per-domain data */
struct sbi_domain_data_priv data_priv;
/** Logical index of this domain */
u32 index;
/**
* HARTs assigned to this domain
* Note: This set by sbi_domain_init() and sbi_domain_finalize()
* in the coldboot path
*/
/** HARTs assigned to this domain */
struct sbi_hartmask assigned_harts;
/** Spinlock for accessing assigned_harts */
spinlock_t assigned_harts_lock;
/** Name of this domain */
char name[64];
/** Possible HARTs in this domain */
@@ -78,32 +188,31 @@ struct sbi_domain {
unsigned long next_mode;
/** Is domain allowed to reset the system */
bool system_reset_allowed;
/** Is domain allowed to suspend the system */
bool system_suspend_allowed;
/** Identifies whether to include the firmware region */
bool fw_region_inited;
};
/** The root domain instance */
extern struct sbi_domain root;
/** HART id to domain table */
extern struct sbi_domain *hartid_to_domain_table[];
/** Get pointer to sbi_domain from HART index */
struct sbi_domain *sbi_hartindex_to_domain(u32 hartindex);
/** Get pointer to sbi_domain from HART id */
#define sbi_hartid_to_domain(__hartid) \
hartid_to_domain_table[__hartid]
/** Update HART local pointer to point to specified domain */
void sbi_update_hartindex_to_domain(u32 hartindex, struct sbi_domain *dom);
/** Get pointer to sbi_domain for current HART */
#define sbi_domain_thishart_ptr() \
sbi_hartid_to_domain(current_hartid())
sbi_hartindex_to_domain(current_hartindex())
/** Index to domain table */
extern struct sbi_domain *domidx_to_domain_table[];
/** Get pointer to sbi_domain from index */
#define sbi_index_to_domain(__index) \
domidx_to_domain_table[__index]
/** Head of linked list of domains */
extern struct sbi_dlist domain_list;
/** Iterate over each domain */
#define sbi_domain_for_each(__i, __d) \
for ((__i) = 0; ((__d) = sbi_index_to_domain(__i)); (__i)++)
#define sbi_domain_for_each(__d) \
sbi_list_for_each_entry(__d, &domain_list, node)
/** Iterate over each memory region of a domain */
#define sbi_domain_for_each_memregion(__d, __r) \
@@ -112,20 +221,19 @@ extern struct sbi_domain *domidx_to_domain_table[];
/**
* Check whether given HART is assigned to specified domain
* @param dom pointer to domain
* @param hartid the HART ID
* @return TRUE if HART is assigned to domain otherwise FALSE
* @param hartindex the HART index
* @return true if HART is assigned to domain otherwise false
*/
bool sbi_domain_is_assigned_hart(const struct sbi_domain *dom, u32 hartid);
bool sbi_domain_is_assigned_hart(const struct sbi_domain *dom, u32 hartindex);
/**
* Get ulong assigned HART mask for given domain and HART base ID
* Get the assigned HART mask for given domain
* @param dom pointer to domain
* @param hbase the HART base ID
* @return ulong possible HART mask
* Note: the return ulong mask will be set to zero on failure.
* @param mask the output hartmask to fill
* @return 0 on success and SBI_Exxx (< 0) on failure
*/
ulong sbi_domain_get_assigned_hartmask(const struct sbi_domain *dom,
ulong hbase);
int sbi_domain_get_assigned_hartmask(const struct sbi_domain *dom,
struct sbi_hartmask *mask);
/**
* Initialize a domain memory region based on it's physical
@@ -148,12 +256,27 @@ void sbi_domain_memregion_init(unsigned long addr,
* @param addr the address to be checked
* @param mode the privilege mode of access
* @param access_flags bitmask of domain access types (enum sbi_domain_access)
* @return TRUE if access allowed otherwise FALSE
* @return true if access allowed otherwise false
*/
bool sbi_domain_check_addr(const struct sbi_domain *dom,
unsigned long addr, unsigned long mode,
unsigned long access_flags);
/**
* Check whether we can access specified address range for given mode and
* memory region flags under a domain
* @param dom pointer to domain
* @param addr the start of the address range to be checked
* @param size the size of the address range to be checked
* @param mode the privilege mode of access
* @param access_flags bitmask of domain access types (enum sbi_domain_access)
* @return TRUE if access allowed otherwise FALSE
*/
bool sbi_domain_check_addr_range(const struct sbi_domain *dom,
unsigned long addr, unsigned long size,
unsigned long mode,
unsigned long access_flags);
/** Dump domain details on the console */
void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix);
@@ -171,15 +294,24 @@ int sbi_domain_register(struct sbi_domain *dom,
const struct sbi_hartmask *assign_mask);
/**
* Add a memory region to the root domain
* @param reg pointer to the memory region to be added
* Add a memory range with its flags to the root domain
* @param addr start physical address of memory range
* @param size physical size of memory range
* @param align alignment of memory region
* @param region_flags memory range flags
*
* @return 0 on success and negative error code on failure
* @return 0 on success
* @return SBI_EALREADY if memory region conflicts with the existing one
* @return SBI_EINVAL otherwise
*/
int sbi_domain_root_add_memregion(const struct sbi_domain_memregion *reg);
int sbi_domain_root_add_memrange(unsigned long addr, unsigned long size,
unsigned long align, unsigned long region_flags);
/** Finalize domain tables and startup non-root domains */
int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid);
/** Startup non-root domains */
int sbi_domain_startup(struct sbi_scratch *scratch, u32 cold_hartid);
/** Finalize domain tables */
int sbi_domain_finalize(struct sbi_scratch *scratch);
/** Initialize domains */
int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid);

View File

@@ -0,0 +1,41 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) IPADS@SJTU 2023. All rights reserved.
*/
#ifndef __SBI_DOMAIN_CONTEXT_H__
#define __SBI_DOMAIN_CONTEXT_H__
#include <sbi/sbi_types.h>
struct sbi_domain;
/**
* Enter a specific domain context synchronously
* @param dom pointer to domain
*
* @return 0 on success and negative error code on failure
*/
int sbi_domain_context_enter(struct sbi_domain *dom);
/**
* Exit the current domain context, and then return to the caller
* of sbi_domain_context_enter or attempt to start the next domain
* context to be initialized
*
* @return 0 on success and negative error code on failure
*/
int sbi_domain_context_exit(void);
/**
* Initialize domain context support
*
* @return 0 on success and negative error code on failure
*/
int sbi_domain_context_init(void);
/* Deinitialize domain context support */
void sbi_domain_context_deinit(void);
#endif // __SBI_DOMAIN_CONTEXT_H__

View File

@@ -0,0 +1,93 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2024 Ventana Micro Systems Inc.
*/
#ifndef __SBI_DOMAIN_DATA_H__
#define __SBI_DOMAIN_DATA_H__
#include <sbi/sbi_types.h>
#include <sbi/sbi_list.h>
struct sbi_domain;
/** Maximum domain data per-domain */
#define SBI_DOMAIN_MAX_DATA_PTRS 32
/** Representation of per-domain data */
struct sbi_domain_data_priv {
/** Array of domain data pointers indexed by domain data identifier */
void *idx_to_data_ptr[SBI_DOMAIN_MAX_DATA_PTRS];
};
/** Representation of a domain data */
struct sbi_domain_data {
/**
* Head is used for maintaining data list
*
* Note: initialized by domain framework
*/
struct sbi_dlist head;
/**
* Identifier which used to locate per-domain data
*
* Note: initialized by domain framework
*/
unsigned long data_idx;
/** Size of per-domain data */
unsigned long data_size;
/** Optional callback to setup domain data */
int (*data_setup)(struct sbi_domain *dom,
struct sbi_domain_data *data, void *data_ptr);
/** Optional callback to cleanup domain data */
void (*data_cleanup)(struct sbi_domain *dom,
struct sbi_domain_data *data, void *data_ptr);
};
/**
* Get per-domain data pointer for a given domain
* @param dom pointer to domain
* @param data pointer to domain data
*
* @return per-domain data pointer
*/
void *sbi_domain_data_ptr(struct sbi_domain *dom, struct sbi_domain_data *data);
/**
* Setup all domain data for a domain
* @param dom pointer to domain
*
* @return 0 on success and negative error code on failure
*
* Note: This function is used internally within domain framework.
*/
int sbi_domain_setup_data(struct sbi_domain *dom);
/**
* Cleanup all domain data for a domain
* @param dom pointer to domain
*
* Note: This function is used internally within domain framework.
*/
void sbi_domain_cleanup_data(struct sbi_domain *dom);
/**
* Register a domain data
* @param hndl pointer to domain data
*
* @return 0 on success and negative error code on failure
*
* Note: This function must be used only in cold boot path.
*/
int sbi_domain_register_data(struct sbi_domain_data *data);
/**
* Unregister a domain data
* @param hndl pointer to domain data
*
* Note: This function must be used only in cold boot path.
*/
void sbi_domain_unregister_data(struct sbi_domain_data *data);
#endif

View File

@@ -0,0 +1,20 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2025 Rivos Inc.
*
* Authors:
* Clément Léger <cleger@rivosinc.com>
*/
#ifndef __SBI_DOUBLE_TRAP_H__
#define __SBI_DOUBLE_TRAP_H__
#include <sbi/sbi_types.h>
#include <sbi/sbi_trap.h>
int sbi_double_trap_handler(struct sbi_trap_context *tcntx);
void sbi_double_trap_init(struct sbi_scratch *scratch);
#endif

View File

@@ -13,33 +13,69 @@
#include <sbi/sbi_types.h>
#include <sbi/sbi_list.h>
#define SBI_ECALL_VERSION_MAJOR 0
#define SBI_ECALL_VERSION_MINOR 3
#define SBI_ECALL_VERSION_MAJOR 3
#define SBI_ECALL_VERSION_MINOR 0
#define SBI_OPENSBI_IMPID 1
struct sbi_trap_regs;
struct sbi_trap_info;
struct sbi_trap_context;
struct sbi_ecall_extension {
struct sbi_dlist head;
unsigned long extid_start;
unsigned long extid_end;
int (* probe)(unsigned long extid, unsigned long *out_val);
int (* handle)(unsigned long extid, unsigned long funcid,
const struct sbi_trap_regs *regs,
unsigned long *out_val,
struct sbi_trap_info *out_trap);
struct sbi_ecall_return {
/* Return flag to skip register update */
bool skip_regs_update;
/* Return value */
unsigned long value;
};
extern struct sbi_ecall_extension ecall_base;
extern struct sbi_ecall_extension ecall_legacy;
extern struct sbi_ecall_extension ecall_time;
extern struct sbi_ecall_extension ecall_rfence;
extern struct sbi_ecall_extension ecall_ipi;
extern struct sbi_ecall_extension ecall_vendor;
extern struct sbi_ecall_extension ecall_hsm;
extern struct sbi_ecall_extension ecall_srst;
extern struct sbi_ecall_extension ecall_pmu;
struct sbi_ecall_extension {
/* head is used by the extension list */
struct sbi_dlist head;
/* short name of the extension */
char name[8];
/*
* extid_start and extid_end specify the range for this extension. As
* the initial range may be wider than the valid runtime range, the
* register_extensions callback is responsible for narrowing the range
* before other callbacks may be invoked.
*/
unsigned long extid_start;
unsigned long extid_end;
/* flag showing whether given extension is experimental or not */
bool experimental;
/*
* register_extensions
*
* Calls sbi_ecall_register_extension() one or more times to register
* extension ID range(s) which should be handled by this extension.
* More than one sbi_ecall_extension struct and
* sbi_ecall_register_extension() call is necessary when the supported
* extension ID ranges have gaps. Additionally, extension availability
* must be checked before registering, which means, when this callback
* returns, only valid extension IDs from the initial range, which are
* also available, have been registered.
*/
int (* register_extensions)(void);
/*
* probe
*
* Implements the Base extension's probe function for the extension. As
* the register_extensions callback ensures that no other extension
* callbacks will be invoked when the extension is not available, then
* probe can never fail. However, an extension may choose to set
* out_val to a nonzero value other than one. In those cases, it should
* implement this callback.
*/
int (* probe)(unsigned long extid, unsigned long *out_val);
/*
* handle
*
* This is the extension handler. register_extensions ensures it is
* never invoked with an invalid or unavailable extension ID.
*/
int (* handle)(unsigned long extid, unsigned long funcid,
struct sbi_trap_regs *regs,
struct sbi_ecall_return *out);
};
u16 sbi_ecall_version_major(void);
@@ -51,11 +87,13 @@ void sbi_ecall_set_impid(unsigned long impid);
struct sbi_ecall_extension *sbi_ecall_find_extension(unsigned long extid);
void sbi_ecall_get_extensions_str(char *exts_str, int exts_str_size, bool experimental);
int sbi_ecall_register_extension(struct sbi_ecall_extension *ext);
void sbi_ecall_unregister_extension(struct sbi_ecall_extension *ext);
int sbi_ecall_handler(struct sbi_trap_regs *regs);
int sbi_ecall_handler(struct sbi_trap_context *tcntx);
int sbi_ecall_init(void);

View File

@@ -12,6 +12,8 @@
/* clang-format off */
#include <sbi/sbi_types.h>
/* SBI Extension IDs */
#define SBI_EXT_0_1_SET_TIMER 0x0
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
@@ -29,6 +31,13 @@
#define SBI_EXT_HSM 0x48534D
#define SBI_EXT_SRST 0x53525354
#define SBI_EXT_PMU 0x504D55
#define SBI_EXT_DBCN 0x4442434E
#define SBI_EXT_SUSP 0x53555350
#define SBI_EXT_CPPC 0x43505043
#define SBI_EXT_DBTR 0x44425452
#define SBI_EXT_SSE 0x535345
#define SBI_EXT_FWFT 0x46574654
#define SBI_EXT_MPXY 0x4D505859
/* SBI function IDs for BASE extension*/
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
@@ -99,6 +108,46 @@
#define SBI_EXT_PMU_COUNTER_START 0x3
#define SBI_EXT_PMU_COUNTER_STOP 0x4
#define SBI_EXT_PMU_COUNTER_FW_READ 0x5
#define SBI_EXT_PMU_COUNTER_FW_READ_HI 0x6
#define SBI_EXT_PMU_SNAPSHOT_SET_SHMEM 0x7
#define SBI_EXT_PMU_EVENT_GET_INFO 0x8
/* SBI function IDs for DBTR extension */
#define SBI_EXT_DBTR_NUM_TRIGGERS 0x0
#define SBI_EXT_DBTR_SETUP_SHMEM 0x1
#define SBI_EXT_DBTR_TRIGGER_READ 0x2
#define SBI_EXT_DBTR_TRIGGER_INSTALL 0x3
#define SBI_EXT_DBTR_TRIGGER_UPDATE 0x4
#define SBI_EXT_DBTR_TRIGGER_UNINSTALL 0x5
#define SBI_EXT_DBTR_TRIGGER_ENABLE 0x6
#define SBI_EXT_DBTR_TRIGGER_DISABLE 0x7
/* SBI function IDs for FW feature extension */
#define SBI_EXT_FWFT_SET 0x0
#define SBI_EXT_FWFT_GET 0x1
enum sbi_fwft_feature_t {
SBI_FWFT_MISALIGNED_EXC_DELEG = 0x0,
SBI_FWFT_LANDING_PAD = 0x1,
SBI_FWFT_SHADOW_STACK = 0x2,
SBI_FWFT_DOUBLE_TRAP = 0x3,
SBI_FWFT_PTE_AD_HW_UPDATING = 0x4,
SBI_FWFT_POINTER_MASKING_PMLEN = 0x5,
SBI_FWFT_LOCAL_RESERVED_START = 0x6,
SBI_FWFT_LOCAL_RESERVED_END = 0x3fffffff,
SBI_FWFT_LOCAL_PLATFORM_START = 0x40000000,
SBI_FWFT_LOCAL_PLATFORM_END = 0x7fffffff,
SBI_FWFT_GLOBAL_RESERVED_START = 0x80000000,
SBI_FWFT_GLOBAL_RESERVED_END = 0xbfffffff,
SBI_FWFT_GLOBAL_PLATFORM_START = 0xc0000000,
SBI_FWFT_GLOBAL_PLATFORM_END = 0xffffffff,
};
#define SBI_FWFT_GLOBAL_FEATURE_BIT (1 << 31)
#define SBI_FWFT_PLATFORM_FEATURE_BIT (1 << 30)
#define SBI_FWFT_SET_FLAG_LOCK (1 << 0)
/** General pmu event codes specified in SBI PMU extension */
enum sbi_pmu_hw_generic_events_t {
@@ -182,6 +231,17 @@ enum sbi_pmu_fw_event_code_id {
SBI_PMU_FW_HFENCE_VVMA_ASID_SENT = 20,
SBI_PMU_FW_HFENCE_VVMA_ASID_RCVD = 21,
SBI_PMU_FW_MAX,
/*
* Event codes 22 to 255 are reserved for future use.
* Event codes 256 to 65534 are reserved for SBI implementation
* specific custom firmware events.
*/
SBI_PMU_FW_RESERVED_MAX = 0xFFFE,
/*
* Event code 0xFFFF is used for platform specific firmware
* events where the event data contains any event specific information.
*/
SBI_PMU_FW_PLATFORM = 0xFFFF,
};
/** SBI PMU event idx type */
@@ -189,6 +249,7 @@ enum sbi_pmu_event_type_id {
SBI_PMU_EVENT_TYPE_HW = 0x0,
SBI_PMU_EVENT_TYPE_HW_CACHE = 0x1,
SBI_PMU_EVENT_TYPE_HW_RAW = 0x2,
SBI_PMU_EVENT_TYPE_HW_RAW_V2 = 0x3,
SBI_PMU_EVENT_TYPE_FW = 0xf,
SBI_PMU_EVENT_TYPE_MAX,
};
@@ -199,15 +260,28 @@ enum sbi_pmu_ctr_type {
SBI_PMU_CTR_TYPE_FW,
};
struct sbi_pmu_event_info {
uint32_t event_idx;
uint32_t output;
uint64_t event_data;
};
/* Helper macros to decode event idx */
#define SBI_PMU_EVENT_IDX_OFFSET 20
#define SBI_PMU_EVENT_IDX_MASK 0xFFFFF
#define SBI_PMU_EVENT_IDX_TYPE_OFFSET 16
#define SBI_PMU_EVENT_IDX_TYPE_MASK (0xF << SBI_PMU_EVENT_IDX_TYPE_OFFSET)
#define SBI_PMU_EVENT_IDX_CODE_MASK 0xFFFF
#define SBI_PMU_EVENT_IDX_TYPE_MASK 0xF0000
#define SBI_PMU_EVENT_RAW_IDX 0x20000
#define SBI_PMU_EVENT_RAW_V2_IDX 0x30000
#define SBI_PMU_EVENT_IDX_INVALID 0xFFFFFFFF
#define SBI_PMU_EVENT_HW_CACHE_OPS_RESULT 0x1
#define SBI_PMU_EVENT_HW_CACHE_OPS_ID_MASK 0x6
#define SBI_PMU_EVENT_HW_CACHE_OPS_ID_OFFSET 1
#define SBI_PMU_EVENT_HW_CACHE_ID_MASK 0xfff8
#define SBI_PMU_EVENT_HW_CACHE_ID_OFFSET 3
/* Flags defined for config matching function */
#define SBI_PMU_CFG_FLAG_SKIP_MATCH (1 << 0)
#define SBI_PMU_CFG_FLAG_CLEAR_VALUE (1 << 1)
@@ -220,14 +294,178 @@ enum sbi_pmu_ctr_type {
/* Flags defined for counter start function */
#define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
#define SBI_PMU_START_FLAG_INIT_FROM_SNAPSHOT (1 << 1)
/* Flags defined for counter stop function */
#define SBI_PMU_STOP_FLAG_RESET (1 << 0)
#define SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT (1 << 1)
/* SBI function IDs for DBCN extension */
#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
#define SBI_EXT_DBCN_CONSOLE_READ 0x1
#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2
/* SBI function IDs for SUSP extension */
#define SBI_EXT_SUSP_SUSPEND 0x0
#define SBI_SUSP_SLEEP_TYPE_SUSPEND 0x0
#define SBI_SUSP_SLEEP_TYPE_LAST SBI_SUSP_SLEEP_TYPE_SUSPEND
#define SBI_SUSP_PLATFORM_SLEEP_START 0x80000000
/* SBI function IDs for CPPC extension */
#define SBI_EXT_CPPC_PROBE 0x0
#define SBI_EXT_CPPC_READ 0x1
#define SBI_EXT_CPPC_READ_HI 0x2
#define SBI_EXT_CPPC_WRITE 0x3
enum sbi_cppc_reg_id {
SBI_CPPC_HIGHEST_PERF = 0x00000000,
SBI_CPPC_NOMINAL_PERF = 0x00000001,
SBI_CPPC_LOW_NON_LINEAR_PERF = 0x00000002,
SBI_CPPC_LOWEST_PERF = 0x00000003,
SBI_CPPC_GUARANTEED_PERF = 0x00000004,
SBI_CPPC_DESIRED_PERF = 0x00000005,
SBI_CPPC_MIN_PERF = 0x00000006,
SBI_CPPC_MAX_PERF = 0x00000007,
SBI_CPPC_PERF_REDUC_TOLERANCE = 0x00000008,
SBI_CPPC_TIME_WINDOW = 0x00000009,
SBI_CPPC_CTR_WRAP_TIME = 0x0000000A,
SBI_CPPC_REFERENCE_CTR = 0x0000000B,
SBI_CPPC_DELIVERED_CTR = 0x0000000C,
SBI_CPPC_PERF_LIMITED = 0x0000000D,
SBI_CPPC_ENABLE = 0x0000000E,
SBI_CPPC_AUTO_SEL_ENABLE = 0x0000000F,
SBI_CPPC_AUTO_ACT_WINDOW = 0x00000010,
SBI_CPPC_ENERGY_PERF_PREFERENCE = 0x00000011,
SBI_CPPC_REFERENCE_PERF = 0x00000012,
SBI_CPPC_LOWEST_FREQ = 0x00000013,
SBI_CPPC_NOMINAL_FREQ = 0x00000014,
SBI_CPPC_ACPI_LAST = SBI_CPPC_NOMINAL_FREQ,
SBI_CPPC_TRANSITION_LATENCY = 0x80000000,
SBI_CPPC_NON_ACPI_LAST = SBI_CPPC_TRANSITION_LATENCY,
};
/* SBI Function IDs for SSE extension */
#define SBI_EXT_SSE_READ_ATTR 0x00000000
#define SBI_EXT_SSE_WRITE_ATTR 0x00000001
#define SBI_EXT_SSE_REGISTER 0x00000002
#define SBI_EXT_SSE_UNREGISTER 0x00000003
#define SBI_EXT_SSE_ENABLE 0x00000004
#define SBI_EXT_SSE_DISABLE 0x00000005
#define SBI_EXT_SSE_COMPLETE 0x00000006
#define SBI_EXT_SSE_INJECT 0x00000007
#define SBI_EXT_SSE_HART_UNMASK 0x00000008
#define SBI_EXT_SSE_HART_MASK 0x00000009
/* SBI SSE Event Attributes. */
enum sbi_sse_attr_id {
SBI_SSE_ATTR_STATUS = 0x00000000,
SBI_SSE_ATTR_PRIO = 0x00000001,
SBI_SSE_ATTR_CONFIG = 0x00000002,
SBI_SSE_ATTR_PREFERRED_HART = 0x00000003,
SBI_SSE_ATTR_ENTRY_PC = 0x00000004,
SBI_SSE_ATTR_ENTRY_ARG = 0x00000005,
SBI_SSE_ATTR_INTERRUPTED_SEPC = 0x00000006,
SBI_SSE_ATTR_INTERRUPTED_FLAGS = 0x00000007,
SBI_SSE_ATTR_INTERRUPTED_A6 = 0x00000008,
SBI_SSE_ATTR_INTERRUPTED_A7 = 0x00000009,
SBI_SSE_ATTR_MAX = 0x0000000A
};
#define SBI_SSE_ATTR_STATUS_STATE_OFFSET 0
#define SBI_SSE_ATTR_STATUS_STATE_MASK 0x3
#define SBI_SSE_ATTR_STATUS_PENDING_OFFSET 2
#define SBI_SSE_ATTR_STATUS_INJECT_OFFSET 3
#define SBI_SSE_ATTR_CONFIG_ONESHOT (1 << 0)
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPP BIT(0)
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPIE BIT(1)
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPV BIT(2)
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_HSTATUS_SPVP BIT(3)
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SPELP BIT(4)
#define SBI_SSE_ATTR_INTERRUPTED_FLAGS_SSTATUS_SDT BIT(5)
enum sbi_sse_state {
SBI_SSE_STATE_UNUSED = 0,
SBI_SSE_STATE_REGISTERED = 1,
SBI_SSE_STATE_ENABLED = 2,
SBI_SSE_STATE_RUNNING = 3,
};
/* SBI SSE Event IDs. */
/* Range 0x00000000 - 0x0000ffff */
#define SBI_SSE_EVENT_LOCAL_HIGH_PRIO_RAS 0x00000000
#define SBI_SSE_EVENT_LOCAL_DOUBLE_TRAP 0x00000001
#define SBI_SSE_EVENT_LOCAL_RESERVED_0_START 0x00000002
#define SBI_SSE_EVENT_LOCAL_RESERVED_0_END 0x00003fff
#define SBI_SSE_EVENT_LOCAL_PLAT_0_START 0x00004000
#define SBI_SSE_EVENT_LOCAL_PLAT_0_END 0x00007fff
#define SBI_SSE_EVENT_GLOBAL_HIGH_PRIO_RAS 0x00008000
#define SBI_SSE_EVENT_GLOBAL_RESERVED_0_START 0x00008001
#define SBI_SSE_EVENT_GLOBAL_RESERVED_0_END 0x0000bfff
#define SBI_SSE_EVENT_GLOBAL_PLAT_0_START 0x0000c000
#define SBI_SSE_EVENT_GLOBAL_PLAT_0_END 0x0000ffff
/* Range 0x00010000 - 0x0001ffff */
#define SBI_SSE_EVENT_LOCAL_PMU_OVERFLOW 0x00010000
#define SBI_SSE_EVENT_LOCAL_RESERVED_1_START 0x00010001
#define SBI_SSE_EVENT_LOCAL_RESERVED_1_END 0x00013fff
#define SBI_SSE_EVENT_LOCAL_PLAT_1_START 0x00014000
#define SBI_SSE_EVENT_LOCAL_PLAT_1_END 0x00017fff
#define SBI_SSE_EVENT_GLOBAL_RESERVED_1_START 0x00018000
#define SBI_SSE_EVENT_GLOBAL_RESERVED_1_END 0x0001bfff
#define SBI_SSE_EVENT_GLOBAL_PLAT_1_START 0x0001c000
#define SBI_SSE_EVENT_GLOBAL_PLAT_1_END 0x0001ffff
/* Range 0x00100000 - 0x0010ffff */
#define SBI_SSE_EVENT_LOCAL_LOW_PRIO_RAS 0x00100000
#define SBI_SSE_EVENT_LOCAL_RESERVED_2_START 0x00100001
#define SBI_SSE_EVENT_LOCAL_RESERVED_2_END 0x00103fff
#define SBI_SSE_EVENT_LOCAL_PLAT_2_START 0x00104000
#define SBI_SSE_EVENT_LOCAL_PLAT_2_END 0x00107fff
#define SBI_SSE_EVENT_GLOBAL_LOW_PRIO_RAS 0x00108000
#define SBI_SSE_EVENT_GLOBAL_RESERVED_2_START 0x00108001
#define SBI_SSE_EVENT_GLOBAL_RESERVED_2_END 0x0010bfff
#define SBI_SSE_EVENT_GLOBAL_PLAT_2_START 0x0010c000
#define SBI_SSE_EVENT_GLOBAL_PLAT_2_END 0x0010ffff
/* Range 0xffff0000 - 0xffffffff */
#define SBI_SSE_EVENT_LOCAL_SOFTWARE 0xffff0000
#define SBI_SSE_EVENT_LOCAL_RESERVED_3_START 0xffff0001
#define SBI_SSE_EVENT_LOCAL_RESERVED_3_END 0xffff3fff
#define SBI_SSE_EVENT_LOCAL_PLAT_3_START 0xffff4000
#define SBI_SSE_EVENT_LOCAL_PLAT_3_END 0xffff7fff
#define SBI_SSE_EVENT_GLOBAL_SOFTWARE 0xffff8000
#define SBI_SSE_EVENT_GLOBAL_RESERVED_3_START 0xffff8001
#define SBI_SSE_EVENT_GLOBAL_RESERVED_3_END 0xffffbfff
#define SBI_SSE_EVENT_GLOBAL_PLAT_3_START 0xffffc000
#define SBI_SSE_EVENT_GLOBAL_PLAT_3_END 0xffffffff
#define SBI_SSE_EVENT_GLOBAL_BIT BIT(15)
#define SBI_SSE_EVENT_PLATFORM_BIT BIT(14)
/* SBI function IDs for MPXY extension */
#define SBI_EXT_MPXY_GET_SHMEM_SIZE 0x0
#define SBI_EXT_MPXY_SET_SHMEM 0x1
#define SBI_EXT_MPXY_GET_CHANNEL_IDS 0x2
#define SBI_EXT_MPXY_READ_ATTRS 0x3
#define SBI_EXT_MPXY_WRITE_ATTRS 0x4
#define SBI_EXT_MPXY_SEND_MSG_WITH_RESP 0x5
#define SBI_EXT_MPXY_SEND_MSG_WITHOUT_RESP 0x6
#define SBI_EXT_MPXY_GET_NOTIFICATION_EVENTS 0x7
/* SBI base specification related macros */
#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff
#define SBI_EXT_EXPERIMENTAL_START 0x08000000
#define SBI_EXT_EXPERIMENTAL_END 0x08FFFFFF
#define SBI_EXT_VENDOR_START 0x09000000
#define SBI_EXT_VENDOR_END 0x09FFFFFF
#define SBI_EXT_FIRMWARE_START 0x0A000000
@@ -243,8 +481,14 @@ enum sbi_pmu_ctr_type {
#define SBI_ERR_ALREADY_AVAILABLE -6
#define SBI_ERR_ALREADY_STARTED -7
#define SBI_ERR_ALREADY_STOPPED -8
#define SBI_ERR_NO_SHMEM -9
#define SBI_ERR_INVALID_STATE -10
#define SBI_ERR_BAD_RANGE -11
#define SBI_ERR_TIMEOUT -12
#define SBI_ERR_IO -13
#define SBI_ERR_DENIED_LOCKED -14
#define SBI_LAST_ERR SBI_ERR_ALREADY_STOPPED
#define SBI_LAST_ERR SBI_ERR_DENIED_LOCKED
/* clang-format on */

View File

@@ -23,17 +23,21 @@
#define SBI_EALREADY SBI_ERR_ALREADY_AVAILABLE
#define SBI_EALREADY_STARTED SBI_ERR_ALREADY_STARTED
#define SBI_EALREADY_STOPPED SBI_ERR_ALREADY_STOPPED
#define SBI_ENO_SHMEM SBI_ERR_NO_SHMEM
#define SBI_EINVALID_STATE SBI_ERR_INVALID_STATE
#define SBI_EBAD_RANGE SBI_ERR_BAD_RANGE
#define SBI_ETIMEOUT SBI_ERR_TIMEOUT
#define SBI_ETIMEDOUT SBI_ERR_TIMEOUT
#define SBI_EIO SBI_ERR_IO
#define SBI_EDENIED_LOCKED SBI_ERR_DENIED_LOCKED
#define SBI_ENODEV -1000
#define SBI_ENOSYS -1001
#define SBI_ETIMEDOUT -1002
#define SBI_EIO -1003
#define SBI_EILL -1004
#define SBI_ENOSPC -1005
#define SBI_ENOMEM -1006
#define SBI_ETRAP -1007
#define SBI_EUNKNOWN -1008
#define SBI_ENOENT -1009
#define SBI_EILL -1002
#define SBI_ENOSPC -1003
#define SBI_ENOMEM -1004
#define SBI_EUNKNOWN -1005
#define SBI_ENOENT -1006
/* clang-format on */

View File

@@ -23,6 +23,18 @@ struct sbi_fifo {
u16 tail;
};
#define SBI_FIFO_INITIALIZER(__queue_mem, __entries, __entry_size) \
{ .queue = __queue_mem, \
.qlock = SPIN_LOCK_INITIALIZER, \
.num_entries = __entries, \
.entry_size = __entry_size, \
.avail = 0, \
.tail = 0, \
}
#define SBI_FIFO_DEFINE(__name, __queue_mem, __entries, __entry_size) \
struct sbi_fifo __name = SBI_FIFO_INITIALIZER(__queue_mem, __entries, __entry_size)
enum sbi_fifo_inplace_update_types {
SBI_FIFO_SKIP,
SBI_FIFO_UPDATED,
@@ -30,7 +42,7 @@ enum sbi_fifo_inplace_update_types {
};
int sbi_fifo_dequeue(struct sbi_fifo *fifo, void *data);
int sbi_fifo_enqueue(struct sbi_fifo *fifo, void *data);
int sbi_fifo_enqueue(struct sbi_fifo *fifo, void *data, bool force);
void sbi_fifo_init(struct sbi_fifo *fifo, void *queue_mem, u16 entries,
u16 entry_size);
int sbi_fifo_is_empty(struct sbi_fifo *fifo);

23
include/sbi/sbi_fwft.h Normal file
View File

@@ -0,0 +1,23 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2024 Rivos Inc.
*
* Authors:
* Clément Léger <cleger@rivosinc.com>
*/
#ifndef __SBI_FW_FEATURE_H__
#define __SBI_FW_FEATURE_H__
#include <sbi/sbi_ecall_interface.h>
struct sbi_scratch;
int sbi_fwft_set(enum sbi_fwft_feature_t feature, unsigned long value,
unsigned long flags);
int sbi_fwft_get(enum sbi_fwft_feature_t feature, unsigned long *out_val);
int sbi_fwft_init(struct sbi_scratch *scratch, bool cold_boot);
#endif

View File

@@ -11,22 +11,121 @@
#define __SBI_HART_H__
#include <sbi/sbi_types.h>
#include <sbi/sbi_bitops.h>
/** Possible feature flags of a hart */
enum sbi_hart_features {
/** Hart has S-mode counter enable */
SBI_HART_HAS_SCOUNTEREN = (1 << 0),
/** Hart has M-mode counter enable */
SBI_HART_HAS_MCOUNTEREN = (1 << 1),
/** Hart has counter inhibit CSR */
SBI_HART_HAS_MCOUNTINHIBIT = (1 << 2),
/** Hart has sscofpmf extension */
SBI_HART_HAS_SSCOFPMF = (1 << 3),
/** HART has timer csr implementation in hardware */
SBI_HART_HAS_TIME = (1 << 4),
/** Possible privileged specification versions of a hart */
enum sbi_hart_priv_versions {
/** Unknown privileged specification */
SBI_HART_PRIV_VER_UNKNOWN = 0,
/** Privileged specification v1.10 */
SBI_HART_PRIV_VER_1_10 = 1,
/** Privileged specification v1.11 */
SBI_HART_PRIV_VER_1_11 = 2,
/** Privileged specification v1.12 */
SBI_HART_PRIV_VER_1_12 = 3,
};
/** Last index of Hart features*/
SBI_HART_HAS_LAST_FEATURE = SBI_HART_HAS_TIME,
/** Possible ISA extensions of a hart */
enum sbi_hart_extensions {
/** HART has AIA M-mode CSRs */
SBI_HART_EXT_SMAIA = 0,
/** HART has Smepmp */
SBI_HART_EXT_SMEPMP,
/** HART has Smstateen extension **/
SBI_HART_EXT_SMSTATEEN,
/** Hart has Sscofpmt extension */
SBI_HART_EXT_SSCOFPMF,
/** HART has Sstc extension */
SBI_HART_EXT_SSTC,
/** HART has Zicntr extension (i.e. HW cycle, time & instret CSRs) */
SBI_HART_EXT_ZICNTR,
/** HART has Zihpm extension */
SBI_HART_EXT_ZIHPM,
/** HART has Zkr extension */
SBI_HART_EXT_ZKR,
/** Hart has Smcntrpmf extension */
SBI_HART_EXT_SMCNTRPMF,
/** Hart has Xandespmu extension */
SBI_HART_EXT_XANDESPMU,
/** Hart has Zicboz extension */
SBI_HART_EXT_ZICBOZ,
/** Hart has Zicbom extension */
SBI_HART_EXT_ZICBOM,
/** Hart has Svpbmt extension */
SBI_HART_EXT_SVPBMT,
/** Hart has debug trigger extension */
SBI_HART_EXT_SDTRIG,
/** Hart has Smcsrind extension */
SBI_HART_EXT_SMCSRIND,
/** Hart has Smcdeleg extension */
SBI_HART_EXT_SMCDELEG,
/** Hart has Sscsrind extension */
SBI_HART_EXT_SSCSRIND,
/** Hart has Ssccfg extension */
SBI_HART_EXT_SSCCFG,
/** Hart has Svade extension */
SBI_HART_EXT_SVADE,
/** Hart has Svadu extension */
SBI_HART_EXT_SVADU,
/** Hart has Smnpm extension */
SBI_HART_EXT_SMNPM,
/** HART has zicfilp extension */
SBI_HART_EXT_ZICFILP,
/** HART has zicfiss extension */
SBI_HART_EXT_ZICFISS,
/** Hart has Ssdbltrp extension */
SBI_HART_EXT_SSDBLTRP,
/** HART has CTR M-mode CSRs */
SBI_HART_EXT_SMCTR,
/** HART has CTR S-mode CSRs */
SBI_HART_EXT_SSCTR,
/** HART has Ssstateen extension **/
SBI_HART_EXT_SSSTATEEN,
/** Maximum index of Hart extension */
SBI_HART_EXT_MAX,
};
struct sbi_hart_ext_data {
const unsigned int id;
const char *name;
};
extern const struct sbi_hart_ext_data sbi_hart_ext[];
/** CSRs should be detected by access and trapping */
enum sbi_hart_csrs {
SBI_HART_CSR_CYCLE = 0,
SBI_HART_CSR_TIME,
SBI_HART_CSR_INSTRET,
SBI_HART_CSR_MAX,
};
/*
* Smepmp enforces access boundaries between M-mode and
* S/U-mode. When it is enabled, the PMPs are programmed
* such that M-mode doesn't have access to S/U-mode memory.
*
* To give M-mode R/W access to the shared memory between M and
* S/U-mode, first entry is reserved. It is disabled at boot.
* When shared memory access is required, the physical address
* should be programmed into the first PMP entry with R/W
* permissions to the M-mode. Once the work is done, it should be
* unmapped. sbi_hart_map_saddr/sbi_hart_unmap_saddr function
* pair should be used to map/unmap the shared memory.
*/
#define SBI_SMEPMP_RESV_ENTRY 0
struct sbi_hart_features {
bool detected;
int priv_version;
unsigned long extensions[BITS_TO_LONGS(SBI_HART_EXT_MAX)];
unsigned long csrs[BITS_TO_LONGS(SBI_HART_CSR_MAX)];
unsigned int pmp_count;
unsigned int pmp_addr_bits;
unsigned int pmp_log2gran;
unsigned int mhpm_mask;
unsigned int mhpm_bits;
};
struct sbi_scratch;
@@ -35,22 +134,28 @@ int sbi_hart_reinit(struct sbi_scratch *scratch);
int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot);
extern void (*sbi_hart_expected_trap)(void);
static inline ulong sbi_hart_expected_trap_addr(void)
{
return (ulong)sbi_hart_expected_trap;
}
unsigned int sbi_hart_mhpm_count(struct sbi_scratch *scratch);
unsigned int sbi_hart_mhpm_mask(struct sbi_scratch *scratch);
void sbi_hart_delegation_dump(struct sbi_scratch *scratch,
const char *prefix, const char *suffix);
unsigned int sbi_hart_pmp_count(struct sbi_scratch *scratch);
unsigned long sbi_hart_pmp_granularity(struct sbi_scratch *scratch);
unsigned int sbi_hart_pmp_log2gran(struct sbi_scratch *scratch);
unsigned int sbi_hart_pmp_addrbits(struct sbi_scratch *scratch);
unsigned int sbi_hart_mhpm_bits(struct sbi_scratch *scratch);
int sbi_hart_pmp_configure(struct sbi_scratch *scratch);
bool sbi_hart_has_feature(struct sbi_scratch *scratch, unsigned long feature);
void sbi_hart_get_features_str(struct sbi_scratch *scratch,
char *features_str, int nfstr);
int sbi_hart_map_saddr(unsigned long base, unsigned long size);
int sbi_hart_unmap_saddr(void);
int sbi_hart_priv_version(struct sbi_scratch *scratch);
void sbi_hart_get_priv_version_str(struct sbi_scratch *scratch,
char *version_str, int nvstr);
void sbi_hart_update_extension(struct sbi_scratch *scratch,
enum sbi_hart_extensions ext,
bool enable);
bool sbi_hart_has_extension(struct sbi_scratch *scratch,
enum sbi_hart_extensions ext);
void sbi_hart_get_extensions_str(struct sbi_scratch *scratch,
char *extension_str, int nestr);
bool sbi_hart_has_csr(struct sbi_scratch *scratch, enum sbi_hart_csrs csr);
void __attribute__((noreturn)) sbi_hart_hang(void);

View File

@@ -11,6 +11,7 @@
#define __SBI_HARTMASK_H__
#include <sbi/sbi_bitmap.h>
#include <sbi/sbi_scratch.h>
/**
* Maximum number of bits in a hartmask
@@ -32,7 +33,10 @@ struct sbi_hartmask {
/** Initialize hartmask to zero except a particular HART id */
#define SBI_HARTMASK_INIT_EXCEPT(__m, __h) \
bitmap_zero_except(((__m)->bits), (__h), SBI_HARTMASK_MAX_BITS)
do { \
u32 __i = sbi_hartid_to_hartindex(__h); \
bitmap_zero_except(((__m)->bits), __i, SBI_HARTMASK_MAX_BITS); \
} while(0)
/**
* Get underlying bitmap of hartmask
@@ -41,37 +45,68 @@ struct sbi_hartmask {
#define sbi_hartmask_bits(__m) ((__m)->bits)
/**
* Set a HART in hartmask
* Set a HART index in hartmask
* @param i HART index to set
* @param m the hartmask pointer
*/
static inline void sbi_hartmask_set_hartindex(u32 i, struct sbi_hartmask *m)
{
if (i < SBI_HARTMASK_MAX_BITS)
__set_bit(i, m->bits);
}
/**
* Set a HART id in hartmask
* @param h HART id to set
* @param m the hartmask pointer
*/
static inline void sbi_hartmask_set_hart(u32 h, struct sbi_hartmask *m)
static inline void sbi_hartmask_set_hartid(u32 h, struct sbi_hartmask *m)
{
if (h < SBI_HARTMASK_MAX_BITS)
__set_bit(h, m->bits);
sbi_hartmask_set_hartindex(sbi_hartid_to_hartindex(h), m);
}
/**
* Clear a HART in hartmask
* Clear a HART index in hartmask
* @param i HART index to clear
* @param m the hartmask pointer
*/
static inline void sbi_hartmask_clear_hartindex(u32 i, struct sbi_hartmask *m)
{
if (i < SBI_HARTMASK_MAX_BITS)
__clear_bit(i, m->bits);
}
/**
* Clear a HART id in hartmask
* @param h HART id to clear
* @param m the hartmask pointer
*/
static inline void sbi_hartmask_clear_hart(u32 h, struct sbi_hartmask *m)
static inline void sbi_hartmask_clear_hartid(u32 h, struct sbi_hartmask *m)
{
if (h < SBI_HARTMASK_MAX_BITS)
__clear_bit(h, m->bits);
sbi_hartmask_clear_hartindex(sbi_hartid_to_hartindex(h), m);
}
/**
* Test a HART in hartmask
* Test a HART index in hartmask
* @param i HART index to test
* @param m the hartmask pointer
*/
static inline int sbi_hartmask_test_hartindex(u32 i,
const struct sbi_hartmask *m)
{
if (i < SBI_HARTMASK_MAX_BITS)
return __test_bit(i, m->bits);
return 0;
}
/**
* Test a HART id in hartmask
* @param h HART id to test
* @param m the hartmask pointer
*/
static inline int sbi_hartmask_test_hart(u32 h, const struct sbi_hartmask *m)
static inline int sbi_hartmask_test_hartid(u32 h, const struct sbi_hartmask *m)
{
if (h < SBI_HARTMASK_MAX_BITS)
return __test_bit(h, m->bits);
return 0;
return sbi_hartmask_test_hartindex(sbi_hartid_to_hartindex(h), m);
}
/**
@@ -92,6 +127,18 @@ static inline void sbi_hartmask_clear_all(struct sbi_hartmask *dstp)
bitmap_zero(sbi_hartmask_bits(dstp), SBI_HARTMASK_MAX_BITS);
}
/**
* *dstp = *srcp
* @param dstp the hartmask destination
* @param srcp the hartmask source
*/
static inline void sbi_hartmask_copy(struct sbi_hartmask *dstp,
const struct sbi_hartmask *srcp)
{
bitmap_copy(sbi_hartmask_bits(dstp), sbi_hartmask_bits(srcp),
SBI_HARTMASK_MAX_BITS);
}
/**
* *dstp = *src1p & *src2p
* @param dstp the hartmask result
@@ -134,8 +181,25 @@ static inline void sbi_hartmask_xor(struct sbi_hartmask *dstp,
sbi_hartmask_bits(src2p), SBI_HARTMASK_MAX_BITS);
}
/** Iterate over each HART in hartmask */
#define sbi_hartmask_for_each_hart(__h, __m) \
for_each_set_bit(__h, (__m)->bits, SBI_HARTMASK_MAX_BITS)
/**
* Count of bits in *srcp
* @param srcp the hartmask to count bits in
*
* Return: count of bits set in *srcp
*/
static inline int sbi_hartmask_weight(const struct sbi_hartmask *srcp)
{
return bitmap_weight(sbi_hartmask_bits(srcp), SBI_HARTMASK_MAX_BITS);
}
/**
* Iterate over each HART index in hartmask
* __i hart index
* __m hartmask
*/
#define sbi_hartmask_for_each_hartindex(__i, __m) \
for((__i) = find_first_bit((__m)->bits, SBI_HARTMASK_MAX_BITS); \
(__i) < SBI_HARTMASK_MAX_BITS; \
(__i) = find_next_bit((__m)->bits, SBI_HARTMASK_MAX_BITS, (__i) + 1))
#endif

101
include/sbi/sbi_heap.h Normal file
View File

@@ -0,0 +1,101 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2023 Ventana Micro Systems Inc.
*
* Authors:
* Anup Patel<apatel@ventanamicro.com>
*/
#ifndef __SBI_HEAP_H__
#define __SBI_HEAP_H__
#include <sbi/sbi_types.h>
/* Opaque declaration of heap control struct */
struct sbi_heap_control;
/* Global heap control structure */
extern struct sbi_heap_control global_hpctrl;
/* Alignment of heap base address and size */
#define HEAP_BASE_ALIGN 1024
struct sbi_scratch;
/** Allocate from heap area */
void *sbi_malloc_from(struct sbi_heap_control *hpctrl, size_t size);
static inline void *sbi_malloc(size_t size)
{
return sbi_malloc_from(&global_hpctrl, size);
}
/** Allocate aligned from heap area */
void *sbi_aligned_alloc_from(struct sbi_heap_control *hpctrl,
size_t alignment,size_t size);
static inline void *sbi_aligned_alloc(size_t alignment, size_t size)
{
return sbi_aligned_alloc_from(&global_hpctrl, alignment, size);
}
/** Zero allocate from heap area */
void *sbi_zalloc_from(struct sbi_heap_control *hpctrl, size_t size);
static inline void *sbi_zalloc(size_t size)
{
return sbi_zalloc_from(&global_hpctrl, size);
}
/** Allocate array from heap area */
static inline void *sbi_calloc(size_t nitems, size_t size)
{
return sbi_zalloc(nitems * size);
}
static inline void *sbi_calloc_from(struct sbi_heap_control *hpctrl,
size_t nitems, size_t size)
{
return sbi_zalloc_from(hpctrl, nitems * size);
}
/** Free-up to heap area */
void sbi_free_from(struct sbi_heap_control *hpctrl, void *ptr);
static inline void sbi_free(void *ptr)
{
return sbi_free_from(&global_hpctrl, ptr);
}
/** Amount (in bytes) of free space in the heap area */
unsigned long sbi_heap_free_space_from(struct sbi_heap_control *hpctrl);
static inline unsigned long sbi_heap_free_space(void)
{
return sbi_heap_free_space_from(&global_hpctrl);
}
/** Amount (in bytes) of used space in the heap area */
unsigned long sbi_heap_used_space_from(struct sbi_heap_control *hpctrl);
static inline unsigned long sbi_heap_used_space(void)
{
return sbi_heap_used_space_from(&global_hpctrl);
}
/** Amount (in bytes) of reserved space in the heap area */
unsigned long sbi_heap_reserved_space_from(struct sbi_heap_control *hpctrl);
static inline unsigned long sbi_heap_reserved_space(void)
{
return sbi_heap_reserved_space_from(&global_hpctrl);
}
/** Initialize heap area */
int sbi_heap_init(struct sbi_scratch *scratch);
int sbi_heap_init_new(struct sbi_heap_control *hpctrl, unsigned long base,
unsigned long size);
int sbi_heap_alloc_new(struct sbi_heap_control **hpctrl);
#endif

View File

@@ -10,6 +10,7 @@
#ifndef __SBI_HSM_H__
#define __SBI_HSM_H__
#include <sbi/sbi_hartmask.h>
#include <sbi/sbi_types.h>
/** Hart state managment device */
@@ -21,8 +22,12 @@ struct sbi_hsm_device {
int (*hart_start)(u32 hartid, ulong saddr);
/**
* Stop (or power-down) the current hart from running. This call
* doesn't expect to return if success.
* Stop (or power-down) the current hart from running.
*
* Return SBI_ENOTSUPP if the hart does not support platform-specific
* stop actions.
*
* For successful stop, the call won't return.
*/
int (*hart_stop)(void);
@@ -34,9 +39,21 @@ struct sbi_hsm_device {
* the hart resumes normal execution.
*
* For successful non-retentive suspend, the hart will resume from
* specified resume address
* the warm boot entry point.
*
* NOTE: mmode_resume_addr(resume address) is optional hence it
* may or may not be honored by the platform. If its not honored
* then platform must ensure to resume from the warmboot address.
*/
int (*hart_suspend)(u32 suspend_type, ulong raddr);
int (*hart_suspend)(u32 suspend_type, ulong mmode_resume_addr);
/**
* Perform platform-specific actions to resume from a suspended state.
*
* This includes restoring any platform state that was lost during
* non-retentive suspend.
*/
void (*hart_resume)(void);
};
struct sbi_domain;
@@ -46,20 +63,26 @@ const struct sbi_hsm_device *sbi_hsm_get_device(void);
void sbi_hsm_set_device(const struct sbi_hsm_device *dev);
int sbi_hsm_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot);
int sbi_hsm_init(struct sbi_scratch *scratch, bool cold_boot);
void __noreturn sbi_hsm_exit(struct sbi_scratch *scratch);
int sbi_hsm_hart_start(struct sbi_scratch *scratch,
const struct sbi_domain *dom,
u32 hartid, ulong saddr, ulong smode, ulong priv);
u32 hartid, ulong saddr, ulong smode, ulong arg1);
int sbi_hsm_hart_stop(struct sbi_scratch *scratch, bool exitnow);
void sbi_hsm_hart_resume_start(struct sbi_scratch *scratch);
void sbi_hsm_hart_resume_finish(struct sbi_scratch *scratch);
void __noreturn sbi_hsm_hart_resume_finish(struct sbi_scratch *scratch,
u32 hartid);
int sbi_hsm_hart_suspend(struct sbi_scratch *scratch, u32 suspend_type,
ulong raddr, ulong rmode, ulong priv);
ulong raddr, ulong rmode, ulong arg1);
bool sbi_hsm_hart_change_state(struct sbi_scratch *scratch, long oldstate,
long newstate);
int __sbi_hsm_hart_get_state(u32 hartindex);
int sbi_hsm_hart_get_state(const struct sbi_domain *dom, u32 hartid);
int sbi_hsm_hart_interruptible_mask(const struct sbi_domain *dom,
ulong hbase, ulong *out_hmask);
void sbi_hsm_prepare_next_jump(struct sbi_scratch *scratch, u32 hartid);
struct sbi_hartmask *mask);
void __sbi_hsm_suspend_non_ret_save(struct sbi_scratch *scratch);
void __noreturn sbi_hsm_hart_start_finish(struct sbi_scratch *scratch,
u32 hartid);
#endif

View File

@@ -0,0 +1,17 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2025 MIPS
*
*/
#ifndef __SBI_ILLEGAL_ATOMIC_H__
#define __SBI_ILLEGAL_ATOMIC_H__
#include <sbi/sbi_types.h>
struct sbi_trap_regs;
int sbi_illegal_atomic(ulong insn, struct sbi_trap_regs *regs);
#endif

View File

@@ -12,8 +12,12 @@
#include <sbi/sbi_types.h>
struct sbi_trap_regs;
struct sbi_trap_context;
int sbi_illegal_insn_handler(ulong insn, struct sbi_trap_regs *regs);
typedef int (*illegal_insn_func)(ulong insn, struct sbi_trap_regs *regs);
int truly_illegal_insn(ulong insn, struct sbi_trap_regs *regs);
int sbi_illegal_insn_handler(struct sbi_trap_context *tcntx);
#endif

View File

@@ -16,7 +16,11 @@ struct sbi_scratch;
void __noreturn sbi_init(struct sbi_scratch *scratch);
unsigned long sbi_init_count(u32 hartid);
void sbi_revert_entry_count(struct sbi_scratch *scratch);
unsigned long sbi_entry_count(u32 hartindex);
unsigned long sbi_init_count(u32 hartindex);
void __noreturn sbi_exit(struct sbi_scratch *scratch);

View File

@@ -14,7 +14,7 @@
/* clang-format off */
#define SBI_IPI_EVENT_MAX __riscv_xlen
#define SBI_IPI_EVENT_MAX (8 * __SIZEOF_LONG__)
/* clang-format on */
@@ -23,11 +23,17 @@ struct sbi_ipi_device {
/** Name of the IPI device */
char name[32];
/** Send IPI to a target HART */
void (*ipi_send)(u32 target_hart);
/** Send IPI to a target HART index */
void (*ipi_send)(u32 hart_index);
/** Clear IPI for a target HART */
void (*ipi_clear)(u32 target_hart);
/** Clear IPI for the current hart */
void (*ipi_clear)(void);
};
enum sbi_ipi_update_type {
SBI_IPI_UPDATE_SUCCESS,
SBI_IPI_UPDATE_BREAK,
SBI_IPI_UPDATE_RETRY,
};
struct sbi_scratch;
@@ -41,10 +47,14 @@ struct sbi_ipi_event_ops {
* Update callback to save/enqueue data for remote HART
* Note: This is an optional callback and it is called just before
* triggering IPI to remote HART.
* @return < 0, error or failure
* @return SBI_IPI_UPDATE_SUCCESS, success
* @return SBI_IPI_UPDATE_BREAK, break IPI, done on local hart
* @return SBI_IPI_UPDATE_RETRY, need retry
*/
int (* update)(struct sbi_scratch *scratch,
struct sbi_scratch *remote_scratch,
u32 remote_hartid, void *data);
u32 remote_hartindex, void *data);
/**
* Sync callback to wait for remote HART
@@ -75,7 +85,9 @@ int sbi_ipi_send_halt(ulong hmask, ulong hbase);
void sbi_ipi_process(void);
void sbi_ipi_raw_send(u32 target_hart);
int sbi_ipi_raw_send(u32 hartindex);
void sbi_ipi_raw_clear(void);
const struct sbi_ipi_device *sbi_ipi_get_device(void);

49
include/sbi/sbi_irqchip.h Normal file
View File

@@ -0,0 +1,49 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2022 Ventana Micro Systems Inc.
*
* Authors:
* Anup Patel <apatel@ventanamicro.com>
*/
#ifndef __SBI_IRQCHIP_H__
#define __SBI_IRQCHIP_H__
#include <sbi/sbi_list.h>
#include <sbi/sbi_types.h>
struct sbi_scratch;
/** irqchip hardware device */
struct sbi_irqchip_device {
/** Node in the list of irqchip devices */
struct sbi_dlist node;
/** Initialize per-hart state for the current hart */
int (*warm_init)(struct sbi_irqchip_device *dev);
/** Handle an IRQ from this irqchip */
int (*irq_handle)(void);
};
/**
* Process external interrupts
*
* This function is called by sbi_trap_handler() to handle external
* interrupts.
*
* @param regs pointer for trap registers
*/
int sbi_irqchip_process(void);
/** Register an irqchip device to receive callbacks */
void sbi_irqchip_add_device(struct sbi_irqchip_device *dev);
/** Initialize interrupt controllers */
int sbi_irqchip_init(struct sbi_scratch *scratch, bool cold_boot);
/** Exit interrupt controllers */
void sbi_irqchip_exit(struct sbi_scratch *scratch);
#endif

View File

@@ -31,7 +31,7 @@ struct sbi_dlist _lname = SBI_LIST_HEAD_INIT(_lname)
#define SBI_INIT_LIST_HEAD(ptr) \
do { \
(ptr)->next = ptr; (ptr)->prev = ptr; \
} while (0);
} while (0)
static inline void __sbi_list_add(struct sbi_dlist *new,
struct sbi_dlist *prev,
@@ -47,7 +47,7 @@ static inline void __sbi_list_add(struct sbi_dlist *new,
* Checks if the list is empty or not.
* @param head List head
*
* Retruns TRUE if list is empty, FALSE otherwise.
* Returns true if list is empty, false otherwise.
*/
static inline bool sbi_list_empty(struct sbi_dlist *head)
{
@@ -160,4 +160,17 @@ static inline void sbi_list_del_init(struct sbi_dlist *entry)
&pos->member != (head); \
pos = sbi_list_entry(pos->member.next, typeof(*pos), member))
/**
* Iterate over list of given type safe against removal of list entry
* @param pos the type * to use as a loop cursor.
* @param n another type * to use as temporary storage.
* @param head the head for your list.
* @param member the name of the list_struct within the struct.
*/
#define sbi_list_for_each_entry_safe(pos, n, head, member) \
for (pos = sbi_list_entry((head)->next, typeof(*pos), member), \
n = sbi_list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = sbi_list_entry(pos->member.next, typeof(*pos), member))
#endif

View File

@@ -1,23 +0,0 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __SBI_MISALIGNED_LDST_H__
#define __SBI_MISALIGNED_LDST_H__
#include <sbi/sbi_types.h>
struct sbi_trap_regs;
int sbi_misaligned_load_handler(ulong addr, ulong tval2, ulong tinst,
struct sbi_trap_regs *regs);
int sbi_misaligned_store_handler(ulong addr, ulong tval2, ulong tinst,
struct sbi_trap_regs *regs);
#endif

185
include/sbi/sbi_mpxy.h Normal file
View File

@@ -0,0 +1,185 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2024 Ventana Micro Systems Inc.
*
* Authors:
* Rahul Pathak <rpathak@ventanamicro.com>
*/
#ifndef __SBI_MPXY_H__
#define __SBI_MPXY_H__
#include <sbi/sbi_list.h>
struct sbi_scratch;
#define SBI_MPXY_MSGPROTO_VERSION(Major, Minor) ((Major << 16) | Minor)
enum sbi_mpxy_attr_id {
/* Standard channel attributes managed by MPXY framework */
SBI_MPXY_ATTR_MSG_PROT_ID = 0x00000000,
SBI_MPXY_ATTR_MSG_PROT_VER = 0x00000001,
SBI_MPXY_ATTR_MSG_MAX_LEN = 0x00000002,
SBI_MPXY_ATTR_MSG_SEND_TIMEOUT = 0x00000003,
SBI_MPXY_ATTR_MSG_COMPLETION_TIMEOUT = 0x00000004,
SBI_MPXY_ATTR_CHANNEL_CAPABILITY = 0x00000005,
SBI_MPXY_ATTR_SSE_EVENT_ID = 0x00000006,
SBI_MPXY_ATTR_MSI_CONTROL = 0x00000007,
SBI_MPXY_ATTR_MSI_ADDR_LO = 0x00000008,
SBI_MPXY_ATTR_MSI_ADDR_HI = 0x00000009,
SBI_MPXY_ATTR_MSI_DATA = 0x0000000A,
SBI_MPXY_ATTR_EVENTS_STATE_CONTROL = 0x0000000B,
SBI_MPXY_ATTR_STD_ATTR_MAX_IDX,
/* Message protocol specific attributes, managed by
* message protocol driver */
SBI_MPXY_ATTR_MSGPROTO_ATTR_START = 0x80000000,
SBI_MPXY_ATTR_MSGPROTO_ATTR_END = 0xffffffff
};
/**
* SBI MPXY Message Protocol IDs
*/
enum sbi_mpxy_msgproto_id {
SBI_MPXY_MSGPROTO_RPMI_ID = 0x00000000,
SBI_MPXY_MSGPROTO_MAX_IDX,
/** Vendor specific message protocol IDs */
SBI_MPXY_MSGPROTO_VENDOR_START = 0x80000000,
SBI_MPXY_MSGPROTO_VENDOR_END = 0xffffffff
};
enum SBI_EXT_MPXY_SHMEM_FLAGS {
SBI_EXT_MPXY_SHMEM_FLAG_OVERWRITE = 0b00,
SBI_EXT_MPXY_SHMEM_FLAG_OVERWRITE_RETURN = 0b01,
SBI_EXT_MPXY_SHMEM_FLAG_MAX_IDX
};
struct sbi_mpxy_msi_info {
/* MSI target address low 32-bit */
u32 msi_addr_lo;
/* MSI target address high 32-bit */
u32 msi_addr_hi;
/* MSI data */
u32 msi_data;
};
/**
* Channel attributes.
* NOTE: The sequence of attribute fields are as per the
* defined sequence in the attribute table in spec(or as
* per the enum sbi_mpxy_attr_id).
*/
struct sbi_mpxy_channel_attrs {
/* Message protocol ID */
u32 msg_proto_id;
/* Message protocol Version */
u32 msg_proto_version;
/* Message protocol maximum message data length(bytes) */
u32 msg_data_maxlen;
/* Message protocol message send timeout
* in microseconds */
u32 msg_send_timeout;
/* Message protocol message response timeout in
* microseconds. Its the aggregate of msg_send_timeout
* and the timeout in receiving the response */
u32 msg_completion_timeout;
/* Bit array for channel capabilities */
u32 capability;
u32 sse_event_id;
u32 msi_control;
struct sbi_mpxy_msi_info msi_info;
/* Events State Control */
u32 eventsstate_ctrl;
};
/** A Message proxy channel accessible through SBI interface */
struct sbi_mpxy_channel {
/** List head to a set of channels */
struct sbi_dlist head;
u32 channel_id;
struct sbi_mpxy_channel_attrs attrs;
/**
* Read message protocol attributes
* NOTE: inmem requires little-endian byte-ordering
*/
int (*read_attributes)(struct sbi_mpxy_channel *channel,
u32 *outmem,
u32 base_attr_id,
u32 attr_count);
/**
* Write message protocol attributes
* NOTE: outmem requires little-endian byte-ordering
*/
int (*write_attributes)(struct sbi_mpxy_channel *channel,
u32 *inmem,
u32 base_attr_id,
u32 attr_count);
/**
* Send a message and wait for response
* NOTE: msgbuf requires little-endian byte-ordering
*/
int (*send_message_with_response)(struct sbi_mpxy_channel *channel,
u32 msg_id, void *msgbuf, u32 msg_len,
void *respbuf, u32 resp_max_len,
unsigned long *resp_len);
/** Send message without response */
int (*send_message_without_response)(struct sbi_mpxy_channel *channel,
u32 msg_id, void *msgbuf, u32 msg_len);
/**
* Get notifications events if supported on a channel
* NOTE: eventsbuf requires little-endian byte-ordering
*/
int (*get_notification_events)(struct sbi_mpxy_channel *channel,
void *eventsbuf, u32 bufsize,
unsigned long *events_len);
/**
* Callback to enable the events state reporting
* in the message protocol implementation
*/
void (*switch_eventsstate)(u32 enable);
};
/** Register a Message proxy channel */
int sbi_mpxy_register_channel(struct sbi_mpxy_channel *channel);
/** Initialize Message proxy subsystem */
int sbi_mpxy_init(struct sbi_scratch *scratch);
/** Check if some Message proxy channel is available */
bool sbi_mpxy_channel_available(void);
/** Get message proxy shared memory size */
unsigned long sbi_mpxy_get_shmem_size(void);
/** Set message proxy shared memory on the calling HART */
int sbi_mpxy_set_shmem(unsigned long shmem_phys_lo,
unsigned long shmem_phys_hi,
unsigned long flags);
/** Get channel IDs list */
int sbi_mpxy_get_channel_ids(u32 start_index);
/** Read MPXY channel attributes */
int sbi_mpxy_read_attrs(u32 channel_id, u32 base_attr_id, u32 attr_count);
/** Write MPXY channel attributes */
int sbi_mpxy_write_attrs(u32 channel_id, u32 base_attr_id, u32 attr_count);
/**
* Send a message over a MPXY channel.
* In case if response is not expected, resp_data_len will be NULL.
*/
int sbi_mpxy_send_message(u32 channel_id, u8 msg_id,
unsigned long msg_data_len,
unsigned long *resp_data_len);
/** Get Message proxy notification events */
int sbi_mpxy_get_notification_events(u32 channel_id,
unsigned long *events_len);
#endif

View File

@@ -29,12 +29,18 @@
#define SBI_PLATFORM_HART_COUNT_OFFSET (0x50)
/** Offset of hart_stack_size in struct sbi_platform */
#define SBI_PLATFORM_HART_STACK_SIZE_OFFSET (0x54)
/** Offset of heap_size in struct sbi_platform */
#define SBI_PLATFORM_HEAP_SIZE_OFFSET (0x58)
/** Offset of reserved in struct sbi_platform */
#define SBI_PLATFORM_RESERVED_OFFSET (0x5c)
/** Offset of platform_ops_addr in struct sbi_platform */
#define SBI_PLATFORM_OPS_OFFSET (0x58)
#define SBI_PLATFORM_OPS_OFFSET (0x60)
/** Offset of firmware_context in struct sbi_platform */
#define SBI_PLATFORM_FIRMWARE_CONTEXT_OFFSET (0x58 + __SIZEOF_POINTER__)
#define SBI_PLATFORM_FIRMWARE_CONTEXT_OFFSET (0x60 + __SIZEOF_POINTER__)
/** Offset of hart_index2id in struct sbi_platform */
#define SBI_PLATFORM_HART_INDEX2ID_OFFSET (0x58 + (__SIZEOF_POINTER__ * 2))
#define SBI_PLATFORM_HART_INDEX2ID_OFFSET (0x60 + (__SIZEOF_POINTER__ * 2))
/** Offset of cbom_block_size in struct sbi_platform */
#define SBI_PLATFORM_CBOM_BLOCK_SIZE_OFFSET (0x60 + (__SIZEOF_POINTER__ * 3))
#define SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT (1UL << 12)
@@ -44,10 +50,13 @@
#include <sbi/sbi_error.h>
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_version.h>
#include <sbi/sbi_trap_ldst.h>
struct sbi_domain_memregion;
struct sbi_trap_info;
struct sbi_ecall_return;
struct sbi_trap_regs;
struct sbi_hart_features;
union sbi_ldst_data;
/** Possible feature flags of a platform */
enum sbi_platform_features {
@@ -64,6 +73,12 @@ enum sbi_platform_features {
/** Platform functions */
struct sbi_platform_operations {
/* Check if specified HART is allowed to do cold boot */
bool (*cold_boot_allowed)(u32 hartid);
/* Platform nascent initialization */
int (*nascent_init)(void);
/** Platform early initialization */
int (*early_init)(bool cold_boot);
/** Platform final initialization */
@@ -86,6 +101,9 @@ struct sbi_platform_operations {
*/
int (*misa_get_xlen)(void);
/** Initialize (or populate) HART extensions for the platform */
int (*extensions_init)(struct sbi_hart_features *hfeatures);
/** Initialize (or populate) domains for the platform */
int (*domains_init)(void);
@@ -95,39 +113,51 @@ struct sbi_platform_operations {
/** Get platform specific mhpmevent value */
uint64_t (*pmu_xlate_to_mhpmevent)(uint32_t event_idx, uint64_t data);
/** Initialize the platform console */
int (*console_init)(void);
/** Initialize the platform interrupt controller during cold boot */
int (*irqchip_init)(void);
/** Initialize the platform interrupt controller for current HART */
int (*irqchip_init)(bool cold_boot);
/** Exit the platform interrupt controller for current HART */
void (*irqchip_exit)(void);
/** Initialize IPI for current HART */
int (*ipi_init)(bool cold_boot);
/** Exit IPI for current HART */
void (*ipi_exit)(void);
/** Initialize IPI during cold boot */
int (*ipi_init)(void);
/** Get tlb flush limit value **/
u64 (*get_tlbr_flush_limit)(void);
/** Initialize platform timer for current HART */
int (*timer_init)(bool cold_boot);
/** Exit platform timer for current HART */
void (*timer_exit)(void);
/** Get tlb fifo num entries*/
u32 (*get_tlb_num_entries)(void);
/** Initialize platform timer during cold boot */
int (*timer_init)(void);
/** Initialize the platform Message Proxy(MPXY) driver */
int (*mpxy_init)(void);
/** platform specific SBI extension implementation probe function */
int (*vendor_ext_check)(long extid);
/** platform specific SBI extension implementation provider */
int (*vendor_ext_provider)(long extid, long funcid,
const struct sbi_trap_regs *regs,
unsigned long *out_value,
struct sbi_trap_info *out_trap);
int (*vendor_ext_provider)(long funcid,
struct sbi_trap_regs *regs,
struct sbi_ecall_return *out);
/** platform specific handler to fixup load fault */
int (*emulate_load)(int rlen, unsigned long addr,
union sbi_ldst_data *out_val);
/** platform specific handler to fixup store fault */
int (*emulate_store)(int wlen, unsigned long addr,
union sbi_ldst_data in_val);
/** platform specific pmp setup on current HART */
void (*pmp_set)(unsigned int n, unsigned long flags,
unsigned long prot, unsigned long addr,
unsigned long log2len);
/** platform specific pmp disable on current HART */
void (*pmp_disable)(unsigned int n);
};
/** Platform default per-HART stack size for exception/interrupt handling */
#define SBI_PLATFORM_DEFAULT_HART_STACK_SIZE 8192
/** Platform default heap size */
#define SBI_PLATFORM_DEFAULT_HEAP_SIZE(__num_hart) \
(0x8000 + 0x1000 * (__num_hart))
/** Representation of a platform */
struct sbi_platform {
/**
@@ -146,10 +176,14 @@ struct sbi_platform {
char name[64];
/** Supported features */
u64 features;
/** Total number of HARTs */
/** Total number of HARTs (at most SBI_HARTMASK_MAX_BITS) */
u32 hart_count;
/** Per-HART stack size for exception/interrupt handling */
u32 hart_stack_size;
/** Size of heap shared by all HARTs */
u32 heap_size;
/** Reserved for future use */
u32 reserved;
/** Pointer to sbi platform operations */
unsigned long platform_ops_addr;
/** Pointer to system firmware specific context */
@@ -157,21 +191,35 @@ struct sbi_platform {
/**
* HART index to HART id table
*
* For used HART index <abc>:
* If hart_index2id != NULL then the table must contain a mapping
* for each HART index 0 <= <abc> < hart_count:
* hart_index2id[<abc>] = some HART id
* For unused HART index <abc>:
* hart_index2id[<abc>] = -1U
*
* If hart_index2id == NULL then we assume identity mapping
* hart_index2id[<abc>] = <abc>
*
* We have only two restrictions:
* 1. HART index < sbi_platform hart_count
* 2. HART id < SBI_HARTMASK_MAX_BITS
*/
const u32 *hart_index2id;
/** Allocation alignment for Scratch */
unsigned long cbom_block_size;
};
/**
* Prevent modification of struct sbi_platform from affecting
* SBI_PLATFORM_xxx_OFFSET
*/
assert_member_offset(struct sbi_platform, opensbi_version, SBI_PLATFORM_OPENSBI_VERSION_OFFSET);
assert_member_offset(struct sbi_platform, platform_version, SBI_PLATFORM_VERSION_OFFSET);
assert_member_offset(struct sbi_platform, name, SBI_PLATFORM_NAME_OFFSET);
assert_member_offset(struct sbi_platform, features, SBI_PLATFORM_FEATURES_OFFSET);
assert_member_offset(struct sbi_platform, hart_count, SBI_PLATFORM_HART_COUNT_OFFSET);
assert_member_offset(struct sbi_platform, hart_stack_size, SBI_PLATFORM_HART_STACK_SIZE_OFFSET);
assert_member_offset(struct sbi_platform, heap_size, SBI_PLATFORM_HEAP_SIZE_OFFSET);
assert_member_offset(struct sbi_platform, reserved, SBI_PLATFORM_RESERVED_OFFSET);
assert_member_offset(struct sbi_platform, platform_ops_addr, SBI_PLATFORM_OPS_OFFSET);
assert_member_offset(struct sbi_platform, firmware_context, SBI_PLATFORM_FIRMWARE_CONTEXT_OFFSET);
assert_member_offset(struct sbi_platform, hart_index2id, SBI_PLATFORM_HART_INDEX2ID_OFFSET);
assert_member_offset(struct sbi_platform, cbom_block_size, SBI_PLATFORM_CBOM_BLOCK_SIZE_OFFSET);
/** Get pointer to sbi_platform for sbi_scratch pointer */
#define sbi_platform_ptr(__s) \
((const struct sbi_platform *)((__s)->platform_addr))
@@ -186,16 +234,6 @@ struct sbi_platform {
#define sbi_platform_has_mfaults_delegation(__p) \
((__p)->features & SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
/**
* Get HART index for the given HART
*
* @param plat pointer to struct sbi_platform
* @param hartid HART ID
*
* @return 0 <= value < hart_count for valid HART otherwise -1U
*/
u32 sbi_platform_hart_index(const struct sbi_platform *plat, u32 hartid);
/**
* Get the platform features in string format
*
@@ -253,6 +291,20 @@ static inline u64 sbi_platform_tlbr_flush_limit(const struct sbi_platform *plat)
return SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT;
}
/**
* Get platform specific tlb fifo num entries.
*
* @param plat pointer to struct sbi_platform
*
* @return number of tlb fifo entries
*/
static inline u32 sbi_platform_tlb_fifo_num_entries(const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->get_tlb_num_entries)
return sbi_platform_ops(plat)->get_tlb_num_entries();
return sbi_hart_count();
}
/**
* Get total number of HARTs supported by the platform
*
@@ -282,28 +334,44 @@ static inline u32 sbi_platform_hart_stack_size(const struct sbi_platform *plat)
}
/**
* Check whether given HART is invalid
* Check whether given HART is allowed to do cold boot
*
* @param plat pointer to struct sbi_platform
* @param hartid HART ID
*
* @return TRUE if HART is invalid and FALSE otherwise
* @return true if HART is allowed to do cold boot and false otherwise
*/
static inline bool sbi_platform_hart_invalid(const struct sbi_platform *plat,
u32 hartid)
static inline bool sbi_platform_cold_boot_allowed(
const struct sbi_platform *plat,
u32 hartid)
{
if (!plat)
return TRUE;
if (plat->hart_count <= sbi_platform_hart_index(plat, hartid))
return TRUE;
return FALSE;
if (plat && sbi_platform_ops(plat)->cold_boot_allowed)
return sbi_platform_ops(plat)->cold_boot_allowed(hartid);
return true;
}
/**
* Nascent (very early) initialization for current HART
*
* NOTE: This function can be used to do very early initialization of
* platform specific per-HART CSRs and devices.
*
* @param plat pointer to struct sbi_platform
*
* @return 0 on success and negative error code on failure
*/
static inline int sbi_platform_nascent_init(const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->nascent_init)
return sbi_platform_ops(plat)->nascent_init();
return 0;
}
/**
* Early initialization for current HART
*
* @param plat pointer to struct sbi_platform
* @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
* @param cold_boot whether cold boot (true) or warm_boot (false)
*
* @return 0 on success and negative error code on failure
*/
@@ -319,7 +387,7 @@ static inline int sbi_platform_early_init(const struct sbi_platform *plat,
* Final initialization for current HART
*
* @param plat pointer to struct sbi_platform
* @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
* @param cold_boot whether cold boot (true) or warm_boot (false)
*
* @return 0 on success and negative error code on failure
*/
@@ -383,6 +451,22 @@ static inline int sbi_platform_misa_xlen(const struct sbi_platform *plat)
return -1;
}
/**
* Initialize (or populate) HART extensions for the platform
*
* @param plat pointer to struct sbi_platform
*
* @return 0 on success and negative error code on failure
*/
static inline int sbi_platform_extensions_init(
const struct sbi_platform *plat,
struct sbi_hart_features *hfeatures)
{
if (plat && sbi_platform_ops(plat)->extensions_init)
return sbi_platform_ops(plat)->extensions_init(hfeatures);
return 0;
}
/**
* Initialize (or populate) domains for the platform
*
@@ -431,122 +515,78 @@ static inline uint64_t sbi_platform_pmu_xlate_to_mhpmevent(const struct sbi_plat
}
/**
* Initialize the platform console
* Initialize the platform interrupt controller during cold boot
*
* @param plat pointer to struct sbi_platform
*
* @return 0 on success and negative error code on failure
*/
static inline int sbi_platform_console_init(const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->console_init)
return sbi_platform_ops(plat)->console_init();
return 0;
}
/**
* Initialize the platform interrupt controller for current HART
*
* @param plat pointer to struct sbi_platform
* @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
*
* @return 0 on success and negative error code on failure
*/
static inline int sbi_platform_irqchip_init(const struct sbi_platform *plat,
bool cold_boot)
static inline int sbi_platform_irqchip_init(const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->irqchip_init)
return sbi_platform_ops(plat)->irqchip_init(cold_boot);
return sbi_platform_ops(plat)->irqchip_init();
return 0;
}
/**
* Exit the platform interrupt controller for current HART
* Initialize the platform IPI support during cold boot
*
* @param plat pointer to struct sbi_platform
*/
static inline void sbi_platform_irqchip_exit(const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->irqchip_exit)
sbi_platform_ops(plat)->irqchip_exit();
}
/**
* Initialize the platform IPI support for current HART
*
* @param plat pointer to struct sbi_platform
* @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
*
* @return 0 on success and negative error code on failure
*/
static inline int sbi_platform_ipi_init(const struct sbi_platform *plat,
bool cold_boot)
static inline int sbi_platform_ipi_init(const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->ipi_init)
return sbi_platform_ops(plat)->ipi_init(cold_boot);
return sbi_platform_ops(plat)->ipi_init();
return 0;
}
/**
* Exit the platform IPI support for current HART
* Initialize the platform timer during cold boot
*
* @param plat pointer to struct sbi_platform
*/
static inline void sbi_platform_ipi_exit(const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->ipi_exit)
sbi_platform_ops(plat)->ipi_exit();
}
/**
* Initialize the platform timer for current HART
*
* @param plat pointer to struct sbi_platform
* @param cold_boot whether cold boot (TRUE) or warm_boot (FALSE)
*
* @return 0 on success and negative error code on failure
*/
static inline int sbi_platform_timer_init(const struct sbi_platform *plat,
bool cold_boot)
static inline int sbi_platform_timer_init(const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->timer_init)
return sbi_platform_ops(plat)->timer_init(cold_boot);
return sbi_platform_ops(plat)->timer_init();
return 0;
}
/**
* Exit the platform timer for current HART
* Initialize the platform Message Proxy drivers
*
* @param plat pointer to struct sbi_platform
*
* @return 0 on success and negative error code on failure
*/
static inline void sbi_platform_timer_exit(const struct sbi_platform *plat)
static inline int sbi_platform_mpxy_init(const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->timer_exit)
sbi_platform_ops(plat)->timer_exit();
if (plat && sbi_platform_ops(plat)->mpxy_init)
return sbi_platform_ops(plat)->mpxy_init();
return 0;
}
/**
* Check if a vendor extension is implemented or not.
* Check if SBI vendor extension is implemented or not.
*
* @param plat pointer to struct sbi_platform
* @param extid vendor SBI extension id
*
* @return 0 if extid is not implemented and 1 if implemented
* @return false if not implemented and true if implemented
*/
static inline int sbi_platform_vendor_ext_check(const struct sbi_platform *plat,
long extid)
static inline bool sbi_platform_vendor_ext_check(
const struct sbi_platform *plat)
{
if (plat && sbi_platform_ops(plat)->vendor_ext_check)
return sbi_platform_ops(plat)->vendor_ext_check(extid);
return 0;
return plat && sbi_platform_ops(plat)->vendor_ext_provider;
}
/**
* Invoke platform specific vendor SBI extension implementation.
*
* @param plat pointer to struct sbi_platform
* @param extid vendor SBI extension id
* @param funcid SBI function id within the extension id
* @param regs pointer to trap registers passed by the caller
* @param out_value output value that can be filled by the callee
@@ -556,21 +596,93 @@ static inline int sbi_platform_vendor_ext_check(const struct sbi_platform *plat,
*/
static inline int sbi_platform_vendor_ext_provider(
const struct sbi_platform *plat,
long extid, long funcid,
const struct sbi_trap_regs *regs,
unsigned long *out_value,
struct sbi_trap_info *out_trap)
long funcid,
struct sbi_trap_regs *regs,
struct sbi_ecall_return *out)
{
if (plat && sbi_platform_ops(plat)->vendor_ext_provider) {
return sbi_platform_ops(plat)->vendor_ext_provider(extid,
funcid, regs,
out_value,
out_trap);
}
if (plat && sbi_platform_ops(plat)->vendor_ext_provider)
return sbi_platform_ops(plat)->vendor_ext_provider(funcid,
regs, out);
return SBI_ENOTSUPP;
}
/**
* Ask platform to emulate the trapped load
*
* @param plat pointer to struct sbi_platform
* @param rlen length of the load: 1/2/4/8...
* @param addr virtual address of the load. Platform needs to page-walk and
* find the physical address if necessary
* @param out_val value loaded
*
* @return 0 on success and negative error code on failure
*/
static inline int sbi_platform_emulate_load(const struct sbi_platform *plat,
int rlen, unsigned long addr,
union sbi_ldst_data *out_val)
{
if (plat && sbi_platform_ops(plat)->emulate_load) {
return sbi_platform_ops(plat)->emulate_load(rlen, addr,
out_val);
}
return SBI_ENOTSUPP;
}
/**
* Ask platform to emulate the trapped store
*
* @param plat pointer to struct sbi_platform
* @param wlen length of the store: 1/2/4/8...
* @param addr virtual address of the store. Platform needs to page-walk and
* find the physical address if necessary
* @param in_val value to store
*
* @return 0 on success and negative error code on failure
*/
static inline int sbi_platform_emulate_store(const struct sbi_platform *plat,
int wlen, unsigned long addr,
union sbi_ldst_data in_val)
{
if (plat && sbi_platform_ops(plat)->emulate_store) {
return sbi_platform_ops(plat)->emulate_store(wlen, addr,
in_val);
}
return SBI_ENOTSUPP;
}
/**
* Platform specific PMP setup on current HART
*
* @param plat pointer to struct sbi_platform
* @param n index of the pmp entry
* @param flags domain memregion flags
* @param prot attribute of the pmp entry
* @param addr address of the pmp entry
* @param log2len size of the pmp entry as power-of-2
*/
static inline void sbi_platform_pmp_set(const struct sbi_platform *plat,
unsigned int n, unsigned long flags,
unsigned long prot, unsigned long addr,
unsigned long log2len)
{
if (plat && sbi_platform_ops(plat)->pmp_set)
sbi_platform_ops(plat)->pmp_set(n, flags, prot, addr, log2len);
}
/**
* Platform specific PMP disable on current HART
*
* @param plat pointer to struct sbi_platform
* @param n index of the pmp entry
*/
static inline void sbi_platform_pmp_disable(const struct sbi_platform *plat,
unsigned int n)
{
if (plat && sbi_platform_ops(plat)->pmp_disable)
sbi_platform_ops(plat)->pmp_disable(n);
}
#endif
#endif

View File

@@ -11,22 +11,99 @@
#define __SBI_PMU_H__
#include <sbi/sbi_types.h>
#include <sbi/sbi_hartmask.h>
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_ecall_interface.h>
#include <sbi/sbi_trap.h>
struct sbi_scratch;
/* Event related macros */
/* Maximum number of hardware events that can mapped by OpenSBI */
#define SBI_PMU_HW_EVENT_MAX 64
/* Maximum number of firmware events that can mapped by OpenSBI */
#define SBI_PMU_FW_EVENT_MAX 32
#define SBI_PMU_HW_EVENT_MAX 256
/* Counter related macros */
#define SBI_PMU_FW_CTR_MAX 16
#define SBI_PMU_HW_CTR_MAX 32
#define SBI_PMU_CTR_MAX (SBI_PMU_HW_CTR_MAX + SBI_PMU_FW_CTR_MAX)
#define SBI_PMU_FIXED_CTR_MASK 0x07
#define SBI_PMU_CY_IR_MASK 0x05
struct sbi_pmu_device {
/** Name of the PMU platform device */
char name[32];
/**
* Validate event code of custom firmware event
*/
int (*fw_event_validate_encoding)(uint32_t hartid, uint64_t event_data);
/**
* Match custom firmware counter with custom firmware event
* Note: 0 <= counter_index < SBI_PMU_FW_CTR_MAX
*/
bool (*fw_counter_match_encoding)(uint32_t hartid,
uint32_t counter_index,
uint64_t event_data);
/**
* Fetch the max width of this counter in number of bits.
*/
int (*fw_counter_width)(void);
/**
* Read value of custom firmware counter
* Note: 0 <= counter_index < SBI_PMU_FW_CTR_MAX
*/
uint64_t (*fw_counter_read_value)(uint32_t hartid,
uint32_t counter_index);
/**
* Write value to custom firmware counter
* Note: 0 <= counter_index < SBI_PMU_FW_CTR_MAX
*/
void (*fw_counter_write_value)(uint32_t hartid, uint32_t counter_index,
uint64_t value);
/**
* Start custom firmware counter
* Note: 0 <= counter_index < SBI_PMU_FW_CTR_MAX
*/
int (*fw_counter_start)(uint32_t hartid, uint32_t counter_index,
uint64_t event_data);
/**
* Stop custom firmware counter
* Note: 0 <= counter_index < SBI_PMU_FW_CTR_MAX
*/
int (*fw_counter_stop)(uint32_t hartid, uint32_t counter_index);
/**
* Custom enable irq for hardware counter
* Note: 0 <= counter_index < SBI_PMU_HW_CTR_MAX
*/
void (*hw_counter_enable_irq)(uint32_t counter_index);
/**
* Custom disable irq for hardware counter
* Note: 0 <= counter_index < SBI_PMU_HW_CTR_MAX
*/
void (*hw_counter_disable_irq)(uint32_t counter_index);
/**
* Custom function returning the machine-specific irq-bit.
*/
int (*hw_counter_irq_bit)(void);
/**
* Custom function to inhibit counting of events while in
* specified mode.
*/
void (*hw_counter_filter_mode)(unsigned long flags, int counter_index);
};
/** Get the PMU platform device */
const struct sbi_pmu_device *sbi_pmu_get_device(void);
/** Set the PMU platform device */
void sbi_pmu_set_device(const struct sbi_pmu_device *dev);
/** Initialize PMU */
int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot);
@@ -34,6 +111,12 @@ int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot);
/** Reset PMU during hart exit */
void sbi_pmu_exit(struct sbi_scratch *scratch);
/** Return the pmu irq bit depending on extension existence */
int sbi_pmu_irq_bit(void);
/** Return the pmu irq mask or 0 if the pmu overflow irq is not supported */
unsigned long sbi_pmu_irq_mask(void);
/**
* Add the hardware event to counter mapping information. This should be called
* from the platform code to update the mapping table.
@@ -53,7 +136,7 @@ int sbi_pmu_add_hw_event_counter_map(u32 eidx_start, u32 eidx_end, u32 cmap);
int sbi_pmu_add_raw_event_counter_map(uint64_t select, uint64_t select_mask, u32 cmap);
int sbi_pmu_ctr_read(uint32_t cidx, unsigned long *cval);
int sbi_pmu_ctr_fw_read(uint32_t cidx, uint64_t *cval);
int sbi_pmu_ctr_stop(unsigned long cidx_base, unsigned long cidx_mask,
unsigned long flag);
@@ -62,6 +145,8 @@ int sbi_pmu_ctr_start(unsigned long cidx_base, unsigned long cidx_mask,
unsigned long flags, uint64_t ival);
int sbi_pmu_ctr_get_info(uint32_t cidx, unsigned long *ctr_info);
int sbi_pmu_event_get_info(unsigned long shmem_lo, unsigned long shmem_high,
unsigned long num_events, unsigned long flags);
unsigned long sbi_pmu_num_ctr(void);
@@ -71,4 +156,6 @@ int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask,
int sbi_pmu_ctr_incr_fw(enum sbi_pmu_fw_event_code_id fw_id);
void sbi_pmu_ovf_irq();
#endif

View File

@@ -18,26 +18,34 @@
#define SBI_SCRATCH_FW_START_OFFSET (0 * __SIZEOF_POINTER__)
/** Offset of fw_size member in sbi_scratch */
#define SBI_SCRATCH_FW_SIZE_OFFSET (1 * __SIZEOF_POINTER__)
/** Offset (in sbi_scratch) of the R/W Offset */
#define SBI_SCRATCH_FW_RW_OFFSET (2 * __SIZEOF_POINTER__)
/** Offset of fw_heap_offset member in sbi_scratch */
#define SBI_SCRATCH_FW_HEAP_OFFSET (3 * __SIZEOF_POINTER__)
/** Offset of fw_heap_size member in sbi_scratch */
#define SBI_SCRATCH_FW_HEAP_SIZE_OFFSET (4 * __SIZEOF_POINTER__)
/** Offset of next_arg1 member in sbi_scratch */
#define SBI_SCRATCH_NEXT_ARG1_OFFSET (2 * __SIZEOF_POINTER__)
#define SBI_SCRATCH_NEXT_ARG1_OFFSET (5 * __SIZEOF_POINTER__)
/** Offset of next_addr member in sbi_scratch */
#define SBI_SCRATCH_NEXT_ADDR_OFFSET (3 * __SIZEOF_POINTER__)
#define SBI_SCRATCH_NEXT_ADDR_OFFSET (6 * __SIZEOF_POINTER__)
/** Offset of next_mode member in sbi_scratch */
#define SBI_SCRATCH_NEXT_MODE_OFFSET (4 * __SIZEOF_POINTER__)
#define SBI_SCRATCH_NEXT_MODE_OFFSET (7 * __SIZEOF_POINTER__)
/** Offset of warmboot_addr member in sbi_scratch */
#define SBI_SCRATCH_WARMBOOT_ADDR_OFFSET (5 * __SIZEOF_POINTER__)
#define SBI_SCRATCH_WARMBOOT_ADDR_OFFSET (8 * __SIZEOF_POINTER__)
/** Offset of platform_addr member in sbi_scratch */
#define SBI_SCRATCH_PLATFORM_ADDR_OFFSET (6 * __SIZEOF_POINTER__)
#define SBI_SCRATCH_PLATFORM_ADDR_OFFSET (9 * __SIZEOF_POINTER__)
/** Offset of hartid_to_scratch member in sbi_scratch */
#define SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET (7 * __SIZEOF_POINTER__)
/** Offset of trap_exit member in sbi_scratch */
#define SBI_SCRATCH_TRAP_EXIT_OFFSET (8 * __SIZEOF_POINTER__)
#define SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET (10 * __SIZEOF_POINTER__)
/** Offset of trap_context member in sbi_scratch */
#define SBI_SCRATCH_TRAP_CONTEXT_OFFSET (11 * __SIZEOF_POINTER__)
/** Offset of tmp0 member in sbi_scratch */
#define SBI_SCRATCH_TMP0_OFFSET (9 * __SIZEOF_POINTER__)
#define SBI_SCRATCH_TMP0_OFFSET (12 * __SIZEOF_POINTER__)
/** Offset of options member in sbi_scratch */
#define SBI_SCRATCH_OPTIONS_OFFSET (10 * __SIZEOF_POINTER__)
#define SBI_SCRATCH_OPTIONS_OFFSET (13 * __SIZEOF_POINTER__)
/** Offset of hartindex member in sbi_scratch */
#define SBI_SCRATCH_HARTINDEX_OFFSET (14 * __SIZEOF_POINTER__)
/** Offset of extra space in sbi_scratch */
#define SBI_SCRATCH_EXTRA_SPACE_OFFSET (11 * __SIZEOF_POINTER__)
#define SBI_SCRATCH_EXTRA_SPACE_OFFSET (15 * __SIZEOF_POINTER__)
/** Maximum size of sbi_scratch (4KB) */
#define SBI_SCRATCH_SIZE (0x1000)
@@ -53,11 +61,17 @@ struct sbi_scratch {
unsigned long fw_start;
/** Size (in bytes) of firmware linked to OpenSBI library */
unsigned long fw_size;
/** Offset (in bytes) of the R/W section */
unsigned long fw_rw_offset;
/** Offset (in bytes) of the heap area */
unsigned long fw_heap_offset;
/** Size (in bytes) of the heap area */
unsigned long fw_heap_size;
/** Arg1 (or 'a1' register) of next booting stage for this HART */
unsigned long next_arg1;
/** Address of next booting stage for this HART */
unsigned long next_addr;
/** Priviledge mode of next booting stage for this HART */
/** Privilege mode of next booting stage for this HART */
unsigned long next_mode;
/** Warm boot entry point address for this HART */
unsigned long warmboot_addr;
@@ -65,14 +79,36 @@ struct sbi_scratch {
unsigned long platform_addr;
/** Address of HART ID to sbi_scratch conversion function */
unsigned long hartid_to_scratch;
/** Address of trap exit function */
unsigned long trap_exit;
/** Address of current trap context */
unsigned long trap_context;
/** Temporary storage */
unsigned long tmp0;
/** Options for OpenSBI library */
unsigned long options;
/** Index of the hart */
unsigned long hartindex;
};
/**
* Prevent modification of struct sbi_scratch from affecting
* SBI_SCRATCH_xxx_OFFSET
*/
assert_member_offset(struct sbi_scratch, fw_start, SBI_SCRATCH_FW_START_OFFSET);
assert_member_offset(struct sbi_scratch, fw_size, SBI_SCRATCH_FW_SIZE_OFFSET);
assert_member_offset(struct sbi_scratch, fw_rw_offset, SBI_SCRATCH_FW_RW_OFFSET);
assert_member_offset(struct sbi_scratch, fw_heap_offset, SBI_SCRATCH_FW_HEAP_OFFSET);
assert_member_offset(struct sbi_scratch, fw_heap_size, SBI_SCRATCH_FW_HEAP_SIZE_OFFSET);
assert_member_offset(struct sbi_scratch, next_arg1, SBI_SCRATCH_NEXT_ARG1_OFFSET);
assert_member_offset(struct sbi_scratch, next_addr, SBI_SCRATCH_NEXT_ADDR_OFFSET);
assert_member_offset(struct sbi_scratch, next_mode, SBI_SCRATCH_NEXT_MODE_OFFSET);
assert_member_offset(struct sbi_scratch, warmboot_addr, SBI_SCRATCH_WARMBOOT_ADDR_OFFSET);
assert_member_offset(struct sbi_scratch, platform_addr, SBI_SCRATCH_PLATFORM_ADDR_OFFSET);
assert_member_offset(struct sbi_scratch, hartid_to_scratch, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET);
assert_member_offset(struct sbi_scratch, trap_context, SBI_SCRATCH_TRAP_CONTEXT_OFFSET);
assert_member_offset(struct sbi_scratch, tmp0, SBI_SCRATCH_TMP0_OFFSET);
assert_member_offset(struct sbi_scratch, options, SBI_SCRATCH_OPTIONS_OFFSET);
assert_member_offset(struct sbi_scratch, hartindex, SBI_SCRATCH_HARTINDEX_OFFSET);
/** Possible options for OpenSBI library */
enum sbi_scratch_options {
/** Disable prints during boot */
@@ -83,7 +119,7 @@ enum sbi_scratch_options {
/** Get pointer to sbi_scratch for current HART */
#define sbi_scratch_thishart_ptr() \
((struct sbi_scratch *)csr_read(CSR_MSCRATCH))
((struct sbi_scratch *)csr_read_relaxed(CSR_MSCRATCH))
/** Get Arg1 of next booting stage for current HART */
#define sbi_scratch_thishart_arg1_ptr() \
@@ -103,25 +139,85 @@ unsigned long sbi_scratch_alloc_offset(unsigned long size);
/** Free-up extra space in sbi_scratch */
void sbi_scratch_free_offset(unsigned long offset);
/** Amount (in bytes) of used space in in sbi_scratch */
unsigned long sbi_scratch_used_space(void);
/** Get pointer from offset in sbi_scratch */
#define sbi_scratch_offset_ptr(scratch, offset) ((void *)scratch + (offset))
#define sbi_scratch_offset_ptr(scratch, offset) (void *)((char *)(scratch) + (offset))
/** Get pointer from offset in sbi_scratch for current HART */
#define sbi_scratch_thishart_offset_ptr(offset) \
((void *)sbi_scratch_thishart_ptr() + (offset))
(void *)((char *)sbi_scratch_thishart_ptr() + (offset))
/** HART id to scratch table */
extern struct sbi_scratch *hartid_to_scratch_table[];
/** Allocate offset for a data type in sbi_scratch */
#define sbi_scratch_alloc_type_offset(__type) \
sbi_scratch_alloc_offset(sizeof(__type))
/** Read a data type from sbi_scratch at given offset */
#define sbi_scratch_read_type(__scratch, __type, __offset) \
({ \
*((__type *)sbi_scratch_offset_ptr((__scratch), (__offset))); \
})
/** Write a data type to sbi_scratch at given offset */
#define sbi_scratch_write_type(__scratch, __type, __offset, __ptr) \
do { \
*((__type *)sbi_scratch_offset_ptr((__scratch), (__offset))) \
= (__type)(__ptr); \
} while (0)
/** Get the hart index of the current hart */
#define current_hartindex() \
(sbi_scratch_thishart_ptr()->hartindex)
/** Number of harts managed by this OpenSBI instance */
extern u32 sbi_scratch_hart_count;
/** Get the number of harts managed by this OpenSBI instance */
#define sbi_hart_count() sbi_scratch_hart_count
/** Iterate over the harts managed by this OpenSBI instance */
#define sbi_for_each_hartindex(__var) \
for (u32 __var = 0; __var < sbi_hart_count(); ++__var)
/** Check whether a particular HART index is valid or not */
#define sbi_hartindex_valid(__hartindex) ((__hartindex) < sbi_hart_count())
/** HART index to HART id table */
extern u32 hartindex_to_hartid_table[];
/** Get sbi_scratch from HART index */
#define sbi_hartindex_to_hartid(__hartindex) \
({ \
((__hartindex) < SBI_HARTMASK_MAX_BITS) ? \
hartindex_to_hartid_table[__hartindex] : -1U; \
})
/** HART index to scratch table */
extern struct sbi_scratch *hartindex_to_scratch_table[];
/** Get sbi_scratch from HART index */
#define sbi_hartindex_to_scratch(__hartindex) \
({ \
((__hartindex) < SBI_HARTMASK_MAX_BITS) ? \
hartindex_to_scratch_table[__hartindex] : NULL; \
})
/**
* Get logical index for given HART id
* @param hartid physical HART id
* @returns value between 0 to SBI_HARTMASK_MAX_BITS upon success and
* SBI_HARTMASK_MAX_BITS upon failure.
*/
u32 sbi_hartid_to_hartindex(u32 hartid);
/** Get sbi_scratch from HART id */
#define sbi_hartid_to_scratch(__hartid) \
hartid_to_scratch_table[__hartid]
sbi_hartindex_to_scratch(sbi_hartid_to_hartindex(__hartid))
/** Last HART id having a sbi_scratch pointer */
extern u32 last_hartid_having_scratch;
/** Get last HART id having a sbi_scratch pointer */
#define sbi_scratch_last_hartid() last_hartid_having_scratch
/** Check whether particular HART id is valid or not */
#define sbi_hartid_valid(__hartid) \
sbi_hartindex_valid(sbi_hartid_to_hartindex(__hartid))
#endif

33
include/sbi/sbi_slist.h Normal file
View File

@@ -0,0 +1,33 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Simple simply-linked list library.
*
* Copyright (c) 2025 Rivos Inc.
*
* Authors:
* Clément Léger <cleger@rivosinc.com>
*/
#ifndef __SBI_SLIST_H__
#define __SBI_SLIST_H__
#include <sbi/sbi_types.h>
#define SBI_SLIST_HEAD_INIT(_ptr) (_ptr)
#define SBI_SLIST_HEAD(_lname, _stype) struct _stype *_lname
#define SBI_SLIST_NODE(_stype) SBI_SLIST_HEAD(next, _stype)
#define SBI_SLIST_NODE_INIT(_ptr) .next = _ptr
#define SBI_INIT_SLIST_HEAD(_head) (_head) = NULL
#define SBI_SLIST_ADD(_ptr, _head) \
do { \
(_ptr)->next = _head; \
(_head) = _ptr; \
} while (0)
#define SBI_SLIST_FOR_EACH_ENTRY(_ptr, _head) \
for (_ptr = _head; _ptr; _ptr = _ptr->next)
#endif

95
include/sbi/sbi_sse.h Normal file
View File

@@ -0,0 +1,95 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2023 Rivos Systems.
*/
#ifndef __SBI_SSE_H__
#define __SBI_SSE_H__
#include <sbi/sbi_types.h>
#include <sbi/sbi_list.h>
#include <sbi/riscv_locks.h>
struct sbi_scratch;
struct sbi_trap_regs;
struct sbi_ecall_return;
#define EXC_MODE_PP_SHIFT 0
#define EXC_MODE_PP BIT(EXC_MODE_PP_SHIFT)
#define EXC_MODE_PV_SHIFT 1
#define EXC_MODE_PV BIT(EXC_MODE_PV_SHIFT)
#define EXC_MODE_SSTATUS_SPIE_SHIFT 2
#define EXC_MODE_SSTATUS_SPIE BIT(EXC_MODE_SSTATUS_SPIE_SHIFT)
struct sbi_sse_cb_ops {
/**
* Called when hart_id is changed on the event.
*/
void (*set_hartid_cb)(uint32_t event_id, unsigned long hart_id);
/**
* Called when the SBI_EXT_SSE_COMPLETE is invoked on the event.
*/
void (*complete_cb)(uint32_t event_id);
/**
* Called when the SBI_EXT_SSE_REGISTER is invoked on the event.
*/
void (*register_cb)(uint32_t event_id);
/**
* Called when the SBI_EXT_SSE_UNREGISTER is invoked on the event.
*/
void (*unregister_cb)(uint32_t event_id);
/**
* Called when the SBI_EXT_SSE_ENABLE is invoked on the event.
*/
void (*enable_cb)(uint32_t event_id);
/**
* Called when the SBI_EXT_SSE_DISABLE is invoked on the event.
*/
void (*disable_cb)(uint32_t event_id);
};
/* Add a supported event with associated callback operations
* @param event_id Event identifier (SBI_SSE_EVENT_* or a custom platform one)
* @param cb_ops Callback operations (Can be NULL if any)
* @return 0 on success, error otherwise
*/
int sbi_sse_add_event(uint32_t event_id, const struct sbi_sse_cb_ops *cb_ops);
/* Inject an event to the current hard
* @param event_id Event identifier (SBI_SSE_EVENT_*)
* @param regs Registers that were used on SBI entry
* @return 0 on success, error otherwise
*/
int sbi_sse_inject_event(uint32_t event_id);
void sbi_sse_process_pending_events(struct sbi_trap_regs *regs);
int sbi_sse_init(struct sbi_scratch *scratch, bool cold_boot);
void sbi_sse_exit(struct sbi_scratch *scratch);
/* Interface called from sbi_ecall_sse.c */
int sbi_sse_register(uint32_t event_id, unsigned long handler_entry_pc,
unsigned long handler_entry_arg);
int sbi_sse_unregister(uint32_t event_id);
int sbi_sse_hart_mask(void);
int sbi_sse_hart_unmask(void);
int sbi_sse_enable(uint32_t event_id);
int sbi_sse_disable(uint32_t event_id);
int sbi_sse_complete(struct sbi_trap_regs *regs, struct sbi_ecall_return *out);
int sbi_sse_inject_from_ecall(uint32_t event_id, unsigned long hart_id,
struct sbi_ecall_return *out);
int sbi_sse_read_attrs(uint32_t event_id, uint32_t base_attr_id,
uint32_t attr_count, unsigned long output_phys_lo,
unsigned long output_phys_hi);
int sbi_sse_write_attrs(uint32_t event_id, uint32_t base_attr_id,
uint32_t attr_count, unsigned long input_phys_lo,
unsigned long input_phys_hi);
#endif

View File

@@ -43,4 +43,38 @@ bool sbi_system_reset_supported(u32 reset_type, u32 reset_reason);
void __noreturn sbi_system_reset(u32 reset_type, u32 reset_reason);
/** System suspend device */
struct sbi_system_suspend_device {
/** Name of the system suspend device */
char name[32];
/**
* Check whether sleep type is supported by the device
*
* Returns 0 when @sleep_type supported, SBI_ERR_INVALID_PARAM
* when @sleep_type is reserved, or SBI_ERR_NOT_SUPPORTED when
* @sleep_type is not reserved and is implemented, but the
* platform doesn't support it due to missing dependencies.
*/
int (*system_suspend_check)(u32 sleep_type);
/**
* Suspend the system
*
* @sleep_type: The sleep type identifier passed to the SBI call.
* @mmode_resume_addr:
* This is the same as sbi_scratch.warmboot_addr. Some platforms
* may not be able to return from system_suspend(), so they will
* jump directly to this address instead. Platforms which can
* return from system_suspend() may ignore this parameter.
*/
int (*system_suspend)(u32 sleep_type, unsigned long mmode_resume_addr);
};
const struct sbi_system_suspend_device *sbi_system_suspend_get_device(void);
void sbi_system_suspend_set_device(struct sbi_system_suspend_device *dev);
void sbi_system_suspend_test_enable(void);
bool sbi_system_suspend_supported(u32 sleep_type);
int sbi_system_suspend(u32 sleep_type, ulong resume_addr, ulong opaque);
#endif

View File

@@ -28,6 +28,9 @@ struct sbi_timer_device {
/** Stop timer event for current HART */
void (*timer_event_stop)(void);
/** Initialize timer device for current HART */
int (*warm_init)(void);
};
struct sbi_scratch;
@@ -48,6 +51,24 @@ static inline void sbi_timer_udelay(ulong usecs)
sbi_timer_delay_loop(usecs, 1000000, NULL, NULL);
}
/**
* A blocking function that will wait until @p predicate returns true or
* @p timeout_ms milliseconds elapsed. @p arg will be passed as argument to
* @p predicate function.
*
* @param predicate Pointer to a function that returns true if certain
* condition is met. It shouldn't block the code execution.
* @param arg Argument to pass to @p predicate.
* @param timeout_ms Timeout value in milliseconds. The function will return
* false if @p timeout_ms time period elapsed but still @p predicate doesn't
* return true.
*
* @return true if @p predicate returns true within @p timeout_ms, false
* otherwise.
*/
bool sbi_timer_waitms_until(bool (*predicate)(void *), void *arg,
uint64_t timeout_ms);
/** Get timer value for current HART */
u64 sbi_timer_value(void);
@@ -60,8 +81,10 @@ u64 sbi_timer_get_delta(void);
/** Set timer delta value for current HART */
void sbi_timer_set_delta(ulong delta);
#if __riscv_xlen == 32
/** Set upper 32-bits of timer delta value for current HART */
void sbi_timer_set_delta_upper(ulong delta_upper);
#endif
/** Start timer event for current HART */
void sbi_timer_event_start(u64 next_event);

View File

@@ -20,34 +20,35 @@
/* clang-format on */
#define SBI_TLB_FIFO_NUM_ENTRIES 8
struct sbi_scratch;
enum sbi_tlb_type {
SBI_TLB_FENCE_I = 0,
SBI_TLB_SFENCE_VMA,
SBI_TLB_SFENCE_VMA_ASID,
SBI_TLB_HFENCE_GVMA_VMID,
SBI_TLB_HFENCE_GVMA,
SBI_TLB_HFENCE_VVMA_ASID,
SBI_TLB_HFENCE_VVMA,
SBI_TLB_TYPE_MAX,
};
struct sbi_tlb_info {
unsigned long start;
unsigned long size;
unsigned long asid;
unsigned long vmid;
void (*local_fn)(struct sbi_tlb_info *tinfo);
uint16_t asid;
uint16_t vmid;
enum sbi_tlb_type type;
struct sbi_hartmask smask;
};
void sbi_tlb_local_hfence_vvma(struct sbi_tlb_info *tinfo);
void sbi_tlb_local_hfence_gvma(struct sbi_tlb_info *tinfo);
void sbi_tlb_local_sfence_vma(struct sbi_tlb_info *tinfo);
void sbi_tlb_local_hfence_vvma_asid(struct sbi_tlb_info *tinfo);
void sbi_tlb_local_hfence_gvma_vmid(struct sbi_tlb_info *tinfo);
void sbi_tlb_local_sfence_vma_asid(struct sbi_tlb_info *tinfo);
void sbi_tlb_local_fence_i(struct sbi_tlb_info *tinfo);
#define SBI_TLB_INFO_INIT(__p, __start, __size, __asid, __vmid, __lfn, __src) \
#define SBI_TLB_INFO_INIT(__p, __start, __size, __asid, __vmid, __type, __src) \
do { \
(__p)->start = (__start); \
(__p)->size = (__size); \
(__p)->asid = (__asid); \
(__p)->vmid = (__vmid); \
(__p)->local_fn = (__lfn); \
(__p)->type = (__type); \
SBI_HARTMASK_INIT_EXCEPT(&(__p)->smask, (__src)); \
} while (0)

View File

@@ -10,6 +10,8 @@
#ifndef __SBI_TRAP_H__
#define __SBI_TRAP_H__
#include <sbi/riscv_encoding.h>
/* clang-format off */
/** Index of zero member in sbi_trap_regs */
@@ -85,16 +87,16 @@
/** Last member index in sbi_trap_regs */
#define SBI_TRAP_REGS_last 35
/** Index of epc member in sbi_trap_info */
#define SBI_TRAP_INFO_epc 0
/** Index of cause member in sbi_trap_info */
#define SBI_TRAP_INFO_cause 1
#define SBI_TRAP_INFO_cause 0
/** Index of tval member in sbi_trap_info */
#define SBI_TRAP_INFO_tval 2
#define SBI_TRAP_INFO_tval 1
/** Index of tval2 member in sbi_trap_info */
#define SBI_TRAP_INFO_tval2 3
#define SBI_TRAP_INFO_tval2 2
/** Index of tinst member in sbi_trap_info */
#define SBI_TRAP_INFO_tinst 4
#define SBI_TRAP_INFO_tinst 3
/** Index of gva member in sbi_trap_info */
#define SBI_TRAP_INFO_gva 4
/** Last member index in sbi_trap_info */
#define SBI_TRAP_INFO_last 5
@@ -110,76 +112,90 @@
/** Size (in bytes) of sbi_trap_info */
#define SBI_TRAP_INFO_SIZE SBI_TRAP_INFO_OFFSET(last)
#define STACK_BOUNDARY 16
#define ALIGN_TO_BOUNDARY(x, a) (((x) + (a) - 1) & ~((a) - 1))
/** Size (in bytes) of sbi_trap_context */
#define SBI_TRAP_CONTEXT_SIZE ALIGN_TO_BOUNDARY((SBI_TRAP_REGS_SIZE + \
SBI_TRAP_INFO_SIZE + \
__SIZEOF_POINTER__), STACK_BOUNDARY)
#ifndef __ASSEMBLER__
#include <sbi/sbi_types.h>
#include <sbi/sbi_scratch.h>
/** Representation of register state at time of trap/interrupt */
struct sbi_trap_regs {
/** zero register state */
unsigned long zero;
/** ra register state */
unsigned long ra;
/** sp register state */
unsigned long sp;
/** gp register state */
unsigned long gp;
/** tp register state */
unsigned long tp;
/** t0 register state */
unsigned long t0;
/** t1 register state */
unsigned long t1;
/** t2 register state */
unsigned long t2;
/** s0 register state */
unsigned long s0;
/** s1 register state */
unsigned long s1;
/** a0 register state */
unsigned long a0;
/** a1 register state */
unsigned long a1;
/** a2 register state */
unsigned long a2;
/** a3 register state */
unsigned long a3;
/** a4 register state */
unsigned long a4;
/** a5 register state */
unsigned long a5;
/** a6 register state */
unsigned long a6;
/** a7 register state */
unsigned long a7;
/** s2 register state */
unsigned long s2;
/** s3 register state */
unsigned long s3;
/** s4 register state */
unsigned long s4;
/** s5 register state */
unsigned long s5;
/** s6 register state */
unsigned long s6;
/** s7 register state */
unsigned long s7;
/** s8 register state */
unsigned long s8;
/** s9 register state */
unsigned long s9;
/** s10 register state */
unsigned long s10;
/** s11 register state */
unsigned long s11;
/** t3 register state */
unsigned long t3;
/** t4 register state */
unsigned long t4;
/** t5 register state */
unsigned long t5;
/** t6 register state */
unsigned long t6;
union {
unsigned long gprs[32];
struct {
/** zero register state */
unsigned long zero;
/** ra register state */
unsigned long ra;
/** sp register state */
unsigned long sp;
/** gp register state */
unsigned long gp;
/** tp register state */
unsigned long tp;
/** t0 register state */
unsigned long t0;
/** t1 register state */
unsigned long t1;
/** t2 register state */
unsigned long t2;
/** s0 register state */
unsigned long s0;
/** s1 register state */
unsigned long s1;
/** a0 register state */
unsigned long a0;
/** a1 register state */
unsigned long a1;
/** a2 register state */
unsigned long a2;
/** a3 register state */
unsigned long a3;
/** a4 register state */
unsigned long a4;
/** a5 register state */
unsigned long a5;
/** a6 register state */
unsigned long a6;
/** a7 register state */
unsigned long a7;
/** s2 register state */
unsigned long s2;
/** s3 register state */
unsigned long s3;
/** s4 register state */
unsigned long s4;
/** s5 register state */
unsigned long s5;
/** s6 register state */
unsigned long s6;
/** s7 register state */
unsigned long s7;
/** s8 register state */
unsigned long s8;
/** s9 register state */
unsigned long s9;
/** s10 register state */
unsigned long s10;
/** s11 register state */
unsigned long s11;
/** t3 register state */
unsigned long t3;
/** t4 register state */
unsigned long t4;
/** t5 register state */
unsigned long t5;
/** t6 register state */
unsigned long t6;
};
};
/** mepc register state */
unsigned long mepc;
/** mstatus register state */
@@ -188,10 +204,23 @@ struct sbi_trap_regs {
unsigned long mstatusH;
};
_Static_assert(
sizeof(((struct sbi_trap_regs *)0)->gprs) ==
offsetof(struct sbi_trap_regs, t6) +
sizeof(((struct sbi_trap_regs *)0)->t6),
"struct sbi_trap_regs's layout differs between gprs and named members");
#define REG_VAL(idx, regs) ((regs)->gprs[(idx)])
#define GET_RS1(insn, regs) REG_VAL(GET_RS1_NUM(insn), regs)
#define GET_RS2(insn, regs) REG_VAL(GET_RS2_NUM(insn), regs)
#define GET_RS1S(insn, regs) REG_VAL(GET_RS1S_NUM(insn), regs)
#define GET_RS2S(insn, regs) REG_VAL(GET_RS2S_NUM(insn), regs)
#define GET_RS2C(insn, regs) REG_VAL(GET_RS2C_NUM(insn), regs)
#define SET_RD(insn, regs, val) (REG_VAL(GET_RD_NUM(insn), regs) = (val))
/** Representation of trap details */
struct sbi_trap_info {
/** epc Trap program counter */
unsigned long epc;
/** cause Trap exception cause */
unsigned long cause;
/** tval Trap value */
@@ -200,14 +229,65 @@ struct sbi_trap_info {
unsigned long tval2;
/** tinst Trap instruction */
unsigned long tinst;
/** gva Guest virtual address in tval flag */
unsigned long gva;
};
/** Representation of trap context saved on stack */
struct sbi_trap_context {
/** Register state */
struct sbi_trap_regs regs;
/** Trap details */
struct sbi_trap_info trap;
/** Pointer to previous trap context */
struct sbi_trap_context *prev_context;
};
static inline unsigned long sbi_regs_gva(const struct sbi_trap_regs *regs)
{
/*
* If the hypervisor extension is not implemented, mstatus[h].GVA is a
* WPRI field, which is guaranteed to read as zero. In addition, in this
* case we don't read mstatush and instead pretend it is zero, which
* handles privileged spec version < 1.12.
*/
#if __riscv_xlen == 32
return (regs->mstatusH & MSTATUSH_GVA) ? 1 : 0;
#else
return (regs->mstatus & MSTATUS_GVA) ? 1 : 0;
#endif
}
static inline bool sbi_regs_from_virt(const struct sbi_trap_regs *regs)
{
#if __riscv_xlen == 32
return (regs->mstatusH & MSTATUSH_MPV) ? true : false;
#else
return (regs->mstatus & MSTATUS_MPV) ? true : false;
#endif
}
static inline int sbi_mstatus_prev_mode(unsigned long mstatus)
{
return (mstatus & MSTATUS_MPP) >> MSTATUS_MPP_SHIFT;
}
int sbi_trap_redirect(struct sbi_trap_regs *regs,
struct sbi_trap_info *trap);
const struct sbi_trap_info *trap);
struct sbi_trap_regs *sbi_trap_handler(struct sbi_trap_regs *regs);
static inline struct sbi_trap_context *sbi_trap_get_context(struct sbi_scratch *scratch)
{
return (scratch) ? (void *)scratch->trap_context : NULL;
}
void __noreturn sbi_trap_exit(const struct sbi_trap_regs *regs);
static inline void sbi_trap_set_context(struct sbi_scratch *scratch,
struct sbi_trap_context *tcntx)
{
scratch->trap_context = (unsigned long)tcntx;
}
struct sbi_trap_context *sbi_trap_handler(struct sbi_trap_context *tcntx);
#endif

View File

@@ -0,0 +1,40 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __SBI_TRAP_LDST_H__
#define __SBI_TRAP_LDST_H__
#include <sbi/sbi_types.h>
#include <sbi/sbi_trap.h>
union sbi_ldst_data {
u64 data_u64;
u32 data_u32;
u8 data_bytes[8];
ulong data_ulong;
};
int sbi_misaligned_load_handler(struct sbi_trap_context *tcntx);
int sbi_misaligned_store_handler(struct sbi_trap_context *tcntx);
int sbi_load_access_handler(struct sbi_trap_context *tcntx);
int sbi_store_access_handler(struct sbi_trap_context *tcntx);
ulong sbi_misaligned_tinst_fixup(ulong orig_tinst, ulong new_tinst,
ulong addr_offset);
int sbi_misaligned_v_ld_emulator(int rlen, union sbi_ldst_data *out_val,
struct sbi_trap_context *tcntx);
int sbi_misaligned_v_st_emulator(int wlen, union sbi_ldst_data in_val,
struct sbi_trap_context *tcntx);
#endif

View File

@@ -44,7 +44,12 @@ typedef unsigned long long uint64_t;
#error "Unexpected __riscv_xlen"
#endif
typedef int bool;
#if __STDC_VERSION__ < 202000L
typedef _Bool bool;
#define true 1
#define false 0
#endif
typedef unsigned long ulong;
typedef unsigned long uintptr_t;
typedef unsigned long size_t;
@@ -54,10 +59,12 @@ typedef unsigned long virtual_size_t;
typedef unsigned long physical_addr_t;
typedef unsigned long physical_size_t;
#define TRUE 1
#define FALSE 0
#define true TRUE
#define false FALSE
typedef uint16_t le16_t;
typedef uint16_t be16_t;
typedef uint32_t le32_t;
typedef uint32_t be32_t;
typedef uint64_t le64_t;
typedef uint64_t be64_t;
#define NULL ((void *)0)
@@ -65,6 +72,10 @@ typedef unsigned long physical_size_t;
#define __noreturn __attribute__((noreturn))
#define __aligned(x) __attribute__((aligned(x)))
#ifndef __always_inline
#define __always_inline inline __attribute__((always_inline))
#endif
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
@@ -85,6 +96,13 @@ typedef unsigned long physical_size_t;
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
#define assert_member_offset(type, member, offset) \
_Static_assert( \
(offsetof(type, member)) == (offset ), \
"The offset " #offset " of " #member " in " #type \
"is not correct, please redefine it.")
#define array_size(x) (sizeof(x) / sizeof((x)[0]))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

View File

@@ -0,0 +1,73 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Author: Ivan Orlov <ivan.orlov0322@gmail.com>
*/
#ifdef CONFIG_SBIUNIT
#ifndef __SBI_UNIT_H__
#define __SBI_UNIT_H__
#include <sbi/sbi_types.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_string.h>
struct sbiunit_test_case {
const char *name;
bool failed;
void (*test_func)(struct sbiunit_test_case *test);
};
struct sbiunit_test_suite {
const char *name;
void (*init)(void);
struct sbiunit_test_case *cases;
};
#define SBIUNIT_TEST_CASE(func) \
{ \
.name = #func, \
.failed = false, \
.test_func = (func) \
}
#define SBIUNIT_END_CASE { }
#define SBIUNIT_TEST_SUITE(suite_name, cases_arr) \
struct sbiunit_test_suite suite_name = { \
.name = #suite_name, \
.init = NULL, \
.cases = cases_arr \
}
#define _sbiunit_msg(test, msg) "[SBIUnit] [%s:%d]: %s: %s", __FILE__, \
__LINE__, test->name, msg
#define SBIUNIT_INFO(test, msg) sbi_printf(_sbiunit_msg(test, msg))
#define SBIUNIT_PANIC(test, msg) sbi_panic(_sbiunit_msg(test, msg))
#define SBIUNIT_EXPECT(test, cond) do { \
if (!(cond)) { \
test->failed = true; \
SBIUNIT_INFO(test, "Condition \"" #cond "\" expected to be true!\n"); \
} \
} while (0)
#define SBIUNIT_ASSERT(test, cond) do { \
if (!(cond)) \
SBIUNIT_PANIC(test, "Condition \"" #cond "\" must be true!\n"); \
} while (0)
#define SBIUNIT_EXPECT_EQ(test, a, b) SBIUNIT_EXPECT(test, (a) == (b))
#define SBIUNIT_ASSERT_EQ(test, a, b) SBIUNIT_ASSERT(test, (a) == (b))
#define SBIUNIT_EXPECT_NE(test, a, b) SBIUNIT_EXPECT(test, (a) != (b))
#define SBIUNIT_ASSERT_NE(test, a, b) SBIUNIT_ASSERT(test, (a) != (b))
#define SBIUNIT_EXPECT_MEMEQ(test, a, b, len) SBIUNIT_EXPECT(test, !sbi_memcmp(a, b, len))
#define SBIUNIT_ASSERT_MEMEQ(test, a, b, len) SBIUNIT_ASSERT(test, !sbi_memcmp(a, b, len))
#define SBIUNIT_EXPECT_STREQ(test, a, b, len) SBIUNIT_EXPECT(test, !sbi_strncmp(a, b, len))
#define SBIUNIT_ASSERT_STREQ(test, a, b, len) SBIUNIT_ASSERT(test, !sbi_strncmp(a, b, len))
void run_all_tests(void);
#endif
#else
#define run_all_tests()
#endif

View File

@@ -11,7 +11,7 @@
#define __SBI_VERSION_H__
#define OPENSBI_VERSION_MAJOR 1
#define OPENSBI_VERSION_MINOR 0
#define OPENSBI_VERSION_MINOR 7
/**
* OpenSBI 32-bit version with:

View File

@@ -0,0 +1,18 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2025 SiFive
*/
#ifndef __SBI_VISIBILITY_H__
#define __SBI_VISIBILITY_H__
#ifndef __DTS__
/*
* Declare all global objects with hidden visibility so access is PC-relative
* instead of going through the GOT.
*/
#pragma GCC visibility push(hidden)
#endif
#endif

View File

@@ -13,6 +13,8 @@
#include <sbi/sbi_types.h>
#ifdef CONFIG_FDT_DOMAIN
struct sbi_domain;
/**
@@ -68,6 +70,13 @@ void fdt_domain_fixup(void *fdt);
*
* @return 0 on success and negative error code on failure
*/
int fdt_domains_populate(void *fdt);
int fdt_domains_populate(const void *fdt);
#else
static inline void fdt_domain_fixup(void *fdt) { }
static inline int fdt_domains_populate(const void *fdt) { return 0; }
#endif
#endif /* __FDT_DOMAIN_H__ */

View File

@@ -0,0 +1,63 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* fdt_driver.h - Generic support for initializing drivers from DT nodes.
*
* Copyright (c) 2024 SiFive
*/
#ifndef __FDT_DRIVER_H__
#define __FDT_DRIVER_H__
#include <sbi_utils/fdt/fdt_helper.h>
struct fdt_driver {
const struct fdt_match *match_table;
int (*init)(const void *fdt, int nodeoff,
const struct fdt_match *match);
bool experimental;
};
/* List of early FDT drivers generated at compile time */
extern const struct fdt_driver *const fdt_early_drivers[];
/**
* Initialize a driver instance for a specific DT node
*
* @param fdt devicetree blob
* @param nodeoff offset of a node in the devicetree blob
* @param drivers NULL-terminated array of drivers to match against this node
*
* @return 0 if a driver was matched and successfully initialized or a negative
* error code on failure
*/
int fdt_driver_init_by_offset(const void *fdt, int nodeoff,
const struct fdt_driver *const *drivers);
/**
* Initialize a driver instance for each DT node that matches any of the
* provided drivers
*
* @param fdt devicetree blob
* @param drivers NULL-terminated array of drivers to match against each node
*
* @return 0 if drivers for all matches (if any) were successfully initialized
* or a negative error code on failure
*/
int fdt_driver_init_all(const void *fdt,
const struct fdt_driver *const *drivers);
/**
* Initialize a driver instance for the first DT node that matches any of the
* provided drivers
*
* @param fdt devicetree blob
* @param drivers NULL-terminated array of drivers to match against each node
*
* @return 0 if a driver was matched and successfully initialized or a negative
* error code on failure
*/
int fdt_driver_init_one(const void *fdt,
const struct fdt_driver *const *drivers);
#endif /* __FDT_DRIVER_H__ */

View File

@@ -9,6 +9,31 @@
#ifndef __FDT_FIXUP_H__
#define __FDT_FIXUP_H__
#include <sbi/sbi_list.h>
struct sbi_cpu_idle_state {
const char *name;
uint32_t suspend_param;
bool local_timer_stop;
uint32_t entry_latency_us;
uint32_t exit_latency_us;
uint32_t min_residency_us;
uint32_t wakeup_latency_us;
};
/**
* Add CPU idle states to cpu nodes in the DT
*
* Add information about CPU idle states to the devicetree. This function
* assumes that CPU idle states are not already present in the devicetree, and
* that all CPU states are equally applicable to all CPUs.
*
* @param fdt: device tree blob
* @param states: array of idle state descriptions, ending with empty element
* @return zero on success and -ve on failure
*/
int fdt_add_cpu_idle_states(void *fdt, const struct sbi_cpu_idle_state *state);
/**
* Fix up the CPU node in the device tree
*
@@ -21,6 +46,30 @@
*/
void fdt_cpu_fixup(void *fdt);
/**
* Fix up the APLIC nodes in the device tree
*
* This routine disables APLIC nodes which are not accessible to the next
* booting stage based on currently assigned domain.
*
* It is recommended that platform codes call this helper in their final_init()
*
* @param fdt: device tree blob
*/
void fdt_aplic_fixup(void *fdt);
/**
* Fix up the IMSIC nodes in the device tree
*
* This routine disables IMSIC nodes which are not accessible to the next
* booting stage based on currently assigned domain.
*
* It is recommended that platform codes call this helper in their final_init()
*
* @param fdt: device tree blob
*/
void fdt_imsic_fixup(void *fdt);
/**
* Fix up the PLIC node in the device tree
*
@@ -46,26 +95,26 @@ void fdt_plic_fixup(void *fdt);
*/
int fdt_reserved_memory_fixup(void *fdt);
/**
* Fix up the reserved memory subnodes in the device tree
*
* This routine adds the no-map property to the reserved memory subnodes so
* that the OS does not map those PMP protected memory regions.
*
* Platform codes must call this helper in their final_init() after fdt_fixups()
* if the OS should not map the PMP protected reserved regions.
*
* @param fdt: device tree blob
* @return zero on success and -ve on failure
*/
int fdt_reserved_memory_nomap_fixup(void *fdt);
/** Representation of a general fixup */
struct fdt_general_fixup {
struct sbi_dlist head;
const char *name;
void (*do_fixup)(struct fdt_general_fixup *f, void *fdt);
};
/** Register a general fixup */
int fdt_register_general_fixup(struct fdt_general_fixup *fixup);
/** UnRegister a general fixup */
void fdt_unregister_general_fixup(struct fdt_general_fixup *fixup);
/**
* General device tree fix-up
*
* This routine do all required device tree fix-ups for a typical platform.
* It fixes up the PLIC node and the reserved memory node in the device tree
* by calling the corresponding helper routines to accomplish the task.
* It fixes up the PLIC node, IMSIC nodes, APLIC nodes, and the reserved
* memory node in the device tree by calling the corresponding helper
* routines to accomplish the task.
*
* It is recommended that platform codes call this helper in their final_init()
*

View File

@@ -11,11 +11,11 @@
#define __FDT_HELPER_H__
#include <sbi/sbi_types.h>
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_domain.h>
struct fdt_match {
const char *compatible;
void *data;
const void *data;
};
#define FDT_MAX_PHANDLE_ARGS 16
@@ -31,60 +31,92 @@ struct platform_uart_data {
unsigned long baud;
unsigned long reg_shift;
unsigned long reg_io_width;
unsigned long reg_offset;
};
const struct fdt_match *fdt_match_node(void *fdt, int nodeoff,
const struct fdt_match *match_table);
int fdt_find_match(void *fdt, int startoff,
const struct fdt_match *match_table,
const struct fdt_match **out_match);
int fdt_parse_phandle_with_args(void *fdt, int nodeoff,
int fdt_parse_phandle_with_args(const void *fdt, int nodeoff,
const char *prop, const char *cells_prop,
int index, struct fdt_phandle_args *out_args);
int fdt_get_node_addr_size(void *fdt, int node, int index,
int fdt_get_node_addr_size(const void *fdt, int node, int index,
uint64_t *addr, uint64_t *size);
int fdt_parse_hart_id(void *fdt, int cpu_offset, u32 *hartid);
int fdt_get_node_addr_size_by_name(const void *fdt, int node, const char *name,
uint64_t *addr, uint64_t *size);
int fdt_parse_max_hart_id(void *fdt, u32 *max_hartid);
bool fdt_node_is_enabled(const void *fdt, int nodeoff);
int fdt_parse_timebase_frequency(void *fdt, unsigned long *freq);
int fdt_parse_hart_id(const void *fdt, int cpu_offset, u32 *hartid);
int fdt_parse_gaisler_uart_node(void *fdt, int nodeoffset,
int fdt_parse_max_enabled_hart_id(const void *fdt, u32 *max_hartid);
int fdt_parse_cbom_block_size(const void *fdt, int cpu_offset, unsigned long *cbom_block_size);
int fdt_parse_timebase_frequency(const void *fdt, unsigned long *freq);
int fdt_parse_isa_extensions(const void *fdt, unsigned int hartid,
unsigned long *extensions);
int fdt_parse_gaisler_uart_node(const void *fdt, int nodeoffset,
struct platform_uart_data *uart);
int fdt_parse_shakti_uart_node(void *fdt, int nodeoffset,
int fdt_parse_renesas_scif_node(const void *fdt, int nodeoffset,
struct platform_uart_data *uart);
int fdt_parse_shakti_uart_node(const void *fdt, int nodeoffset,
struct platform_uart_data *uart);
int fdt_parse_sifive_uart_node(void *fdt, int nodeoffset,
int fdt_parse_sifive_uart_node(const void *fdt, int nodeoffset,
struct platform_uart_data *uart);
int fdt_parse_uart8250_node(void *fdt, int nodeoffset,
struct platform_uart_data *uart);
int fdt_parse_uart_node(const void *fdt, int nodeoffset,
struct platform_uart_data *uart);
int fdt_parse_uart8250(void *fdt, struct platform_uart_data *uart,
int fdt_parse_uart8250(const void *fdt, struct platform_uart_data *uart,
const char *compatible);
int fdt_parse_xlnx_uartlite_node(const void *fdt, int nodeoffset,
struct platform_uart_data *uart);
struct aplic_data;
int fdt_parse_aplic_node(const void *fdt, int nodeoff, struct aplic_data *aplic);
struct imsic_data;
bool fdt_check_imsic_mlevel(const void *fdt);
int fdt_parse_imsic_node(const void *fdt, int nodeoff, struct imsic_data *imsic);
struct plic_data;
int fdt_parse_plic_node(void *fdt, int nodeoffset, struct plic_data *plic);
int fdt_parse_plic_node(const void *fdt, int nodeoffset, struct plic_data *plic);
int fdt_parse_plic(void *fdt, struct plic_data *plic, const char *compat);
int fdt_parse_plic(const void *fdt, struct plic_data *plic, const char *compat);
int fdt_parse_aclint_node(void *fdt, int nodeoffset, bool for_timer,
int fdt_parse_aclint_node(const void *fdt, int nodeoffset,
bool for_timer, bool allow_regname,
unsigned long *out_addr1, unsigned long *out_size1,
unsigned long *out_addr2, unsigned long *out_size2,
u32 *out_first_hartid, u32 *out_hart_count);
int fdt_parse_compat_addr(void *fdt, uint64_t *addr,
int fdt_parse_plmt_node(const void *fdt, int nodeoffset, unsigned long *plmt_base,
unsigned long *plmt_size, u32 *hart_count);
int fdt_parse_plicsw_node(const void *fdt, int nodeoffset, unsigned long *plicsw_base,
unsigned long *size, u32 *hart_count);
int fdt_parse_compat_addr(const void *fdt, uint64_t *addr,
const char *compatible);
static inline void *fdt_get_address(void)
static inline const void *fdt_get_address(void)
{
return sbi_scratch_thishart_arg1_ptr();
return (const void *)root.next_arg1;
}
static inline void *fdt_get_address_rw(void)
{
return (void *)root.next_arg1;
}
#endif /* __FDT_HELPER_H__ */

View File

@@ -13,6 +13,25 @@
#include <sbi/sbi_types.h>
struct fdt_pmu_hw_event_select_map {
uint32_t eidx;
uint64_t select;
};
struct fdt_pmu_hw_event_counter_map {
uint32_t eidx_start;
uint32_t eidx_end;
uint32_t ctr_map;
};
struct fdt_pmu_raw_event_counter_map {
uint64_t select;
uint64_t select_mask;
uint32_t ctr_map;
};
#ifdef CONFIG_FDT_PMU
/**
* Fix up the PMU node in the device tree
*
@@ -24,7 +43,7 @@
*
* @param fdt device tree blob
*/
void fdt_pmu_fixup(void *fdt);
int fdt_pmu_fixup(void *fdt);
/**
* Setup PMU data from device tree
@@ -33,7 +52,7 @@ void fdt_pmu_fixup(void *fdt);
*
* @return 0 on success and negative error code on failure
*/
int fdt_pmu_setup(void *fdt);
int fdt_pmu_setup(const void *fdt);
/**
* Get the mhpmevent select value read from DT for a given event
@@ -43,4 +62,12 @@ int fdt_pmu_setup(void *fdt);
*/
uint64_t fdt_pmu_get_select_value(uint32_t event_idx);
#else
static inline void fdt_pmu_fixup(void *fdt) { }
static inline int fdt_pmu_setup(const void *fdt) { return 0; }
static inline uint64_t fdt_pmu_get_select_value(uint32_t event_idx) { return 0; }
#endif
#endif

View File

@@ -10,20 +10,21 @@
#ifndef __FDT_GPIO_H__
#define __FDT_GPIO_H__
#include <sbi_utils/fdt/fdt_driver.h>
#include <sbi_utils/gpio/gpio.h>
struct fdt_phandle_args;
/** FDT based GPIO driver */
struct fdt_gpio {
const struct fdt_match *match_table;
struct fdt_driver driver;
int (*xlate)(struct gpio_chip *chip,
const struct fdt_phandle_args *pargs,
struct gpio_pin *out_pin);
int (*init)(void *fdt, int nodeoff, u32 phandle,
const struct fdt_match *match);
};
/** Get a GPIO pin using "gpios" DT property of client DT node */
int fdt_gpio_pin_get(void *fdt, int nodeoff, int index,
int fdt_gpio_pin_get(const void *fdt, int nodeoff, int index,
struct gpio_pin *out_pin);
/** Simple xlate function to convert two GPIO FDT cells into GPIO pin */

View File

@@ -40,7 +40,7 @@ struct gpio_pin {
/** Representation of a GPIO chip */
struct gpio_chip {
/** Pointer to GPIO driver owning this GPIO chip */
void *driver;
const void *driver;
/** Uniquie ID of the GPIO chip assigned by the driver */
unsigned int id;
/** Number of GPIOs supported by the GPIO chip */

View File

@@ -0,0 +1,21 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2022 StarFive Technology Co., Ltd.
*
* Author: Minda Chen <minda.chen@starfivetech.com>
*/
#ifndef __DW_I2C_H__
#define __DW_I2C_H__
#include <sbi_utils/i2c/i2c.h>
int dw_i2c_init(struct i2c_adapter *, int nodeoff);
struct dw_i2c_adapter {
unsigned long addr;
struct i2c_adapter adapter;
};
#endif

View File

@@ -10,17 +10,11 @@
#ifndef __FDT_I2C_H__
#define __FDT_I2C_H__
#include <sbi_utils/fdt/fdt_driver.h>
#include <sbi_utils/i2c/i2c.h>
/** FDT based I2C adapter driver */
struct fdt_i2c_adapter {
const struct fdt_match *match_table;
int (*init)(void *fdt, int nodeoff,
const struct fdt_match *match);
};
/** Get I2C adapter identified by nodeoff */
int fdt_i2c_adapter_get(void *fdt, int nodeoff,
int fdt_i2c_adapter_get(const void *fdt, int nodeoff,
struct i2c_adapter **out_adapter);
#endif

View File

@@ -15,9 +15,6 @@
/** Representation of a I2C adapter */
struct i2c_adapter {
/** Pointer to I2C driver owning this I2C adapter */
void *driver;
/** Unique ID of the I2C adapter assigned by the driver */
int id;

View File

@@ -26,8 +26,6 @@ struct aclint_mswi_data {
u32 hart_count;
};
int aclint_mswi_warm_init(void);
int aclint_mswi_cold_init(struct aclint_mswi_data *mswi);
#endif

Some files were not shown because too many files have changed in this diff Show More