Skip to content

Commit f216c43

Browse files
jimmyzhekartben
authored andcommitted
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 <[email protected]>
1 parent 3804387 commit f216c43

File tree

5 files changed

+76
-0
lines changed

5 files changed

+76
-0
lines changed

soc/gd/gd32/gd32vf103/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
zephyr_sources(entry.S)
55
zephyr_sources(soc.c)
6+
zephyr_sources(soc_irq.S)
67

78
zephyr_include_directories(.)
89

soc/gd/gd32/gd32vf103/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ config SOC_SERIES_GD32VF103
1414
select RISCV_ISA_EXT_ZIFENCEI
1515
select RISCV_HAS_CLIC
1616
select RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING
17+
select RISCV_SOC_CONTEXT_SAVE
1718
select ATOMIC_OPERATIONS_C
1819
select INCLUDE_RESET_VECTOR
1920
select GD32_HAS_AFIO_PINMUX

soc/gd/gd32/gd32vf103/soc_context.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright (c) 2024 Andes Technology Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef SOC_RISCV_GD32_GD32VF103_SOC_CONTEXT_H
8+
#define SOC_RISCV_GD32_GD32VF103_SOC_CONTEXT_H
9+
10+
#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE
11+
12+
#define SOC_ESF_MEMBERS
13+
14+
#define SOC_ESF_INIT
15+
16+
#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */
17+
18+
#endif /* SOC_RISCV_GD32_GD32VF103_SOC_CONTEXT_H */

soc/gd/gd32/gd32vf103/soc_irq.S

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2024 Andes Technology Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/offsets.h>
8+
#include <zephyr/toolchain.h>
9+
#include <zephyr/arch/riscv/irq.h>
10+
11+
/* Exports */
12+
#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE
13+
GTEXT(__soc_save_context)
14+
GTEXT(__soc_restore_context)
15+
#endif
16+
17+
#ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE
18+
19+
SECTION_FUNC(exception.other, __soc_save_context)
20+
21+
ret
22+
23+
SECTION_FUNC(exception.other, __soc_restore_context)
24+
25+
/*
26+
* For Nuclei ECLIC, the interrupt level (mintstatus.MIL) is restored
27+
* from the previous interrupt level (mcause.MPIL) only if
28+
* mcause.interrupt is set when executing MRET.
29+
* Always set the next context's mcause.interrupt to ensure the
30+
* interrupt level is restored correctly after MRET.
31+
*/
32+
addi a0, a0, -__struct_arch_esf_soc_context_OFFSET
33+
lw t0, __struct_arch_esf_mcause_OFFSET(a0)
34+
li t1, 1 << RISCV_MCAUSE_IRQ_POS
35+
or t0, t0, t1
36+
sw t0, __struct_arch_esf_mcause_OFFSET(a0)
37+
38+
ret
39+
40+
#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */

soc/gd/gd32/gd32vf103/soc_offsets.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright (c) 2024 Andes Technology Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef SOC_RISCV_GD32_GD32VF103_SOC_OFFSETS_H_
8+
#define SOC_RISCV_GD32_GD32VF103_SOC_OFFSETS_H_
9+
10+
#ifdef CONFIG_RISCV_SOC_OFFSETS
11+
12+
#define GEN_SOC_OFFSET_SYMS()
13+
14+
#endif /* CONFIG_RISCV_SOC_OFFSETS */
15+
16+
#endif /* SOC_RISCV_GD32_GD32VF103_SOC_OFFSETS_H_*/

0 commit comments

Comments
 (0)