1/* 2 * Copyright (c) 2015-2020, 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 /* Enable GPIOs for UART TX */ 152 ldr r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG) 153 ldr r2, [r1] 154 /* Configure GPIO */ 155 orr r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN 156 str r2, [r1] 157 ldr r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS 158 /* Set GPIO mode alternate */ 159 ldr r2, [r1, #GPIO_MODE_OFFSET] 160 bic r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT) 161 orr r2, r2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT) 162 str r2, [r1, #GPIO_MODE_OFFSET] 163 /* Set GPIO speed low */ 164 ldr r2, [r1, #GPIO_SPEED_OFFSET] 165 bic r2, r2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT) 166 str r2, [r1, #GPIO_SPEED_OFFSET] 167 /* Set no-pull */ 168 ldr r2, [r1, #GPIO_PUPD_OFFSET] 169 bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT) 170 str r2, [r1, #GPIO_PUPD_OFFSET] 171 /* Set alternate */ 172#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT 173 ldr r2, [r1, #GPIO_AFRH_OFFSET] 174 bic r2, r2, #(GPIO_ALTERNATE_MASK << \ 175 ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) 176 orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \ 177 ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)) 178 str r2, [r1, #GPIO_AFRH_OFFSET] 179#else 180 ldr r2, [r1, #GPIO_AFRL_OFFSET] 181 bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2)) 182 orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2)) 183 str r2, [r1, #GPIO_AFRL_OFFSET] 184#endif 185 /* Enable UART clock, with its source */ 186 ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG) 187 mov r2, #DEBUG_UART_TX_CLKSRC 188 str r2, [r1] 189 ldr r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG) 190 ldr r2, [r1] 191 orr r2, r2, #DEBUG_UART_TX_EN 192 str r2, [r1] 193 194 ldr r0, =STM32MP_DEBUG_USART_BASE 195 ldr r1, =STM32MP_DEBUG_USART_CLK_FRQ 196 ldr r2, =STM32MP_UART_BAUDRATE 197 b console_stm32_core_init 198endfunc plat_crash_console_init 199 200 /* --------------------------------------------- 201 * void plat_crash_console_flush(void) 202 * 203 * Flush the crash console without a C Runtime stack. 204 * --------------------------------------------- 205 */ 206func plat_crash_console_flush 207 ldr r0, =STM32MP_DEBUG_USART_BASE 208 b console_stm32_core_flush 209endfunc plat_crash_console_flush 210 211 /* --------------------------------------------- 212 * int plat_crash_console_putc(int c) 213 * 214 * Print a character on the crash console without a C Runtime stack. 215 * Clobber list : r1 - r3 216 * 217 * In case of bootloading through uart, we keep console crash as this. 218 * Characters could be sent to the programmer, but will be ignored. 219 * No specific code in that case. 220 * --------------------------------------------- 221 */ 222func plat_crash_console_putc 223 ldr r1, =STM32MP_DEBUG_USART_BASE 224 b console_stm32_core_putc 225endfunc plat_crash_console_putc 226 227 /* ---------------------------------------------------------- 228 * void plat_panic_handler(void) __dead2; 229 * Report exception + endless loop. 230 * 231 * r6 holds the address where the fault occurred. 232 * Filling lr with this value allows debuggers to reconstruct 233 * the backtrace. 234 * ---------------------------------------------------------- 235 */ 236func plat_panic_handler 237 mrs r0, cpsr 238 and r0, #MODE32_MASK 239 bl plat_report_exception 240 mov lr, r6 241 b . 242endfunc plat_panic_handler 243 244#if DEBUG 245.section .rodata.rev_err_str, "aS" 246abort_str: 247 .asciz "\nAbort at: 0x" 248undefined_str: 249 .asciz "\nUndefined instruction at: 0x" 250exception_start_str: 251 .asciz "\nException mode=0x" 252exception_end_str: 253 .asciz " at: 0x" 254end_error_str: 255 .asciz "\n\r" 256#endif 257