blob: 0add2764aec005aae9a8c56109f9602d5dc77ebf [file] [log] [blame]
Sandrine Bailleuxa43b0032019-01-14 14:04:32 +01001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdint.h>
8#include <stdio.h>
9
10#include <arch_helpers.h>
11#include <debug.h>
12#include <platform.h>
13#include <utils_def.h>
14
15/* We save x0-x30. */
16#define GPREGS_CNT 31
17
18/* Set of registers saved by the crash_dump() assembly function. */
19struct cpu_context {
20 u_register_t regs[GPREGS_CNT];
21 u_register_t sp;
22};
23
24/*
25 * Read the EL1 or EL2 version of a register, depending on the current exception
26 * level.
27 */
28#define read_sysreg(_name) \
29 (IS_IN_EL2() ? read_##_name##_el2() : read_##_name##_el1())
30
31void __dead2 print_exception(const struct cpu_context *ctx)
32{
33 u_register_t mpid = read_mpidr_el1();
34
35 /*
36 * The instruction barrier ensures we don't read stale values of system
37 * registers.
38 */
39 isb();
40
41 printf("Unhandled exception on CPU%u.\n", platform_get_core_pos(mpid));
42
43 /* Dump some interesting system registers. */
44 printf("System registers:\n");
45 printf(" MPIDR=0x%lx\n", mpid);
46 printf(" ESR=0x%lx ELR=0x%lx FAR=0x%lx\n", read_sysreg(esr),
47 read_sysreg(elr), read_sysreg(far));
48 printf(" SCTLR=0x%lx SPSR=0x%lx DAIF=0x%lx\n",
49 read_sysreg(sctlr), read_sysreg(spsr), read_daif());
50
51 /* Dump general-purpose registers. */
52 printf("General-purpose registers:\n");
53 for (int i = 0; i < GPREGS_CNT; ++i) {
54 printf(" x%u=0x%lx\n", i, ctx->regs[i]);
55 }
56 printf(" SP=0x%lx\n", ctx->sp);
57
58 while (1)
59 wfi();
60}