mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-27 15:24:54 +00:00

The previous code used 64-bit registers as the target and source for load and store operations on 32-bit hardware registers. In certain cases (e.g., when using USART1 as the debug console), this could result in deadlocks where the A35 gets stuck in a permanent loop due to test conditions that are never fulfilled. To resolve this issue, 32-bit registers are now used for these operations. Change-Id: Id2c03a1df26738fe815079da042cc2dd989f4f8e Signed-off-by: Boerge Struempfel <boerge.struempfel@gmail.com>
225 lines
5.8 KiB
ArmAsm
225 lines
5.8 KiB
ArmAsm
/*
|
|
* Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <asm_macros.S>
|
|
#include <drivers/st/stm32_gpio.h>
|
|
|
|
#include <platform_def.h>
|
|
|
|
#define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1)
|
|
|
|
.globl platform_mem_init
|
|
.globl plat_secondary_cold_boot_setup
|
|
.globl plat_is_my_cpu_primary
|
|
.globl plat_my_core_pos
|
|
.globl plat_crash_console_init
|
|
.globl plat_crash_console_flush
|
|
.globl plat_crash_console_putc
|
|
.globl plat_report_exception
|
|
|
|
func platform_mem_init
|
|
/* Nothing to do, don't need to init SYSRAM */
|
|
ret
|
|
endfunc platform_mem_init
|
|
|
|
/* ---------------------------------------------
|
|
* void plat_secondary_cold_boot_setup (void);
|
|
*
|
|
* Set secondary core in WFI waiting for core reset.
|
|
* ---------------------------------------------
|
|
*/
|
|
func plat_secondary_cold_boot_setup
|
|
dsb sy
|
|
1:
|
|
wfi
|
|
/*
|
|
* This shouldn't be reached, but when a debugger halts the
|
|
* secondary core it causes exit from wfi.
|
|
* Put back the core in wfi.
|
|
*/
|
|
b 1b
|
|
endfunc plat_secondary_cold_boot_setup
|
|
|
|
/* ----------------------------------------------
|
|
* unsigned int plat_is_my_cpu_primary(void);
|
|
* This function checks if this is the primary CPU
|
|
* ----------------------------------------------
|
|
*/
|
|
func plat_is_my_cpu_primary
|
|
mrs x0, mpidr_el1
|
|
and x0, x0, #(MPIDR_CPU_MASK)
|
|
cmp x0, #STM32MP_PRIMARY_CPU
|
|
cset x0, eq
|
|
ret
|
|
endfunc plat_is_my_cpu_primary
|
|
|
|
/* -----------------------------------------------------------
|
|
* unsigned int plat_stm32mp_get_core_pos(u_register_t mpidr)
|
|
* Helper function to calculate the core position.
|
|
* With this function: CorePos = (ClusterId * 4) +
|
|
* CoreId
|
|
* -----------------------------------------------------------
|
|
*/
|
|
func plat_stm32mp_get_core_pos
|
|
and x1, x0, #MPIDR_CPU_MASK
|
|
and x0, x0, #MPIDR_CLUSTER_MASK
|
|
add x0, x1, x0, LSR #6
|
|
ret
|
|
endfunc plat_stm32mp_get_core_pos
|
|
|
|
/* -----------------------------------------------------
|
|
* unsigned int plat_my_core_pos(void)
|
|
* This function uses the plat_stm32mp_get_core_pos()
|
|
* definition to get the index of the calling CPU.
|
|
* -----------------------------------------------------
|
|
*/
|
|
func plat_my_core_pos
|
|
mrs x0, mpidr_el1
|
|
b plat_stm32mp_get_core_pos
|
|
endfunc plat_my_core_pos
|
|
|
|
/* ---------------------------------------------
|
|
* int plat_crash_console_init(void)
|
|
*
|
|
* Initialize the crash console without a C Runtime stack.
|
|
* ---------------------------------------------
|
|
*/
|
|
func plat_crash_console_init
|
|
/* Reset UART peripheral */
|
|
mov_imm x1, (RCC_BASE + DEBUG_UART_RST_REG)
|
|
ldr w2, =DEBUG_UART_RST_BIT
|
|
ldr w0, [x1]
|
|
orr w0, w0, w2
|
|
str w0, [x1]
|
|
1:
|
|
ldr w0, [x1]
|
|
tst w0, #DEBUG_UART_RST_BIT
|
|
beq 1b
|
|
bic w0, w0, #DEBUG_UART_RST_BIT
|
|
str w0, [x1]
|
|
2:
|
|
ldr w0, [x1]
|
|
tst w0, #DEBUG_UART_RST_BIT
|
|
bne 2b
|
|
/* Enable GPIOs for UART TX */
|
|
mov_imm x1, (RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
|
|
ldr w2, [x1]
|
|
/* Configure GPIO */
|
|
orr w2, w2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
|
|
str w2, [x1]
|
|
mov_imm x1, DEBUG_UART_TX_GPIO_BANK_ADDRESS
|
|
/* Set GPIO mode alternate */
|
|
ldr w2, [x1, #GPIO_MODE_OFFSET]
|
|
bic w2, w2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
|
|
orr w2, w2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT)
|
|
str w2, [x1, #GPIO_MODE_OFFSET]
|
|
/* Set GPIO speed low */
|
|
ldr w2, [x1, #GPIO_SPEED_OFFSET]
|
|
bic w2, w2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT)
|
|
str w2, [x1, #GPIO_SPEED_OFFSET]
|
|
/* Set no-pull */
|
|
ldr w2, [x1, #GPIO_PUPD_OFFSET]
|
|
bic w2, w2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
|
|
str w2, [x1, #GPIO_PUPD_OFFSET]
|
|
/* Set alternate */
|
|
#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT
|
|
ldr w2, [x1, #GPIO_AFRH_OFFSET]
|
|
bic w2, w2, #(GPIO_ALTERNATE_MASK << \
|
|
((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
|
|
orr w2, w2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \
|
|
((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
|
|
str w2, [x1, #GPIO_AFRH_OFFSET]
|
|
#else
|
|
ldr w2, [x1, #GPIO_AFRL_OFFSET]
|
|
bic w2, w2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2))
|
|
orr w2, w2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2))
|
|
str w2, [x1, #GPIO_AFRL_OFFSET]
|
|
#endif
|
|
/* Clear UART clock flexgen divisors, keep enable bit */
|
|
mov_imm x1, (RCC_BASE + DEBUG_UART_PREDIV_CFGR)
|
|
mov x2, #0
|
|
str w2, [x1]
|
|
mov_imm x1, (RCC_BASE + DEBUG_UART_FINDIV_CFGR)
|
|
mov x2, #0x40
|
|
str w2, [x1]
|
|
/* Enable UART clock, with its source */
|
|
mov_imm x1, (RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
|
|
mov_imm w2, (DEBUG_UART_TX_CLKSRC | RCC_XBARxCFGR_XBARxEN)
|
|
str w2, [x1]
|
|
mov_imm x1, (RCC_BASE + DEBUG_UART_TX_EN_REG)
|
|
ldr w2, [x1]
|
|
orr w2, w2, #DEBUG_UART_TX_EN
|
|
str w2, [x1]
|
|
|
|
mov_imm x0, STM32MP_DEBUG_USART_BASE
|
|
mov_imm x1, STM32MP_DEBUG_USART_CLK_FRQ
|
|
mov_imm x2, STM32MP_UART_BAUDRATE
|
|
b console_stm32_core_init
|
|
endfunc plat_crash_console_init
|
|
|
|
func plat_crash_console_flush
|
|
mov_imm x0, STM32MP_DEBUG_USART_BASE
|
|
b console_stm32_core_flush
|
|
endfunc plat_crash_console_flush
|
|
|
|
func plat_crash_console_putc
|
|
mov_imm x1, STM32MP_DEBUG_USART_BASE
|
|
cmp x0, #'\n'
|
|
b.ne 1f
|
|
mov x15, x30
|
|
mov x0, #'\r'
|
|
bl console_stm32_core_putc
|
|
mov x30, x15
|
|
mov x0, #'\n'
|
|
1:
|
|
b console_stm32_core_putc
|
|
endfunc plat_crash_console_putc
|
|
|
|
#ifdef IMAGE_BL2
|
|
/* ---------------------------------------------
|
|
* void plat_report_exception(unsigned int type)
|
|
* Function to report an unhandled exception
|
|
* with platform-specific means.
|
|
* ---------------------------------------------
|
|
*/
|
|
func plat_report_exception
|
|
mov x8, x30
|
|
|
|
adr x4, plat_err_str
|
|
bl asm_print_str
|
|
|
|
adr x4, esr_el3_str
|
|
bl asm_print_str
|
|
|
|
mrs x4, esr_el3
|
|
bl asm_print_hex
|
|
|
|
adr x4, elr_el3_str
|
|
bl asm_print_str
|
|
|
|
mrs x4, elr_el3
|
|
bl asm_print_hex
|
|
|
|
adr x4, far_el3_str
|
|
bl asm_print_str
|
|
|
|
mrs x4, far_el3
|
|
bl asm_print_hex
|
|
|
|
mov x30, x8
|
|
ret
|
|
endfunc plat_report_exception
|
|
|
|
.section .rodata.rev_err_str, "aS"
|
|
plat_err_str:
|
|
.asciz "\nPlatform exception reporting:"
|
|
esr_el3_str:
|
|
.asciz "\nESR_EL3: "
|
|
elr_el3_str:
|
|
.asciz "\nELR_EL3: "
|
|
far_el3_str:
|
|
.asciz "\nFAR_EL3: "
|
|
#endif /* IMAGE_BL2 */
|