soc: gd32: gd32vf103: keep the mcause.interrupt by SOC-specific context
For Nuclei ECLIC, the interrupt level (mintstatus.MIL) is restored from the previous interrupt level (mcause.MPIL) only if mcause.interrupt is set. This behavior is not defined in the RISC-V CLIC spec. If an ISR causes a context switch and mcause.interrupt is not set in the next context (e.g. the next context is yielded from ecall), interrupts will be masked after MRET because the interrupt level is not restored. Use SOC-specific context to set mcause.interrupt to ensure the interrupt level is restored correctly. Signed-off-by: Jimmy Zheng <jimmyzhe@andestech.com>
This commit is contained in:
parent
3804387350
commit
f216c434d0
5 changed files with 76 additions and 0 deletions
|
@ -3,6 +3,7 @@
|
|||
|
||||
zephyr_sources(entry.S)
|
||||
zephyr_sources(soc.c)
|
||||
zephyr_sources(soc_irq.S)
|
||||
|
||||
zephyr_include_directories(.)
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ config SOC_SERIES_GD32VF103
|
|||
select RISCV_ISA_EXT_ZIFENCEI
|
||||
select RISCV_HAS_CLIC
|
||||
select RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING
|
||||
select RISCV_SOC_CONTEXT_SAVE
|
||||
select ATOMIC_OPERATIONS_C
|
||||
select INCLUDE_RESET_VECTOR
|
||||
select GD32_HAS_AFIO_PINMUX
|
||||
|
|
18
soc/gd/gd32/gd32vf103/soc_context.h
Normal file
18
soc/gd/gd32/gd32vf103/soc_context.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Andes Technology Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef SOC_RISCV_GD32_GD32VF103_SOC_CONTEXT_H
|
||||
#define SOC_RISCV_GD32_GD32VF103_SOC_CONTEXT_H
|
||||
|
||||
#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE
|
||||
|
||||
#define SOC_ESF_MEMBERS
|
||||
|
||||
#define SOC_ESF_INIT
|
||||
|
||||
#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */
|
||||
|
||||
#endif /* SOC_RISCV_GD32_GD32VF103_SOC_CONTEXT_H */
|
40
soc/gd/gd32/gd32vf103/soc_irq.S
Normal file
40
soc/gd/gd32/gd32vf103/soc_irq.S
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Andes Technology Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/offsets.h>
|
||||
#include <zephyr/toolchain.h>
|
||||
#include <zephyr/arch/riscv/irq.h>
|
||||
|
||||
/* Exports */
|
||||
#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE
|
||||
GTEXT(__soc_save_context)
|
||||
GTEXT(__soc_restore_context)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE
|
||||
|
||||
SECTION_FUNC(exception.other, __soc_save_context)
|
||||
|
||||
ret
|
||||
|
||||
SECTION_FUNC(exception.other, __soc_restore_context)
|
||||
|
||||
/*
|
||||
* For Nuclei ECLIC, the interrupt level (mintstatus.MIL) is restored
|
||||
* from the previous interrupt level (mcause.MPIL) only if
|
||||
* mcause.interrupt is set when executing MRET.
|
||||
* Always set the next context's mcause.interrupt to ensure the
|
||||
* interrupt level is restored correctly after MRET.
|
||||
*/
|
||||
addi a0, a0, -__struct_arch_esf_soc_context_OFFSET
|
||||
lw t0, __struct_arch_esf_mcause_OFFSET(a0)
|
||||
li t1, 1 << RISCV_MCAUSE_IRQ_POS
|
||||
or t0, t0, t1
|
||||
sw t0, __struct_arch_esf_mcause_OFFSET(a0)
|
||||
|
||||
ret
|
||||
|
||||
#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */
|
16
soc/gd/gd32/gd32vf103/soc_offsets.h
Normal file
16
soc/gd/gd32/gd32vf103/soc_offsets.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Andes Technology Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef SOC_RISCV_GD32_GD32VF103_SOC_OFFSETS_H_
|
||||
#define SOC_RISCV_GD32_GD32VF103_SOC_OFFSETS_H_
|
||||
|
||||
#ifdef CONFIG_RISCV_SOC_OFFSETS
|
||||
|
||||
#define GEN_SOC_OFFSET_SYMS()
|
||||
|
||||
#endif /* CONFIG_RISCV_SOC_OFFSETS */
|
||||
|
||||
#endif /* SOC_RISCV_GD32_GD32VF103_SOC_OFFSETS_H_*/
|
Loading…
Add table
Add a link
Reference in a new issue