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