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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>