1/* 2 * Copyright (c) 2016-2017, 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 10 .globl asm_assert 11 .globl do_panic 12 .globl report_exception 13 14/* Since the max decimal input number is 65536 */ 15#define MAX_DEC_DIVISOR 10000 16 17/* The offset to add to get ascii for numerals '0 - 9' */ 18#define ASCII_OFFSET_NUM '0' 19 20 .section .rodata.panic_str, "aS" 21panic_msg: 22 .asciz "PANIC at PC : 0x" 23panic_end: 24 .asciz "\r\n" 25 26 /*********************************************************** 27 * The common implementation of do_panic for all BL stages 28 ***********************************************************/ 29func do_panic 30 /* Have LR copy point to PC at the time of panic */ 31 sub r6, lr, #4 32 33 /* Initialize crash console and verify success */ 34 bl plat_crash_console_init 35 cmp r0, #0 36 beq 1f 37 38 /* Print panic message */ 39 ldr r4, =panic_msg 40 bl asm_print_str 41 42 /* Print LR in hex */ 43 mov r4, r6 44 bl asm_print_hex 45 46 /* Print new line */ 47 ldr r4, =panic_end 48 bl asm_print_str 49 50 bl plat_crash_console_flush 51 521: 53 mov lr, r6 54 b plat_panic_handler 55endfunc do_panic 56 57 /*********************************************************** 58 * This function is called from the vector table for 59 * unhandled exceptions. It reads the current mode and 60 * passes it to platform. 61 ***********************************************************/ 62func report_exception 63 mrs r0, cpsr 64 and r0, #MODE32_MASK 65 bl plat_report_exception 66 no_ret plat_panic_handler 67endfunc report_exception 68 69#if ENABLE_ASSERTIONS 70.section .rodata.assert_str, "aS" 71assert_msg1: 72 .asciz "ASSERT: File " 73assert_msg2: 74#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) 75 /****************************************************************** 76 * Virtualization comes with the UDIV/SDIV instructions. If missing 77 * write file line number in hexadecimal format. 78 ******************************************************************/ 79 .asciz " Line 0x" 80#else 81 .asciz " Line " 82#endif 83 84/* --------------------------------------------------------------------------- 85 * Assertion support in assembly. 86 * The below function helps to support assertions in assembly where we do not 87 * have a C runtime stack. Arguments to the function are : 88 * r0 - File name 89 * r1 - Line no 90 * Clobber list : lr, r0 - r6 91 * --------------------------------------------------------------------------- 92 */ 93func asm_assert 94#if LOG_LEVEL >= LOG_LEVEL_INFO 95 /* 96 * Only print the output if LOG_LEVEL is higher or equal to 97 * LOG_LEVEL_INFO, which is the default value for builds with DEBUG=1. 98 */ 99 /* Stash the parameters already in r0 and r1 */ 100 mov r5, r0 101 mov r6, r1 102 103 /* Initialize crash console and verify success */ 104 bl plat_crash_console_init 105 cmp r0, #0 106 beq 1f 107 108 /* Print file name */ 109 ldr r4, =assert_msg1 110 bl asm_print_str 111 mov r4, r5 112 bl asm_print_str 113 114 /* Print line number string */ 115 ldr r4, =assert_msg2 116 bl asm_print_str 117 118 /* Test for maximum supported line number */ 119 ldr r4, =~0xffff 120 tst r6, r4 121 bne 1f 122 mov r4, r6 123 124#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) 125 /****************************************************************** 126 * Virtualization comes with the UDIV/SDIV instructions. If missing 127 * write file line number in hexadecimal format. 128 ******************************************************************/ 129 bl asm_print_hex 130#else 131 /* Print line number in decimal */ 132 mov r6, #10 /* Divide by 10 after every loop iteration */ 133 ldr r5, =MAX_DEC_DIVISOR 134dec_print_loop: 135 udiv r0, r4, r5 /* Quotient */ 136 mls r4, r0, r5, r4 /* Remainder */ 137 add r0, r0, #ASCII_OFFSET_NUM /* Convert to ASCII */ 138 bl plat_crash_console_putc 139 udiv r5, r5, r6 /* Reduce divisor */ 140 cmp r5, #0 141 bne dec_print_loop 142#endif 143 144 bl plat_crash_console_flush 145 1461: 147#endif /* LOG_LEVEL >= LOG_LEVEL_INFO */ 148 no_ret plat_panic_handler 149endfunc asm_assert 150#endif /* ENABLE_ASSERTIONS */ 151 152/* 153 * This function prints a string from address in r4 154 * Clobber: lr, r0 - r4 155 */ 156func asm_print_str 157 mov r3, lr 1581: 159 ldrb r0, [r4], #0x1 160 cmp r0, #0 161 beq 2f 162 bl plat_crash_console_putc 163 b 1b 1642: 165 bx r3 166endfunc asm_print_str 167 168/* 169 * This function prints a hexadecimal number in r4. 170 * In: r4 = the hexadecimal to print. 171 * Clobber: lr, r0 - r3, r5 172 */ 173func asm_print_hex 174 mov r3, lr 175 mov r5, #32 /* No of bits to convert to ascii */ 1761: 177 sub r5, r5, #4 178 lsr r0, r4, r5 179 and r0, r0, #0xf 180 cmp r0, #0xa 181 blo 2f 182 /* Add by 0x27 in addition to ASCII_OFFSET_NUM 183 * to get ascii for characters 'a - f'. 184 */ 185 add r0, r0, #0x27 1862: 187 add r0, r0, #ASCII_OFFSET_NUM 188 bl plat_crash_console_putc 189 cmp r5, #0 190 bne 1b 191 bx r3 192endfunc asm_print_hex 193