1*91f16700Schasinglulu/* 2*91f16700Schasinglulu * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu#include <platform_def.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu#include <arch.h> 10*91f16700Schasinglulu#include <asm_macros.S> 11*91f16700Schasinglulu#include <common/bl_common.h> 12*91f16700Schasinglulu#include <drivers/st/stm32_gpio.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu#define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1) 15*91f16700Schasinglulu 16*91f16700Schasinglulu .globl platform_mem_init 17*91f16700Schasinglulu .globl plat_report_exception 18*91f16700Schasinglulu .globl plat_report_prefetch_abort 19*91f16700Schasinglulu .globl plat_report_data_abort 20*91f16700Schasinglulu .globl plat_get_my_entrypoint 21*91f16700Schasinglulu .globl plat_secondary_cold_boot_setup 22*91f16700Schasinglulu .globl plat_reset_handler 23*91f16700Schasinglulu .globl plat_is_my_cpu_primary 24*91f16700Schasinglulu .globl plat_my_core_pos 25*91f16700Schasinglulu .globl plat_crash_console_init 26*91f16700Schasinglulu .globl plat_crash_console_flush 27*91f16700Schasinglulu .globl plat_crash_console_putc 28*91f16700Schasinglulu .globl plat_panic_handler 29*91f16700Schasinglulu 30*91f16700Schasinglulufunc platform_mem_init 31*91f16700Schasinglulu /* Nothing to do, don't need to init SYSRAM */ 32*91f16700Schasinglulu bx lr 33*91f16700Schasingluluendfunc platform_mem_init 34*91f16700Schasinglulu 35*91f16700Schasinglulu#if DEBUG 36*91f16700Schasinglulufunc plat_report_exception 37*91f16700Schasinglulu mov r8, lr 38*91f16700Schasinglulu 39*91f16700Schasinglulu /* 40*91f16700Schasinglulu * Test if an abort occurred 41*91f16700Schasinglulu * In this case the error message has already been displayed 42*91f16700Schasinglulu * by dedicated functions 43*91f16700Schasinglulu */ 44*91f16700Schasinglulu cmp r0, #MODE32_abt 45*91f16700Schasinglulu beq 1f 46*91f16700Schasinglulu 47*91f16700Schasinglulu /* Test for an undefined instruction */ 48*91f16700Schasinglulu cmp r0, #MODE32_und 49*91f16700Schasinglulu bne other_exception_lbl 50*91f16700Schasinglulu ldr r4, =undefined_str 51*91f16700Schasinglulu bl asm_print_str 52*91f16700Schasinglulu mrs r4, lr_und 53*91f16700Schasinglulu b print_exception_info 54*91f16700Schasinglulu 55*91f16700Schasingluluother_exception_lbl: 56*91f16700Schasinglulu /* Other exceptions */ 57*91f16700Schasinglulu mov r9, r0 58*91f16700Schasinglulu ldr r4, =exception_start_str 59*91f16700Schasinglulu bl asm_print_str 60*91f16700Schasinglulu mov r4, r9 61*91f16700Schasinglulu bl asm_print_hex 62*91f16700Schasinglulu ldr r4, =exception_end_str 63*91f16700Schasinglulu bl asm_print_str 64*91f16700Schasinglulu mov r4, r6 65*91f16700Schasinglulu 66*91f16700Schasingluluprint_exception_info: 67*91f16700Schasinglulu bl asm_print_hex 68*91f16700Schasinglulu 69*91f16700Schasinglulu ldr r4, =end_error_str 70*91f16700Schasinglulu bl asm_print_str 71*91f16700Schasinglulu 72*91f16700Schasinglulu1: 73*91f16700Schasinglulu bx r8 74*91f16700Schasingluluendfunc plat_report_exception 75*91f16700Schasinglulu 76*91f16700Schasinglulufunc plat_report_prefetch_abort 77*91f16700Schasinglulu mov r8, lr 78*91f16700Schasinglulu mov r9, r0 79*91f16700Schasinglulu 80*91f16700Schasinglulu ldr r4, =prefetch_abort_str 81*91f16700Schasinglulu bl asm_print_str 82*91f16700Schasinglulu 83*91f16700Schasinglulu mov r4, r9 84*91f16700Schasinglulu sub r4, r4, #4 85*91f16700Schasinglulu bl asm_print_hex 86*91f16700Schasinglulu 87*91f16700Schasinglulu ldr r4, =ifsr_str 88*91f16700Schasinglulu bl asm_print_str 89*91f16700Schasinglulu 90*91f16700Schasinglulu ldcopr r4, IFSR 91*91f16700Schasinglulu bl asm_print_hex 92*91f16700Schasinglulu 93*91f16700Schasinglulu ldr r4, =ifar_str 94*91f16700Schasinglulu bl asm_print_str 95*91f16700Schasinglulu 96*91f16700Schasinglulu ldcopr r4, IFAR 97*91f16700Schasinglulu bl asm_print_hex 98*91f16700Schasinglulu 99*91f16700Schasinglulu ldr r4, =end_error_str 100*91f16700Schasinglulu bl asm_print_str 101*91f16700Schasinglulu 102*91f16700Schasinglulu bx r8 103*91f16700Schasingluluendfunc plat_report_prefetch_abort 104*91f16700Schasinglulu 105*91f16700Schasinglulufunc plat_report_data_abort 106*91f16700Schasinglulu mov r8, lr 107*91f16700Schasinglulu mov r9, r0 108*91f16700Schasinglulu 109*91f16700Schasinglulu ldr r4, =data_abort_str 110*91f16700Schasinglulu bl asm_print_str 111*91f16700Schasinglulu 112*91f16700Schasinglulu mov r4, r9 113*91f16700Schasinglulu sub r4, r4, #8 114*91f16700Schasinglulu bl asm_print_hex 115*91f16700Schasinglulu 116*91f16700Schasinglulu ldr r4, =dfsr_str 117*91f16700Schasinglulu bl asm_print_str 118*91f16700Schasinglulu 119*91f16700Schasinglulu ldcopr r4, DFSR 120*91f16700Schasinglulu bl asm_print_hex 121*91f16700Schasinglulu 122*91f16700Schasinglulu ldr r4, =dfar_str 123*91f16700Schasinglulu bl asm_print_str 124*91f16700Schasinglulu 125*91f16700Schasinglulu ldcopr r4, DFAR 126*91f16700Schasinglulu bl asm_print_hex 127*91f16700Schasinglulu 128*91f16700Schasinglulu ldr r4, =end_error_str 129*91f16700Schasinglulu bl asm_print_str 130*91f16700Schasinglulu 131*91f16700Schasinglulu bx r8 132*91f16700Schasingluluendfunc plat_report_data_abort 133*91f16700Schasinglulu#endif /* DEBUG */ 134*91f16700Schasinglulu 135*91f16700Schasinglulufunc plat_reset_handler 136*91f16700Schasinglulu bx lr 137*91f16700Schasingluluendfunc plat_reset_handler 138*91f16700Schasinglulu 139*91f16700Schasinglulu /* ------------------------------------------------------------------ 140*91f16700Schasinglulu * unsigned long plat_get_my_entrypoint (void); 141*91f16700Schasinglulu * 142*91f16700Schasinglulu * Main job of this routine is to distinguish between a cold and warm 143*91f16700Schasinglulu * boot. 144*91f16700Schasinglulu * 145*91f16700Schasinglulu * Currently supports only cold boot 146*91f16700Schasinglulu * ------------------------------------------------------------------ 147*91f16700Schasinglulu */ 148*91f16700Schasinglulufunc plat_get_my_entrypoint 149*91f16700Schasinglulu mov r0, #0 150*91f16700Schasinglulu bx lr 151*91f16700Schasingluluendfunc plat_get_my_entrypoint 152*91f16700Schasinglulu 153*91f16700Schasinglulu /* --------------------------------------------- 154*91f16700Schasinglulu * void plat_secondary_cold_boot_setup (void); 155*91f16700Schasinglulu * 156*91f16700Schasinglulu * Cold-booting secondary CPUs is not supported. 157*91f16700Schasinglulu * --------------------------------------------- 158*91f16700Schasinglulu */ 159*91f16700Schasinglulufunc plat_secondary_cold_boot_setup 160*91f16700Schasinglulu b . 161*91f16700Schasingluluendfunc plat_secondary_cold_boot_setup 162*91f16700Schasinglulu 163*91f16700Schasinglulu /* ----------------------------------------------------- 164*91f16700Schasinglulu * unsigned int plat_is_my_cpu_primary (void); 165*91f16700Schasinglulu * 166*91f16700Schasinglulu * Find out whether the current cpu is the primary cpu. 167*91f16700Schasinglulu * ----------------------------------------------------- 168*91f16700Schasinglulu */ 169*91f16700Schasinglulufunc plat_is_my_cpu_primary 170*91f16700Schasinglulu ldcopr r0, MPIDR 171*91f16700Schasinglulu ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) 172*91f16700Schasinglulu and r0, r1 173*91f16700Schasinglulu cmp r0, #STM32MP_PRIMARY_CPU 174*91f16700Schasinglulu moveq r0, #1 175*91f16700Schasinglulu movne r0, #0 176*91f16700Schasinglulu bx lr 177*91f16700Schasingluluendfunc plat_is_my_cpu_primary 178*91f16700Schasinglulu 179*91f16700Schasinglulu /* ------------------------------------------- 180*91f16700Schasinglulu * int plat_stm32mp1_get_core_pos(int mpidr); 181*91f16700Schasinglulu * 182*91f16700Schasinglulu * Return CorePos = (ClusterId * 4) + CoreId 183*91f16700Schasinglulu * ------------------------------------------- 184*91f16700Schasinglulu */ 185*91f16700Schasinglulufunc plat_stm32mp1_get_core_pos 186*91f16700Schasinglulu and r1, r0, #MPIDR_CPU_MASK 187*91f16700Schasinglulu and r0, r0, #MPIDR_CLUSTER_MASK 188*91f16700Schasinglulu add r0, r1, r0, LSR #6 189*91f16700Schasinglulu bx lr 190*91f16700Schasingluluendfunc plat_stm32mp1_get_core_pos 191*91f16700Schasinglulu 192*91f16700Schasinglulu /* ------------------------------------ 193*91f16700Schasinglulu * unsigned int plat_my_core_pos(void) 194*91f16700Schasinglulu * ------------------------------------ 195*91f16700Schasinglulu */ 196*91f16700Schasinglulufunc plat_my_core_pos 197*91f16700Schasinglulu ldcopr r0, MPIDR 198*91f16700Schasinglulu b plat_stm32mp1_get_core_pos 199*91f16700Schasingluluendfunc plat_my_core_pos 200*91f16700Schasinglulu 201*91f16700Schasinglulu /* --------------------------------------------- 202*91f16700Schasinglulu * int plat_crash_console_init(void) 203*91f16700Schasinglulu * 204*91f16700Schasinglulu * Initialize the crash console without a C Runtime stack. 205*91f16700Schasinglulu * --------------------------------------------- 206*91f16700Schasinglulu */ 207*91f16700Schasinglulufunc plat_crash_console_init 208*91f16700Schasinglulu /* Reset UART peripheral */ 209*91f16700Schasinglulu ldr r1, =(RCC_BASE + DEBUG_UART_RST_REG) 210*91f16700Schasinglulu ldr r2, =DEBUG_UART_RST_BIT 211*91f16700Schasinglulu str r2, [r1] 212*91f16700Schasinglulu1: 213*91f16700Schasinglulu ldr r0, [r1] 214*91f16700Schasinglulu ands r2, r0, r2 215*91f16700Schasinglulu beq 1b 216*91f16700Schasinglulu str r2, [r1, #4] /* RSTCLR register */ 217*91f16700Schasinglulu2: 218*91f16700Schasinglulu ldr r0, [r1] 219*91f16700Schasinglulu ands r2, r0, r2 220*91f16700Schasinglulu bne 2b 221*91f16700Schasinglulu /* Enable GPIOs for UART TX */ 222*91f16700Schasinglulu ldr r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG) 223*91f16700Schasinglulu ldr r2, [r1] 224*91f16700Schasinglulu /* Configure GPIO */ 225*91f16700Schasinglulu orr r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN 226*91f16700Schasinglulu str r2, [r1] 227*91f16700Schasinglulu ldr r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS 228*91f16700Schasinglulu /* Set GPIO mode alternate */ 229*91f16700Schasinglulu ldr r2, [r1, #GPIO_MODE_OFFSET] 230*91f16700Schasinglulu bic r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT) 231*91f16700Schasinglulu orr r2, r2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT) 232*91f16700Schasinglulu str r2, [r1, #GPIO_MODE_OFFSET] 233*91f16700Schasinglulu /* Set GPIO speed low */ 234*91f16700Schasinglulu ldr r2, [r1, #GPIO_SPEED_OFFSET] 235*91f16700Schasinglulu bic r2, r2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT) 236*91f16700Schasinglulu str r2, [r1, #GPIO_SPEED_OFFSET] 237*91f16700Schasinglulu /* Set no-pull */ 238*91f16700Schasinglulu ldr r2, [r1, #GPIO_PUPD_OFFSET] 239*91f16700Schasinglulu bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT) 240*91f16700Schasinglulu str r2, [r1, #GPIO_PUPD_OFFSET] 241*91f16700Schasinglulu /* Set alternate */ 242*91f16700Schasinglulu#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT 243*91f16700Schasinglulu ldr r2, [r1, #GPIO_AFRH_OFFSET] 244*91f16700Schasinglulu bic r2, r2, #(GPIO_ALTERNATE_MASK << \ 245*91f16700Schasinglulu ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) 246*91f16700Schasinglulu orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \ 247*91f16700Schasinglulu ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) 248*91f16700Schasinglulu str r2, [r1, #GPIO_AFRH_OFFSET] 249*91f16700Schasinglulu#else 250*91f16700Schasinglulu ldr r2, [r1, #GPIO_AFRL_OFFSET] 251*91f16700Schasinglulu bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2)) 252*91f16700Schasinglulu orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2)) 253*91f16700Schasinglulu str r2, [r1, #GPIO_AFRL_OFFSET] 254*91f16700Schasinglulu#endif 255*91f16700Schasinglulu /* Enable UART clock, with its source */ 256*91f16700Schasinglulu ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG) 257*91f16700Schasinglulu mov r2, #DEBUG_UART_TX_CLKSRC 258*91f16700Schasinglulu str r2, [r1] 259*91f16700Schasinglulu ldr r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG) 260*91f16700Schasinglulu ldr r2, [r1] 261*91f16700Schasinglulu orr r2, r2, #DEBUG_UART_TX_EN 262*91f16700Schasinglulu str r2, [r1] 263*91f16700Schasinglulu 264*91f16700Schasinglulu ldr r0, =STM32MP_DEBUG_USART_BASE 265*91f16700Schasinglulu ldr r1, =STM32MP_DEBUG_USART_CLK_FRQ 266*91f16700Schasinglulu ldr r2, =STM32MP_UART_BAUDRATE 267*91f16700Schasinglulu b console_stm32_core_init 268*91f16700Schasingluluendfunc plat_crash_console_init 269*91f16700Schasinglulu 270*91f16700Schasinglulu /* --------------------------------------------- 271*91f16700Schasinglulu * void plat_crash_console_flush(void) 272*91f16700Schasinglulu * 273*91f16700Schasinglulu * Flush the crash console without a C Runtime stack. 274*91f16700Schasinglulu * --------------------------------------------- 275*91f16700Schasinglulu */ 276*91f16700Schasinglulufunc plat_crash_console_flush 277*91f16700Schasinglulu ldr r0, =STM32MP_DEBUG_USART_BASE 278*91f16700Schasinglulu b console_stm32_core_flush 279*91f16700Schasingluluendfunc plat_crash_console_flush 280*91f16700Schasinglulu 281*91f16700Schasinglulu /* --------------------------------------------- 282*91f16700Schasinglulu * int plat_crash_console_putc(int c) 283*91f16700Schasinglulu * 284*91f16700Schasinglulu * Print a character on the crash console without a C Runtime stack. 285*91f16700Schasinglulu * Clobber list : r1 - r3 286*91f16700Schasinglulu * 287*91f16700Schasinglulu * In case of bootloading through uart, we keep console crash as this. 288*91f16700Schasinglulu * Characters could be sent to the programmer, but will be ignored. 289*91f16700Schasinglulu * No specific code in that case. 290*91f16700Schasinglulu * --------------------------------------------- 291*91f16700Schasinglulu */ 292*91f16700Schasinglulufunc plat_crash_console_putc 293*91f16700Schasinglulu ldr r1, =STM32MP_DEBUG_USART_BASE 294*91f16700Schasinglulu b console_stm32_core_putc 295*91f16700Schasingluluendfunc plat_crash_console_putc 296*91f16700Schasinglulu 297*91f16700Schasinglulu /* ---------------------------------------------------------- 298*91f16700Schasinglulu * void plat_panic_handler(void) __dead2; 299*91f16700Schasinglulu * Report exception + endless loop. 300*91f16700Schasinglulu * 301*91f16700Schasinglulu * r6 holds the address where the fault occurred. 302*91f16700Schasinglulu * Filling lr with this value allows debuggers to reconstruct 303*91f16700Schasinglulu * the backtrace. 304*91f16700Schasinglulu * ---------------------------------------------------------- 305*91f16700Schasinglulu */ 306*91f16700Schasinglulufunc plat_panic_handler 307*91f16700Schasinglulu mrs r0, cpsr 308*91f16700Schasinglulu and r0, #MODE32_MASK 309*91f16700Schasinglulu bl plat_report_exception 310*91f16700Schasinglulu mov lr, r6 311*91f16700Schasinglulu b . 312*91f16700Schasingluluendfunc plat_panic_handler 313*91f16700Schasinglulu 314*91f16700Schasinglulu#if DEBUG 315*91f16700Schasinglulu.section .rodata.rev_err_str, "aS" 316*91f16700Schasingluluprefetch_abort_str: 317*91f16700Schasinglulu .asciz "\nPrefetch Abort at: 0x" 318*91f16700Schasingluludata_abort_str: 319*91f16700Schasinglulu .asciz "\nData Abort at: 0x" 320*91f16700Schasingluluundefined_str: 321*91f16700Schasinglulu .asciz "\nUndefined instruction at: 0x" 322*91f16700Schasingluluexception_start_str: 323*91f16700Schasinglulu .asciz "\nException mode=0x" 324*91f16700Schasingluluexception_end_str: 325*91f16700Schasinglulu .asciz " at: 0x" 326*91f16700Schasingluludfsr_str: 327*91f16700Schasinglulu .asciz " DFSR = 0x" 328*91f16700Schasingluludfar_str: 329*91f16700Schasinglulu .asciz " DFAR = 0x" 330*91f16700Schasingluluifsr_str: 331*91f16700Schasinglulu .asciz " IFSR = 0x" 332*91f16700Schasingluluifar_str: 333*91f16700Schasinglulu .asciz " IFAR = 0x" 334*91f16700Schasingluluend_error_str: 335*91f16700Schasinglulu .asciz "\n\r" 336*91f16700Schasinglulu#endif 337