blob: 0df3e088d66ac0c6616321f2229262e85602993e [file] [log] [blame]
/*
* 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 x2, =DEBUG_UART_RST_BIT
ldr x0, [x1]
orr x0, x0, x2
str x0, [x1]
1:
ldr x0, [x1]
tst x0, #DEBUG_UART_RST_BIT
beq 1b
bic x0, x0, #DEBUG_UART_RST_BIT
str x0, [x1]
2:
ldr x0, [x1]
tst x0, #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 */