Skip to content

Commit

Permalink
soc: gd32: gd32vf103: keep the mcause.interrupt by SOC-specific context
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jimmyzhe committed Sep 23, 2024
1 parent bcf3c28 commit 8221aac
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 0 deletions.
1 change: 1 addition & 0 deletions soc/gd/gd32/gd32vf103/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

zephyr_sources(entry.S)
zephyr_sources(soc.c)
zephyr_sources(soc_irq.S)

zephyr_include_directories(.)

Expand Down
1 change: 1 addition & 0 deletions soc/gd/gd32/gd32vf103/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ config SOC_SERIES_GD32VF103
select RISCV_ISA_EXT_ZICSR
select RISCV_ISA_EXT_ZIFENCEI
select RISCV_HAS_CLIC
select RISCV_SOC_CONTEXT_SAVE
select ATOMIC_OPERATIONS_C
select INCLUDE_RESET_VECTOR
select GD32_HAS_AFIO_PINMUX
Expand Down
18 changes: 18 additions & 0 deletions soc/gd/gd32/gd32vf103/soc_context.h
Original file line number Diff line number Diff line change
@@ -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 changes: 40 additions & 0 deletions soc/gd/gd32/gd32vf103/soc_irq.S
Original file line number Diff line number Diff line change
@@ -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 changes: 16 additions & 0 deletions soc/gd/gd32/gd32vf103/soc_offsets.h
Original file line number Diff line number Diff line change
@@ -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_*/

0 comments on commit 8221aac

Please sign in to comment.