debug.S 6.1 KB

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