blob: 9d410df07ead4f94912804b8f363db369bff5384 [file] [log] [blame]
Soby Mathewd29f67b2016-05-05 12:31:57 +01001/*
Yann Gautierd04c7ae2020-09-17 15:15:27 +02002 * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
Soby Mathewd29f67b2016-05-05 12:31:57 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soby Mathewd29f67b2016-05-05 12:31:57 +01005 */
6
7#include <arch.h>
8#include <asm_macros.S>
Yann Gautierd04c7ae2020-09-17 15:15:27 +02009#include <common/debug.h>
Soby Mathewd29f67b2016-05-05 12:31:57 +010010
Yann Gautierd04c7ae2020-09-17 15:15:27 +020011 .globl asm_print_str
12 .globl asm_print_hex
13 .globl asm_print_hex_bits
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000014 .globl asm_assert
Soby Mathewd29f67b2016-05-05 12:31:57 +010015 .globl do_panic
Yatharth Kocharf528faf2016-06-28 16:58:26 +010016 .globl report_exception
Soby Mathewd29f67b2016-05-05 12:31:57 +010017
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000018/* Since the max decimal input number is 65536 */
19#define MAX_DEC_DIVISOR 10000
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000020/* The offset to add to get ascii for numerals '0 - 9' */
21#define ASCII_OFFSET_NUM '0'
22
Antonio Nino Diaz7c65c1e2017-04-20 09:58:28 +010023#if ENABLE_ASSERTIONS
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000024.section .rodata.assert_str, "aS"
25assert_msg1:
26 .asciz "ASSERT: File "
27assert_msg2:
Etienne Carriere4cce8352017-11-08 14:38:33 +010028#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
29 /******************************************************************
30 * Virtualization comes with the UDIV/SDIV instructions. If missing
31 * write file line number in hexadecimal format.
32 ******************************************************************/
33 .asciz " Line 0x"
34#else
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000035 .asciz " Line "
Yann Gautierd04c7ae2020-09-17 15:15:27 +020036
37 /*
38 * This macro is intended to be used to print the
39 * line number in decimal. Used by asm_assert macro.
40 * The max number expected is 65536.
41 * In: r4 = the decimal to print.
42 * Clobber: lr, r0, r1, r2, r5, r6
43 */
44 .macro asm_print_line_dec
45 mov r6, #10 /* Divide by 10 after every loop iteration */
46 ldr r5, =MAX_DEC_DIVISOR
47dec_print_loop:
48 udiv r0, r4, r5 /* Get the quotient */
49 mls r4, r0, r5, r4 /* Find the remainder */
50 add r0, r0, #ASCII_OFFSET_NUM /* Convert to ascii */
51 bl plat_crash_console_putc
52 udiv r5, r5, r6 /* Reduce divisor */
53 cmp r5, #0
54 bne dec_print_loop
55 .endm
Etienne Carriere4cce8352017-11-08 14:38:33 +010056#endif
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000057
58/* ---------------------------------------------------------------------------
59 * Assertion support in assembly.
60 * The below function helps to support assertions in assembly where we do not
61 * have a C runtime stack. Arguments to the function are :
62 * r0 - File name
63 * r1 - Line no
64 * Clobber list : lr, r0 - r6
65 * ---------------------------------------------------------------------------
66 */
67func asm_assert
Antonio Nino Diaz808c2292017-04-18 15:16:05 +010068#if LOG_LEVEL >= LOG_LEVEL_INFO
69 /*
70 * Only print the output if LOG_LEVEL is higher or equal to
71 * LOG_LEVEL_INFO, which is the default value for builds with DEBUG=1.
72 */
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000073 /* Stash the parameters already in r0 and r1 */
74 mov r5, r0
75 mov r6, r1
76
Yann Gautierd04c7ae2020-09-17 15:15:27 +020077 /* Ensure the console is initialized */
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000078 bl plat_crash_console_init
Yann Gautierd04c7ae2020-09-17 15:15:27 +020079
80 /* Check if the console is initialized */
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000081 cmp r0, #0
Yann Gautierd04c7ae2020-09-17 15:15:27 +020082 beq _assert_loop
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000083
Yann Gautierd04c7ae2020-09-17 15:15:27 +020084 /* The console is initialized */
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000085 ldr r4, =assert_msg1
86 bl asm_print_str
87 mov r4, r5
88 bl asm_print_str
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000089 ldr r4, =assert_msg2
90 bl asm_print_str
91
Yann Gautierd04c7ae2020-09-17 15:15:27 +020092 /* Check if line number higher than max permitted */
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000093 ldr r4, =~0xffff
94 tst r6, r4
Yann Gautierd04c7ae2020-09-17 15:15:27 +020095 bne _assert_loop
Jeenu Viswambharanff640c42016-11-28 09:59:27 +000096 mov r4, r6
97
Etienne Carriere4cce8352017-11-08 14:38:33 +010098#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
99 /******************************************************************
100 * Virtualization comes with the UDIV/SDIV instructions. If missing
101 * write file line number in hexadecimal format.
102 ******************************************************************/
103 bl asm_print_hex
104#else
Yann Gautierd04c7ae2020-09-17 15:15:27 +0200105 asm_print_line_dec
Etienne Carriere4cce8352017-11-08 14:38:33 +0100106#endif
Antonio Nino Diazd3ec5432017-02-17 17:11:27 +0000107 bl plat_crash_console_flush
Yann Gautierd04c7ae2020-09-17 15:15:27 +0200108_assert_loop:
Antonio Nino Diaz808c2292017-04-18 15:16:05 +0100109#endif /* LOG_LEVEL >= LOG_LEVEL_INFO */
Jeenu Viswambharanff640c42016-11-28 09:59:27 +0000110 no_ret plat_panic_handler
111endfunc asm_assert
Antonio Nino Diaz7c65c1e2017-04-20 09:58:28 +0100112#endif /* ENABLE_ASSERTIONS */
Jeenu Viswambharanff640c42016-11-28 09:59:27 +0000113
114/*
115 * This function prints a string from address in r4
116 * Clobber: lr, r0 - r4
117 */
118func asm_print_str
119 mov r3, lr
1201:
121 ldrb r0, [r4], #0x1
122 cmp r0, #0
123 beq 2f
124 bl plat_crash_console_putc
125 b 1b
1262:
127 bx r3
128endfunc asm_print_str
129
130/*
131 * This function prints a hexadecimal number in r4.
132 * In: r4 = the hexadecimal to print.
133 * Clobber: lr, r0 - r3, r5
134 */
135func asm_print_hex
Jeenu Viswambharanff640c42016-11-28 09:59:27 +0000136 mov r5, #32 /* No of bits to convert to ascii */
Yann Gautierd04c7ae2020-09-17 15:15:27 +0200137
138 /* Convert to ascii number of bits in r5 */
139asm_print_hex_bits:
140 mov r3, lr
Jeenu Viswambharanff640c42016-11-28 09:59:27 +00001411:
142 sub r5, r5, #4
143 lsr r0, r4, r5
144 and r0, r0, #0xf
145 cmp r0, #0xa
146 blo 2f
147 /* Add by 0x27 in addition to ASCII_OFFSET_NUM
148 * to get ascii for characters 'a - f'.
149 */
150 add r0, r0, #0x27
1512:
152 add r0, r0, #ASCII_OFFSET_NUM
153 bl plat_crash_console_putc
154 cmp r5, #0
155 bne 1b
156 bx r3
157endfunc asm_print_hex
Yann Gautierd04c7ae2020-09-17 15:15:27 +0200158
159 /***********************************************************
160 * The common implementation of do_panic for all BL stages
161 ***********************************************************/
162
163.section .rodata.panic_str, "aS"
164 panic_msg: .asciz "PANIC at PC : 0x"
165 panic_end: .asciz "\r\n"
166
167func do_panic
168 /* Have LR copy point to PC at the time of panic */
169 sub r6, lr, #4
170
171 /* Initialize crash console and verify success */
172 bl plat_crash_console_init
173
174 /* Check if the console is initialized */
175 cmp r0, #0
176 beq _panic_handler
177
178 /* The console is initialized */
179 ldr r4, =panic_msg
180 bl asm_print_str
181
182 /* Print LR in hex */
183 mov r4, r6
184 bl asm_print_hex
185
186 /* Print new line */
187 ldr r4, =panic_end
188 bl asm_print_str
189
190 bl plat_crash_console_flush
191
192_panic_handler:
193 mov lr, r6
194 b plat_panic_handler
195endfunc do_panic
196
197 /***********************************************************
198 * This function is called from the vector table for
199 * unhandled exceptions. It reads the current mode and
200 * passes it to platform.
201 ***********************************************************/
202func report_exception
203 mrs r0, cpsr
204 and r0, #MODE32_MASK
205 bl plat_report_exception
206 no_ret plat_panic_handler
207endfunc report_exception