Skip to content

Commit f44b961

Browse files
sangtranjcquytranpzz
authored andcommitted
arch: rx: Add NMI vector table for Renesas RX MCU
Add support for non-maskable interrupt (NMI) vector table for Renesas RX architecture Signed-off-by: Sang Tran <[email protected]>
1 parent 9697425 commit f44b961

File tree

7 files changed

+166
-9
lines changed

7 files changed

+166
-9
lines changed

arch/rx/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ zephyr_library_sources(
1313
isr_exit.S
1414
fatal.c
1515
reboot.c
16+
nmi.c
1617
)
1718

1819
zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c)

arch/rx/core/nmi.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright (c) 2025 Renesas Electronics Corporation
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <zephyr/sw_isr_table.h>
7+
#include <zephyr/irq.h>
8+
#include <kswap.h>
9+
#include <zephyr/tracing/tracing.h>
10+
#include <zephyr/arch/rx/sw_nmi_table.h>
11+
12+
#define NMI_NMIST_MASK 0x01
13+
#define NMI_OSTST_MASK 0x02
14+
#define NMI_IWDTST_MASK 0x08
15+
#define NMI_LVD1ST_MASK 0x10
16+
#define NMI_LVD2ST_MASK 0x20
17+
18+
#define NMIER_BASE_ADDRESS DT_REG_ADDR_BY_NAME(DT_NODELABEL(icu), NMIER)
19+
#define NMISR_BASE_ADDRESS DT_REG_ADDR_BY_NAME(DT_NODELABEL(icu), NMISR)
20+
#define NMICLR_BASE_ADDRESS DT_REG_ADDR_BY_NAME(DT_NODELABEL(icu), NMICLR)
21+
#define REG(addr) *((uint8_t *)(addr))
22+
23+
struct nmi_vector_entry _nmi_vector_table[NMI_TABLE_SIZE] = {
24+
{(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* NMI Pin Interrupt */
25+
{(nmi_callback_t)0xFFFFFFFFU,
26+
(void *)0xFFFFFFFFU}, /* Oscillation Stop Detection Interrupt */
27+
{(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* IWDT Underflow/Refresh Error */
28+
{(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* Voltage Monitoring 1 Interrupt */
29+
{(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* Voltage Monitoring 2 Interrupt */
30+
};
31+
32+
void nmi_enable(uint8_t nmi_vector, nmi_callback_t callback, void *arg)
33+
{
34+
if (nmi_vector >= NMI_TABLE_SIZE) {
35+
return;
36+
}
37+
38+
_nmi_vector_table[nmi_vector].callback = callback;
39+
_nmi_vector_table[nmi_vector].arg = arg;
40+
41+
switch (nmi_vector) {
42+
/* NMI Pin Interrupt */
43+
case 0:
44+
REG(NMIER_BASE_ADDRESS) |= (1 << 0);
45+
break;
46+
/* Oscillation Stop Detection Interrupt */
47+
case 1:
48+
REG(NMIER_BASE_ADDRESS) |= (1 << 1);
49+
break;
50+
/* IWDT Underflow/Refresh Error */
51+
case 2:
52+
REG(NMIER_BASE_ADDRESS) |= (1 << 3);
53+
break;
54+
/* Voltage Monitoring 1 Interrupt */
55+
case 3:
56+
REG(NMIER_BASE_ADDRESS) |= (1 << 4);
57+
break;
58+
/* Voltage Monitoring 2 Interrupt */
59+
case 4:
60+
REG(NMIER_BASE_ADDRESS) |= (1 << 5);
61+
break;
62+
default:
63+
break;
64+
}
65+
}
66+
67+
int get_nmi_request(void)
68+
{
69+
uint8_t nmi_status = REG(NMISR_BASE_ADDRESS);
70+
71+
if (nmi_status & NMI_NMIST_MASK) {
72+
return 0;
73+
} else if (nmi_status & NMI_OSTST_MASK) {
74+
return 1;
75+
} else if (nmi_status & NMI_IWDTST_MASK) {
76+
return 2;
77+
} else if (nmi_status & NMI_LVD1ST_MASK) {
78+
return 3;
79+
} else if (nmi_status & NMI_LVD2ST_MASK) {
80+
return 4;
81+
}
82+
83+
return NMI_TABLE_SIZE;
84+
}
85+
86+
void handle_nmi(uint8_t nmi_vector)
87+
{
88+
if (nmi_vector >= NMI_TABLE_SIZE) {
89+
return;
90+
}
91+
92+
_nmi_vector_table[nmi_vector].callback(_nmi_vector_table[nmi_vector].arg);
93+
94+
switch (nmi_vector) {
95+
case 0:
96+
REG(NMICLR_BASE_ADDRESS) |= (1 << 0);
97+
break;
98+
case 1:
99+
REG(NMICLR_BASE_ADDRESS) |= (1 << 1);
100+
break;
101+
case 2:
102+
REG(NMICLR_BASE_ADDRESS) |= (1 << 3);
103+
break;
104+
case 3:
105+
REG(NMICLR_BASE_ADDRESS) |= (1 << 4);
106+
break;
107+
case 4:
108+
REG(NMICLR_BASE_ADDRESS) |= (1 << 5);
109+
break;
110+
default:
111+
break;
112+
}
113+
}

arch/rx/core/vects.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
#include <zephyr/irq.h>
99
#include <kswap.h>
1010
#include <zephyr/tracing/tracing.h>
11+
#include <zephyr/arch/rx/sw_nmi_table.h>
12+
#ifndef CONFIG_SOC_SERIES_RX62N
1113
#include <ofsm.h>
14+
#endif
1215

1316
typedef void (*fp)(void);
1417
extern void _start(void);
@@ -108,9 +111,9 @@ static void __ISR__ INT_Excep_FloatingPoint(void)
108111
static void __ISR__ INT_NonMaskableInterrupt(void)
109112
{
110113
REGISTER_SAVE();
111-
ISR_DIRECT_HEADER();
112-
z_fatal_error(K_ERR_CPU_EXCEPTION, NULL);
113-
ISR_DIRECT_FOOTER(1);
114+
int nmi_vector = get_nmi_request();
115+
116+
handle_nmi(nmi_vector);
114117
REGISTER_RESTORE_EXIT();
115118
}
116119

dts/rx/renesas/rx-qemu.dtsi

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@
4141
<0x00872f0 0x02>,
4242
<0x0087500 0x0f>,
4343
<0x0087510 0x01>,
44-
<0x0087514 0x01>;
45-
reg-names = "IR", "IER", "IPR", "FIR", "IRQCR", "IRQFLTE", "IRQFLTC0";
44+
<0x0087514 0x01>,
45+
<0x0087580 0x01>,
46+
<0x0087581 0x01>,
47+
<0x0087582 0x01>;
48+
reg-names = "IR", "IER", "IPR", "FIR", "IRQCR", "IRQFLTE", "IRQFLTC0", "NMISR",
49+
"NMIER", "NMICLR";
4650

4751
swint1: swint1@872e0 {
4852
compatible = "renesas,rx-swint";

dts/rx/renesas/rx130-common.dtsi

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@
4141
<0x00872f0 0x02>,
4242
<0x0087500 0x0f>,
4343
<0x0087510 0x01>,
44-
<0x0087514 0x01>;
45-
reg-names = "IR", "IER", "IPR", "FIR", "IRQCR", "IRQFLTE", "IRQFLTC0";
44+
<0x0087514 0x01>,
45+
<0x0087580 0x01>,
46+
<0x0087581 0x01>,
47+
<0x0087582 0x01>;
48+
reg-names = "IR", "IER", "IPR", "FIR", "IRQCR","IRQFLTE","IRQFLTC0", "NMISR",
49+
"NMIER", "NMICLR";
4650

4751
swint1: swint1@872e0 {
4852
compatible = "renesas,rx-swint";

dts/rx/renesas/rx261-common.dtsi

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,12 @@
4040
<0x00872f0 0x02>,
4141
<0x0087500 0x0f>,
4242
<0x0087510 0x01>,
43-
<0x0087514 0x01>;
44-
reg-names = "IR", "IER", "IPR", "FIR", "IRQCR", "IRQFLTE", "IRQFLTC0";
43+
<0x0087514 0x01>,
44+
<0x0087580 0x01>,
45+
<0x0087581 0x01>,
46+
<0x0087582 0x01>;
47+
reg-names = "IR", "IER", "IPR", "FIR", "IRQCR", "IRQFLTE", "IRQFLTC0", "NMISR",
48+
"NMIER", "NMICLR";
4549

4650
swint1: swint1@872e0 {
4751
compatible = "renesas,rx-swint";
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2025 Renesas Electronics Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_ARCH_RX_SW_NMI_TABLE_H
8+
#define ZEPHYR_INCLUDE_ARCH_RX_SW_NMI_TABLE_H
9+
10+
#include <stdint.h>
11+
#include <soc.h>
12+
13+
#define NMI_TABLE_SIZE (5)
14+
15+
typedef void (*nmi_callback_t)(void *arg);
16+
17+
struct nmi_vector_entry {
18+
nmi_callback_t callback;
19+
void *arg;
20+
};
21+
22+
extern struct nmi_vector_entry _nmi_vector_table[NMI_TABLE_SIZE];
23+
24+
void nmi_enable(uint8_t nmi_vector, nmi_callback_t callback, void *arg);
25+
int get_nmi_request(void);
26+
void handle_nmi(uint8_t nmi_vector);
27+
28+
#endif /* ZEPHYR_INCLUDE_ARCH_RX_SW_NMI_TABLE_H */

0 commit comments

Comments
 (0)