xref: /optee_os/core/kernel/panic.c (revision 7653887e496156c4bfd9dd9a1478d277f14ef128)
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
multi_core_halt_it_handler(struct itr_handler * hdl __unused)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 
halt_other_cores(void)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 
init_multi_core_halt_handler(void)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 
__do_panic(const char * file __maybe_unused,const int line __maybe_unused,const char * func __maybe_unused,const char * msg __maybe_unused)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 
cpu_idle(void)89 void __weak cpu_idle(void)
90 {
91 }
92