Commit graph

274 commits

Author SHA1 Message Date
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
Carlo Caione c13d23a43e riscv: Add support for hardware stacking / unstacking
Some RISC-V SoCs implement a mechanism for hardware supported stacking /
unstacking of registers during ISR / exceptions. What happens is that on
ISR / exception entry part of the context is automatically saved by the
hardware on the stack without software intervention, and the same part
of the context is restored by the hardware usually on mret.

This is currently not yet supported by Zephyr, where the full context
must be saved by software in the full fledged ESF. This patcheset is
trying to address exactly this case.

At least three things are needed to support in a general fashion this
problem: (1) a way to store in software only the part of the ESF not
already stacked by hardware, (2) a way to restore in software only the
part of the context that is not going to be restored by hardware and (3)
a way to define a custom ESF.

Point (3) is important because the full ESF frame is now composed by a
custom part depending on the hardware (that can choose which register to
stack / unstack and the order they are saved onto the stack) and a part
defined in software for the remaining part of the context.

In this patch a new CONFIG_RISCV_SOC_HAS_ISR_STACKING is introduced that
enables the code path supporting the three points by the mean of three
macros that must be implemented by the user in a soc_stacking.h file:
SOC_ISR_SW_STACKING, SOC_ISR_SW_UNSTACKING and SOC_ISR_STACKING_ESF
(refer to the symbol help for more details).

This is an example of soc_isr_stacking.h for an hardware that doesn't do
any hardware stacking / unstacking but everything is managed in
software:

    #ifndef __SOC_ISR_STACKING
    #define __SOC_ISR_STACKING

    #if !defined(_ASMLANGUAGE)

    #define SOC_ISR_STACKING_ESF_DECLARE \
    	struct __esf { \
    		unsigned long ra; \
    		unsigned long t0; \
    		unsigned long t1; \
    		unsigned long t2; \
    		unsigned long t3; \
    		unsigned long t4; \
    		unsigned long t5; \
    		unsigned long t6; \
    		unsigned long a0; \
    		unsigned long a1; \
    		unsigned long a2; \
    		unsigned long a3; \
    		unsigned long a4; \
    		unsigned long a5; \
    		unsigned long a6; \
    		unsigned long a7; \
    		unsigned long mepc; \
    		unsigned long mstatus; \
    		unsigned long s0; \
    	} __aligned(16)
    #else

    #define SOC_ISR_SW_STACKING \
    	addi sp, sp, -__z_arch_esf_t_SIZEOF; \
    	DO_CALLER_SAVED(sr);

    #define SOC_ISR_SW_UNSTACKING \
    	DO_CALLER_SAVED(lr);

    #endif /* _ASMLANGUAGE */
    #endif /* __SOC_ISR_STACKING */

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-01-09 10:15:07 +01:00
Nicolas Pitre 74fbf8edf5 Revert "riscv: PMP-based stack guard is incompatible with stack sentinel"
This reverts commit a7b5d606c7.

The assumption behind that commit was wrong. The software-based stack
sentinel writes to the very bottom of the _writable_ stack area i.e.
right next to the actual PMP based guard area. So they are compatible.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-10-25 10:53:34 +02:00
Kumar Gala 3369997dd2 arch: riscv: Convert to CONFIG_MP_MAX_NUM_CPUS
Convert CONFIG_MP_NUM_CPUS to CONFIG_MP_MAX_NUM_CPUS as we work on
phasing out CONFIG_MP_NUM_CPUS.

Signed-off-by: Kumar Gala <kumar.gala@intel.com>
2022-10-25 10:52:25 +02:00
Kumar Gala a1195ae39b smp: Move for loops to use arch_num_cpus instead of CONFIG_MP_NUM_CPUS
Change for loops of the form:

for (i = 0; i < CONFIG_MP_NUM_CPUS; i++)
   ...

to

unsigned int num_cpus = arch_num_cpus();
for (i = 0; i < num_cpus; i++)
   ...

We do the call outside of the for loop so that it only happens once,
rather than on every iteration.

Signed-off-by: Kumar Gala <kumar.gala@intel.com>
2022-10-21 13:14:58 +02:00
Gerard Marull-Paretas 178bdc4afc include: add missing zephyr/irq.h include
Change automated searching for files using "IRQ_CONNECT()" API not
including <zephyr/irq.h>.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-10-17 22:57:39 +09:00
Kumar Gala c778eb2a56 smp: Move arrays to use CONFIG_MP_MAX_NUM_CPUS
Move to use CONFIG_MP_MAX_NUM_CPUS for array size declarations instead
of CONFIG_MP_NUM_CPUS.

Signed-off-by: Kumar Gala <kumar.gala@intel.com>
2022-10-17 14:40:12 +09:00
Nicolas Pitre 1f362a81f1 riscv: fix crash resulting from touching the initial stack's guard area
The interrupt stack is used as the system stack during kernel
initialization while IRQs are not yet enabled. The sp register is
set to z_interrupt_stacks + CONFIG_ISR_STACK_SIZE.

CONFIG_ISR_STACK_SIZE only represents the desired usable stack size.
This does not take into account the added guard area. Result is a stack
whose pointer is much closer to the trigger zone than expected when
CONFIG_PMP_STACK_GUARD=y, and the SMP configuration in particular pushes
it over the edge during many CI test cases.

Worse: during early init we're not quite ready to handle exceptions
yet and complete havoc ensues with no meaningful debugging output.

Make sure the early assembly code locates the actual top of the stack
by generating a constant with its true size.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-09-28 07:53:56 +00:00
Nicolas Pitre a7b5d606c7 riscv: PMP-based stack guard is incompatible with stack sentinel
The software-based stack sentinel writes to the very bottom of the
stack area triggering the PMP stack protection. Obviously they can't
be used together.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-09-28 07:53:56 +00:00
Nicolas Pitre 4a733694ca riscv: pmp: fix stackguard when used on SMP
The IRQ stack in particular is different on each CPU, and so is its
stack guard PMP entry value. This creates 2 issues:

- The assertion ensuring the last global PMP address is the same
  for each CPU does fail;

- That last global PMP address can't be relied upon to create a
  single-slot per-thread TOR mapping.

Fix both issues by not remembering the actual address for the last
global entry but a dummy address instead that is guaranteed not to
match any opportunistic single-slot TOR mapping.

While at it, lock that IRQ stack guard PMP entry.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-09-28 07:53:56 +00:00
Nicolas Pitre c76d8c88c0 riscv: smp: fix secondary cpus' initial stack
Z_THREAD_STACK_BUFFER() must not be used here. This is meant for stacks
defined with K_THREAD_STACK_ARRAY_DEFINE() whereas in this case we are
given a stack created with K_KERNEL_STACK_ARRAY_DEFINE().

If CONFIG_USERSPACE=y then K_THREAD_STACK_RESERVED gets defined with
a bigger value than K_KERNEL_STACK_RESERVED. Then Z_THREAD_STACK_BUFFER()
returns a pointer that is more advanced than expected, resulting in a
stack pointer outside its actual stack area and therefore memory
corruption ensues.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-09-21 09:01:58 +00:00
Nicolas Pitre 1c857f37da riscv: pmp: fix SMP build with assertion enabled
Fix SMP build with assertion enabled.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-09-20 09:39:35 +02:00
Mateusz Sierszulski 2ed5763baa arch: riscv: core: Place vectors section through zephyr_linker_sources()
This commit is fixing placing the vectors section through
zephyr_linker_sources(ROM_START ...) (as done in the ARM
architecture port) so its order can be adjusted by SORT_KEY.

Fixes #49903

Signed-off-by: Mateusz Sierszulski <msierszulski@antmicro.com>
2022-09-08 10:39:31 +02:00
Gerard Marull-Paretas be38456279 include: types: remove ulong_t
ulong_t was mainly used in MIPS/RISC-V. Just use "unsigned long".

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-09-06 18:16:33 +02:00
Carlo Caione 6503795dc1 riscv: Introduce BitManip extensions
Add Zba, Zbb, Zbc and Zbs BitManip extensions.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-08-29 16:57:18 +02:00
Carlo Caione 5fece03d7d riscv: Introduce Zicsr and Zifencei extensions
And enable the new extensions on all the SoCs.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-08-29 16:57:18 +02:00
Stephanos Ioannidis 7751fbca44 arch: riscv: Align semihost_exec function at 16-byte boundary
QEMU requires that the semihosting trap instruction sequence, which
consists of three uncompressed instructions, lie in the same page, and
refuses to interpret the trap sequence if these instructions are placed
across two different pages.

This commit adds 16-byte alignment requirement to the `semihost_exec`
function, which occupies 12 bytes, to ensure that the three trap
sequence instructions in this function are never placed across two
different pages.

Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
2022-08-08 10:52:34 +02:00
Gerard Marull-Paretas 736a1a9113 soc: riscv: remove usage of SOC_ERET
All SOC_ERET definitions expand to the mret instruction (used to return
from a trap: exception or interruption). The 'eret' instruction existed
in previous RISC-V privileged specs, but it doesn't seem to be used in
Zephyr (ref. RISC-V Privileged Architectures 3.2.2).

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-08-04 13:44:48 +02:00
Carlo Caione 0e788b89a6 riscv: Use IRQ vector table for vectored mode
For vectored interrupts use the generated IRQ vector table instead of
relying on a custom-generated table.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-07-07 10:00:20 +02:00
Carlo Caione 7a11d883cc riscv: Introduce RISCV_ALWAYS_SWITCH_THROUGH_ECALL
Some early RISC-V SoCs have a problem when an `mret` instruction is used
outside a trap handler.

After the latest Zephyr RISC-V huge rework, the arch_switch code is
indeed calling `mret` when not in handler mode, breaking some early
RISC-V platforms.

Optionally restore the old behavior by adding a new
CONFIG_RISCV_ALWAYS_SWITCH_THROUGH_ECALL symbol.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-07-04 18:18:10 +02:00
Nicolas Pitre 83de5b4532 riscv: _isr_wrapper: get rid of the ASSUME_EQUAL() macro
This is really useful only for one case i.e. when testing against zero.
Do that test inline where it is needed and make the rest of the code
independent from the actual numerical value being tested to make code
maintenance easier if/when new cases are added.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-07-04 09:49:16 +02:00
Nicolas Pitre 147728775f riscv: pmp: properly initialize per-thread m-mode/u-mode entry array
Retrieve the pmpaddr value matching the last global PMP slot and add it
to the per-thread m-mode and u-mode entry array. Even if that value is
not written out again on thread context switch, that value can still be
used by set_pmp_entry() to attempt a single-slot TOR mapping with it.

Nicely abstract this with the new z_riscv_pmp_thread_init() where the
PMP_M_MODE(thread) and PMP_U_MODE(thread) argument generators can be
used.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-06-23 15:56:00 -05:00
Nicolas Pitre b6377ccdd7 riscv: pmp: work around another QEMU bug
A QEMU bug may create bad transient PMP representations causing
false access faults to be reported. Work around it by setting
pmp registers to zero from the update start point to the end
before updating them with new values.

The QEMU fix is here with more details about this bug:
https://lists.gnu.org/archive/html/qemu-devel/2022-06/msg02800.html

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-06-23 13:12:05 -04:00
Nicolas Pitre 00a9634c05 riscv: new TLS-based arch_is_user_context() implementation
This reverts the bulk of commit c8bfc2afda ("riscv: make
arch_is_user_context() SMP compatible") and replaces it with a flag
stored in the thread local storage (TLS) area, therefore making TLS
mandatory for userspace support on RISC-V.

This has many advantages:

- The tp (x4) register is already dedicated by the standard for this
  purpose, making TLS support almost free.

- This is very efficient, requiring only a single instruction to clear
  and 2 instructions to set.

- This makes the SMP case much more efficient. No need for funky
  exception code any longer.

- SMP and non-SMP now use the same implementation making maintenance
  easier.

- The is_user_mode variable no longer requires a dedicated PMP mapping
  and therefore freeing one PMP slot for other purposes.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>

5f65dbcc9dab3d39473b05397e05.
2022-06-23 13:12:05 -04:00
Nicolas Pitre 3f8e326d1a riscv: stop preserving the tp register needlessly
The tp (x4) register is neither caller nor callee saved according to
the RISC-V standard calling convention. It only has to be set on thread
context switching and is otherwise read-only.

To protect the kernel against a possible rogue user thread, the tp is
also re-set on exception entry from u-mode.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-06-23 13:12:05 -04:00
Nicolas Pitre 95b18c7f9f riscv: abstract RV32E register access
... and avoid macro duplication.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-06-23 13:12:05 -04:00
Carlo Caione 741b9dc65d riscv: Rename __irq_wrapper to _isr_wrapper
For some reasons RISCV is the only arch where the vector table entry is
called __irq_wrapper instead of _isr_wrapper. This is not only a
cosmetic change but Zephyr expects the common ISR handler to be called
_isr_wrapper (for example when generating the IRQ vector table).

Change it.

find ./ -type f -exec sed -i 's/__irq_wrapper/_isr_wrapper/g' {} \;

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-06-21 20:27:20 -04:00
Carlo Caione 673f41e708 riscv: Introduce support for RV32E
Introduce support for RV32E.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-06-08 18:50:22 +09:00
Carlo Caione 737dccec1a riscv: Move syscall parameter from a7 to t0
To prepare for RV32E support.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-06-08 18:50:22 +09:00
Carlo Caione 3e92f11d1f riscv: Optimize t* registers usage
In preparation for the support of RV32E optimize a bit the t* registers
usage limiting that to t{0-2}.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-06-05 14:44:06 +02:00
Carlo Caione 10061efdc4 riscv: Rework and cleanup Kconfig
This patch is doing several things:

- Core ISA and extension Kconfig symbols have now a formalized name
  (CONFIG_RISCV_ISA_* and CONFIG_RISCV_ISA_EXT_*)

- a new Kconfig.isa file was introduced with the full set of extensions
  currently supported by the v2.2 spec

- a new Kconfig.core file was introduced to host all the RISCV cores
  (currently only E31)

- ISA and extensions settings are moved to SoC configuration files

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-06-05 14:28:42 +02:00
Carles Cufi 56512dae8b arch: riscv: switch: Add a comment on the return of z_riscv_switch
When returning from z_riscv_switch, depending on whether the thread that
has just been swapped in was earlier swapped out synchronously (i.e. via
regular function call) or asynchronously (i.e. via exception/irq) we
will return to arch_switch() or __irq_wrapper respectively. Comment this
fact for clarity.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2022-05-26 17:15:21 +02:00
Carles Cufi 11da0b6f28 arch: riscv: Remove outdated comment
After the introduction of arch_switch() in #43085, ECALL is no longer
used for context switching by default, so remove the comment stating so.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2022-05-26 17:15:21 +02:00
Nicolas Pitre 1cb557dccf riscv: rationalize PMP related Kconfig options
ARCH_HAS_USERSPACE and ARCH_HAS_STACK_PROTECTION are direct functions
of RISCV_PMP regardless of the SoC.

PMP_STACK_GUARD is a function of HW_STACK_PROTECTION (from
ARCH_HAS_STACK_PROTECTION) and not the other way around.

This allows for tests/kernel/fatal/exception to test protection against
various stack overflows based on the PMP stack guard functionality.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-05-18 10:54:53 +02:00
Nicolas Pitre e76fb204db riscv: report stack overflow errors correctly
Add the necessary checks to determine when the stack pointer is
 out of bounds.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-05-18 10:54:53 +02:00
Nicolas Pitre a4b82ab4fe riscv: fix IRQ stack guard location
_current_cpu->irq_stack is not yet initialized when this is executed on
CPU 0. Also the guard area is outside of CONFIG_ISR_STACK_SIZE now
e.g. it is within the K_KERNEL_STACK_RESERVED area at the start of
the buffer. So simply use z_interrupt_stacks[] directly instead.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-05-18 10:54:53 +02:00
Nicolas Pitre 92409f36de riscv: drop user stack guard area when using separate privileged stacks
A separate privileged stack is used when CONFIG_GEN_PRIV_STACKS=y. The
main stack guard area is no longer needed and can be made available to
the application upon transitioning to user mode. And that's actually
required if we want a naturally aligned power-of-two buffer to let the
PMP map a NAPOT entry on it which is the whole point of having this
CONFIG_PMP_POWER_OF_TWO_ALIGNMENT option in the first place.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-05-18 10:54:53 +02:00
Nicolas Pitre 6051ea7d3c riscv: clarify stack size and alignment parameters
The StackGuard area is used to save the esf and run the exception code
resulting from a StackGuard trap. Size it appropriately.

Remove redundancy, clarify documentation, etc.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-05-18 10:54:53 +02:00
Nicolas Pitre 3997f7bed2 riscv: pmp: make PMP debug display more comprehensive
Decoding those values by hand gets tedious.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-05-18 10:54:53 +02:00
Robert Szczepanski 8647e2f63c tracing: riscv: Add missing invoke of sys_trace_isr_exit()
Change suggested by @WealianLiao in #41995.

Signed-off-by: Robert Szczepanski <rszczepanski@antmicro.com>
2022-05-11 12:03:41 -04:00
Gerard Marull-Paretas 4b91c2d79f asm: update files with <zephyr/...> include prefix
Assembler files were not migrated with the new <zephyr/...> prefix.
Note that the conversion has been scripted, refer to #45388 for more
details.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-05-09 12:45:29 -04:00
Gerard Marull-Paretas 16811660ee arch: migrate includes to <zephyr/...>
In order to bring consistency in-tree, migrate all arch code to the new
prefix <zephyr/...>. Note that the conversion has been scripted, refer
to zephyrproject-rtos#45388 for more details.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-05-06 19:57:22 +02:00
Nicolas Pitre f51d89df30 riscv: pmp: work around a QEMU bug
The NAPOT mode isn't computed properly in qemu when the full address
range is covered. Let's hardcode the value that the qemu code checks
explicitly until the appropriate fix is applied to qemu itself.

For reference, here's the qemu patch:
https://lists.gnu.org/archive/html/qemu-devel/2022-04/msg00961.html

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-04-29 15:30:00 +02:00
Nicolas Pitre ec9c2ec2d8 riscv: pmp: rename CONFIG_PMP_SLOT
The plural form is clearer.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-04-29 15:30:00 +02:00
Nicolas Pitre 554f24661f riscv: pmp: remove previous implementation
Overall diffstat with the new PMP code in place:

 18 files changed, 866 insertions(+), 1372 deletions(-)

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-04-29 15:30:00 +02:00
Nicolas Pitre 2fece49a14 riscv: pmp: switch over to the new implementation
Add the appropriate hooks effectively replacing the old implementation
with the new one.

Also the stackguard wasn't properly enforced especially with the
usermode combination. This is now fixed.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-04-29 15:30:00 +02:00
Nicolas Pitre 7a55bda7e1 riscv: pmp: add new usermode support
The idea here is to compute the PMP register set on demand i.e. upon
scheduling in the affected threads, and only if changes occurred.
A simple sequence number is used to stay in sync with the latest update.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-04-29 15:30:00 +02:00
Nicolas Pitre 68b8f0e5ce riscv: pmp: new stackguard implementation
Stackguard uses the PMP to prevents many types of stack overflow by
making any access to the bottom stack area raise a CPU exception. Each
thread has its set of precomputed PMP entries and those are written to
PMP registers at context switch time.

This is the code to set it up. It will be connected later.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-04-29 15:30:00 +02:00
Nicolas Pitre 2e66da3bc3 riscv: pmp: new implementation
This is the core code to manage PMP entries with only the global entries
initialisation for now. It is not yet linked into the build.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-04-29 15:30:00 +02:00
Keith Packard f623571a73 riscv: Initialize TP register when starting threads
Set TP in exception context so that it gets loaded into the CPU when
first running the thread. Set TP for secondary cores to related idle TLS
area.

Signed-off-by: Keith Packard <keithp@keithp.com>
2022-04-28 11:09:01 +09:00
Nicolas Pitre f61b8b8c16 semihosting: fix inline assembly output dependency
Commit d8f186aa4a ("arch: common: semihost: add semihosting
operations") encapsulated semihosting invocation in a per-arch
semihost_exec() function. There is a fixed register variable declaration
for the return value but this variable is not listed as an output
operand to respective inline assembly segments which is an error.
This is not reported as such by gcc and the generated code is still OK
in those particular instances but this is not guaranteed, and clang
does complain about such cases.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-04-24 19:46:15 +02:00
Jordan Yates d8f186aa4a arch: common: semihost: add semihosting operations
Add an API that utilizes the ARM semihosting mechanism to interact with
the host system when a device is being emulated or run under a debugger.

RISCV is implemented in terms of the ARM implementation, and therefore
the ARM definitions cross enough architectures to be defined 'common'.

Functionality is exposed as a separate API instead of syscall
implementations (`_lseek`, `_open`, etc) due to various quirks with
the ARM mechanisms that means function arguments are not standard.

For more information see:
https://developer.arm.com/documentation/dui0471/m/what-is-semihosting-

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>

impl
2022-04-21 13:04:52 +02:00
Nathan Krueger 6a5520c626 arch/riscv: Adding KConfig options for 'A' and 'M' RISC-V extensions
New KConfig options for 'A' and 'M' RISC-V extensions have been
added.  These are used to configure the '-march' string used by GCC
to produce a compatible binary for the requested RISC-V variant.
In order to maintain compatibility with all currently defined SoC,
default the options for HW mul / Atomics support to 'y', but allow
them to be overridden for any SoC which does not support these.

I tested this change locally via twister agaisnt a few RISC-V platforms
including some 32bit and 64bit. To verify the 4 possibilities of Atomics
& HW Mul: (No, No), (No, Yes), (Yes, No), (Yes, Yes -- current behavior),
I used an out-of-tree GCC (xPack RISC-V GCC) which has multilib support
for rv32i, rv32ia, rv32ima to test against our out-of-tree Intel Nios V/m
processor in HW.  The Zephyr SDK RISCV GCC currently does not contain
multilib support for all variants exposed by these new KConfig options.

Signed-off-by: Nathan Krueger <nathan.krueger@intel.com>
2022-03-22 18:00:32 -04:00
Nicolas Pitre c8bfc2afda riscv: make arch_is_user_context() SMP compatible
This is painful. There is no way for u-mode code to know if we're
currently executing in u-mode without generating a fault, besides
stealing a general purpose register away from the standard ABI
that is. And a global variable doesn't work on SMP as this must be
per-CPU and we could be migrated to another CPU just at the right
moment to peek at the wrong CPU variable (and u-mode can't disable
preemption either).

So, given that we'll have to pay the price of an exception entry
anyway, let's at least make it free to privileged threads by using
the mscratch register as the non-user context indicator (it must
be zero in m-mode for exception entry to work properly). In the
case of u-mode we'll simulate a proper return value in the
exception trap code. Let's settle on the return value in t0
and omit the volatile to give the compiler a chance to cache
the result.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre af2d875c5d riscv: isr.S: compute _current_cpu using CPU number on SMP
To do so efficiently on systems without the mul instruction, we use
shifts and adds which is faster and sometimes smaller than a plain loop.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00