1 // © 2021 Qualcomm Innovation Center, Inc. All rights reserved.
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 // Note, do not call panic or assert here, they will recurse!
6 
7 #include <hyptypes.h>
8 
9 #include <abort.h>
10 #include <attributes.h>
11 #include <compiler.h>
12 #include <idle.h>
13 #include <ipi.h>
14 #include <log.h>
15 #include <preempt.h>
16 #include <thread.h>
17 #include <trace.h>
18 
19 #include <events/abort.h>
20 #include <events/scheduler.h>
21 #include <events/thread.h>
22 
23 #include <asm/event.h>
24 
25 #include "event_handlers.h"
26 
27 void NOINLINE
abort_handle_scheduler_stop(void)28 abort_handle_scheduler_stop(void)
29 {
30 	if (!idle_is_current()) {
31 		trigger_thread_save_state_event();
32 	}
33 }
34 
35 noreturn void NOINLINE
abort_handle_ipi_received(void)36 abort_handle_ipi_received(void)
37 {
38 	preempt_disable();
39 
40 	if (!idle_is_current()) {
41 		trigger_thread_save_state_event();
42 	}
43 
44 	trigger_abort_kernel_remote_event();
45 
46 	void *mem = NULL;
47 	while (1) {
48 		asm_event_wait(&mem);
49 	}
50 }
51 
52 noreturn void NOINLINE COLD
abort(const char * str,abort_reason_t reason)53 abort(const char *str, abort_reason_t reason) LOCK_IMPL
54 {
55 	void *from  = __builtin_return_address(0);
56 	void *frame = __builtin_frame_address(0);
57 
58 	from = __builtin_extract_return_addr(from);
59 
60 	// Stop all cores and disable preemption
61 	trigger_scheduler_stop_event();
62 
63 	TRACE_AND_LOG(ERROR, PANIC, "Abort: {:s} from PC {:#x}, FP {:#x}",
64 		      (register_t)(uintptr_t)str, (register_t)(uintptr_t)from,
65 		      (register_t)(uintptr_t)frame);
66 
67 	trigger_abort_kernel_event(reason);
68 
69 	while (1) {
70 		asm_event_wait(str);
71 	}
72 }
73