/* * Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #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 */