From cb5221c0879c75ead5982bcccc155a7b9855c2d0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 7 Mar 2022 13:24:38 -0500 Subject: [PATCH] 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 --- arch/riscv/core/irq_offload.c | 22 ++-------------------- arch/riscv/core/isr.S | 22 +++++++++++++--------- 2 files changed, 15 insertions(+), 29 deletions(-) diff --git a/arch/riscv/core/irq_offload.c b/arch/riscv/core/irq_offload.c index 38d07f831b1..0e62c82aeb3 100644 --- a/arch/riscv/core/irq_offload.c +++ b/arch/riscv/core/irq_offload.c @@ -1,31 +1,13 @@ /* - * Copyright (c) 2016 Jean-Paul Etienne + * Copyright (c) 2022 BayLibre SAS * * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include -static irq_offload_routine_t offload_routine; -static const void *offload_param; - -/* - * Called by _enter_irq - */ -void z_irq_do_offload(void) -{ - offload_routine(offload_param); -} - void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) { - unsigned int key; - - key = irq_lock(); - offload_routine = routine; - offload_param = parameter; - arch_syscall_invoke0(RV_ECALL_IRQ_OFFLOAD); - irq_unlock(key); + arch_syscall_invoke2((uintptr_t)routine, (uintptr_t)parameter, RV_ECALL_IRQ_OFFLOAD); } diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index 95d02bf5052..af1bfd2b895 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -318,6 +318,14 @@ do_fault: #if defined(CONFIG_IRQ_OFFLOAD) do_irq_offload: + /* + * Retrieve provided routine and argument from the stack. + * Routine pointer is in saved a0, argument in saved a1 + * so we load them with a1/a0 (reversed). + */ + lr a1, __z_arch_esf_t_a0_OFFSET(sp) + lr a0, __z_arch_esf_t_a1_OFFSET(sp) + /* Set _kernel.cpus[0].nested variable to 1 */ la t1, _kernel li t0, 1 @@ -331,16 +339,11 @@ do_irq_offload: addi sp, sp, -16 sr t0, 0(sp) - call z_irq_do_offload + /* Execute provided routine (argument is in a0 already). */ + jalr ra, a1, 0 - /* Set _kernel.cpus[0].nested variable back to 0 */ - la t1, _kernel - sw zero, _kernel_offset_to_nested(t1) - - /* return to the regular stack */ - lr sp, 0(sp) - - j no_reschedule + /* Leave through the regular IRQ exit path */ + j irq_done #endif /* CONFIG_IRQ_OFFLOAD */ #ifdef CONFIG_USERSPACE @@ -446,6 +449,7 @@ on_irq_stack: /* Call ISR function */ jalr ra, t1, 0 +irq_done: /* Decrement _kernel.cpus[0].nested variable */ la t1, _kernel lw t2, _kernel_offset_to_nested(t1)