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>
This commit is contained in:
parent
a50c433012
commit
cb5221c087
2 changed files with 15 additions and 29 deletions
|
@ -1,31 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016 Jean-Paul Etienne <fractalclone@gmail.com>
|
* Copyright (c) 2022 BayLibre SAS
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <irq.h>
|
|
||||||
#include <irq_offload.h>
|
#include <irq_offload.h>
|
||||||
#include <arch/riscv/syscall.h>
|
#include <arch/riscv/syscall.h>
|
||||||
|
|
||||||
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)
|
void arch_irq_offload(irq_offload_routine_t routine, const void *parameter)
|
||||||
{
|
{
|
||||||
unsigned int key;
|
arch_syscall_invoke2((uintptr_t)routine, (uintptr_t)parameter, RV_ECALL_IRQ_OFFLOAD);
|
||||||
|
|
||||||
key = irq_lock();
|
|
||||||
offload_routine = routine;
|
|
||||||
offload_param = parameter;
|
|
||||||
arch_syscall_invoke0(RV_ECALL_IRQ_OFFLOAD);
|
|
||||||
irq_unlock(key);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,6 +318,14 @@ do_fault:
|
||||||
|
|
||||||
#if defined(CONFIG_IRQ_OFFLOAD)
|
#if defined(CONFIG_IRQ_OFFLOAD)
|
||||||
do_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 */
|
/* Set _kernel.cpus[0].nested variable to 1 */
|
||||||
la t1, _kernel
|
la t1, _kernel
|
||||||
li t0, 1
|
li t0, 1
|
||||||
|
@ -331,16 +339,11 @@ do_irq_offload:
|
||||||
addi sp, sp, -16
|
addi sp, sp, -16
|
||||||
sr t0, 0(sp)
|
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 */
|
/* Leave through the regular IRQ exit path */
|
||||||
la t1, _kernel
|
j irq_done
|
||||||
sw zero, _kernel_offset_to_nested(t1)
|
|
||||||
|
|
||||||
/* return to the regular stack */
|
|
||||||
lr sp, 0(sp)
|
|
||||||
|
|
||||||
j no_reschedule
|
|
||||||
#endif /* CONFIG_IRQ_OFFLOAD */
|
#endif /* CONFIG_IRQ_OFFLOAD */
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
|
@ -446,6 +449,7 @@ on_irq_stack:
|
||||||
/* Call ISR function */
|
/* Call ISR function */
|
||||||
jalr ra, t1, 0
|
jalr ra, t1, 0
|
||||||
|
|
||||||
|
irq_done:
|
||||||
/* Decrement _kernel.cpus[0].nested variable */
|
/* Decrement _kernel.cpus[0].nested variable */
|
||||||
la t1, _kernel
|
la t1, _kernel
|
||||||
lw t2, _kernel_offset_to_nested(t1)
|
lw t2, _kernel_offset_to_nested(t1)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue