Commit 428518c6 authored by Manish Pandey's avatar Manish Pandey Committed by TrustedFirmware Code Review
Browse files

Merge changes from topic "stm32_exceptions" into integration

* changes:
  stm32mp1: correct crash console GPIO alternate configuration
  stm32mp1: add plat_panic_handler function
  stm32mp1: update plat_report_exception
  Align AARCH32 version of debug.S with AARCH64
parents 2173b3e0 4170079a
/* /*
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include <arch.h> #include <arch.h>
#include <asm_macros.S> #include <asm_macros.S>
#include <common/debug.h>
.globl asm_print_str
.globl asm_print_hex
.globl asm_print_hex_bits
.globl asm_assert .globl asm_assert
.globl do_panic .globl do_panic
.globl report_exception .globl report_exception
/* Since the max decimal input number is 65536 */ /* Since the max decimal input number is 65536 */
#define MAX_DEC_DIVISOR 10000 #define MAX_DEC_DIVISOR 10000
/* The offset to add to get ascii for numerals '0 - 9' */ /* The offset to add to get ascii for numerals '0 - 9' */
#define ASCII_OFFSET_NUM '0' #define ASCII_OFFSET_NUM '0'
.section .rodata.panic_str, "aS"
panic_msg:
.asciz "PANIC at PC : 0x"
panic_end:
.asciz "\r\n"
/***********************************************************
* The common implementation of do_panic for all BL stages
***********************************************************/
func do_panic
/* Have LR copy point to PC at the time of panic */
sub r6, lr, #4
/* Initialize crash console and verify success */
bl plat_crash_console_init
cmp r0, #0
beq 1f
/* Print panic message */
ldr r4, =panic_msg
bl asm_print_str
/* Print LR in hex */
mov r4, r6
bl asm_print_hex
/* Print new line */
ldr r4, =panic_end
bl asm_print_str
bl plat_crash_console_flush
1:
mov lr, r6
b plat_panic_handler
endfunc do_panic
/***********************************************************
* This function is called from the vector table for
* unhandled exceptions. It reads the current mode and
* passes it to platform.
***********************************************************/
func report_exception
mrs r0, cpsr
and r0, #MODE32_MASK
bl plat_report_exception
no_ret plat_panic_handler
endfunc report_exception
#if ENABLE_ASSERTIONS #if ENABLE_ASSERTIONS
.section .rodata.assert_str, "aS" .section .rodata.assert_str, "aS"
assert_msg1: assert_msg1:
...@@ -79,6 +33,26 @@ assert_msg2: ...@@ -79,6 +33,26 @@ assert_msg2:
.asciz " Line 0x" .asciz " Line 0x"
#else #else
.asciz " Line " .asciz " Line "
/*
* This macro is intended to be used to print the
* line number in decimal. Used by asm_assert macro.
* The max number expected is 65536.
* In: r4 = the decimal to print.
* Clobber: lr, r0, r1, r2, r5, r6
*/
.macro asm_print_line_dec
mov r6, #10 /* Divide by 10 after every loop iteration */
ldr r5, =MAX_DEC_DIVISOR
dec_print_loop:
udiv r0, r4, r5 /* Get the quotient */
mls r4, r0, r5, r4 /* Find the remainder */
add r0, r0, #ASCII_OFFSET_NUM /* Convert to ascii */
bl plat_crash_console_putc
udiv r5, r5, r6 /* Reduce divisor */
cmp r5, #0
bne dec_print_loop
.endm
#endif #endif
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
...@@ -100,25 +74,25 @@ func asm_assert ...@@ -100,25 +74,25 @@ func asm_assert
mov r5, r0 mov r5, r0
mov r6, r1 mov r6, r1
/* Initialize crash console and verify success */ /* Ensure the console is initialized */
bl plat_crash_console_init bl plat_crash_console_init
/* Check if the console is initialized */
cmp r0, #0 cmp r0, #0
beq 1f beq _assert_loop
/* Print file name */ /* The console is initialized */
ldr r4, =assert_msg1 ldr r4, =assert_msg1
bl asm_print_str bl asm_print_str
mov r4, r5 mov r4, r5
bl asm_print_str bl asm_print_str
/* Print line number string */
ldr r4, =assert_msg2 ldr r4, =assert_msg2
bl asm_print_str bl asm_print_str
/* Test for maximum supported line number */ /* Check if line number higher than max permitted */
ldr r4, =~0xffff ldr r4, =~0xffff
tst r6, r4 tst r6, r4
bne 1f bne _assert_loop
mov r4, r6 mov r4, r6
#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) #if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
...@@ -128,22 +102,10 @@ func asm_assert ...@@ -128,22 +102,10 @@ func asm_assert
******************************************************************/ ******************************************************************/
bl asm_print_hex bl asm_print_hex
#else #else
/* Print line number in decimal */ asm_print_line_dec
mov r6, #10 /* Divide by 10 after every loop iteration */
ldr r5, =MAX_DEC_DIVISOR
dec_print_loop:
udiv r0, r4, r5 /* Quotient */
mls r4, r0, r5, r4 /* Remainder */
add r0, r0, #ASCII_OFFSET_NUM /* Convert to ASCII */
bl plat_crash_console_putc
udiv r5, r5, r6 /* Reduce divisor */
cmp r5, #0
bne dec_print_loop
#endif #endif
bl plat_crash_console_flush bl plat_crash_console_flush
_assert_loop:
1:
#endif /* LOG_LEVEL >= LOG_LEVEL_INFO */ #endif /* LOG_LEVEL >= LOG_LEVEL_INFO */
no_ret plat_panic_handler no_ret plat_panic_handler
endfunc asm_assert endfunc asm_assert
...@@ -171,8 +133,11 @@ endfunc asm_print_str ...@@ -171,8 +133,11 @@ endfunc asm_print_str
* Clobber: lr, r0 - r3, r5 * Clobber: lr, r0 - r3, r5
*/ */
func asm_print_hex func asm_print_hex
mov r3, lr
mov r5, #32 /* No of bits to convert to ascii */ mov r5, #32 /* No of bits to convert to ascii */
/* Convert to ascii number of bits in r5 */
asm_print_hex_bits:
mov r3, lr
1: 1:
sub r5, r5, #4 sub r5, r5, #4
lsr r0, r4, r5 lsr r0, r4, r5
...@@ -190,3 +155,53 @@ func asm_print_hex ...@@ -190,3 +155,53 @@ func asm_print_hex
bne 1b bne 1b
bx r3 bx r3
endfunc asm_print_hex endfunc asm_print_hex
/***********************************************************
* The common implementation of do_panic for all BL stages
***********************************************************/
.section .rodata.panic_str, "aS"
panic_msg: .asciz "PANIC at PC : 0x"
panic_end: .asciz "\r\n"
func do_panic
/* Have LR copy point to PC at the time of panic */
sub r6, lr, #4
/* Initialize crash console and verify success */
bl plat_crash_console_init
/* Check if the console is initialized */
cmp r0, #0
beq _panic_handler
/* The console is initialized */
ldr r4, =panic_msg
bl asm_print_str
/* Print LR in hex */
mov r4, r6
bl asm_print_hex
/* Print new line */
ldr r4, =panic_end
bl asm_print_str
bl plat_crash_console_flush
_panic_handler:
mov lr, r6
b plat_panic_handler
endfunc do_panic
/***********************************************************
* This function is called from the vector table for
* unhandled exceptions. It reads the current mode and
* passes it to platform.
***********************************************************/
func report_exception
mrs r0, cpsr
and r0, #MODE32_MASK
bl plat_report_exception
no_ret plat_panic_handler
endfunc report_exception
...@@ -38,11 +38,11 @@ assert_msg2: ...@@ -38,11 +38,11 @@ assert_msg2:
mov x6, #10 /* Divide by 10 after every loop iteration */ mov x6, #10 /* Divide by 10 after every loop iteration */
mov x5, #MAX_DEC_DIVISOR mov x5, #MAX_DEC_DIVISOR
dec_print_loop: dec_print_loop:
udiv x0, x4, x5 /* Get the quotient */ udiv x0, x4, x5 /* Get the quotient */
msub x4, x0, x5, x4 /* Find the remainder */ msub x4, x0, x5, x4 /* Find the remainder */
add x0, x0, #ASCII_OFFSET_NUM /* Convert to ascii */ add x0, x0, #ASCII_OFFSET_NUM /* Convert to ascii */
bl plat_crash_console_putc bl plat_crash_console_putc
udiv x5, x5, x6 /* Reduce divisor */ udiv x5, x5, x6 /* Reduce divisor */
cbnz x5, dec_print_loop cbnz x5, dec_print_loop
.endm .endm
...@@ -64,10 +64,13 @@ func asm_assert ...@@ -64,10 +64,13 @@ func asm_assert
*/ */
mov x5, x0 mov x5, x0
mov x6, x1 mov x6, x1
/* Ensure the console is initialized */ /* Ensure the console is initialized */
bl plat_crash_console_init bl plat_crash_console_init
/* Check if the console is initialized */ /* Check if the console is initialized */
cbz x0, _assert_loop cbz x0, _assert_loop
/* The console is initialized */ /* The console is initialized */
adr x4, assert_msg1 adr x4, assert_msg1
bl asm_print_str bl asm_print_str
...@@ -75,6 +78,7 @@ func asm_assert ...@@ -75,6 +78,7 @@ func asm_assert
bl asm_print_str bl asm_print_str
adr x4, assert_msg2 adr x4, assert_msg2
bl asm_print_str bl asm_print_str
/* Check if line number higher than max permitted */ /* Check if line number higher than max permitted */
tst x6, #~0xffff tst x6, #~0xffff
b.ne _assert_loop b.ne _assert_loop
...@@ -191,12 +195,15 @@ panic_common: ...@@ -191,12 +195,15 @@ panic_common:
el3_panic: el3_panic:
mov x6, x30 mov x6, x30
bl plat_crash_console_init bl plat_crash_console_init
/* Check if the console is initialized */ /* Check if the console is initialized */
cbz x0, _panic_handler cbz x0, _panic_handler
/* The console is initialized */ /* The console is initialized */
adr x4, panic_msg adr x4, panic_msg
bl asm_print_str bl asm_print_str
mov x4, x6 mov x4, x6
/* The panic location is lr -4 */ /* The panic location is lr -4 */
sub x4, x4, #4 sub x4, x4, #4
bl asm_print_hex bl asm_print_hex
......
/* /*
* Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <drivers/st/stm32_gpio.h> #include <drivers/st/stm32_gpio.h>
#define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1) #define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1)
#define GPIO_TX_ALT_SHIFT ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
.globl platform_mem_init .globl platform_mem_init
.globl plat_report_exception .globl plat_report_exception
...@@ -32,7 +31,48 @@ func platform_mem_init ...@@ -32,7 +31,48 @@ func platform_mem_init
endfunc platform_mem_init endfunc platform_mem_init
func plat_report_exception func plat_report_exception
#if DEBUG
mov r8, lr
/* Test if an abort occurred */
cmp r0, #MODE32_abt
bne undef_inst_lbl
ldr r4, =abort_str
bl asm_print_str
mrs r4, lr_abt
sub r4, r4, #4
b print_exception_info
undef_inst_lbl:
/* Test for an undefined instruction */
cmp r0, #MODE32_und
bne other_exception_lbl
ldr r4, =undefined_str
bl asm_print_str
mrs r4, lr_und
b print_exception_info
other_exception_lbl:
/* Other exceptions */
mov r9, r0
ldr r4, =exception_start_str
bl asm_print_str
mov r4, r9
bl asm_print_hex
ldr r4, =exception_end_str
bl asm_print_str
mov r4, r6
print_exception_info:
bl asm_print_hex
ldr r4, =end_error_str
bl asm_print_str
bx r8
#else
bx lr bx lr
#endif
endfunc plat_report_exception endfunc plat_report_exception
func plat_reset_handler func plat_reset_handler
...@@ -129,10 +169,19 @@ func plat_crash_console_init ...@@ -129,10 +169,19 @@ func plat_crash_console_init
bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT) bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
str r2, [r1, #GPIO_PUPD_OFFSET] str r2, [r1, #GPIO_PUPD_OFFSET]
/* Set alternate */ /* Set alternate */
#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT
ldr r2, [r1, #GPIO_AFRH_OFFSET] ldr r2, [r1, #GPIO_AFRH_OFFSET]
bic r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT) bic r2, r2, #(GPIO_ALTERNATE_MASK << \
orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << GPIO_TX_ALT_SHIFT) ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \
((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
str r2, [r1, #GPIO_AFRH_OFFSET] str r2, [r1, #GPIO_AFRH_OFFSET]
#else
ldr r2, [r1, #GPIO_AFRL_OFFSET]
bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2))
orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2))
str r2, [r1, #GPIO_AFRL_OFFSET]
#endif
/* Enable UART clock, with its source */ /* Enable UART clock, with its source */
ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG) ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
mov r2, #DEBUG_UART_TX_CLKSRC mov r2, #DEBUG_UART_TX_CLKSRC
...@@ -174,3 +223,34 @@ func plat_crash_console_putc ...@@ -174,3 +223,34 @@ func plat_crash_console_putc
ldr r1, =STM32MP_DEBUG_USART_BASE ldr r1, =STM32MP_DEBUG_USART_BASE
b console_stm32_core_putc b console_stm32_core_putc
endfunc plat_crash_console_putc endfunc plat_crash_console_putc
/* ----------------------------------------------------------
* void plat_panic_handler(void) __dead2;
* Report exception + endless loop.
*
* r6 holds the address where the fault occurred.
* Filling lr with this value allows debuggers to reconstruct
* the backtrace.
* ----------------------------------------------------------
*/
func plat_panic_handler
mrs r0, cpsr
and r0, #MODE32_MASK
bl plat_report_exception
mov lr, r6
b .
endfunc plat_panic_handler
#if DEBUG
.section .rodata.rev_err_str, "aS"
abort_str:
.asciz "\nAbort at: 0x"
undefined_str:
.asciz "\nUndefined instruction at: 0x"
exception_start_str:
.asciz "\nException mode=0x"
exception_end_str:
.asciz " at: 0x"
end_error_str:
.asciz "\n\r"
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment