Commit graph

128 commits

Author SHA1 Message Date
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
Nicolas Pitre
4f5374854e riscv: isr.S: dedicate a register to &current_cpu
Stop using &_kernel as this is not SMP friendly. Let's use s0 (after
preserving its content) to hold &current_cpu instead so it won't have
to be reloaded 	each time it is needed. This will be even more relevant
when SMP support is added.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
69d06a901c riscv: isr.S: optimize FP regs save/restore decision
Rely on mstatus rather than thread->base.user_options since it is always
up to date (updated by z_riscv_switch) to simplify the code and be SMP
proof. Also carry over SF_INIT to the mstatus being restored in case
it was changed in the mean time.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
ce8dabfe9e riscv: implement arch_switch()
The move to arch_switch() is a prerequisite for SMP support.

Make it optimal without the need for an ECALL roundtrip on every
context switch. Performance numbers from tests/benchmarks/sched:

Before:
unpend  107 ready  102 switch  188 pend  218 tot  615 (avg  615)

After:
unpend  107 ready  102 switch  170 pend  217 tot  596 (avg  595)

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
247d2c8e3b riscv: move the tp register from caller-saved to callee-saved
This is a per-thread register that gets updated only when context
switching. No need to load and save it on every exception entry.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
50c0df1bd2 riscv: align struct __esf properly
The minimum stack alignment is 16. Therefore, the stack space to store
a struct __esf object must be rounded up to the next 16-byte boundary.

It is not sufficient to do the rounding on the __z_arch_esf_t_SIZEOF
definition. When the stack is constructed in arch_new_thread() it is
also necessary to do the rounding there too.

Let's make the structure itself carry the alignment attribute instead to
make it work in all cases.

While at it, remove the unused _K_THREAD_NO_FLOAT_SIZEOF definition.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
df852a0b77 riscv: implement CONFIG_IRQ_OFFLOAD_NESTED
It can easily be done now, so why not. Suffice to increment the nested
count like with actual IRQs.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
cb5221c087 riscv: irq_offload: simpler implementation
Get rid of all those global variables and IRQ locking.
Use the regular IRQ exit path to let tests validate preemption properly.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
a50c433012 riscv: exception code mega simplification and optimization
Complete revamp of the exception entry code, including syscall handling.
Proper syscall frame exception trigger. Many correctness fixes, hacks
removal, etc. etc.

I tried to make this into several commits, but this stuff is all
inter-related and a pain to split.

The diffstat summary:

 14 files changed, 250 insertions(+), 802 deletions(-)

Binary size (before):

   text	   data	    bss	    dec	    hex	filename
   1104	      0	      0	   1104	    450	isr.S.obj
     64	      0	      0	     64	     40	userspace.S.obj

Binary size (after):

   text	   data	    bss	    dec	    hex	filename
    600	      0	      0	    600	    258	isr.S.obj
     36	      0	      0	     36	     24	userspace.S.obj

Run of samples/userspace/syscall_perf (before):

*** Booting Zephyr OS build zephyr-v3.0.0-325-g3748accae018  ***
Main Thread started; qemu_riscv32
Supervisor thread started
User thread started
Supervisor thread(0x80010048):       384 cycles	     509 instructions
User thread(0x80010140):           77312 cycles	   77437 instructions

Run of samples/userspace/syscall_perf (after):

*** Booting Zephyr OS build zephyr-v3.0.0-326-g4c877a2753b3  ***
Main Thread started; qemu_riscv32
Supervisor thread started
User thread started
Supervisor thread(0x80010048):       384 cycles	     509 instructions
User thread(0x80010138):            7040 cycles     7165 instructions

Yes, that's more than a 10x speed-up!

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
bfb7919ed0 riscv: better abstraction for register-wide FP load/store opcodes
Same rationale as preceding commit. Let's create pseudo-instructions in
assembly scope to make the code more uniform and readable.

Furthermore the definition of COPY_ESF_FP() was wrong as the width of
floating point registers vary not according to CONFIG_64BIT but
CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION. It is therefore wrong to use
lr/sr (previously RV_OP_LOADREG/RV_OP_STOREREG) and a regular temporary
register to transfer such content.

Note: There are far more efficient ways to copy FP context around but
      such optimisations will come separately.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
1fd79b3ef4 riscv: better abstraction for register-wide load/store opcodes
Those are prominent enough that having RV_OP_LOADREG and RV_OP_STOREREG
shouting at you all over the place is rather unpleasant and bad taste.

Let's create pseudo-instructions of our own with assembler macros
rather than preprocessor defines and only in assembly scope.
This makes the asm code way more uniform and readable.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
94f39e5a80 riscv: fix wrong access width in assembly code
The thread->base.user_options field is an uint8_t. Access it using lb.
A "copy" of it is made into __esf.fp_state. Make that field an uint8_t
too and access it with lb/sb.

_callee_saved.fcsr is an uint32_t. Access it with lw/sw.
Ditto for is_user_mode.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
9ed17943b9 riscv: use simplest asm expression when possible
Let's take advantage of assembler pseudoinstructions:

- convert `addi rd, rs, 0` to `mv rd, rs`
- convert `jal x0, somewhere` to `j somewhere`
- convert `csrrs x0, csrreg, rs` to `csrs csrreg, rs`
- convert `fscsr x0, rs` to `fscsr rs`

And simplify zero offsets to simply 0.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
f2bb937547 Revert "arch/riscv: Get current CPU properly instead of assuming single CPU"
This reverts commit 8686ab5472.

The purpose of this commit will be reintroduced later on top of
a cleaner codebase.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
442ab22bdc Revert "arch/riscv: Use arch_switch() for context swap"
This reverts commit be28de692c.

The purpose of this commit will be reintroduced later on top of
a cleaner codebase.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nicolas Pitre
13a7047ea9 Revert "arch/riscv: Do not use irq_lock() on arch_irq_offload"
This reverts commit b0458201cc.

The purpose of this commit will be reintroduced later on top of
a cleaner codebase.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2022-03-21 07:28:05 -04:00
Nazar Kazakov
f483b1bc4c everywhere: fix typos
Fix a lot of typos

Signed-off-by: Nazar Kazakov <nazar.kazakov.work@gmail.com>
2022-03-18 13:24:08 -04:00
Corey Wharton
72afd96c9b arch: riscv: ensure fcsr is cleared on thread start or FPU enable
Ensure fcsr is always initially cleared for FPU enabled threads.

Signed-off-by: Corey Wharton <xodus7@cwharton.com>
2022-03-16 10:25:50 +01:00
Gerard Marull-Paretas
95fb0ded6b kconfig: remove Enable from boolean prompts
According to Kconfig guidelines, boolean prompts must not start with
"Enable...". The following command has been used to automate the changes
in this patch:

sed -i "s/bool \"[Ee]nables\? \(\w\)/bool \"\U\1/g" **/Kconfig*

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-03-09 15:35:54 +01:00
Ederson de Souza
2aab236c12 arch/riscv: Add IPI support
Use CLINT to send interrupts to another CPU. SMP support is kinda
incomplete without it.

This patch only enables it for riscv-privilege platforms - specifically,
"virt" one.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
2022-02-25 19:13:50 -05:00
Ederson de Souza
b0458201cc arch/riscv: Do not use irq_lock() on arch_irq_offload
With SMP, it's the wrong with to do, according to
3b145c0d4b.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
2022-02-25 19:13:50 -05:00
Ederson de Souza
d9ab35577b arch/riscv: Boot secondary CPUs for SMP support
Secondary CPUs are now initialised and made available to the system. If
the system has more CPUs than configured via CONFIG_MP_NUM_CPUS, those
are still left looping as before.

Some implementations of `soc_interrupt_init` also changed to use
`arch_irq_lock` instead of `irq_lock`.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
2022-02-25 19:13:50 -05:00
Ederson de Souza
be28de692c arch/riscv: Use arch_switch() for context swap
Enable `arch_switch()` as preparation for SMP support. This patch
doesn't try to keep support for old style context swap - only switch
based swap is supported, to keep things simple.

A fair amount of refactoring was done in this patch, specially regarding
the code that decides what to do about the ISR. In RISC-V, ECALL
instructions are used to signalize several events, such as user space
system calls, forced syscall, IRQ offload, return from syscall and
context switch. All those handled by the ISR - which also handles
interrupts. After refactor, this "dispatching" step is done at the
beginning of ISR (just after saving generic registers).

As with other platforms, the thread object itself is used as the thread
"switch handle" for the context swap.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
2022-02-25 19:13:50 -05:00
Ederson de Souza
8686ab5472 arch/riscv: Get current CPU properly instead of assuming single CPU
isr.S code currently gets CPU information from global `_kernel` assuming
there's only one CPU. In order to prepare for upcoming SMP support,
change code to actually get current CPU information.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
2022-02-25 19:13:50 -05:00
Ederson de Souza
fdf7c96994 arch/riscv: Implement arch_curr_cpu()
Implement function that will be necessary for upcoming SMP support.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
2022-02-25 19:13:50 -05:00
Carles Cufi
e83a13aabf kconfig: Rename the TEST_EXTRA stack size option to align with the rest
All stack sizes should end with STACK_SIZE.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2022-02-22 08:23:05 -05:00
Carlo Caione
240c975ad4 core: z_data_copy does not depend on CONFIG_XIP
When XIP is not enabled, z_data_copy() already falls back to an empty
function. No need to ifdef it.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2022-02-22 10:22:53 +01:00
Henry Hsieh
58d50a0e97 riscv: fix non-standard assembly of RISC-V
Non-standard `jalr rd, rs` pseudo-instructions are used.
This commit changes them to `ret` for standard return pseudo-instruction
or `jalr rd, rs, 0` for no offset jump register and link.

Fixes #41100.

Signed-off-by: Henry Hsieh <r901042004@yahoo.com.tw>
2022-02-04 11:23:39 +01:00
Jim Shu
fd2c07682e arch: riscv: pmp: Fix is_user_mode in RV64
Currently, is_user_mode is 8-byte in riscv64 and it breaks a 4-byte PMP
region protecting it. Because is_user_mode is a single flag, we could
just fix it's size to 4-byte in both riscv32 and riscv64.

Signed-off-by: Jim Shu <cwshu09@gmail.com>
2022-01-18 13:11:36 -05:00
Jim Shu
10e618ff33 arch: riscv: pmp: Fix RV64 compatibility of register size
In RV64, all general-purpose registers and pmpcfg CSR are 64-bit
instead of 32-bit. Fix these registers and related C variables/literals
to be 32/64-bit compatible.

Signed-off-by: Jim Shu <cwshu09@gmail.com>
2022-01-18 13:11:36 -05:00
Jim Shu
595b01fc1d arch: riscv: pmp: Fix 64-bit compatibility of pointer size
Fix 64-bit compatibility of pointer size of RISC-V PMP/userspace code.

Signed-off-by: Jim Shu <cwshu09@gmail.com>
2022-01-18 13:11:36 -05:00
Daniel Leung
61d0c3cfe7 riscv: remove @return doc for void functions
For functions returning nothing, there is no need to document
with @return, as Doxgen complains about "documented empty
return type of ...".

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2022-01-12 16:02:16 -05:00
Jim Shu
76c8c6ed79 arch: riscv: pmp: add PMP protection of code and rodata
This commit enable PMP-based memory protection of code and rodata
instead of relying on non-writable real HW (e.g. flash). Use static
PMP region with PMP Lock bit to protect them in both user/supervisor
mode.

Signed-off-by: Jim Shu <cwshu@andestech.com>
2022-01-11 11:47:03 +01:00
Jim Shu
df166ddda1 arch: riscv: pmp: change mechanism of arch_buffer_validate()
Implement new mechanism of arch_buffer_validate() to support checking
static PMP regions. This is preparation patch for code/rodate protection
via RISC-V PMP.

Signed-off-by: Jim Shu <cwshu@andestech.com>
2022-01-11 11:47:03 +01:00
Jim Shu
35ef71f7c0 arch: riscv: pmp: simplify thread initialization
Thread init related to PMP & userspace contains 5 parts:

1. User/supervisor thread clear PMP context
2. User thread clear it's context
3. User/supervisor thread assign to different entry
4. Supervisor thread assign mstatus.MPRV for M-mode PMP protection
5. User/supervisor thread setup PMP regions of stack guard if enabled

Signed-off-by: Jim Shu <cwshu@andestech.com>
2022-01-11 11:47:03 +01:00
Jim Shu
9683c9e71c arch: riscv: pmp: reorder function definitions
Reorder the memory domain async functions to:
  arch_mem_domain_partition_add()
  arch_mem_domain_partition_remove()
  arch_mem_domain_thread_add()
  arch_mem_domain_thread_remove()

Signed-off-by: Jim Shu <cwshu@andestech.com>
2022-01-11 11:47:03 +01:00
Jim Shu
b13dd54fb4 arch: riscv: pmp: simplify pmp region number computation
Simplify multiple ifdef case in computing region number. Also move these
macros to core_pmp.c because they are only used in one file.

Signed-off-by: Jim Shu <cwshu@andestech.com>
2022-01-11 11:47:03 +01:00
Jim Shu
e3c8b4cae4 arch: riscv: pmp: introduce riscv_pmp_region structure
Using struct riscv_pmp_region to modulize PMP CSR handling, including
PMP NAPOT/TOR mode handling. This patch can make us more easily to
add/remove RISC-V PMP regions without considering register handling.

Signed-off-by: Jim Shu <cwshu@andestech.com>
2022-01-11 11:47:03 +01:00
Jim Shu
e4c5d96a8b arch: riscv: pmp: enable MPU log module for debugging
Cleanup logging API in core_pmp.c. Remove old printf-based debugging API
and change the log module of PMP to individual MPU log module.

Signed-off-by: Jim Shu <cwshu@andestech.com>
2022-01-11 11:47:03 +01:00
Jim Shu
5fc5beabe2 arch: riscv: pmp: fix IRQ handling of PMP stack guard
This commit add 2 minor fixes of IRQ handling:

1. Save caller registers before calling z_riscv_configure_stack_guard()
in RISC-V assembly.

2. reschedule and no_reschdule code paths use different interrupt
return path after supporting of CONFIG_PMP_STACK_GUARD. back-to-back
interrupt checking is in the reschedule code path so that it should
jump to interrupt return path of reschedule.

Signed-off-by: Jim Shu <cwshu09@gmail.com>
2022-01-11 11:47:03 +01:00
Jim Shu
e0329a5525 arch: riscv: pmp: fix return value of arch_mem_domain_partition_remove()
If no thread use this memory domain, there isn't any user PMP region
translated from memory partitions in domain. In this case, memory
partition removal doesn't need to remove user PMP region and
arch_mem_domain_partition_remove() could just successfully return.

Signed-off-by: Jim Shu <cwshu@andestech.com>
2022-01-11 11:47:03 +01:00
Jim Shu
fd1e5aebc0 arch: riscv: fix sp of supervisor thread in _Fault function.
Although CONFIG_USERSPACE is enabled, there are supervisor threads who
don't have privileged stack using exception handler. Only let user
threads to switch to privileged stack in exception handler.

Signed-off-by: Jim Shu <cwshu@andestech.com>
2022-01-11 11:47:03 +01:00
Mark Holden
7803a4e590 arch: riscv: ARCH_EXCEPT macro
Enable ARCH_EXCEPT macro for non-usermode scenario for RISC-V
Macro will now raise an illegal instruction exception so that mepc will
hold expected value in exception handler, and generated coredump can
reconstruct the failing stack

Coredump tests running on renode (for RISC-V) can now utilize fatal error
path through k_panic

Signed-off-by: Mark Holden <mholden@fb.com>
2022-01-01 07:38:20 -05:00
TOKITA Hiroshi
2de3133a05 riscv: Add an option for configuring mcause exception mask
GD32V processor core is used non-standard bitmask
for mcause register. Add option to configure the bitmask
to support GD32V.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
2021-12-20 17:51:30 +01:00
Mark Holden
1a697ccf59 coredump: add support for RISC-V
This adds the necessary bits in arch code, and Python scripts
to enable coredump support for RISC-V

Signed-off-by: Mark Holden <mholden@fb.com>
2021-12-08 08:54:32 -05:00
Daniel Leung
1cd7cccbb1 kernel: mem_domain: arch_mem_domain functions to return errors
This changes the arch_mem_domain_*() functions to return errors.
This allows the callers a chance to recover if needed.

Note that:
() For assertions where it can bail out early without side
   effects, these are converted to CHECKIF(). (Usually means
   that updating of page tables or translation tables has not
   been started yet.)
() Other assertions are retained to signal fatal errors during
   development.
() The additional CHECKIF() are structured so that it will bail
   early if possible. If errors are encountered inside a loop,
   it will still continue with the loop so it works as before
   this changes with assertions disabled.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2021-11-22 12:45:22 -05:00
Wolfgang Reißnegger
535fc38fe7 riscv: Don't reschedule on back-to-back interrupts
In some cases the 'reschedule' code path is executed when the current
thread is the same as the next thread in the ready Q. If this happens,
the swap_return_value of the thread is ifalsely being reset to -EAGAIN.

This commit prevents the rescheduling code to run if the current thread
is the same as the thread in the ready Q.

Signed-off-by: Wolfgang Reißnegger <gnagflow@fb.com>
2021-09-03 12:20:03 -04:00