Commit graph

228 commits

Author SHA1 Message Date
Anas Nashif 37f427a5c7 arch: introduce arch_smp_init
Introduce a new arch interface for intializing smp.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2024-01-09 10:00:17 +01:00
Gerard Marull-Paretas 0106e8d14c arch: riscv: introduce RISCV_PRIVILEGED
Introduce a new arch level Kconfig option to signal the implementation
of the RISCV Privileged ISA spec. This replaces
SOC_FAMILY_RISCV_PRIVILEGED, because this is not a SoC specific
property, nor a SoC family.

Note that the SoC family naming scheme will be fixed in upcoming
commits.

Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
2024-01-09 09:40:07 +01:00
Anas Nashif e25f31ab78 arch: guard more code with CONFIG_EXCEPTION_DEBUG
It should be possible to disable exception debug, which is enabled by
default to reduce image size. Add missing guards now that the option is
cross architecture.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2023-12-14 09:32:27 +01:00
Anas Nashif 9f3ed1b2b3 arch: _PrepC -> z_prep_c
Rename to use common naming for z_prep_c applied to all architectures.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2023-12-11 18:23:52 -05:00
Katsuhiro Suzuki 9e29c70a1f arch: riscv: fix hangup in boot if hart0 is not boot hart
This patch changes the section of riscv_cpu_wake_flag variable to
noinit from bss to fix hangup of RISC-V multicore boot if hart0 is
not boot hart (CONFIG_RV_BOOT_HART != 0).

Current boot sequence initializes a riscv_cpu_wake_flag to -1 but
this variable is unintentionally changed to 0 by boot hart.
This is because the variable is placed in bss section so this patch
changes the section of the variable to noinit.

Signed-off-by: Katsuhiro Suzuki <katsuhiro@katsuster.net>
2023-11-14 09:24:17 +01:00
Katsuhiro Suzuki 4ce5f7ebe1 arch: riscv: fix hangup of multicore boot
This patch fixes hangup of RISC-V multicore boot.
Currently boot sequence uses a riscv_cpu_wake_flag to notify wakeup
request for secondary core(s).

But initial value of riscv_cpu_wake_flag is undefined, so current
mechanism is going to hangup if riscv_cpu_wake_flag and mhartid of
secondary core have the same value.

This is an example situation of this problem:

- hart1: check riscv_cpu_wake_flag (value is 1) and end the loop
- hart1: set riscv_cpu_wake_flag to 0
- hart0: set riscv_cpu_wake_flag to 1
         hart0 expects it will be changed to 0 by hart1 but it
         has never happened

Note:
  - hart0's mhartid is 0, hart1's mhartid is 1
  - hart0 is main, hart1 is secondary in this example

Signed-off-by: Katsuhiro Suzuki <katsuhiro@katsuster.net>
2023-11-10 10:40:01 +01:00
Nicolas Pitre 38373aa599 riscv: FPU trap: catch fused multiply-add instructions
The FMADD, FMSUB, FNMSUB and FNMADD instructions occupy major opcode
spaces of their own, separate from LOAD-FP/STORE-FP and OP-FP spaces.
Insert code to cover them.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-11-10 10:39:28 +01:00
Yong Cong Sin e538b0e5a6 drivers: plic: support multiple instances for multi-level
Most of the public APIs in `riscv_plic.h`
(except `riscv_plic_get_irq` & `riscv_plic_get_dev`) expect the
`irq` argument to be in Zephyr-encoded format, instead of the
previously `irq_from_level_2`-stripped version. The first level
IRQ is needed by `intc_plic` to differentiate between the
parent interrupt controllers, so that correct ISR offset can be
obtained using the LUT in `sw_isr_common`.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
2023-11-09 18:20:43 +01:00
Yong Cong Sin d7302f417e irq: relocate multi-level irq out of irq.h
Relocate multi-level interrupts APIs out of `irq.h` into
a new file named `irq_multilevel.h` to provide cleaner
separation between typical irq & multilevel ones.

Added preprocessor versions of `irq_to_level_x` as `IRQ_TO_Lx`.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
2023-10-30 11:43:39 -04:00
Rick Tsao 7c25a7562b riscv: pmp: Fix assertion for PMP misaligned start address and size
Fix assertion to check whether the start address and size align with
PMP granularity.

Signed-off-by: Rick Tsao <rick592@andestech.com>
2023-10-25 10:05:24 +02:00
Lingutla Chandrasekhar 64aa25a8a4 RISCV: Support pm cpu ops for SMP
Add pm cpu ops to call the platform specific implementations for
bringing up secondary cores.

Signed-off-by: Lingutla Chandrasekhar <quic_lingutla@quicinc.com>
2023-10-23 11:36:01 +02:00
Alexander Razinkov 176713abfe arch: riscv: Trap handler alignment configuration
RISC-V Spec requires minimum alignment of trap handling code to be
dependent from MTVEC.BASE field size. Minimum alignment for RISC-V
platforms is 4 bytes, but maximum is platform or application-specific.

Currently there is no common approach to align the trap handling
code for RISC-V and some platforms use custom wrappers to align
_isr_wrapper properly.

This change introduces a generic solution,
CONFIG_RISCV_TRAP_HANDLER_ALIGNMENT configuration option which sets
the alignment of a RISC-V trap handling code.

The existing custom solutions for some platforms remain operational,
since the default alignment is set to minimal possible (4 bytes)
and will be overloaded by potentially larger alignment of custom solutions.

Signed-off-by: Alexander Razinkov <alexander.razinkov@syntacore.com>
2023-09-05 16:16:46 +02:00
Anas Nashif 6baa622958 arch: move exc_handle.h under zephyr/arch/common
This header is private and included only in architecture code, no need for
it to be in the top of the public include directory.

Note: This might move to a more private location later. For now just
cleaning up the obvious issues.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2023-08-31 09:19:19 -04:00
Daniel Leung 6b740b20de riscv: renames shadow variables
In print_pmp_entries(), start and end are function arguments
and yet another start and end are declared inside the for
loop. So rename the function arguments to fix shadow variables
warning.

The changes in csr_*() macros are needed to avoid shadowing
__v when nesting those functions together, for example,
csr_write(..., csr_read(...)).

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2023-08-10 08:14:12 +00:00
Yong Cong Sin 84b86d9b0c soc: riscv: Add ability to use custom sys_io functions
Add Kconfig RISCV_SOC_HAS_CUSTOM_SYS_IO symbol so that a riscv
SoC can set to specify that it has a custom implementation for
sys_io functions.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
2023-07-26 09:43:59 +02:00
Daniel Leung 97dc67e666 riscv: syscalls: use zephyr_syscall_header
This adds a few line use zephyr_syscall_header() to include
headers containing syscall function prototypes.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2023-06-17 07:57:45 -04:00
Carlo Caione d395b7f1e8 riscv: Add CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET
Some RISCV platforms shipping a CLIC have a peculiar interrupt ID
ordering / mapping.

According to the "Core-Local Interrupt Controller (CLIC) RISC-V
Privileged Architecture Extensions" Version 0.9-draft at paragraph 16.1
one of these ordering recommendations is "CLIC-mode interrupt-map for
systems retaining interrupt ID compatible with CLINT mode" that is
described how:

  The CLINT-mode interrupts retain their interrupt ID in CLIC mode.
  [...]
  The existing CLINT software interrupt bits are primarily intended for
  inter-hart interrupt signaling, and so are retained for that purpose.
  [...]
  CLIC interrupt inputs are allocated IDs beginning at interrupt ID
  17. Any fast local interrupts that would have been connected at
  interrupt ID 16 and above should now be mapped into corresponding
  inputs of the CLIC.

That is a very convoluted way to say that interrupts 0 to 15 are
reserved for internal use and CLIC only controls interrupts reserved for
platform use (16 up to n + 16, where n is the maximum number of
interrupts supported).

Let's now take now into consideration this situation in the DT:

  clic: interrupt-controller {
    ...
  };

  device0: some-device {
    interrupt-parent = <&clic>;
    interrupts = <0x1>;
    ...
  };

and in the driver for device0:

  IRQ_CONNECT(DT_IRQN(node), ...);

From the hardware prospective:

(1a) device0 is using the first IRQ line of the CLIC
(2a) the interrupt ID / exception code of the `MSTATUS` register
     associated to this IRQ is 17, because the IDs 0 to 15 are reserved

From the software / Zephyr prospective:

(1b) Zephyr is installing the IRQ vector into the SW ISR table (and into
     the IRQ vector table for DIRECT ISRs in case of CLIC vectored mode)
     at index 0x1.
(2b) Zephyr is using the interrupt ID of the `MSTATUS` register to index
     into the SW ISR table (or IRQ vector table)

It's now clear how (2a) and (2b) are in contrast with each other.

To fix this problem we have to take into account the offset introduced
by the reserved interrupts. To do so we introduce
CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET as hidden option for the
platforms to set.

This Kconfig option is used to shift the interrupt numbers when
installing the IRQ vector into the SW ISR table and/or IRQ vector table.
So for example in the previous case and using
CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET == 16, the IRQ vector
associated to the device0 would be correctly installed at index 17 (16 +
1), matching what is reported by the `MSTATUS` register.

CONFIG_NUM_IRQS must be increased accordingly.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-06-17 07:49:16 -04:00
Carlo Caione 6160383ec7 riscv: Rename RISCV_MTVEC_VECTORED_MODE to RISCV_VECTORED_MODE
Before adding support for the CLIC vectored mode, rename
CONFIG_RISCV_MTVEC_VECTORED_MODE to CONFIG_RISCV_VECTORED_MODE to be
more generic and eventually include also the CLIC vectored mode.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-06-17 07:48:52 -04:00
Dino Li 252d68ff9f arch/riscv: add support for detecting null pointer exception using PMP
This change uses a PMP slot to implement null pointer detection.

Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
2023-06-17 07:45:30 -04:00
Carlo Caione edd3437826 riscv: Rename Kconfig symbol to *_PRIVILEGED
Rename SOC_FAMILY_RISCV_PRIVILEGE to SOC_FAMILY_RISCV_PRIVILEGED because
the spec is "privileged".

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-06-09 11:46:29 -04:00
Nicolas Pitre 5c7d2f1a90 riscv: exclude more code when multithreading is disabled
This will avoid unconditionally pulling z_riscv_switch() into the build
as it is not used, reducing the resulting binary some more.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-05-31 06:17:10 -04:00
Marek Matej 92b7d37397 arch: riscv: Fix bogus condition
Remove double preprocessor condition.

Signed-off-by: Marek Matej <marek.matej@espressif.com>
2023-05-26 10:36:15 -04:00
Nicolas Pitre 6935ea54d5 Revert "arch: riscv: Enable builds without the multithreading"
This reverts commit f0b458a619.

This is a pointless change that simply increases footprint.
Existing code already supports compilation without multithreading.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-05-26 09:04:30 -04:00
Marek Matej f0b458a619 arch: riscv: Enable builds without the multithreading
Allow builds which has CONFIG_MULTITHREADING disabled.
This is reduce code footprint which is handy for
constrained targets as bootloaders.

Signed-off-by: Marek Matej <marek.matej@espressif.com>
2023-05-25 16:15:54 +02:00
Marek Matej 4796746b5e soc: esp32: MCUboot support
This make MCUboot build as Zephyr application.
Providing optinal 2nd stage bootloader to the
IDF bootloader, which is used by default.
This provides more flexibility when building
and loading multiple images and aims to
brings better DX to users by using the sysbuild.
MCUboot and applications has now separate
linker scripts.

Signed-off-by: Marek Matej <marek.matej@espressif.com>
2023-05-25 16:15:54 +02:00
Nicolas Pitre 18ff7ae998 riscv: prevent possible deadlock on SMP with FPU sharing
Let's consider CPU1 waiting on a spinlock already taken by CPU2.

It is possible for CPU2 to invoke the FPU and trigger an FPU exception
when the FPU context for CPU2 is not live on that CPU. If the FPU context
for the thread on CPU2 is still held in CPU1's FPU then an IPI is sent
to CPU1 asking to flush its FPU to memory.

But if CPU1 is spinning on a lock already taken by CPU2, it won't see
the pending IPI as IRQs are disabled. CPU2 won't get its FPU state
restored and won't complete the required work to release the lock.

Let's prevent this deadlock scenario by looking for a pending FPU IPI
from the arch_spin_relax() hook and honor it.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-05-25 08:25:11 +00:00
Nicolas Pitre 03a73fa0db riscv: use atomic bit helpers with IPI values
This is cleaner and less error prone, especially when comes the time
to test and clear a bit.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-05-25 08:25:11 +00:00
TOKITA Hiroshi b674bf6e71 arch: riscv: add ARCH_HAS_SINGLE_THREAD_SUPPORT
Enable single-threading support for the riscv architecture.

Add z_riscv_switch_to_main_no_multithreading function for
supporting single-threading.

The single-threading does not work with enabling PMP_STACK_GUARD.
It is because single-threading does not use context-switching.
But the privileged mode transition that PMP depends on implicitly
presupposes using context-switching. It is a contradiction.
Thus, disable PMP_STACK_GUARD when MULTITHREADING is not enabled.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
2023-05-12 09:56:40 +02:00
Manojkumar Subramaniam d57363bc97 riscv: refactor: Utilize the available helper macro
use helper macros from csr.h instead of inline assembly which results
in cleaner and more maintainable code

Signed-off-by: Manojkumar Subramaniam <manoj@electrolance.com>
2023-04-21 12:54:55 +02:00
Gerard Marull-Paretas a5fd0d184a init: remove the need for a dummy device pointer in SYS_INIT functions
The init infrastructure, found in `init.h`, is currently used by:

- `SYS_INIT`: to call functions before `main`
- `DEVICE_*`: to initialize devices

They are all sorted according to an initialization level + a priority.
`SYS_INIT` calls are really orthogonal to devices, however, the required
function signature requires a `const struct device *dev` as a first
argument. The only reason for that is because the same init machinery is
used by devices, so we have something like:

```c
struct init_entry {
	int (*init)(const struct device *dev);
	/* only set by DEVICE_*, otherwise NULL */
	const struct device *dev;
}
```

As a result, we end up with such weird/ugly pattern:

```c
static int my_init(const struct device *dev)
{
	/* always NULL! add ARG_UNUSED to avoid compiler warning */
	ARG_UNUSED(dev);
	...
}
```

This is really a result of poor internals isolation. This patch proposes
a to make init entries more flexible so that they can accept sytem
initialization calls like this:

```c
static int my_init(void)
{
	...
}
```

This is achieved using a union:

```c
union init_function {
	/* for SYS_INIT, used when init_entry.dev == NULL */
	int (*sys)(void);
	/* for DEVICE*, used when init_entry.dev != NULL */
	int (*dev)(const struct device *dev);
};

struct init_entry {
	/* stores init function (either for SYS_INIT or DEVICE*)
	union init_function init_fn;
	/* stores device pointer for DEVICE*, NULL for SYS_INIT. Allows
	 * to know which union entry to call.
	 */
	const struct device *dev;
}
```

This solution **does not increase ROM usage**, and allows to offer clean
public APIs for both SYS_INIT and DEVICE*. Note that however, init
machinery keeps a coupling with devices.

**NOTE**: This is a breaking change! All `SYS_INIT` functions will need
to be converted to the new signature. See the script offered in the
following commit.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>

init: convert SYS_INIT functions to the new signature

Conversion scripted using scripts/utils/migrate_sys_init.py.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>

manifest: update projects for SYS_INIT changes

Update modules with updated SYS_INIT calls:

- hal_ti
- lvgl
- sof
- TraceRecorderSource

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>

tests: devicetree: devices: adjust test

Adjust test according to the recently introduced SYS_INIT
infrastructure.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>

tests: kernel: threads: adjust SYS_INIT call

Adjust to the new signature: int (*init_fn)(void);

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2023-04-12 14:28:07 +00:00
Rick Tsao d839194a5c riscv: pmp: Add kconfig option for granularity of PMP
Add Kconfig option CONIFG_PMP_GRANULARITY to specify the granularity
of PMP.

Signed-off-by: Rick Tsao <rick592@andestech.com>
2023-04-06 11:50:43 +02:00
Peter Mitsis 2ab7286c71 arch: riscv: Remove unused offset symbols
Removes unused offset symbols under the RISCV architecture.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
2023-02-23 16:44:07 +01:00
Nicolas Pitre 3c440af975 riscv: pmp: provision for implementations with partial PMP support
Looks like some implementors decided not to implement the full set of
PMP range matching modes. Let's rearrange the code so that any of those
modes can be disabled.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-02-20 10:57:11 +01:00
Nicolas Pitre ea34acb62c riscv: stack PMP: fix CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT=y case
Let's honor CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT even for kernel
stacks. This saves one global PMP slot when creating the guard area for
the IRQ stack, and some hw implementations might require that anyway.

With this changes, arch_mem_domain_max_partitions_get() becomes much
more reliable and tests/kernel/mem_protect is more likely to pass even
with the stack guard enabled.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-02-20 10:57:11 +01:00
Carlo Caione 61a204c831 riscv: Do not remove ESF when SOC_ISR_SW_UNSTACKING
When CONFIG_SOC_ISR_SW_UNSTACKING is defined, it's up to the custom soc
code to remove the ESF, because the software-managed part of the ESF is
depending on the hardware. Fix this in the ISR code.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-02-01 03:52:14 +09:00
Nicolas Pitre 10500f1b41 riscv: cope with MTVAL not updated on illegal instruction faults
Some implementations may not capture the faulting instruction in mtval
and set it to zero when an illegal instruction fault is raised This is
notably the case with QEMU version 7.0.0 when a CSR instruction is
involved.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-30 23:47:36 +00:00
Nicolas Pitre 83f849e00e riscv: FPU trap: catch CSR access to fcsr, frm and fflags
The FRCSR, FSCSR, FRRM, FSRM, FSRMI, FRFLAGS, FSFLAGS and FSFLAGSI
are in fact CSR instructions targeting the fcsr, frm and fflags
registers. They should be caught as FPU instructions as well.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-30 23:47:36 +00:00
Nicolas Pitre b2ffee7fe2 riscv: FPU switching fixes
- IRQ state for the interrupted context corresponds to the PIE bit not
  the IE bit.

- Restoring the saved FPU state should clear the entire field before
  or'ing wanted bits in.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-30 23:47:36 +00:00
Conor Paxton 804aa29f89 riscv: smp: use devicetree to map hartids to zephyr cpus
For RISC-V, the reg property of a cpu node in the devicetree describes
the low level unique ID of each hart. Using devicetree macro's, a list
of all cpus with status "okay" can be generated.

Using devicetree overlays, a hart or multiple harts can be marked as
"disabled", thus excluding them from the list. This allows platforms
that have non-zero indexed SMP capable harts to be functionally mapped
to Zephyr's sequential CPU numbering scheme.

On kernel init, if the application has MP_MAX_NUM_CPUS greater than 1,
generate the list of cpu nodes from the device tree with status "okay"
and  map the unique hartid's to zephyr cpu's

While we are at it, as the hartid is the value that gets passed to
z_riscv_secondary_cpu_init, use that as the variable name instead of
cpu_num

Signed-off-by: Conor Paxton <conor.paxton@microchip.com>
2023-01-30 23:45:35 +00:00
Conor Paxton 02391ed00d riscv: enable booting from non-zero indexed RISC-V hart
RISC-V multi-hart systems that employ a heterogeneous core complex are
not guaranteed to have the smp capable harts starting with a unique id
of zero, matching Zephyr's sequential zero indexed cpu numbering scheme.

Add option, RV_BOOT_HART to choose the hart to boot from.
On reset, check the current hart equals RV_BOOT_HART: if so, boot first
core. else, loop in the boot secondary core and wait to be brought up.

For multi-hart systems that are not running a Zephyr mp or smp
application, park the non zephyr related harts in a wfi loop.

Signed-off-by: Conor Paxton <conor.paxton@microchip.com>
2023-01-30 23:45:35 +00:00
David Reiss fb9cdee02d riscv: Fix whitespace in ISR handler
This one line was using spaces instead of tabs for indentation.

Signed-off-by: David Reiss <dreiss@meta.com>
2023-01-27 19:23:21 +09:00
Nicolas Pitre 6b9526c09b riscv: properly clear pending IPI flags
Commit 4f9b547ebd ("riscv: smp: prepare for more than one IPI type")
didn't clear pending IPI flags.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-25 19:51:03 -05:00
Nicolas Pitre a211970b42 riscv: improve contended FPU switching
We can leverage the FPU dirty state as an indicator for preemptively
reloading the FPU content when a thread that did use the FPU before
being scheduled out is scheduled back in. This avoids the FPU access
trap overhead when switching between multiple threads with heavy FPU
usage.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-24 15:26:18 +01:00
Nicolas Pitre ff07da6ff1 riscv: integrate the new FPU context switching support
FPU context switching is always performed on demand through the FPU
access exception handler. Actual task switching only grants or denies
FPU access depending on the current FPU owner.

Because RISC-V doesn't have a dedicated FPU access exception, we must
catch the Illegal Instruction exception and look for actual FP opcodes.

There is no longer a need to allocate FPU storage on the stack for every
exception making esf smaller and stack overflows less likely.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-24 15:26:18 +01:00
Nicolas Pitre cb4c0f6c94 riscv: smarter FPU context switching support
Instead of saving/restoring FPU content on every exception and task
switch, this replaces FPU sharing support with a "lazy" (on-demand)
context switching algorithm similar to the one used on ARM64.

Every thread starts with FPU access disabled. On the first access the
FPU trap is invoked to:

- flush the FPU content to the previous thread's memory storage;

- restore the current thread's FPU content from memory.

When a thread loads its data in the FPU, it becomes the FPU owner.

FPU content is preserved across task switching, however FPU access is
either allowed if the new thread is the FPU owner, or denied otherwise.
A thread may claim FPU ownership only through the FPU trap. This way,
threads that don't use the FPU won't force an FPU context switch.
If only one running thread uses the FPU, there will be no FPU context
switching to do at all.

It is possible to do FP accesses in ISRs and syscalls. This is not the
norm though, so the same principle is applied here, although exception
contexts may not own the FPU. When they access the FPU, the FPU content
is flushed and the exception context is granted FPU access for the
duration of the exception. Nested IRQs are disallowed in that case to
dispense with the need to save and restore exception's FPU context data.

This is the core implementation only to ease reviewing. It is not yet
hooked into the build.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-24 15:26:18 +01:00
Nicolas Pitre 4f9b547ebd riscv: smp: prepare for more than one IPI type
Right now this is hardcoded to z_sched_ipi(). Make it so that other IPI
services can be added in the future.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-24 15:26:18 +01:00
Nicolas Pitre 883e9d367f riscv: translate CPU numbers to hartid values for IPI
Given the Zephyr CPU number is no longer tied to the hartid, we must
consider the actual hartid when sending an IPI to a given CPU. Since
those hartids can be anything, let's just save them in the cpu structure
as each CPU is brought online.

While at it, throw in some `get_hart_msip()` cleanups.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-19 13:48:42 +01:00
Nicolas Pitre 26d7bd47a0 riscv: decouple the Zephyr CPU number from the hart ID
Currently it is assumed that Zephyr CPU numbers match their hartid
value one for one. This assumption was relied upon to efficiently
retrieve the current CPU's `struct _cpu` pointer.

People are starting to have systems with a mix of different usage for
each CPU and such assumption may no longer be true.

Let's completely decouple the hartid from the Zephyr CPU number by
stuffing each CPU's `struct _cpu` pointer in their respective scratch
register instead. `arch_curr_cpu()` becomes more efficient as well.

Since the scratch register was previously used to store userspace's
exception stack pointer, that is now moved into `struct _cpu_arch`
which implied minor user space entry code cleanup and rationalization.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-19 13:48:42 +01:00
Nicolas Pitre 96a65e2fc0 riscv: don't include the secondary CPU boot code when not needed
Linker garbage collection couldn't work due to the explicit reference
in reset.S.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2023-01-19 13:48:42 +01:00
Carlo Caione 43a61329cc riscv: Allow SOC to override arch_irq_{lock,unlock,unlocked}
RISC-V has a modular design. Some hardware with a custom interrupt
controller needs a bit more work to lock / unlock IRQs.

Account for this hardware by introducing a set of new
z_soc_irq_* functions that can override the default behaviour.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-01-09 19:21:39 +01:00