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