1 /*
2  * Copyright (c) 2021 KT-Elektronik, Klaucke und Partner GmbH
3  * Copyright (c) 2024 Renesas Electronics Corporation
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/sw_isr_table.h>
8 #include <zephyr/irq.h>
9 #include <kswap.h>
10 #include <zephyr/tracing/tracing.h>
11 #include <zephyr/drivers/clock_control/renesas_rx_cgc.h>
12 
13 typedef void (*fp)(void);
14 extern void _start(void);
15 extern void z_rx_irq_exit(void);
16 
17 /* this is mainly to give Visual Studio Code peace of mind */
18 #ifndef CONFIG_GEN_IRQ_START_VECTOR
19 #define CONFIG_GEN_IRQ_START_VECTOR 0
20 #endif
21 
22 #define EXVECT_SECT __attribute__((section(".exvectors")))
23 #define RVECT_SECT  __attribute__((section(".rvectors")))
24 #define FVECT_SECT  __attribute__((section(".fvectors")))
25 
26 #define __ISR__ __attribute__((interrupt, naked))
27 
28 #define SET_OFS1_HOCO_BITS(reg, freq)                                                              \
29 	((reg) & ~(0b11 << 12)) | ((((freq) == 24000000   ? 0b10                                   \
30 				     : (freq) == 32000000 ? 0b11                                   \
31 				     : (freq) == 48000000 ? 0b01                                   \
32 				     : (freq) == 64000000 ? 0b00                                   \
33 							  : 0b11)                                  \
34 				    << 12))
35 
REGISTER_SAVE(void)36 static ALWAYS_INLINE void REGISTER_SAVE(void)
37 {
38 	__asm volatile(
39 		/* Save the Registers to ISP at the top of ISR.					*/
40 		/* This code is relate on arch_new_thread() at thread.c				*/
41 		/* You should store the registers at the same registers arch_new_thread()	*/
42 		/* except PC and PSW.								*/
43 		"PUSHM		R1-R15\n"
44 
45 		"MVFACHI	R15\n"
46 		"PUSH.L		R15\n"
47 		"MVFACMI	R15\n"
48 		"SHLL		#16, R15\n"
49 		"PUSH.L		R15\n");
50 }
51 
REGISTER_RESTORE_EXIT(void)52 static ALWAYS_INLINE void REGISTER_RESTORE_EXIT(void)
53 {
54 	__asm volatile(
55 		/* Restore the registers and do the RTE at the End of ISR. */
56 		"POP		R15\n"
57 		"MVTACLO	R15\n"
58 		"POP		R15\n"
59 		"MVTACHI	R15\n"
60 
61 		"POPM		R1-R15\n"
62 		"RTE\n");
63 }
64 
65 /* Privileged instruction execption */
INT_Excep_SuperVisorInst(void)66 static void __ISR__ INT_Excep_SuperVisorInst(void)
67 {
68 	REGISTER_SAVE();
69 	ISR_DIRECT_HEADER();
70 	z_rx_fatal_error(K_ERR_CPU_EXCEPTION, NULL);
71 	ISR_DIRECT_FOOTER(1);
72 	REGISTER_RESTORE_EXIT();
73 }
74 
75 /* Access exception */
INT_Excep_AccessInst(void)76 static void __ISR__ INT_Excep_AccessInst(void)
77 {
78 	REGISTER_SAVE();
79 	ISR_DIRECT_HEADER();
80 	z_rx_fatal_error(K_ERR_CPU_EXCEPTION, NULL);
81 	ISR_DIRECT_FOOTER(1);
82 	REGISTER_RESTORE_EXIT();
83 }
84 
85 /* Undefined instruction exception */
INT_Excep_UndefinedInst(void)86 static void __ISR__ INT_Excep_UndefinedInst(void)
87 {
88 	REGISTER_SAVE();
89 	ISR_DIRECT_HEADER();
90 	z_rx_fatal_error(K_ERR_CPU_EXCEPTION, NULL);
91 	ISR_DIRECT_FOOTER(1);
92 	REGISTER_RESTORE_EXIT();
93 }
94 
95 /* floating point exception */
INT_Excep_FloatingPoint(void)96 static void __ISR__ INT_Excep_FloatingPoint(void)
97 {
98 	REGISTER_SAVE();
99 	ISR_DIRECT_HEADER();
100 	z_rx_fatal_error(K_ERR_CPU_EXCEPTION, NULL);
101 	ISR_DIRECT_FOOTER(1);
102 	REGISTER_RESTORE_EXIT();
103 }
104 
105 /* Non-maskable interrupt */
INT_NonMaskableInterrupt(void)106 static void __ISR__ INT_NonMaskableInterrupt(void)
107 {
108 	REGISTER_SAVE();
109 	ISR_DIRECT_HEADER();
110 	z_fatal_error(K_ERR_CPU_EXCEPTION, NULL);
111 	ISR_DIRECT_FOOTER(1);
112 	REGISTER_RESTORE_EXIT();
113 }
114 
115 /* dummy function */
Dummy(void)116 static void __ISR__ Dummy(void)
117 {
118 	REGISTER_SAVE();
119 	ISR_DIRECT_HEADER();
120 	ISR_DIRECT_FOOTER(1);
121 	REGISTER_RESTORE_EXIT();
122 }
123 
124 /**
125  * @brief select Zephyr ISR and argument from software ISR table and call
126  * function
127  *
128  * @param irq    interrupt to handle
129  */
handle_interrupt(uint8_t irq)130 static ALWAYS_INLINE void handle_interrupt(uint8_t irq)
131 {
132 	ISR_DIRECT_HEADER();
133 	_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
134 	ISR_DIRECT_FOOTER(1);
135 }
136 
137 /**
138  * @brief isr for reserved interrupts (0-15) that are not handled through
139  *        the zephyr sw isr table
140  */
reserved_isr(void)141 static void __ISR__ reserved_isr(void)
142 {
143 	REGISTER_SAVE();
144 	ISR_DIRECT_HEADER();
145 	z_fatal_error(K_ERR_CPU_EXCEPTION, NULL);
146 	ISR_DIRECT_FOOTER(1);
147 	REGISTER_RESTORE_EXIT();
148 }
149 
INT_RuntimeFatalInterrupt(void)150 static void __ISR__ INT_RuntimeFatalInterrupt(void)
151 {
152 	REGISTER_SAVE();
153 	ISR_DIRECT_HEADER();
154 
155 	uint32_t reason;
156 	const struct arch_esf *esf;
157 
158 	/* Read the current values of CPU registers r1 and r0 into C variables
159 	 * 'reason' is expected to contain the exception reason (from r1)
160 	 * 'esf' is expected to contain a pointer to the exception stack frame (from r0)
161 	 */
162 	__asm__ volatile("mov r1, %0\n\t"
163 			 "mov r0, %1\n\t"
164 			 : "=r"(reason), "=r"(esf));
165 
166 	z_rx_fatal_error(reason, esf);
167 
168 	ISR_DIRECT_FOOTER(1);
169 	REGISTER_RESTORE_EXIT();
170 }
171 
172 /* wrapper for z_rx_context_switch_isr, defined in switch.S */
173 extern void __ISR__ switch_isr_wrapper(void);
174 
175 /* this macro is used to define "demuxing" ISRs for all interrupts that are
176  * handled through Zephyr's software isr table.
177  */
178 
179 #define INT_DEMUX(irq)                                                                             \
180 	static __attribute__((interrupt, naked)) void int_demux_##irq(void)                        \
181 	{                                                                                          \
182 		REGISTER_SAVE();                                                                   \
183 		handle_interrupt(irq - CONFIG_GEN_IRQ_START_VECTOR);                               \
184 		REGISTER_RESTORE_EXIT();                                                           \
185 	}
186 
187 INT_DEMUX(16);
188 INT_DEMUX(17);
189 INT_DEMUX(18);
190 INT_DEMUX(19);
191 INT_DEMUX(20);
192 INT_DEMUX(21);
193 INT_DEMUX(22);
194 INT_DEMUX(23);
195 INT_DEMUX(24);
196 INT_DEMUX(25);
197 INT_DEMUX(27);
198 INT_DEMUX(26);
199 INT_DEMUX(28);
200 INT_DEMUX(29);
201 INT_DEMUX(30);
202 INT_DEMUX(31);
203 INT_DEMUX(32);
204 INT_DEMUX(33);
205 INT_DEMUX(34);
206 INT_DEMUX(35);
207 INT_DEMUX(36);
208 INT_DEMUX(37);
209 INT_DEMUX(38);
210 INT_DEMUX(39);
211 INT_DEMUX(40);
212 INT_DEMUX(41);
213 INT_DEMUX(42);
214 INT_DEMUX(43);
215 INT_DEMUX(44);
216 INT_DEMUX(45);
217 INT_DEMUX(46);
218 INT_DEMUX(47);
219 INT_DEMUX(48);
220 INT_DEMUX(49);
221 INT_DEMUX(50);
222 INT_DEMUX(51);
223 INT_DEMUX(52);
224 INT_DEMUX(53);
225 INT_DEMUX(54);
226 INT_DEMUX(55);
227 INT_DEMUX(56);
228 INT_DEMUX(57);
229 INT_DEMUX(58);
230 INT_DEMUX(59);
231 INT_DEMUX(60);
232 INT_DEMUX(61);
233 INT_DEMUX(62);
234 INT_DEMUX(63);
235 INT_DEMUX(64);
236 INT_DEMUX(65);
237 INT_DEMUX(66);
238 INT_DEMUX(67);
239 INT_DEMUX(68);
240 INT_DEMUX(69);
241 INT_DEMUX(70);
242 INT_DEMUX(71);
243 INT_DEMUX(72);
244 INT_DEMUX(73);
245 INT_DEMUX(74);
246 INT_DEMUX(75);
247 INT_DEMUX(76);
248 INT_DEMUX(77);
249 INT_DEMUX(78);
250 INT_DEMUX(79);
251 INT_DEMUX(80);
252 INT_DEMUX(81);
253 INT_DEMUX(82);
254 INT_DEMUX(83);
255 INT_DEMUX(84);
256 INT_DEMUX(85);
257 INT_DEMUX(86);
258 INT_DEMUX(87);
259 INT_DEMUX(88);
260 INT_DEMUX(89);
261 INT_DEMUX(90);
262 INT_DEMUX(91);
263 INT_DEMUX(92);
264 INT_DEMUX(93);
265 INT_DEMUX(94);
266 INT_DEMUX(95);
267 INT_DEMUX(96);
268 INT_DEMUX(97);
269 INT_DEMUX(98);
270 INT_DEMUX(99);
271 INT_DEMUX(100)
272 INT_DEMUX(101);
273 INT_DEMUX(102);
274 INT_DEMUX(103);
275 INT_DEMUX(104);
276 INT_DEMUX(105);
277 INT_DEMUX(106);
278 INT_DEMUX(107);
279 INT_DEMUX(108);
280 INT_DEMUX(109);
281 INT_DEMUX(110);
282 INT_DEMUX(111);
283 INT_DEMUX(112);
284 INT_DEMUX(113);
285 INT_DEMUX(114);
286 INT_DEMUX(115);
287 INT_DEMUX(116);
288 INT_DEMUX(117);
289 INT_DEMUX(118);
290 INT_DEMUX(119);
291 INT_DEMUX(120);
292 INT_DEMUX(121);
293 INT_DEMUX(122);
294 INT_DEMUX(123);
295 INT_DEMUX(124);
296 INT_DEMUX(125);
297 INT_DEMUX(126);
298 INT_DEMUX(127);
299 INT_DEMUX(128);
300 INT_DEMUX(129);
301 INT_DEMUX(130);
302 INT_DEMUX(131);
303 INT_DEMUX(132);
304 INT_DEMUX(133);
305 INT_DEMUX(134);
306 INT_DEMUX(135);
307 INT_DEMUX(136);
308 INT_DEMUX(137);
309 INT_DEMUX(138);
310 INT_DEMUX(139);
311 INT_DEMUX(140);
312 INT_DEMUX(141);
313 INT_DEMUX(142);
314 INT_DEMUX(143);
315 INT_DEMUX(144);
316 INT_DEMUX(145);
317 INT_DEMUX(146);
318 INT_DEMUX(147);
319 INT_DEMUX(148);
320 INT_DEMUX(149);
321 INT_DEMUX(150);
322 INT_DEMUX(151);
323 INT_DEMUX(152);
324 INT_DEMUX(153);
325 INT_DEMUX(154);
326 INT_DEMUX(155);
327 INT_DEMUX(156);
328 INT_DEMUX(157);
329 INT_DEMUX(158);
330 INT_DEMUX(159);
331 INT_DEMUX(160);
332 INT_DEMUX(161);
333 INT_DEMUX(162);
334 INT_DEMUX(163);
335 INT_DEMUX(164);
336 INT_DEMUX(165);
337 INT_DEMUX(166);
338 INT_DEMUX(167);
339 INT_DEMUX(168);
340 INT_DEMUX(169);
341 INT_DEMUX(170);
342 INT_DEMUX(171);
343 INT_DEMUX(172);
344 INT_DEMUX(173);
345 INT_DEMUX(174);
346 INT_DEMUX(175);
347 INT_DEMUX(176);
348 INT_DEMUX(177);
349 INT_DEMUX(178);
350 INT_DEMUX(179);
351 INT_DEMUX(180);
352 INT_DEMUX(181);
353 INT_DEMUX(182);
354 INT_DEMUX(183);
355 INT_DEMUX(184);
356 INT_DEMUX(185);
357 INT_DEMUX(186);
358 INT_DEMUX(187);
359 INT_DEMUX(188);
360 INT_DEMUX(189);
361 INT_DEMUX(190);
362 INT_DEMUX(191);
363 INT_DEMUX(192);
364 INT_DEMUX(193);
365 INT_DEMUX(194);
366 INT_DEMUX(195);
367 INT_DEMUX(196);
368 INT_DEMUX(197);
369 INT_DEMUX(198);
370 INT_DEMUX(199);
371 INT_DEMUX(200);
372 INT_DEMUX(201);
373 INT_DEMUX(202);
374 INT_DEMUX(203);
375 INT_DEMUX(204);
376 INT_DEMUX(205);
377 INT_DEMUX(206);
378 INT_DEMUX(207);
379 INT_DEMUX(208);
380 INT_DEMUX(209);
381 INT_DEMUX(210);
382 INT_DEMUX(211);
383 INT_DEMUX(212);
384 INT_DEMUX(213);
385 INT_DEMUX(214);
386 INT_DEMUX(215);
387 INT_DEMUX(216);
388 INT_DEMUX(217);
389 INT_DEMUX(218);
390 INT_DEMUX(219);
391 INT_DEMUX(220);
392 INT_DEMUX(221);
393 INT_DEMUX(222);
394 INT_DEMUX(223);
395 INT_DEMUX(224);
396 INT_DEMUX(225);
397 INT_DEMUX(226);
398 INT_DEMUX(227);
399 INT_DEMUX(228);
400 INT_DEMUX(229);
401 INT_DEMUX(230);
402 INT_DEMUX(231);
403 INT_DEMUX(232);
404 INT_DEMUX(233);
405 INT_DEMUX(234);
406 INT_DEMUX(235);
407 INT_DEMUX(236);
408 INT_DEMUX(237);
409 INT_DEMUX(238);
410 INT_DEMUX(239);
411 INT_DEMUX(240);
412 INT_DEMUX(241);
413 INT_DEMUX(242);
414 INT_DEMUX(243);
415 INT_DEMUX(244);
416 INT_DEMUX(245);
417 INT_DEMUX(246);
418 INT_DEMUX(247);
419 INT_DEMUX(248);
420 INT_DEMUX(249);
421 INT_DEMUX(250);
422 INT_DEMUX(251);
423 INT_DEMUX(252);
424 INT_DEMUX(253);
425 INT_DEMUX(254);
426 INT_DEMUX(255);
427 
428 const void *FixedVectors[] FVECT_SECT = {
429 	/* 0x00-0x4c: Reserved, must be 0xff (according to e2 studio example) */
430 	/* Reserved for OFSM */
431 	(fp)0xFFFFFFFF,
432 	(fp)0xFFFFFFFF,
433 	(fp)(SET_OFS1_HOCO_BITS(
434 		0xFFFFFFFF,
435 		(RX_CGC_PROP_HAS_STATUS_OKAY_OR(DT_NODELABEL(hoco), clock_frequency, 32000000)))),
436 	(fp)0xFFFFFFFF,
437 	/* Reserved area */
438 	(fp)0xFFFFFFFF,
439 	(fp)0xFFFFFFFF,
440 	(fp)0xFFFFFFFF,
441 	(fp)0xFFFFFFFF,
442 	/* Reserved for ID Code */
443 	(fp)0xFFFFFFFF,
444 	(fp)0xFFFFFFFF,
445 	(fp)0xFFFFFFFF,
446 	(fp)0xFFFFFFFF,
447 	/* Reserved area */
448 	(fp)0xFFFFFFFF,
449 	(fp)0xFFFFFFFF,
450 	(fp)0xFFFFFFFF,
451 	(fp)0xFFFFFFFF,
452 	/* Reserved area */
453 	(fp)0xFFFFFFFF,
454 	(fp)0xFFFFFFFF,
455 	(fp)0xFFFFFFFF,
456 	(fp)0xFFFFFFFF,
457 	/* 0x50: Privileged instruction exception */
458 	INT_Excep_SuperVisorInst,
459 	/* 0x54: Access exception */
460 	INT_Excep_AccessInst,
461 	/* 0x58: Reserved */
462 	Dummy,
463 	/* 0x5c: Undefined Instruction Exception */
464 	INT_Excep_UndefinedInst,
465 	/* 0x60: Reserved */
466 	Dummy,
467 	/* 0x64: Floating Point Exception */
468 	INT_Excep_FloatingPoint,
469 	/* 0x68-0x74: Reserved */
470 	Dummy,
471 	Dummy,
472 	Dummy,
473 	Dummy,
474 	/* 0x78: Non-maskable interrupt */
475 	INT_NonMaskableInterrupt,
476 	_start,
477 };
478 
479 const fp RelocatableVectors[] RVECT_SECT = {
480 	reserved_isr,  switch_isr_wrapper, INT_RuntimeFatalInterrupt,
481 	reserved_isr,  reserved_isr,       reserved_isr,
482 	reserved_isr,  reserved_isr,       reserved_isr,
483 	reserved_isr,  reserved_isr,       reserved_isr,
484 	reserved_isr,  reserved_isr,       reserved_isr,
485 	reserved_isr,  int_demux_16,       int_demux_17,
486 	int_demux_18,  int_demux_19,       int_demux_20,
487 	int_demux_21,  int_demux_22,       int_demux_23,
488 	int_demux_24,  int_demux_25,       int_demux_26,
489 	int_demux_27,  int_demux_28,       int_demux_29,
490 	int_demux_30,  int_demux_31,       int_demux_32,
491 	int_demux_33,  int_demux_34,       int_demux_35,
492 	int_demux_36,  int_demux_37,       int_demux_38,
493 	int_demux_39,  int_demux_40,       int_demux_41,
494 	int_demux_42,  int_demux_43,       int_demux_44,
495 	int_demux_45,  int_demux_46,       int_demux_47,
496 	int_demux_48,  int_demux_49,       int_demux_50,
497 	int_demux_51,  int_demux_52,       int_demux_53,
498 	int_demux_54,  int_demux_55,       int_demux_56,
499 	int_demux_57,  int_demux_58,       int_demux_59,
500 	int_demux_60,  int_demux_61,       int_demux_62,
501 	int_demux_63,  int_demux_64,       int_demux_65,
502 	int_demux_66,  int_demux_67,       int_demux_68,
503 	int_demux_69,  int_demux_70,       int_demux_71,
504 	int_demux_72,  int_demux_73,       int_demux_74,
505 	int_demux_75,  int_demux_76,       int_demux_77,
506 	int_demux_78,  int_demux_79,       int_demux_80,
507 	int_demux_81,  int_demux_82,       int_demux_83,
508 	int_demux_84,  int_demux_85,       int_demux_86,
509 	int_demux_87,  int_demux_88,       int_demux_89,
510 	int_demux_90,  int_demux_91,       int_demux_92,
511 	int_demux_93,  int_demux_94,       int_demux_95,
512 	int_demux_96,  int_demux_97,       int_demux_98,
513 	int_demux_99,  int_demux_100,      int_demux_101,
514 	int_demux_102, int_demux_103,      int_demux_104,
515 	int_demux_105, int_demux_106,      int_demux_107,
516 	int_demux_108, int_demux_109,      int_demux_110,
517 	int_demux_111, int_demux_112,      int_demux_113,
518 	int_demux_114, int_demux_115,      int_demux_116,
519 	int_demux_117, int_demux_118,      int_demux_119,
520 	int_demux_120, int_demux_121,      int_demux_122,
521 	int_demux_123, int_demux_124,      int_demux_125,
522 	int_demux_126, int_demux_127,      int_demux_128,
523 	int_demux_129, int_demux_130,      int_demux_131,
524 	int_demux_132, int_demux_133,      int_demux_134,
525 	int_demux_135, int_demux_136,      int_demux_137,
526 	int_demux_138, int_demux_139,      int_demux_140,
527 	int_demux_141, int_demux_142,      int_demux_143,
528 	int_demux_144, int_demux_145,      int_demux_146,
529 	int_demux_147, int_demux_148,      int_demux_149,
530 	int_demux_150, int_demux_151,      int_demux_152,
531 	int_demux_153, int_demux_154,      int_demux_155,
532 	int_demux_156, int_demux_157,      int_demux_158,
533 	int_demux_159, int_demux_160,      int_demux_161,
534 	int_demux_162, int_demux_163,      int_demux_164,
535 	int_demux_165, int_demux_166,      int_demux_167,
536 	int_demux_168, int_demux_169,      int_demux_170,
537 	int_demux_171, int_demux_172,      int_demux_173,
538 	int_demux_174, int_demux_175,      int_demux_176,
539 	int_demux_177, int_demux_178,      int_demux_179,
540 	int_demux_180, int_demux_181,      int_demux_182,
541 	int_demux_183, int_demux_184,      int_demux_185,
542 	int_demux_186, int_demux_187,      int_demux_188,
543 	int_demux_189, int_demux_190,      int_demux_191,
544 	int_demux_192, int_demux_193,      int_demux_194,
545 	int_demux_195, int_demux_196,      int_demux_197,
546 	int_demux_198, int_demux_199,      int_demux_200,
547 	int_demux_201, int_demux_202,      int_demux_203,
548 	int_demux_204, int_demux_205,      int_demux_206,
549 	int_demux_207, int_demux_208,      int_demux_209,
550 	int_demux_210, int_demux_211,      int_demux_212,
551 	int_demux_213, int_demux_214,      int_demux_215,
552 	int_demux_216, int_demux_217,      int_demux_218,
553 	int_demux_219, int_demux_220,      int_demux_221,
554 	int_demux_222, int_demux_223,      int_demux_224,
555 	int_demux_225, int_demux_226,      int_demux_227,
556 	int_demux_228, int_demux_229,      int_demux_230,
557 	int_demux_231, int_demux_232,      int_demux_233,
558 	int_demux_234, int_demux_235,      int_demux_236,
559 	int_demux_237, int_demux_238,      int_demux_239,
560 	int_demux_240, int_demux_241,      int_demux_242,
561 	int_demux_243, int_demux_244,      int_demux_245,
562 	int_demux_246, int_demux_247,      int_demux_248,
563 	int_demux_249, int_demux_250,      int_demux_251,
564 	int_demux_252, int_demux_253,      int_demux_254,
565 	int_demux_255,
566 };
567