aboutsummaryrefslogtreecommitdiff
path: root/tftf/framework/aarch32/exception_report.c
diff options
context:
space:
mode:
Diffstat (limited to 'tftf/framework/aarch32/exception_report.c')
-rw-r--r--tftf/framework/aarch32/exception_report.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/tftf/framework/aarch32/exception_report.c b/tftf/framework/aarch32/exception_report.c
new file mode 100644
index 000000000..46665e3e9
--- /dev/null
+++ b/tftf/framework/aarch32/exception_report.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <platform.h>
+#include <utils_def.h>
+
+/* We save r0-r12. */
+#define GPREGS_CNT 13
+
+/* Set of registers saved by the crash_dump() assembly function. */
+struct cpu_context {
+ u_register_t regs[GPREGS_CNT];
+ u_register_t lr;
+ u_register_t sp;
+};
+
+void __dead2 print_exception(const struct cpu_context *ctx)
+{
+ u_register_t mpid = read_mpidr();
+
+ /*
+ * The instruction barrier ensures we don't read stale values of system
+ * registers.
+ */
+ isb();
+
+ printf("Unhandled exception on CPU%u.\n", platform_get_core_pos(mpid));
+
+ /* Dump some interesting system registers. */
+ printf("System registers:\n");
+ printf(" MPIDR=0x%lx\n", mpid);
+ printf(" HSR=0x%lx ELR=0x%lx SPSR=0x%lx\n", read_hsr(),
+ read_elr_hyp(), read_spsr());
+
+ /* Dump general-purpose registers. */
+ printf("General-purpose registers:\n");
+ for (int i = 0; i < GPREGS_CNT; ++i) {
+ printf(" r%u=0x%lx\n", i, ctx->regs[i]);
+ }
+ printf(" LR=0x%lx\n", ctx->lr);
+ printf(" SP=0x%lx\n", ctx->sp);
+
+ while (1)
+ wfi();
+}