1f24307deSSoby Mathew/* 2801cf93cSAntonio Nino Diaz * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. 3f24307deSSoby Mathew * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5f24307deSSoby Mathew */ 6f24307deSSoby Mathew 7f24307deSSoby Mathew#include <arch.h> 8f24307deSSoby Mathew#include <asm_macros.S> 9f24307deSSoby Mathew 10e12cb61fSJeenu Viswambharan .globl asm_assert 11f24307deSSoby Mathew .globl do_panic 121a0a3f06SYatharth Kochar .globl report_exception 13f24307deSSoby Mathew 14e12cb61fSJeenu Viswambharan/* Since the max decimal input number is 65536 */ 15e12cb61fSJeenu Viswambharan#define MAX_DEC_DIVISOR 10000 16e12cb61fSJeenu Viswambharan 17e12cb61fSJeenu Viswambharan/* The offset to add to get ascii for numerals '0 - 9' */ 18e12cb61fSJeenu Viswambharan#define ASCII_OFFSET_NUM '0' 19e12cb61fSJeenu Viswambharan 20e12cb61fSJeenu Viswambharan .section .rodata.panic_str, "aS" 21e12cb61fSJeenu Viswambharanpanic_msg: 22e12cb61fSJeenu Viswambharan .asciz "PANIC at PC : 0x" 23e12cb61fSJeenu Viswambharanpanic_end: 24e12cb61fSJeenu Viswambharan .asciz "\r\n" 25e12cb61fSJeenu Viswambharan 26f24307deSSoby Mathew /*********************************************************** 27f24307deSSoby Mathew * The common implementation of do_panic for all BL stages 28f24307deSSoby Mathew ***********************************************************/ 29f24307deSSoby Mathewfunc do_panic 30e12cb61fSJeenu Viswambharan /* Have LR copy point to PC at the time of panic */ 31e12cb61fSJeenu Viswambharan sub r6, lr, #4 32e12cb61fSJeenu Viswambharan 33e12cb61fSJeenu Viswambharan /* Initialize crash console and verify success */ 34e12cb61fSJeenu Viswambharan bl plat_crash_console_init 35e12cb61fSJeenu Viswambharan cmp r0, #0 36e12cb61fSJeenu Viswambharan beq 1f 37e12cb61fSJeenu Viswambharan 38e12cb61fSJeenu Viswambharan /* Print panic message */ 39e12cb61fSJeenu Viswambharan ldr r4, =panic_msg 40e12cb61fSJeenu Viswambharan bl asm_print_str 41e12cb61fSJeenu Viswambharan 42e12cb61fSJeenu Viswambharan /* Print LR in hex */ 43e12cb61fSJeenu Viswambharan mov r4, r6 44e12cb61fSJeenu Viswambharan bl asm_print_hex 45e12cb61fSJeenu Viswambharan 46e12cb61fSJeenu Viswambharan /* Print new line */ 47e12cb61fSJeenu Viswambharan ldr r4, =panic_end 48e12cb61fSJeenu Viswambharan bl asm_print_str 49801cf93cSAntonio Nino Diaz 50801cf93cSAntonio Nino Diaz bl plat_crash_console_flush 51801cf93cSAntonio Nino Diaz 52e12cb61fSJeenu Viswambharan1: 53e12cb61fSJeenu Viswambharan mov lr, r6 544d91838bSJulius Werner b plat_panic_handler 55f24307deSSoby Mathewendfunc do_panic 56f24307deSSoby Mathew 571a0a3f06SYatharth Kochar /*********************************************************** 581a0a3f06SYatharth Kochar * This function is called from the vector table for 591a0a3f06SYatharth Kochar * unhandled exceptions. It reads the current mode and 601a0a3f06SYatharth Kochar * passes it to platform. 611a0a3f06SYatharth Kochar ***********************************************************/ 621a0a3f06SYatharth Kocharfunc report_exception 631a0a3f06SYatharth Kochar mrs r0, cpsr 641a0a3f06SYatharth Kochar and r0, #MODE32_MASK 651a0a3f06SYatharth Kochar bl plat_report_exception 66a806dad5SJeenu Viswambharan no_ret plat_panic_handler 671a0a3f06SYatharth Kocharendfunc report_exception 68e12cb61fSJeenu Viswambharan 69044bb2faSAntonio Nino Diaz#if ENABLE_ASSERTIONS 70e12cb61fSJeenu Viswambharan.section .rodata.assert_str, "aS" 71e12cb61fSJeenu Viswambharanassert_msg1: 72e12cb61fSJeenu Viswambharan .asciz "ASSERT: File " 73e12cb61fSJeenu Viswambharanassert_msg2: 74*64cc6e91SEtienne Carriere#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) 75*64cc6e91SEtienne Carriere /****************************************************************** 76*64cc6e91SEtienne Carriere * Virtualization comes with the UDIV/SDIV instructions. If missing 77*64cc6e91SEtienne Carriere * write file line number in hexadecimal format. 78*64cc6e91SEtienne Carriere ******************************************************************/ 79*64cc6e91SEtienne Carriere .asciz " Line 0x" 80*64cc6e91SEtienne Carriere#else 81e12cb61fSJeenu Viswambharan .asciz " Line " 82*64cc6e91SEtienne Carriere#endif 83e12cb61fSJeenu Viswambharan 84e12cb61fSJeenu Viswambharan/* --------------------------------------------------------------------------- 85e12cb61fSJeenu Viswambharan * Assertion support in assembly. 86e12cb61fSJeenu Viswambharan * The below function helps to support assertions in assembly where we do not 87e12cb61fSJeenu Viswambharan * have a C runtime stack. Arguments to the function are : 88e12cb61fSJeenu Viswambharan * r0 - File name 89e12cb61fSJeenu Viswambharan * r1 - Line no 90e12cb61fSJeenu Viswambharan * Clobber list : lr, r0 - r6 91e12cb61fSJeenu Viswambharan * --------------------------------------------------------------------------- 92e12cb61fSJeenu Viswambharan */ 93e12cb61fSJeenu Viswambharanfunc asm_assert 94cc8b5632SAntonio Nino Diaz#if LOG_LEVEL >= LOG_LEVEL_INFO 95cc8b5632SAntonio Nino Diaz /* 96cc8b5632SAntonio Nino Diaz * Only print the output if LOG_LEVEL is higher or equal to 97cc8b5632SAntonio Nino Diaz * LOG_LEVEL_INFO, which is the default value for builds with DEBUG=1. 98cc8b5632SAntonio Nino Diaz */ 99e12cb61fSJeenu Viswambharan /* Stash the parameters already in r0 and r1 */ 100e12cb61fSJeenu Viswambharan mov r5, r0 101e12cb61fSJeenu Viswambharan mov r6, r1 102e12cb61fSJeenu Viswambharan 103e12cb61fSJeenu Viswambharan /* Initialize crash console and verify success */ 104e12cb61fSJeenu Viswambharan bl plat_crash_console_init 105e12cb61fSJeenu Viswambharan cmp r0, #0 106e12cb61fSJeenu Viswambharan beq 1f 107e12cb61fSJeenu Viswambharan 108e12cb61fSJeenu Viswambharan /* Print file name */ 109e12cb61fSJeenu Viswambharan ldr r4, =assert_msg1 110e12cb61fSJeenu Viswambharan bl asm_print_str 111e12cb61fSJeenu Viswambharan mov r4, r5 112e12cb61fSJeenu Viswambharan bl asm_print_str 113e12cb61fSJeenu Viswambharan 114e12cb61fSJeenu Viswambharan /* Print line number string */ 115e12cb61fSJeenu Viswambharan ldr r4, =assert_msg2 116e12cb61fSJeenu Viswambharan bl asm_print_str 117e12cb61fSJeenu Viswambharan 118e12cb61fSJeenu Viswambharan /* Test for maximum supported line number */ 119e12cb61fSJeenu Viswambharan ldr r4, =~0xffff 120e12cb61fSJeenu Viswambharan tst r6, r4 121e12cb61fSJeenu Viswambharan bne 1f 122e12cb61fSJeenu Viswambharan mov r4, r6 123e12cb61fSJeenu Viswambharan 124*64cc6e91SEtienne Carriere#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) 125*64cc6e91SEtienne Carriere /****************************************************************** 126*64cc6e91SEtienne Carriere * Virtualization comes with the UDIV/SDIV instructions. If missing 127*64cc6e91SEtienne Carriere * write file line number in hexadecimal format. 128*64cc6e91SEtienne Carriere ******************************************************************/ 129*64cc6e91SEtienne Carriere bl asm_print_hex 130*64cc6e91SEtienne Carriere#else 131e12cb61fSJeenu Viswambharan /* Print line number in decimal */ 132e12cb61fSJeenu Viswambharan mov r6, #10 /* Divide by 10 after every loop iteration */ 133e12cb61fSJeenu Viswambharan ldr r5, =MAX_DEC_DIVISOR 134e12cb61fSJeenu Viswambharandec_print_loop: 135e12cb61fSJeenu Viswambharan udiv r0, r4, r5 /* Quotient */ 136e12cb61fSJeenu Viswambharan mls r4, r0, r5, r4 /* Remainder */ 137e12cb61fSJeenu Viswambharan add r0, r0, #ASCII_OFFSET_NUM /* Convert to ASCII */ 138e12cb61fSJeenu Viswambharan bl plat_crash_console_putc 139e12cb61fSJeenu Viswambharan udiv r5, r5, r6 /* Reduce divisor */ 140e12cb61fSJeenu Viswambharan cmp r5, #0 141e12cb61fSJeenu Viswambharan bne dec_print_loop 142*64cc6e91SEtienne Carriere#endif 143801cf93cSAntonio Nino Diaz 144801cf93cSAntonio Nino Diaz bl plat_crash_console_flush 145801cf93cSAntonio Nino Diaz 146e12cb61fSJeenu Viswambharan1: 147cc8b5632SAntonio Nino Diaz#endif /* LOG_LEVEL >= LOG_LEVEL_INFO */ 148e12cb61fSJeenu Viswambharan no_ret plat_panic_handler 149e12cb61fSJeenu Viswambharanendfunc asm_assert 150044bb2faSAntonio Nino Diaz#endif /* ENABLE_ASSERTIONS */ 151e12cb61fSJeenu Viswambharan 152e12cb61fSJeenu Viswambharan/* 153e12cb61fSJeenu Viswambharan * This function prints a string from address in r4 154e12cb61fSJeenu Viswambharan * Clobber: lr, r0 - r4 155e12cb61fSJeenu Viswambharan */ 156e12cb61fSJeenu Viswambharanfunc asm_print_str 157e12cb61fSJeenu Viswambharan mov r3, lr 158e12cb61fSJeenu Viswambharan1: 159e12cb61fSJeenu Viswambharan ldrb r0, [r4], #0x1 160e12cb61fSJeenu Viswambharan cmp r0, #0 161e12cb61fSJeenu Viswambharan beq 2f 162e12cb61fSJeenu Viswambharan bl plat_crash_console_putc 163e12cb61fSJeenu Viswambharan b 1b 164e12cb61fSJeenu Viswambharan2: 165e12cb61fSJeenu Viswambharan bx r3 166e12cb61fSJeenu Viswambharanendfunc asm_print_str 167e12cb61fSJeenu Viswambharan 168e12cb61fSJeenu Viswambharan/* 169e12cb61fSJeenu Viswambharan * This function prints a hexadecimal number in r4. 170e12cb61fSJeenu Viswambharan * In: r4 = the hexadecimal to print. 171e12cb61fSJeenu Viswambharan * Clobber: lr, r0 - r3, r5 172e12cb61fSJeenu Viswambharan */ 173e12cb61fSJeenu Viswambharanfunc asm_print_hex 174e12cb61fSJeenu Viswambharan mov r3, lr 175e12cb61fSJeenu Viswambharan mov r5, #32 /* No of bits to convert to ascii */ 176e12cb61fSJeenu Viswambharan1: 177e12cb61fSJeenu Viswambharan sub r5, r5, #4 178e12cb61fSJeenu Viswambharan lsr r0, r4, r5 179e12cb61fSJeenu Viswambharan and r0, r0, #0xf 180e12cb61fSJeenu Viswambharan cmp r0, #0xa 181e12cb61fSJeenu Viswambharan blo 2f 182e12cb61fSJeenu Viswambharan /* Add by 0x27 in addition to ASCII_OFFSET_NUM 183e12cb61fSJeenu Viswambharan * to get ascii for characters 'a - f'. 184e12cb61fSJeenu Viswambharan */ 185e12cb61fSJeenu Viswambharan add r0, r0, #0x27 186e12cb61fSJeenu Viswambharan2: 187e12cb61fSJeenu Viswambharan add r0, r0, #ASCII_OFFSET_NUM 188e12cb61fSJeenu Viswambharan bl plat_crash_console_putc 189e12cb61fSJeenu Viswambharan cmp r5, #0 190e12cb61fSJeenu Viswambharan bne 1b 191e12cb61fSJeenu Viswambharan bx r3 192e12cb61fSJeenu Viswambharanendfunc asm_print_hex 193