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_MULTI_CORE_HALTING) || 17 (CFG_HALT_CORES_SGI >= 8 && CFG_HALT_CORES_SGI < 16)); 18 19 static enum itr_return __noreturn 20 multi_core_halt_it_handler(struct itr_handler *hdl __unused) 21 { 22 IMSG("Halting CPU %zu", get_core_pos()); 23 24 while (true) 25 cpu_idle(); 26 } 27 28 static struct itr_handler multi_core_halt_handler __nex_data = { 29 .it = CFG_HALT_CORES_SGI, 30 .handler = multi_core_halt_it_handler, 31 }; 32 DECLARE_KEEP_PAGER(multi_core_halt_handler); 33 34 static void halt_other_cores(void) 35 { 36 struct itr_chip *chip = interrupt_get_main_chip_may_fail(); 37 38 if (chip) 39 interrupt_raise_sgi(chip, CFG_HALT_CORES_SGI, 40 ITR_CPU_MASK_TO_OTHER_CPUS); 41 else 42 EMSG("Can't halt other cores, main interrupt chip not set"); 43 } 44 45 static TEE_Result init_multi_core_halt_handler(void) 46 { 47 if (!IS_ENABLED(CFG_MULTI_CORE_HALTING) || CFG_TEE_CORE_NB_CORE == 1) 48 return TEE_SUCCESS; 49 50 if (interrupt_add_handler_with_chip(interrupt_get_main_chip(), 51 &multi_core_halt_handler)) 52 panic(); 53 54 interrupt_enable(interrupt_get_main_chip(), 55 multi_core_halt_handler.it); 56 57 return TEE_SUCCESS; 58 } 59 60 nex_driver_init_late(init_multi_core_halt_handler); 61 62 void __do_panic(const char *file __maybe_unused, 63 const int line __maybe_unused, 64 const char *func __maybe_unused, 65 const char *msg __maybe_unused) 66 { 67 /* disable preemption */ 68 (void)thread_mask_exceptions(THREAD_EXCP_ALL); 69 70 /* trace: Panic ['panic-string-message' ]at FILE:LINE [<FUNCTION>]" */ 71 if (!file && !func && !msg) 72 EMSG_RAW("Panic"); 73 else 74 EMSG_RAW("Panic %s%s%sat %s:%d %s%s%s", 75 msg ? "'" : "", msg ? msg : "", msg ? "' " : "", 76 file ? file : "?", file ? line : 0, 77 func ? "<" : "", func ? func : "", func ? ">" : ""); 78 79 print_kernel_stack(); 80 81 if (IS_ENABLED(CFG_HALT_CORES_ON_PANIC) && CFG_TEE_CORE_NB_CORE > 1) 82 halt_other_cores(); 83 84 /* abort current execution */ 85 while (1) 86 cpu_idle(); 87 } 88 89 void __weak cpu_idle(void) 90 { 91 } 92