1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2016, Linaro Limited 4 * Copyright (c) 2014, STMicroelectronics International N.V. 5 */ 6 7 #include <initcall.h> 8 #include <kernel/interrupt.h> 9 #include <kernel/misc.h> 10 #include <kernel/panic.h> 11 #include <kernel/thread.h> 12 #include <kernel/unwind.h> 13 #include <trace.h> 14 15 /* SGI number chosen to halt other cores must be in the secure SGI range */ 16 static_assert(!IS_ENABLED(CFG_HALT_CORES_ON_PANIC) || 17 (CFG_HALT_CORES_ON_PANIC_SGI >= 8 && 18 CFG_HALT_CORES_ON_PANIC_SGI < 16)); 19 20 static enum itr_return __noreturn 21 multi_core_panic_it_handler(struct itr_handler *hdl __unused) 22 { 23 IMSG("Halting CPU %zu", get_core_pos()); 24 25 while (true) 26 cpu_idle(); 27 } 28 29 static struct itr_handler multi_core_panic_handler = { 30 .it = CFG_HALT_CORES_ON_PANIC_SGI, 31 .handler = multi_core_panic_it_handler, 32 }; 33 DECLARE_KEEP_PAGER(multi_core_panic_handler); 34 35 static void notify_other_cores(void) 36 { 37 interrupt_raise_sgi(interrupt_get_main_chip(), 38 CFG_HALT_CORES_ON_PANIC_SGI, 39 ITR_CPU_MASK_TO_OTHER_CPUS); 40 } 41 42 static TEE_Result init_multi_core_panic_handler(void) 43 { 44 if (!IS_ENABLED(CFG_HALT_CORES_ON_PANIC) || CFG_TEE_CORE_NB_CORE == 1) 45 return TEE_SUCCESS; 46 47 if (interrupt_add_handler_with_chip(interrupt_get_main_chip(), 48 &multi_core_panic_handler)) 49 panic(); 50 51 interrupt_enable(interrupt_get_main_chip(), 52 multi_core_panic_handler.it); 53 54 return TEE_SUCCESS; 55 } 56 57 boot_final(init_multi_core_panic_handler); 58 59 void __do_panic(const char *file __maybe_unused, 60 const int line __maybe_unused, 61 const char *func __maybe_unused, 62 const char *msg __maybe_unused) 63 { 64 /* disable prehemption */ 65 (void)thread_mask_exceptions(THREAD_EXCP_ALL); 66 67 /* trace: Panic ['panic-string-message' ]at FILE:LINE [<FUNCTION>]" */ 68 if (!file && !func && !msg) 69 EMSG_RAW("Panic"); 70 else 71 EMSG_RAW("Panic %s%s%sat %s:%d %s%s%s", 72 msg ? "'" : "", msg ? msg : "", msg ? "' " : "", 73 file ? file : "?", file ? line : 0, 74 func ? "<" : "", func ? func : "", func ? ">" : ""); 75 76 print_kernel_stack(); 77 78 if (IS_ENABLED(CFG_HALT_CORES_ON_PANIC) && CFG_TEE_CORE_NB_CORE > 1) 79 notify_other_cores(); 80 81 /* abort current execution */ 82 while (1) 83 cpu_idle(); 84 } 85 86 void __weak cpu_idle(void) 87 { 88 } 89