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 __nex_data = { 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 struct itr_chip *chip = interrupt_get_main_chip_may_fail(); 38 39 if (chip) 40 interrupt_raise_sgi(chip, CFG_HALT_CORES_ON_PANIC_SGI, 41 ITR_CPU_MASK_TO_OTHER_CPUS); 42 else 43 EMSG("Can't notify other cores, main interrupt chip not set"); 44 } 45 46 static TEE_Result init_multi_core_panic_handler(void) 47 { 48 if (!IS_ENABLED(CFG_HALT_CORES_ON_PANIC) || CFG_TEE_CORE_NB_CORE == 1) 49 return TEE_SUCCESS; 50 51 if (interrupt_add_handler_with_chip(interrupt_get_main_chip(), 52 &multi_core_panic_handler)) 53 panic(); 54 55 interrupt_enable(interrupt_get_main_chip(), 56 multi_core_panic_handler.it); 57 58 return TEE_SUCCESS; 59 } 60 61 nex_driver_init_late(init_multi_core_panic_handler); 62 63 void __do_panic(const char *file __maybe_unused, 64 const int line __maybe_unused, 65 const char *func __maybe_unused, 66 const char *msg __maybe_unused) 67 { 68 /* disable preemption */ 69 (void)thread_mask_exceptions(THREAD_EXCP_ALL); 70 71 /* trace: Panic ['panic-string-message' ]at FILE:LINE [<FUNCTION>]" */ 72 if (!file && !func && !msg) 73 EMSG_RAW("Panic"); 74 else 75 EMSG_RAW("Panic %s%s%sat %s:%d %s%s%s", 76 msg ? "'" : "", msg ? msg : "", msg ? "' " : "", 77 file ? file : "?", file ? line : 0, 78 func ? "<" : "", func ? func : "", func ? ">" : ""); 79 80 print_kernel_stack(); 81 82 if (IS_ENABLED(CFG_HALT_CORES_ON_PANIC) && CFG_TEE_CORE_NB_CORE > 1) 83 notify_other_cores(); 84 85 /* abort current execution */ 86 while (1) 87 cpu_idle(); 88 } 89 90 void __weak cpu_idle(void) 91 { 92 } 93