14353bb20SYann Gautier/* 2*04238683SYann Gautier * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. 34353bb20SYann Gautier * 44353bb20SYann Gautier * SPDX-License-Identifier: BSD-3-Clause 54353bb20SYann Gautier */ 64353bb20SYann Gautier 709d40e0eSAntonio Nino Diaz#include <platform_def.h> 809d40e0eSAntonio Nino Diaz 94353bb20SYann Gautier#include <arch.h> 104353bb20SYann Gautier#include <asm_macros.S> 1109d40e0eSAntonio Nino Diaz#include <common/bl_common.h> 1209d40e0eSAntonio Nino Diaz#include <drivers/st/stm32_gpio.h> 13278c34dfSYann Gautier 141fc2130cSYann Gautier#define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1) 154353bb20SYann Gautier 164353bb20SYann Gautier .globl platform_mem_init 174353bb20SYann Gautier .globl plat_report_exception 18*04238683SYann Gautier .globl plat_report_prefetch_abort 19*04238683SYann Gautier .globl plat_report_data_abort 204353bb20SYann Gautier .globl plat_get_my_entrypoint 214353bb20SYann Gautier .globl plat_secondary_cold_boot_setup 224353bb20SYann Gautier .globl plat_reset_handler 234353bb20SYann Gautier .globl plat_is_my_cpu_primary 244353bb20SYann Gautier .globl plat_my_core_pos 25278c34dfSYann Gautier .globl plat_crash_console_init 26278c34dfSYann Gautier .globl plat_crash_console_flush 27278c34dfSYann Gautier .globl plat_crash_console_putc 284353bb20SYann Gautier .globl plat_panic_handler 294353bb20SYann Gautier 304353bb20SYann Gautierfunc platform_mem_init 314353bb20SYann Gautier /* Nothing to do, don't need to init SYSRAM */ 324353bb20SYann Gautier bx lr 334353bb20SYann Gautierendfunc platform_mem_init 344353bb20SYann Gautier 35a9eda77cSYann Gautier#if DEBUG 36*04238683SYann Gautierfunc plat_report_exception 37a9eda77cSYann Gautier mov r8, lr 38a9eda77cSYann Gautier 39*04238683SYann Gautier /* 40*04238683SYann Gautier * Test if an abort occurred 41*04238683SYann Gautier * In this case the error message has already been displayed 42*04238683SYann Gautier * by dedicated functions 43*04238683SYann Gautier */ 44a9eda77cSYann Gautier cmp r0, #MODE32_abt 45*04238683SYann Gautier beq 1f 46a9eda77cSYann Gautier 47a9eda77cSYann Gautier /* Test for an undefined instruction */ 48a9eda77cSYann Gautier cmp r0, #MODE32_und 49a9eda77cSYann Gautier bne other_exception_lbl 50a9eda77cSYann Gautier ldr r4, =undefined_str 51a9eda77cSYann Gautier bl asm_print_str 52a9eda77cSYann Gautier mrs r4, lr_und 53a9eda77cSYann Gautier b print_exception_info 54a9eda77cSYann Gautier 55a9eda77cSYann Gautierother_exception_lbl: 56a9eda77cSYann Gautier /* Other exceptions */ 57a9eda77cSYann Gautier mov r9, r0 58a9eda77cSYann Gautier ldr r4, =exception_start_str 59a9eda77cSYann Gautier bl asm_print_str 60a9eda77cSYann Gautier mov r4, r9 61a9eda77cSYann Gautier bl asm_print_hex 62a9eda77cSYann Gautier ldr r4, =exception_end_str 63a9eda77cSYann Gautier bl asm_print_str 64a9eda77cSYann Gautier mov r4, r6 65a9eda77cSYann Gautier 66a9eda77cSYann Gautierprint_exception_info: 67a9eda77cSYann Gautier bl asm_print_hex 68a9eda77cSYann Gautier 69a9eda77cSYann Gautier ldr r4, =end_error_str 70a9eda77cSYann Gautier bl asm_print_str 71a9eda77cSYann Gautier 72*04238683SYann Gautier1: 73a9eda77cSYann Gautier bx r8 744353bb20SYann Gautierendfunc plat_report_exception 754353bb20SYann Gautier 76*04238683SYann Gautierfunc plat_report_prefetch_abort 77*04238683SYann Gautier mov r8, lr 78*04238683SYann Gautier mov r9, r0 79*04238683SYann Gautier 80*04238683SYann Gautier ldr r4, =prefetch_abort_str 81*04238683SYann Gautier bl asm_print_str 82*04238683SYann Gautier 83*04238683SYann Gautier mov r4, r9 84*04238683SYann Gautier sub r4, r4, #4 85*04238683SYann Gautier bl asm_print_hex 86*04238683SYann Gautier 87*04238683SYann Gautier ldr r4, =ifsr_str 88*04238683SYann Gautier bl asm_print_str 89*04238683SYann Gautier 90*04238683SYann Gautier ldcopr r4, IFSR 91*04238683SYann Gautier bl asm_print_hex 92*04238683SYann Gautier 93*04238683SYann Gautier ldr r4, =ifar_str 94*04238683SYann Gautier bl asm_print_str 95*04238683SYann Gautier 96*04238683SYann Gautier ldcopr r4, IFAR 97*04238683SYann Gautier bl asm_print_hex 98*04238683SYann Gautier 99*04238683SYann Gautier ldr r4, =end_error_str 100*04238683SYann Gautier bl asm_print_str 101*04238683SYann Gautier 102*04238683SYann Gautier bx r8 103*04238683SYann Gautierendfunc plat_report_prefetch_abort 104*04238683SYann Gautier 105*04238683SYann Gautierfunc plat_report_data_abort 106*04238683SYann Gautier mov r8, lr 107*04238683SYann Gautier mov r9, r0 108*04238683SYann Gautier 109*04238683SYann Gautier ldr r4, =data_abort_str 110*04238683SYann Gautier bl asm_print_str 111*04238683SYann Gautier 112*04238683SYann Gautier mov r4, r9 113*04238683SYann Gautier sub r4, r4, #8 114*04238683SYann Gautier bl asm_print_hex 115*04238683SYann Gautier 116*04238683SYann Gautier ldr r4, =dfsr_str 117*04238683SYann Gautier bl asm_print_str 118*04238683SYann Gautier 119*04238683SYann Gautier ldcopr r4, DFSR 120*04238683SYann Gautier bl asm_print_hex 121*04238683SYann Gautier 122*04238683SYann Gautier ldr r4, =dfar_str 123*04238683SYann Gautier bl asm_print_str 124*04238683SYann Gautier 125*04238683SYann Gautier ldcopr r4, DFAR 126*04238683SYann Gautier bl asm_print_hex 127*04238683SYann Gautier 128*04238683SYann Gautier ldr r4, =end_error_str 129*04238683SYann Gautier bl asm_print_str 130*04238683SYann Gautier 131*04238683SYann Gautier bx r8 132*04238683SYann Gautierendfunc plat_report_data_abort 133*04238683SYann Gautier#endif /* DEBUG */ 134*04238683SYann Gautier 1354353bb20SYann Gautierfunc plat_reset_handler 1364353bb20SYann Gautier bx lr 1374353bb20SYann Gautierendfunc plat_reset_handler 1384353bb20SYann Gautier 1394353bb20SYann Gautier /* ------------------------------------------------------------------ 1404353bb20SYann Gautier * unsigned long plat_get_my_entrypoint (void); 1414353bb20SYann Gautier * 1424353bb20SYann Gautier * Main job of this routine is to distinguish between a cold and warm 1434353bb20SYann Gautier * boot. 1444353bb20SYann Gautier * 1454353bb20SYann Gautier * Currently supports only cold boot 1464353bb20SYann Gautier * ------------------------------------------------------------------ 1474353bb20SYann Gautier */ 1484353bb20SYann Gautierfunc plat_get_my_entrypoint 1494353bb20SYann Gautier mov r0, #0 1504353bb20SYann Gautier bx lr 1514353bb20SYann Gautierendfunc plat_get_my_entrypoint 1524353bb20SYann Gautier 1534353bb20SYann Gautier /* --------------------------------------------- 1544353bb20SYann Gautier * void plat_secondary_cold_boot_setup (void); 1554353bb20SYann Gautier * 1564353bb20SYann Gautier * Cold-booting secondary CPUs is not supported. 1574353bb20SYann Gautier * --------------------------------------------- 1584353bb20SYann Gautier */ 1594353bb20SYann Gautierfunc plat_secondary_cold_boot_setup 1604353bb20SYann Gautier b . 1614353bb20SYann Gautierendfunc plat_secondary_cold_boot_setup 1624353bb20SYann Gautier 1634353bb20SYann Gautier /* ----------------------------------------------------- 1644353bb20SYann Gautier * unsigned int plat_is_my_cpu_primary (void); 1654353bb20SYann Gautier * 1664353bb20SYann Gautier * Find out whether the current cpu is the primary cpu. 1674353bb20SYann Gautier * ----------------------------------------------------- 1684353bb20SYann Gautier */ 1694353bb20SYann Gautierfunc plat_is_my_cpu_primary 1704353bb20SYann Gautier ldcopr r0, MPIDR 1714353bb20SYann Gautier ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 1724353bb20SYann Gautier and r0, r1 1733f9c9784SYann Gautier cmp r0, #STM32MP_PRIMARY_CPU 1744353bb20SYann Gautier moveq r0, #1 1754353bb20SYann Gautier movne r0, #0 1764353bb20SYann Gautier bx lr 1774353bb20SYann Gautierendfunc plat_is_my_cpu_primary 1784353bb20SYann Gautier 1794353bb20SYann Gautier /* ------------------------------------------- 1804353bb20SYann Gautier * int plat_stm32mp1_get_core_pos(int mpidr); 1814353bb20SYann Gautier * 1824353bb20SYann Gautier * Return CorePos = (ClusterId * 4) + CoreId 1834353bb20SYann Gautier * ------------------------------------------- 1844353bb20SYann Gautier */ 1854353bb20SYann Gautierfunc plat_stm32mp1_get_core_pos 1864353bb20SYann Gautier and r1, r0, #MPIDR_CPU_MASK 1874353bb20SYann Gautier and r0, r0, #MPIDR_CLUSTER_MASK 1884353bb20SYann Gautier add r0, r1, r0, LSR #6 1894353bb20SYann Gautier bx lr 1904353bb20SYann Gautierendfunc plat_stm32mp1_get_core_pos 1914353bb20SYann Gautier 1924353bb20SYann Gautier /* ------------------------------------ 1934353bb20SYann Gautier * unsigned int plat_my_core_pos(void) 1944353bb20SYann Gautier * ------------------------------------ 1954353bb20SYann Gautier */ 1964353bb20SYann Gautierfunc plat_my_core_pos 1974353bb20SYann Gautier ldcopr r0, MPIDR 1984353bb20SYann Gautier b plat_stm32mp1_get_core_pos 1994353bb20SYann Gautierendfunc plat_my_core_pos 200278c34dfSYann Gautier 201278c34dfSYann Gautier /* --------------------------------------------- 202278c34dfSYann Gautier * int plat_crash_console_init(void) 203278c34dfSYann Gautier * 204278c34dfSYann Gautier * Initialize the crash console without a C Runtime stack. 205278c34dfSYann Gautier * --------------------------------------------- 206278c34dfSYann Gautier */ 207278c34dfSYann Gautierfunc plat_crash_console_init 208b38e2ed2SYann Gautier /* Reset UART peripheral */ 209b38e2ed2SYann Gautier ldr r1, =(RCC_BASE + DEBUG_UART_RST_REG) 210b38e2ed2SYann Gautier ldr r2, =DEBUG_UART_RST_BIT 211b38e2ed2SYann Gautier str r2, [r1] 212b38e2ed2SYann Gautier1: 213b38e2ed2SYann Gautier ldr r0, [r1] 214b38e2ed2SYann Gautier ands r2, r0, r2 215b38e2ed2SYann Gautier beq 1b 216b38e2ed2SYann Gautier str r2, [r1, #4] /* RSTCLR register */ 217b38e2ed2SYann Gautier2: 218b38e2ed2SYann Gautier ldr r0, [r1] 219b38e2ed2SYann Gautier ands r2, r0, r2 220b38e2ed2SYann Gautier bne 2b 2211fc2130cSYann Gautier /* Enable GPIOs for UART TX */ 2221fc2130cSYann Gautier ldr r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG) 223278c34dfSYann Gautier ldr r2, [r1] 2241fc2130cSYann Gautier /* Configure GPIO */ 2251fc2130cSYann Gautier orr r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN 226278c34dfSYann Gautier str r2, [r1] 2271fc2130cSYann Gautier ldr r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS 228278c34dfSYann Gautier /* Set GPIO mode alternate */ 229278c34dfSYann Gautier ldr r2, [r1, #GPIO_MODE_OFFSET] 230278c34dfSYann Gautier bic r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT) 231278c34dfSYann Gautier orr r2, r2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT) 232278c34dfSYann Gautier str r2, [r1, #GPIO_MODE_OFFSET] 233278c34dfSYann Gautier /* Set GPIO speed low */ 234278c34dfSYann Gautier ldr r2, [r1, #GPIO_SPEED_OFFSET] 235278c34dfSYann Gautier bic r2, r2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT) 236278c34dfSYann Gautier str r2, [r1, #GPIO_SPEED_OFFSET] 237278c34dfSYann Gautier /* Set no-pull */ 238278c34dfSYann Gautier ldr r2, [r1, #GPIO_PUPD_OFFSET] 239278c34dfSYann Gautier bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT) 240278c34dfSYann Gautier str r2, [r1, #GPIO_PUPD_OFFSET] 2411fc2130cSYann Gautier /* Set alternate */ 2424170079aSYann Gautier#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT 243278c34dfSYann Gautier ldr r2, [r1, #GPIO_AFRH_OFFSET] 2444170079aSYann Gautier bic r2, r2, #(GPIO_ALTERNATE_MASK << \ 2454170079aSYann Gautier ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) 2464170079aSYann Gautier orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \ 2474170079aSYann Gautier ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) 248278c34dfSYann Gautier str r2, [r1, #GPIO_AFRH_OFFSET] 2494170079aSYann Gautier#else 2504170079aSYann Gautier ldr r2, [r1, #GPIO_AFRL_OFFSET] 2514170079aSYann Gautier bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2)) 2524170079aSYann Gautier orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2)) 2534170079aSYann Gautier str r2, [r1, #GPIO_AFRL_OFFSET] 2544170079aSYann Gautier#endif 2551fc2130cSYann Gautier /* Enable UART clock, with its source */ 2561fc2130cSYann Gautier ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG) 2571fc2130cSYann Gautier mov r2, #DEBUG_UART_TX_CLKSRC 258278c34dfSYann Gautier str r2, [r1] 2591fc2130cSYann Gautier ldr r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG) 260278c34dfSYann Gautier ldr r2, [r1] 2611fc2130cSYann Gautier orr r2, r2, #DEBUG_UART_TX_EN 262278c34dfSYann Gautier str r2, [r1] 263278c34dfSYann Gautier 2643f9c9784SYann Gautier ldr r0, =STM32MP_DEBUG_USART_BASE 2653f9c9784SYann Gautier ldr r1, =STM32MP_DEBUG_USART_CLK_FRQ 2663f9c9784SYann Gautier ldr r2, =STM32MP_UART_BAUDRATE 267cce37d44SYann Gautier b console_stm32_core_init 268278c34dfSYann Gautierendfunc plat_crash_console_init 269278c34dfSYann Gautier 270278c34dfSYann Gautier /* --------------------------------------------- 271831b0e98SJimmy Brisson * void plat_crash_console_flush(void) 272278c34dfSYann Gautier * 273278c34dfSYann Gautier * Flush the crash console without a C Runtime stack. 274278c34dfSYann Gautier * --------------------------------------------- 275278c34dfSYann Gautier */ 276278c34dfSYann Gautierfunc plat_crash_console_flush 277aeb727f3SYann Gautier ldr r0, =STM32MP_DEBUG_USART_BASE 278cce37d44SYann Gautier b console_stm32_core_flush 279278c34dfSYann Gautierendfunc plat_crash_console_flush 280278c34dfSYann Gautier 281278c34dfSYann Gautier /* --------------------------------------------- 282278c34dfSYann Gautier * int plat_crash_console_putc(int c) 283278c34dfSYann Gautier * 284278c34dfSYann Gautier * Print a character on the crash console without a C Runtime stack. 285278c34dfSYann Gautier * Clobber list : r1 - r3 286278c34dfSYann Gautier * 287278c34dfSYann Gautier * In case of bootloading through uart, we keep console crash as this. 288278c34dfSYann Gautier * Characters could be sent to the programmer, but will be ignored. 289278c34dfSYann Gautier * No specific code in that case. 290278c34dfSYann Gautier * --------------------------------------------- 291278c34dfSYann Gautier */ 292278c34dfSYann Gautierfunc plat_crash_console_putc 2933f9c9784SYann Gautier ldr r1, =STM32MP_DEBUG_USART_BASE 294cce37d44SYann Gautier b console_stm32_core_putc 295278c34dfSYann Gautierendfunc plat_crash_console_putc 296a9eda77cSYann Gautier 2976397423eSYann Gautier /* ---------------------------------------------------------- 2986397423eSYann Gautier * void plat_panic_handler(void) __dead2; 2996397423eSYann Gautier * Report exception + endless loop. 3006397423eSYann Gautier * 3016397423eSYann Gautier * r6 holds the address where the fault occurred. 3026397423eSYann Gautier * Filling lr with this value allows debuggers to reconstruct 3036397423eSYann Gautier * the backtrace. 3046397423eSYann Gautier * ---------------------------------------------------------- 3056397423eSYann Gautier */ 3066397423eSYann Gautierfunc plat_panic_handler 3076397423eSYann Gautier mrs r0, cpsr 3086397423eSYann Gautier and r0, #MODE32_MASK 3096397423eSYann Gautier bl plat_report_exception 3106397423eSYann Gautier mov lr, r6 3116397423eSYann Gautier b . 3126397423eSYann Gautierendfunc plat_panic_handler 3136397423eSYann Gautier 314a9eda77cSYann Gautier#if DEBUG 315a9eda77cSYann Gautier.section .rodata.rev_err_str, "aS" 316*04238683SYann Gautierprefetch_abort_str: 317*04238683SYann Gautier .asciz "\nPrefetch Abort at: 0x" 318*04238683SYann Gautierdata_abort_str: 319*04238683SYann Gautier .asciz "\nData Abort at: 0x" 320a9eda77cSYann Gautierundefined_str: 321a9eda77cSYann Gautier .asciz "\nUndefined instruction at: 0x" 322a9eda77cSYann Gautierexception_start_str: 323a9eda77cSYann Gautier .asciz "\nException mode=0x" 324a9eda77cSYann Gautierexception_end_str: 325a9eda77cSYann Gautier .asciz " at: 0x" 326*04238683SYann Gautierdfsr_str: 327*04238683SYann Gautier .asciz " DFSR = 0x" 328*04238683SYann Gautierdfar_str: 329*04238683SYann Gautier .asciz " DFAR = 0x" 330*04238683SYann Gautierifsr_str: 331*04238683SYann Gautier .asciz " IFSR = 0x" 332*04238683SYann Gautierifar_str: 333*04238683SYann Gautier .asciz " IFAR = 0x" 334a9eda77cSYann Gautierend_error_str: 335a9eda77cSYann Gautier .asciz "\n\r" 336a9eda77cSYann Gautier#endif 337