diff --git a/arch/rx/core/CMakeLists.txt b/arch/rx/core/CMakeLists.txt index 5b3e888db6a5..db3bbc550d99 100644 --- a/arch/rx/core/CMakeLists.txt +++ b/arch/rx/core/CMakeLists.txt @@ -11,6 +11,7 @@ zephyr_library_sources( thread.c vects.c isr_exit.S + fatal.c ) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) diff --git a/arch/rx/core/fatal.c b/arch/rx/core/fatal.c new file mode 100644 index 000000000000..a6dbcaa72fd0 --- /dev/null +++ b/arch/rx/core/fatal.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Fatal fault handling + * + * This module implements the routines necessary for handling fatal faults on + * RX CPUs. + */ + +#include +#include +#include +#include +#include +LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); + +#ifdef CONFIG_EXCEPTION_DEBUG +static void dump_rx_esf(const struct arch_esf *esf) +{ + LOG_ERR(" ACC_L: 0x%08x ACC_H: 0x%08x", esf->acc_l, esf->acc_h); + LOG_ERR(" r1: 0x%08x r2: 0x%08x r3: 0x%08x", esf->r1, esf->r2, esf->r3); + LOG_ERR(" r4: 0x%08x r5: 0x%08x r6: 0x%08x", esf->r4, esf->r5, esf->r6); + LOG_ERR(" r7: 0x%08x r8: 0x%08x r9: 0x%08x", esf->r7, esf->r8, esf->r9); + LOG_ERR(" r10: 0x%08x r11: 0x%08x r12: 0x%08x", esf->r10, esf->r11, esf->r12); + LOG_ERR(" r13: 0x%08x r14: 0x%08x r15: 0x%08x", esf->r13, esf->r14, esf->r15); + LOG_ERR(" PC: 0x%08x PSW: 0x%08x", esf->entry_point, esf->psw); +} +#endif + +void z_rx_fatal_error(unsigned int reason, const struct arch_esf *esf) +{ +#ifdef CONFIG_EXCEPTION_DEBUG + if (esf != NULL) { + dump_rx_esf(esf); + } +#endif /* CONFIG_EXCEPTION_DEBUG */ + + z_fatal_error(reason, esf); +} +FUNC_NORETURN void arch_system_halt(unsigned int reason) +{ + ARG_UNUSED(reason); + + __asm__("brk"); + + CODE_UNREACHABLE; +} diff --git a/arch/rx/core/vects.c b/arch/rx/core/vects.c index 836e9d3adb2f..ed4630c3c260 100644 --- a/arch/rx/core/vects.c +++ b/arch/rx/core/vects.c @@ -138,6 +138,28 @@ static void __ISR__ reserved_isr(void) REGISTER_RESTORE_EXIT(); } +static void __ISR__ INT_RuntimeFatalInterrupt(void) +{ + REGISTER_SAVE(); + ISR_DIRECT_HEADER(); + + uint32_t reason; + const struct arch_esf *esf; + + /* Read the current values of CPU registers r1 and r0 into C variables + * 'reason' is expected to contain the exception reason (from r1) + * 'esf' is expected to contain a pointer to the exception stack frame (from r0) + */ + __asm__ volatile("mov r1, %0\n\t" + "mov r0, %1\n\t" + : "=r"(reason), "=r"(esf)); + + z_rx_fatal_error(reason, esf); + + ISR_DIRECT_FOOTER(1); + REGISTER_RESTORE_EXIT(); +} + /* wrapper for z_rx_context_switch_isr, defined in switch.S */ extern void __ISR__ switch_isr_wrapper(void); @@ -444,56 +466,90 @@ const void *FixedVectors[] FVECT_SECT = { }; const fp RelocatableVectors[] RVECT_SECT = { - reserved_isr, switch_isr_wrapper, reserved_isr, reserved_isr, reserved_isr, - reserved_isr, reserved_isr, reserved_isr, reserved_isr, reserved_isr, - reserved_isr, reserved_isr, reserved_isr, reserved_isr, reserved_isr, - reserved_isr, int_demux_16, int_demux_17, int_demux_18, int_demux_19, - int_demux_20, int_demux_21, int_demux_22, int_demux_23, int_demux_24, - int_demux_25, int_demux_26, int_demux_27, int_demux_28, int_demux_29, - int_demux_30, int_demux_31, int_demux_32, int_demux_33, int_demux_34, - int_demux_35, int_demux_36, int_demux_37, int_demux_38, int_demux_39, - int_demux_40, int_demux_41, int_demux_42, int_demux_43, int_demux_44, - int_demux_45, int_demux_46, int_demux_47, int_demux_48, int_demux_49, - int_demux_50, int_demux_51, int_demux_52, int_demux_53, int_demux_54, - int_demux_55, int_demux_56, int_demux_57, int_demux_58, int_demux_59, - int_demux_60, int_demux_61, int_demux_62, int_demux_63, int_demux_64, - int_demux_65, int_demux_66, int_demux_67, int_demux_68, int_demux_69, - int_demux_70, int_demux_71, int_demux_72, int_demux_73, int_demux_74, - int_demux_75, int_demux_76, int_demux_77, int_demux_78, int_demux_79, - int_demux_80, int_demux_81, int_demux_82, int_demux_83, int_demux_84, - int_demux_85, int_demux_86, int_demux_87, int_demux_88, int_demux_89, - int_demux_90, int_demux_91, int_demux_92, int_demux_93, int_demux_94, - int_demux_95, int_demux_96, int_demux_97, int_demux_98, int_demux_99, - int_demux_100, int_demux_101, int_demux_102, int_demux_103, int_demux_104, - int_demux_105, int_demux_106, int_demux_107, int_demux_108, int_demux_109, - int_demux_110, int_demux_111, int_demux_112, int_demux_113, int_demux_114, - int_demux_115, int_demux_116, int_demux_117, int_demux_118, int_demux_119, - int_demux_120, int_demux_121, int_demux_122, int_demux_123, int_demux_124, - int_demux_125, int_demux_126, int_demux_127, int_demux_128, int_demux_129, - int_demux_130, int_demux_131, int_demux_132, int_demux_133, int_demux_134, - int_demux_135, int_demux_136, int_demux_137, int_demux_138, int_demux_139, - int_demux_140, int_demux_141, int_demux_142, int_demux_143, int_demux_144, - int_demux_145, int_demux_146, int_demux_147, int_demux_148, int_demux_149, - int_demux_150, int_demux_151, int_demux_152, int_demux_153, int_demux_154, - int_demux_155, int_demux_156, int_demux_157, int_demux_158, int_demux_159, - int_demux_160, int_demux_161, int_demux_162, int_demux_163, int_demux_164, - int_demux_165, int_demux_166, int_demux_167, int_demux_168, int_demux_169, - int_demux_170, int_demux_171, int_demux_172, int_demux_173, int_demux_174, - int_demux_175, int_demux_176, int_demux_177, int_demux_178, int_demux_179, - int_demux_180, int_demux_181, int_demux_182, int_demux_183, int_demux_184, - int_demux_185, int_demux_186, int_demux_187, int_demux_188, int_demux_189, - int_demux_190, int_demux_191, int_demux_192, int_demux_193, int_demux_194, - int_demux_195, int_demux_196, int_demux_197, int_demux_198, int_demux_199, - int_demux_200, int_demux_201, int_demux_202, int_demux_203, int_demux_204, - int_demux_205, int_demux_206, int_demux_207, int_demux_208, int_demux_209, - int_demux_210, int_demux_211, int_demux_212, int_demux_213, int_demux_214, - int_demux_215, int_demux_216, int_demux_217, int_demux_218, int_demux_219, - int_demux_220, int_demux_221, int_demux_222, int_demux_223, int_demux_224, - int_demux_225, int_demux_226, int_demux_227, int_demux_228, int_demux_229, - int_demux_230, int_demux_231, int_demux_232, int_demux_233, int_demux_234, - int_demux_235, int_demux_236, int_demux_237, int_demux_238, int_demux_239, - int_demux_240, int_demux_241, int_demux_242, int_demux_243, int_demux_244, - int_demux_245, int_demux_246, int_demux_247, int_demux_248, int_demux_249, - int_demux_250, int_demux_251, int_demux_252, int_demux_253, int_demux_254, + reserved_isr, switch_isr_wrapper, INT_RuntimeFatalInterrupt, + reserved_isr, reserved_isr, reserved_isr, + reserved_isr, reserved_isr, reserved_isr, + reserved_isr, reserved_isr, reserved_isr, + reserved_isr, reserved_isr, reserved_isr, + reserved_isr, int_demux_16, int_demux_17, + int_demux_18, int_demux_19, int_demux_20, + int_demux_21, int_demux_22, int_demux_23, + int_demux_24, int_demux_25, int_demux_26, + int_demux_27, int_demux_28, int_demux_29, + int_demux_30, int_demux_31, int_demux_32, + int_demux_33, int_demux_34, int_demux_35, + int_demux_36, int_demux_37, int_demux_38, + int_demux_39, int_demux_40, int_demux_41, + int_demux_42, int_demux_43, int_demux_44, + int_demux_45, int_demux_46, int_demux_47, + int_demux_48, int_demux_49, int_demux_50, + int_demux_51, int_demux_52, int_demux_53, + int_demux_54, int_demux_55, int_demux_56, + int_demux_57, int_demux_58, int_demux_59, + int_demux_60, int_demux_61, int_demux_62, + int_demux_63, int_demux_64, int_demux_65, + int_demux_66, int_demux_67, int_demux_68, + int_demux_69, int_demux_70, int_demux_71, + int_demux_72, int_demux_73, int_demux_74, + int_demux_75, int_demux_76, int_demux_77, + int_demux_78, int_demux_79, int_demux_80, + int_demux_81, int_demux_82, int_demux_83, + int_demux_84, int_demux_85, int_demux_86, + int_demux_87, int_demux_88, int_demux_89, + int_demux_90, int_demux_91, int_demux_92, + int_demux_93, int_demux_94, int_demux_95, + int_demux_96, int_demux_97, int_demux_98, + int_demux_99, int_demux_100, int_demux_101, + int_demux_102, int_demux_103, int_demux_104, + int_demux_105, int_demux_106, int_demux_107, + int_demux_108, int_demux_109, int_demux_110, + int_demux_111, int_demux_112, int_demux_113, + int_demux_114, int_demux_115, int_demux_116, + int_demux_117, int_demux_118, int_demux_119, + int_demux_120, int_demux_121, int_demux_122, + int_demux_123, int_demux_124, int_demux_125, + int_demux_126, int_demux_127, int_demux_128, + int_demux_129, int_demux_130, int_demux_131, + int_demux_132, int_demux_133, int_demux_134, + int_demux_135, int_demux_136, int_demux_137, + int_demux_138, int_demux_139, int_demux_140, + int_demux_141, int_demux_142, int_demux_143, + int_demux_144, int_demux_145, int_demux_146, + int_demux_147, int_demux_148, int_demux_149, + int_demux_150, int_demux_151, int_demux_152, + int_demux_153, int_demux_154, int_demux_155, + int_demux_156, int_demux_157, int_demux_158, + int_demux_159, int_demux_160, int_demux_161, + int_demux_162, int_demux_163, int_demux_164, + int_demux_165, int_demux_166, int_demux_167, + int_demux_168, int_demux_169, int_demux_170, + int_demux_171, int_demux_172, int_demux_173, + int_demux_174, int_demux_175, int_demux_176, + int_demux_177, int_demux_178, int_demux_179, + int_demux_180, int_demux_181, int_demux_182, + int_demux_183, int_demux_184, int_demux_185, + int_demux_186, int_demux_187, int_demux_188, + int_demux_189, int_demux_190, int_demux_191, + int_demux_192, int_demux_193, int_demux_194, + int_demux_195, int_demux_196, int_demux_197, + int_demux_198, int_demux_199, int_demux_200, + int_demux_201, int_demux_202, int_demux_203, + int_demux_204, int_demux_205, int_demux_206, + int_demux_207, int_demux_208, int_demux_209, + int_demux_210, int_demux_211, int_demux_212, + int_demux_213, int_demux_214, int_demux_215, + int_demux_216, int_demux_217, int_demux_218, + int_demux_219, int_demux_220, int_demux_221, + int_demux_222, int_demux_223, int_demux_224, + int_demux_225, int_demux_226, int_demux_227, + int_demux_228, int_demux_229, int_demux_230, + int_demux_231, int_demux_232, int_demux_233, + int_demux_234, int_demux_235, int_demux_236, + int_demux_237, int_demux_238, int_demux_239, + int_demux_240, int_demux_241, int_demux_242, + int_demux_243, int_demux_244, int_demux_245, + int_demux_246, int_demux_247, int_demux_248, + int_demux_249, int_demux_250, int_demux_251, + int_demux_252, int_demux_253, int_demux_254, int_demux_255, }; diff --git a/arch/rx/include/kernel_arch_func.h b/arch/rx/include/kernel_arch_func.h index 70058fb5c96a..65041bddc348 100644 --- a/arch/rx/include/kernel_arch_func.h +++ b/arch/rx/include/kernel_arch_func.h @@ -25,6 +25,7 @@ static inline bool arch_is_in_isr(void) } extern void z_rx_arch_switch(void *switch_to, void **switched_from); +extern void z_rx_fatal_error(unsigned int reason, const struct arch_esf *esf); static inline void arch_switch(void *switch_to, void **switched_from) { diff --git a/include/zephyr/arch/rx/arch.h b/include/zephyr/arch/rx/arch.h index db3bebc8ba02..86c730e7bdbc 100644 --- a/include/zephyr/arch/rx/arch.h +++ b/include/zephyr/arch/rx/arch.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/include/zephyr/arch/rx/error.h b/include/zephyr/arch/rx/error.h new file mode 100644 index 000000000000..2e0b8da6cc9f --- /dev/null +++ b/include/zephyr/arch/rx/error.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Renesas RX arch public error handling + * + * Renesas RX-specific kernel error handling interface. Included by + * rx/arch.h. + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_RX_ERROR_H_ +#define ZEPHYR_INCLUDE_ARCH_RX_ERROR_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ARCH_EXCEPT(reason_p) \ + do { \ + arch_irq_unlock(0); \ + __asm__ volatile("mov %[_reason], r1\n\t" \ + "int #2\n\t" ::[_reason] "r"(reason_p) \ + : "r1", "memory"); \ + } while (false) + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_ARCH_RX_ERROR_H_ */