summaryrefslogtreecommitdiff
path: root/core/cortex-m/panic.S
diff options
context:
space:
mode:
Diffstat (limited to 'core/cortex-m/panic.S')
-rw-r--r--core/cortex-m/panic.S108
1 files changed, 108 insertions, 0 deletions
diff --git a/core/cortex-m/panic.S b/core/cortex-m/panic.S
new file mode 100644
index 0000000000..766af75143
--- /dev/null
+++ b/core/cortex-m/panic.S
@@ -0,0 +1,108 @@
+/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Fatal exception handling and debug tracing
+ */
+
+#include "config.h"
+
+.text
+
+.syntax unified
+.code 16
+
+.macro hex_reg r, offset @ prepare to build
+ add r1, r3, #\offset @ .. hexadecimal string
+ mov r0, \r @ .. from the reg value
+ bl buildhex
+.endm
+
+/* fatal exception handler */
+.global panic
+.thumb_func
+panic:
+#ifndef CONFIG_DEBUG
+ b EcSystemReset @ Reboot the system
+#else /* CONFIG_DEBUG */
+ /* check that the exception stack pointer is valid */
+ ldr r0, =CONFIG_RAM_BASE @ start of RAM
+ ldr r1, =CONFIG_RAM_BASE+CONFIG_RAM_SIZE @ end of RAM
+ mrs r12, psp @ process stack pointer
+ cmp r12, r0 @ is sp >= RAM start ?
+ it ge
+ cmpge r1, r12 @ is sp < RAM end ?
+ blt panic_print @ no => no values to read
+ /* output registers value */
+ ldr r3, =msg_excep @ pointer to the text buffer
+ mrs r2, ipsr @ get exception num from IPSR
+ bfc r2, #9, #23 @ the exception is the 3 LSB
+ hex_reg r2, 18 @ prepare hexa for excep number
+ hex_reg r4, 119 @ prepare hexa for R4
+ hex_reg r5, 132 @ prepare hexa for R5
+ hex_reg r6, 145 @ prepare hexa for R6
+ hex_reg r7, 156 @ prepare hexa for R7
+ hex_reg r8, 171 @ prepare hexa for R8
+ hex_reg r9, 184 @ prepare hexa for R9
+ hex_reg r10, 197 @ prepare hexa for R10
+ hex_reg r11, 210 @ prepare hexa for R11
+ ldmia r12!, {r4-r11} @ load saved r0-r3,r12,lr,pc,psr
+ hex_reg r4, 66 @ prepare hexa for R0
+ hex_reg r5, 79 @ prepare hexa for R1
+ hex_reg r6, 92 @ prepare hexa for R2
+ hex_reg r7, 105 @ prepare hexa for R3
+ hex_reg r8, 225 @ prepare hexa for R12
+ hex_reg r12, 238 @ prepare hexa for SP
+ hex_reg r9, 251 @ prepare hexa for LR
+ hex_reg r10, 264 @ prepare hexa for PC
+ hex_reg r11, 40 @ prepare hexa for xPSR
+ /* print exception trace */
+panic_print:
+ ldr r0, =msg_excep @ pointer to the text buffer
+ bl emergency_puts @ print the banner
+ b system_reset @ Reboot the system
+
+/* Helpers for exception trace */
+/* print a string on the UART
+ * r0: asciiZ string pointer
+ */
+emergency_puts:
+ ldr r1, =CONFIG_UART_ADDRESS @ UART base address
+1:
+ ldrb r3, [r0], #1 @ read one character
+ cmp r3, #0 @ end of the string ?
+ beq 3f @ if yes, return
+2: /* putchar */
+ ldr r2, [r1, #CONFIG_UART_SR_OFFSET] @ read UART status
+ tst r2, #CONFIG_UART_SR_TXEMPTY @ free space on TX ?
+ beq 2b @ if no, wait
+ str r3, [r1, #CONFIG_UART_DR_OFFSET] @ send character to UART DR
+ b 1b @ goto next character
+3: /* return */
+ bx lr
+
+/* write a number in hexadecimal in a text buffer
+ * r0: number to print
+ * r1: pointer to *end* of the buffer (filled with '0')
+ */
+buildhex:
+ cmp r0, #0
+ it eq
+ bxeq lr
+ and r2, r0, #0xf
+ cmp r2, #10
+ ite lt
+ addlt r2, #'0'
+ addge r2, #'A'-10
+ strb r2, [r1],#-1
+ lsr r0, #4
+ b buildhex
+
+.data
+msg_excep: .ascii "\r\n=== EXCEPTION: 00 ====== xPSR: 00000000 ===========\r\n"
+msg_reg0: .ascii "R0 :00000000 R1 :00000000 R2 :00000000 R3 :00000000\r\n"
+msg_reg1: .ascii "R4 :00000000 R5 :00000000 R6 :00000000 R7 :00000000\r\n"
+msg_reg2: .ascii "R8 :00000000 R9 :00000000 R10:00000000 R11:00000000\r\n"
+msg_reg3: .ascii "R12:00000000 SP :00000000 LR :00000000 PC :00000000\r\n\0"
+.align 4
+#endif /* CONFIG_DEBUG */