Skip to content

Commit 087888e

Browse files
soc: wch: work-around a bug in wfi in the QingKe V2A
The RISC-V Machine-Level ISA section 3.3.3 says that `wfi` will complete even if interrupts are masked, but the QingKe V2A does not do this. Work-around by enabling interrupts first. This is the same mitigation as used for the Nordic VPR. Signed-off-by: Michael Hope <michaelh@juju.nz> Co-authored-by: Pete Johanson <peter@peterjohanson.com>
1 parent faae10e commit 087888e

File tree

9 files changed

+51
-5
lines changed

9 files changed

+51
-5
lines changed

drivers/interrupt_controller/intc_wch_pfic.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ int arch_irq_is_enabled(unsigned int irq)
3434

3535
static int pfic_init(void)
3636
{
37-
/* `wfi` is called with interrupts disabled. Configure the PFIC to wake up on any event,
38-
* including any interrupt.
39-
*/
40-
PFIC->SCTLR = SEVONPEND | WFITOWFE;
4137
return 0;
4238
}
4339

soc/wch/ch32v/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright (c) 2024 Michael Hope
22
# SPDX-License-Identifier: Apache-2.0
33

4+
add_subdirectory(common)
45
add_subdirectory(${SOC_SERIES})
56

67
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "")

soc/wch/ch32v/common/soc_idle.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (C) 2025 Michael Hope <michaelh@juju.nz>
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <zephyr/irq.h>
7+
#include <zephyr/tracing/tracing.h>
8+
9+
void arch_cpu_idle(void)
10+
{
11+
/*
12+
* The RISC-V Machine-Level ISA section 3.3.3 says that `wfi` will complete even if
13+
* interrupts are masked, but the QingKe V2A does not do this. Work-around by enabling
14+
* interrupts first.
15+
*/
16+
sys_trace_idle();
17+
irq_unlock(MSTATUS_IEN);
18+
__asm__ volatile("wfi");
19+
sys_trace_idle_exit();
20+
}
21+
22+
void arch_cpu_atomic_idle(unsigned int key)
23+
{
24+
sys_trace_idle();
25+
irq_unlock(key);
26+
__asm__ volatile("wfi");
27+
sys_trace_idle_exit();
28+
}

soc/wch/ch32v/qingke_v2a/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ config SOC_SERIES_QINGKE_V2A
66
select RISCV_ISA_EXT_ZICSR
77
select RISCV_ISA_EXT_ZIFENCEI
88
select RISCV_ISA_EXT_C
9+
select RISCV_ALWAYS_SWITCH_THROUGH_ECALL
10+
select ARCH_HAS_CUSTOM_CPU_IDLE
11+
select ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE

soc/wch/ch32v/qingke_v4b/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ config SOC_SERIES_QINGKE_V4B
88
select RISCV_ISA_EXT_C
99
select RISCV_ISA_EXT_ZICSR
1010
select RISCV_ISA_EXT_ZIFENCEI
11+
select RISCV_ALWAYS_SWITCH_THROUGH_ECALL
12+
select ARCH_HAS_CUSTOM_CPU_IDLE
13+
select ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE

soc/wch/ch32v/qingke_v4c/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ config SOC_SERIES_QINGKE_V4C
88
select RISCV_ISA_EXT_C
99
select RISCV_ISA_EXT_ZICSR
1010
select RISCV_ISA_EXT_ZIFENCEI
11+
select RISCV_ALWAYS_SWITCH_THROUGH_ECALL
12+
select ARCH_HAS_CUSTOM_CPU_IDLE
13+
select ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE

soc/wch/ch32v/qingke_v4f/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ config SOC_SERIES_QINGKE_V4F
99
select RISCV_ISA_EXT_F
1010
select RISCV_ISA_EXT_ZICSR
1111
select RISCV_ISA_EXT_ZIFENCEI
12+
select RISCV_ALWAYS_SWITCH_THROUGH_ECALL
13+
select ARCH_HAS_CUSTOM_CPU_IDLE
14+
select ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE

soc/wch/ch32v/qingke_v4f/Kconfig.defconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC
99
config CLOCK_CONTROL
1010
default y
1111

12+
config ISR_TABLES_LOCAL_DECLARATION_SUPPORTED
13+
default n
14+
1215
rsource "Kconfig.defconfig.*"
1316

1417
endif # SOC_SERIES_QINGKE_V4F

soc/wch/ch32v/qingke_v4f/vector.S

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,17 @@ SECTION_FUNC(vectors, ivt)
2222
lui x5, 0x8000
2323
jr 0x8(x5)
2424
j __start
25+
_irq_vector_table:
2526
.rept CONFIG_VECTOR_TABLE_SIZE
2627
.word _isr_wrapper
2728
.endr
2829

2930
SECTION_FUNC(vectors, __start)
30-
li a0, 0xf
31+
li a0, 0x1f
32+
csrw 0xbc0, a0
33+
li a0, 0x1e
34+
csrw 0x804, a0
35+
la t0, _irq_vector_table /* Load address of interrupt vector table */
36+
ori t0, t0, 0x03
3137
csrw mtvec, a0
3238
j __initialize

0 commit comments

Comments
 (0)