xref: /rk3399_ARM-atf/common/aarch64/debug.S (revision f300ef662844e4b4b766b317f8083b778f79e303)
1/*
2 * Copyright (c) 2014-2023 Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <common/debug.h>
10
11	.globl	asm_print_str
12	.globl	asm_print_hex
13	.globl	asm_print_hex_bits
14	.globl	asm_print_newline
15	.globl	asm_assert
16	.globl	do_panic
17	.globl	el3_panic
18
19/* Since the max decimal input number is 65536 */
20#define MAX_DEC_DIVISOR		10000
21/* The offset to add to get ascii for numerals '0 - 9' */
22#define ASCII_OFFSET_NUM	0x30
23
24#if ENABLE_ASSERTIONS
25.section .rodata.assert_str, "aS"
26assert_msg1:
27	.asciz "ASSERT: File "
28assert_msg2:
29	.asciz " Line "
30
31	/*
32	 * This macro is intended to be used to print the
33	 * line number in decimal. Used by asm_assert macro.
34	 * The max number expected is 65536.
35	 * In: x4 = the decimal to print.
36	 * Clobber: x30, x0, x1, x2, x5, x6
37	 */
38	.macro asm_print_line_dec
39	mov	x6, #10		/* Divide by 10 after every loop iteration */
40	mov	x5, #MAX_DEC_DIVISOR
41dec_print_loop:
42	udiv	x0, x4, x5			/* Get the quotient */
43	msub	x4, x0, x5, x4			/* Find the remainder */
44	add	x0, x0, #ASCII_OFFSET_NUM	/* Convert to ascii */
45	bl	plat_crash_console_putc
46	udiv	x5, x5, x6			/* Reduce divisor */
47	cbnz	x5, dec_print_loop
48	.endm
49
50
51/* ---------------------------------------------------------------------------
52 * Assertion support in assembly.
53 * The below function helps to support assertions in assembly where we do not
54 * have a C runtime stack. Arguments to the function are :
55 * x0 - File name
56 * x1 - Line no
57 * Clobber list : x30, x0, x1, x2, x3, x4, x5, x6.
58 * ---------------------------------------------------------------------------
59 */
60func asm_assert
61#if LOG_LEVEL >= LOG_LEVEL_INFO
62	/*
63	 * Only print the output if LOG_LEVEL is higher or equal to
64	 * LOG_LEVEL_INFO, which is the default value for builds with DEBUG=1.
65	 */
66	mov	x5, x0
67	mov	x6, x1
68
69	/* Ensure the console is initialized */
70	bl	plat_crash_console_init
71
72	/* Check if the console is initialized */
73	cbz	x0, _assert_loop
74
75	/* The console is initialized */
76	adr	x4, assert_msg1
77	bl	asm_print_str
78	mov	x4, x5
79	bl	asm_print_str
80	adr	x4, assert_msg2
81	bl	asm_print_str
82
83	/* Check if line number higher than max permitted */
84	tst	x6, #~0xffff
85	b.ne	_assert_loop
86	mov	x4, x6
87	asm_print_line_dec
88	bl	plat_crash_console_flush
89_assert_loop:
90#endif /* LOG_LEVEL >= LOG_LEVEL_INFO */
91	no_ret	plat_panic_handler
92endfunc asm_assert
93#endif /* ENABLE_ASSERTIONS */
94
95/*
96 * This function prints a string from address in x4.
97 * In: x4 = pointer to string.
98 * Clobber: x30, x0, x1, x2, x3
99 */
100func asm_print_str
101	mov	x3, x30
1021:
103	ldrb	w0, [x4], #0x1
104	cbz	x0, 2f
105	bl	plat_crash_console_putc
106	b	1b
1072:
108	ret	x3
109endfunc asm_print_str
110
111/*
112 * This function prints a hexadecimal number in x4.
113 * In: x4 = the hexadecimal to print.
114 * Clobber: x30, x0 - x3, x5
115 */
116func asm_print_hex
117	mov	x5, #64  /* No of bits to convert to ascii */
118
119	/* Convert to ascii number of bits in x5 */
120asm_print_hex_bits:
121	mov	x3, x30
1221:
123	sub	x5, x5, #4
124	lsrv	x0, x4, x5
125	and	x0, x0, #0xf
126	cmp	x0, #0xA
127	b.lo	2f
128	/* Add by 0x27 in addition to ASCII_OFFSET_NUM
129	 * to get ascii for characters 'a - f'.
130	 */
131	add	x0, x0, #0x27
1322:
133	add	x0, x0, #ASCII_OFFSET_NUM
134	bl	plat_crash_console_putc
135	cbnz	x5, 1b
136	ret	x3
137endfunc asm_print_hex
138
139/*
140 * Helper function to print newline to console
141 * Clobber: x0
142 */
143func asm_print_newline
144	mov	x0, '\n'
145	b	plat_crash_console_putc
146endfunc asm_print_newline
147
148	/***********************************************************
149	 * The common implementation of do_panic for all BL stages
150	 ***********************************************************/
151
152.section .rodata.panic_str, "aS"
153	panic_msg: .asciz "PANIC at PC : 0x"
154
155/* ---------------------------------------------------------------------------
156 * do_panic assumes that it is invoked from a C Runtime Environment ie a
157 * valid stack exists. This call will not return.
158 * Clobber list : if CRASH_REPORTING is not enabled then x30, x0 - x6
159 * ---------------------------------------------------------------------------
160 */
161
162func do_panic
163#if CRASH_REPORTING && defined(IMAGE_BL31)
164	b	report_el3_panic
165#endif /* CRASH_REPORTING && IMAGE_BL31 */
166
167panic_common:
168/*
169 * el3_panic will be redefined by the BL31
170 * crash reporting mechanism (if enabled)
171 */
172el3_panic:
173	mov	x6, x30
174	bl	plat_crash_console_init
175
176	/* Check if the console is initialized */
177	cbz	x0, _panic_handler
178
179	/* The console is initialized */
180	adr	x4, panic_msg
181	bl	asm_print_str
182	mov	x4, x6
183
184	/* The panic location is lr -4 */
185	sub	x4, x4, #4
186	bl	asm_print_hex
187
188	/* Print new line */
189	bl	asm_print_newline
190
191	bl	plat_crash_console_flush
192
193_panic_handler:
194	/* Pass to plat_panic_handler the address from where el3_panic was
195	 * called, not the address of the call from el3_panic. */
196	mov	x30, x6
197	b	plat_panic_handler
198
199endfunc do_panic