diff --git a/soc/gd/gd32/gd32vf103/CMakeLists.txt b/soc/gd/gd32/gd32vf103/CMakeLists.txt index 6778c0a4f1b..649c118de67 100644 --- a/soc/gd/gd32/gd32vf103/CMakeLists.txt +++ b/soc/gd/gd32/gd32vf103/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_sources(entry.S) zephyr_sources(soc.c) +zephyr_sources(soc_irq.S) zephyr_include_directories(.) diff --git a/soc/gd/gd32/gd32vf103/Kconfig b/soc/gd/gd32/gd32vf103/Kconfig index b14bddbd46a..99f60cd6ab8 100644 --- a/soc/gd/gd32/gd32vf103/Kconfig +++ b/soc/gd/gd32/gd32vf103/Kconfig @@ -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 diff --git a/soc/gd/gd32/gd32vf103/soc_context.h b/soc/gd/gd32/gd32vf103/soc_context.h new file mode 100644 index 00000000000..51a082aa0bf --- /dev/null +++ b/soc/gd/gd32/gd32vf103/soc_context.h @@ -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 */ diff --git a/soc/gd/gd32/gd32vf103/soc_irq.S b/soc/gd/gd32/gd32vf103/soc_irq.S new file mode 100644 index 00000000000..fe0248dad16 --- /dev/null +++ b/soc/gd/gd32/gd32vf103/soc_irq.S @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Andes Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/* 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 */ diff --git a/soc/gd/gd32/gd32vf103/soc_offsets.h b/soc/gd/gd32/gd32vf103/soc_offsets.h new file mode 100644 index 00000000000..7322e91b81d --- /dev/null +++ b/soc/gd/gd32/gd32vf103/soc_offsets.h @@ -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_*/