Commit Graph

1305 Commits

Author SHA1 Message Date
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