zephyr/arch
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
..
arc ARC: introduce reworked irq_offload implementation 2022-12-20 22:51:24 +01:00
arm Kconfig: add config for low-priority debug mon isr 2022-12-28 12:00:46 +01:00
arm64 arch/arm64: Implement ASID support in ARM64 MMU 2022-12-13 17:21:11 +09:00
common include: add missing irq.h include 2022-10-11 18:05:17 +02:00
mips include: types: remove ulong_t 2022-09-06 18:16:33 +02:00
nios2 arch: comply to coding guidelines MISRA C:2012 Rule 14.4 2022-07-20 09:28:38 -05:00
posix arch: posix: Declare _posix_zephyr_main with int return type 2022-11-05 16:41:45 +09:00
riscv riscv: Add support for hardware stacking / unstacking 2023-01-09 10:15:07 +01:00
sparc SPARC: reduce z_thread_entry_wrapper 2022-08-03 12:05:49 +02:00
x86 cache: Rework cache API 2022-12-01 13:40:56 -05:00
xtensa arch: xtensa: save FPU register in context switching 2022-12-27 13:23:17 +01:00
CMakeLists.txt cmake: fix include directories to work with out-of-tree arch 2020-08-05 08:06:07 -04:00
Kconfig cache: Rework cache API 2022-12-01 13:40:56 -05:00