blob: eb8823b020e66ae52da4b6ceffe15f891f6ac306 [file] [log] [blame]
Yann Gautier4b0c72a2018-07-16 10:54:09 +02001/*
Yann Gautier0f634ec2019-08-29 19:04:29 +02002 * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
Yann Gautier4b0c72a2018-07-16 10:54:09 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00007#include <platform_def.h>
8
Yann Gautier4b0c72a2018-07-16 10:54:09 +02009#include <arch.h>
10#include <asm_macros.S>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000011#include <common/bl_common.h>
12#include <drivers/st/stm32_gpio.h>
Yann Gautier69035a82018-07-05 16:48:16 +020013
Yann Gautier038bff22019-01-17 19:17:47 +010014#define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1)
Yann Gautier4b0c72a2018-07-16 10:54:09 +020015
16 .globl platform_mem_init
17 .globl plat_report_exception
Yann Gautier0f634ec2019-08-29 19:04:29 +020018 .globl plat_report_prefetch_abort
19 .globl plat_report_data_abort
Yann Gautier4b0c72a2018-07-16 10:54:09 +020020 .globl plat_get_my_entrypoint
21 .globl plat_secondary_cold_boot_setup
22 .globl plat_reset_handler
23 .globl plat_is_my_cpu_primary
24 .globl plat_my_core_pos
Yann Gautier69035a82018-07-05 16:48:16 +020025 .globl plat_crash_console_init
26 .globl plat_crash_console_flush
27 .globl plat_crash_console_putc
Yann Gautier4b0c72a2018-07-16 10:54:09 +020028 .globl plat_panic_handler
29
30func platform_mem_init
31 /* Nothing to do, don't need to init SYSRAM */
32 bx lr
33endfunc platform_mem_init
34
Yann Gautiere0b4fde2020-09-15 12:24:46 +020035#if DEBUG
Yann Gautier0f634ec2019-08-29 19:04:29 +020036func plat_report_exception
Yann Gautiere0b4fde2020-09-15 12:24:46 +020037 mov r8, lr
38
Yann Gautier0f634ec2019-08-29 19:04:29 +020039 /*
40 * Test if an abort occurred
41 * In this case the error message has already been displayed
42 * by dedicated functions
43 */
Yann Gautiere0b4fde2020-09-15 12:24:46 +020044 cmp r0, #MODE32_abt
Yann Gautier0f634ec2019-08-29 19:04:29 +020045 beq 1f
Yann Gautiere0b4fde2020-09-15 12:24:46 +020046
Yann Gautiere0b4fde2020-09-15 12:24:46 +020047 /* 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
Yann Gautier0f634ec2019-08-29 19:04:29 +0200721:
Yann Gautiere0b4fde2020-09-15 12:24:46 +020073 bx r8
Yann Gautier4b0c72a2018-07-16 10:54:09 +020074endfunc plat_report_exception
75
Yann Gautier0f634ec2019-08-29 19:04:29 +020076func plat_report_prefetch_abort
77 mov r8, lr
78 mov r9, r0
79
80 ldr r4, =prefetch_abort_str
81 bl asm_print_str
82
83 mov r4, r9
84 sub r4, r4, #4
85 bl asm_print_hex
86
87 ldr r4, =ifsr_str
88 bl asm_print_str
89
90 ldcopr r4, IFSR
91 bl asm_print_hex
92
93 ldr r4, =ifar_str
94 bl asm_print_str
95
96 ldcopr r4, IFAR
97 bl asm_print_hex
98
99 ldr r4, =end_error_str
100 bl asm_print_str
101
102 bx r8
103endfunc plat_report_prefetch_abort
104
105func plat_report_data_abort
106 mov r8, lr
107 mov r9, r0
108
109 ldr r4, =data_abort_str
110 bl asm_print_str
111
112 mov r4, r9
113 sub r4, r4, #8
114 bl asm_print_hex
115
116 ldr r4, =dfsr_str
117 bl asm_print_str
118
119 ldcopr r4, DFSR
120 bl asm_print_hex
121
122 ldr r4, =dfar_str
123 bl asm_print_str
124
125 ldcopr r4, DFAR
126 bl asm_print_hex
127
128 ldr r4, =end_error_str
129 bl asm_print_str
130
131 bx r8
132endfunc plat_report_data_abort
133#endif /* DEBUG */
134
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200135func plat_reset_handler
136 bx lr
137endfunc plat_reset_handler
138
139 /* ------------------------------------------------------------------
140 * unsigned long plat_get_my_entrypoint (void);
141 *
142 * Main job of this routine is to distinguish between a cold and warm
143 * boot.
144 *
145 * Currently supports only cold boot
146 * ------------------------------------------------------------------
147 */
148func plat_get_my_entrypoint
149 mov r0, #0
150 bx lr
151endfunc plat_get_my_entrypoint
152
153 /* ---------------------------------------------
154 * void plat_secondary_cold_boot_setup (void);
155 *
156 * Cold-booting secondary CPUs is not supported.
157 * ---------------------------------------------
158 */
159func plat_secondary_cold_boot_setup
160 b .
161endfunc plat_secondary_cold_boot_setup
162
163 /* -----------------------------------------------------
164 * unsigned int plat_is_my_cpu_primary (void);
165 *
166 * Find out whether the current cpu is the primary cpu.
167 * -----------------------------------------------------
168 */
169func plat_is_my_cpu_primary
170 ldcopr r0, MPIDR
171 ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
172 and r0, r1
Yann Gautiera2e2a302019-02-14 11:13:39 +0100173 cmp r0, #STM32MP_PRIMARY_CPU
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200174 moveq r0, #1
175 movne r0, #0
176 bx lr
177endfunc plat_is_my_cpu_primary
178
179 /* -------------------------------------------
180 * int plat_stm32mp1_get_core_pos(int mpidr);
181 *
182 * Return CorePos = (ClusterId * 4) + CoreId
183 * -------------------------------------------
184 */
185func plat_stm32mp1_get_core_pos
186 and r1, r0, #MPIDR_CPU_MASK
187 and r0, r0, #MPIDR_CLUSTER_MASK
188 add r0, r1, r0, LSR #6
189 bx lr
190endfunc plat_stm32mp1_get_core_pos
191
192 /* ------------------------------------
193 * unsigned int plat_my_core_pos(void)
194 * ------------------------------------
195 */
196func plat_my_core_pos
197 ldcopr r0, MPIDR
198 b plat_stm32mp1_get_core_pos
199endfunc plat_my_core_pos
Yann Gautier69035a82018-07-05 16:48:16 +0200200
201 /* ---------------------------------------------
202 * int plat_crash_console_init(void)
203 *
204 * Initialize the crash console without a C Runtime stack.
205 * ---------------------------------------------
206 */
207func plat_crash_console_init
Yann Gautier5c84e742020-09-14 17:21:59 +0200208 /* Reset UART peripheral */
209 ldr r1, =(RCC_BASE + DEBUG_UART_RST_REG)
210 ldr r2, =DEBUG_UART_RST_BIT
211 str r2, [r1]
2121:
213 ldr r0, [r1]
214 ands r2, r0, r2
215 beq 1b
216 str r2, [r1, #4] /* RSTCLR register */
2172:
218 ldr r0, [r1]
219 ands r2, r0, r2
220 bne 2b
Yann Gautier038bff22019-01-17 19:17:47 +0100221 /* Enable GPIOs for UART TX */
222 ldr r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
Yann Gautier69035a82018-07-05 16:48:16 +0200223 ldr r2, [r1]
Yann Gautier038bff22019-01-17 19:17:47 +0100224 /* Configure GPIO */
225 orr r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
Yann Gautier69035a82018-07-05 16:48:16 +0200226 str r2, [r1]
Yann Gautier038bff22019-01-17 19:17:47 +0100227 ldr r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS
Yann Gautier69035a82018-07-05 16:48:16 +0200228 /* Set GPIO mode alternate */
229 ldr r2, [r1, #GPIO_MODE_OFFSET]
230 bic r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
231 orr r2, r2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT)
232 str r2, [r1, #GPIO_MODE_OFFSET]
233 /* Set GPIO speed low */
234 ldr r2, [r1, #GPIO_SPEED_OFFSET]
235 bic r2, r2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT)
236 str r2, [r1, #GPIO_SPEED_OFFSET]
237 /* Set no-pull */
238 ldr r2, [r1, #GPIO_PUPD_OFFSET]
239 bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
240 str r2, [r1, #GPIO_PUPD_OFFSET]
Yann Gautier038bff22019-01-17 19:17:47 +0100241 /* Set alternate */
Yann Gautier868007e2020-02-25 17:51:52 +0100242#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT
Yann Gautier69035a82018-07-05 16:48:16 +0200243 ldr r2, [r1, #GPIO_AFRH_OFFSET]
Yann Gautier868007e2020-02-25 17:51:52 +0100244 bic r2, r2, #(GPIO_ALTERNATE_MASK << \
245 ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
246 orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \
247 ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
Yann Gautier69035a82018-07-05 16:48:16 +0200248 str r2, [r1, #GPIO_AFRH_OFFSET]
Yann Gautier868007e2020-02-25 17:51:52 +0100249#else
250 ldr r2, [r1, #GPIO_AFRL_OFFSET]
251 bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2))
252 orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2))
253 str r2, [r1, #GPIO_AFRL_OFFSET]
254#endif
Yann Gautier038bff22019-01-17 19:17:47 +0100255 /* Enable UART clock, with its source */
256 ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
257 mov r2, #DEBUG_UART_TX_CLKSRC
Yann Gautier69035a82018-07-05 16:48:16 +0200258 str r2, [r1]
Yann Gautier038bff22019-01-17 19:17:47 +0100259 ldr r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG)
Yann Gautier69035a82018-07-05 16:48:16 +0200260 ldr r2, [r1]
Yann Gautier038bff22019-01-17 19:17:47 +0100261 orr r2, r2, #DEBUG_UART_TX_EN
Yann Gautier69035a82018-07-05 16:48:16 +0200262 str r2, [r1]
263
Yann Gautiera2e2a302019-02-14 11:13:39 +0100264 ldr r0, =STM32MP_DEBUG_USART_BASE
265 ldr r1, =STM32MP_DEBUG_USART_CLK_FRQ
266 ldr r2, =STM32MP_UART_BAUDRATE
Yann Gautier8593e442018-11-14 18:46:15 +0100267 b console_stm32_core_init
Yann Gautier69035a82018-07-05 16:48:16 +0200268endfunc plat_crash_console_init
269
270 /* ---------------------------------------------
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500271 * void plat_crash_console_flush(void)
Yann Gautier69035a82018-07-05 16:48:16 +0200272 *
273 * Flush the crash console without a C Runtime stack.
274 * ---------------------------------------------
275 */
276func plat_crash_console_flush
Yann Gautierf94d85a2020-12-09 13:35:27 +0100277 ldr r0, =STM32MP_DEBUG_USART_BASE
Yann Gautier8593e442018-11-14 18:46:15 +0100278 b console_stm32_core_flush
Yann Gautier69035a82018-07-05 16:48:16 +0200279endfunc plat_crash_console_flush
280
281 /* ---------------------------------------------
282 * int plat_crash_console_putc(int c)
283 *
284 * Print a character on the crash console without a C Runtime stack.
285 * Clobber list : r1 - r3
286 *
287 * In case of bootloading through uart, we keep console crash as this.
288 * Characters could be sent to the programmer, but will be ignored.
289 * No specific code in that case.
290 * ---------------------------------------------
291 */
292func plat_crash_console_putc
Yann Gautiera2e2a302019-02-14 11:13:39 +0100293 ldr r1, =STM32MP_DEBUG_USART_BASE
Yann Gautier8593e442018-11-14 18:46:15 +0100294 b console_stm32_core_putc
Yann Gautier69035a82018-07-05 16:48:16 +0200295endfunc plat_crash_console_putc
Yann Gautiere0b4fde2020-09-15 12:24:46 +0200296
Yann Gautiera0388f32020-09-15 12:29:53 +0200297 /* ----------------------------------------------------------
298 * void plat_panic_handler(void) __dead2;
299 * Report exception + endless loop.
300 *
301 * r6 holds the address where the fault occurred.
302 * Filling lr with this value allows debuggers to reconstruct
303 * the backtrace.
304 * ----------------------------------------------------------
305 */
306func plat_panic_handler
307 mrs r0, cpsr
308 and r0, #MODE32_MASK
309 bl plat_report_exception
310 mov lr, r6
311 b .
312endfunc plat_panic_handler
313
Yann Gautiere0b4fde2020-09-15 12:24:46 +0200314#if DEBUG
315.section .rodata.rev_err_str, "aS"
Yann Gautier0f634ec2019-08-29 19:04:29 +0200316prefetch_abort_str:
317 .asciz "\nPrefetch Abort at: 0x"
318data_abort_str:
319 .asciz "\nData Abort at: 0x"
Yann Gautiere0b4fde2020-09-15 12:24:46 +0200320undefined_str:
321 .asciz "\nUndefined instruction at: 0x"
322exception_start_str:
323 .asciz "\nException mode=0x"
324exception_end_str:
325 .asciz " at: 0x"
Yann Gautier0f634ec2019-08-29 19:04:29 +0200326dfsr_str:
327 .asciz " DFSR = 0x"
328dfar_str:
329 .asciz " DFAR = 0x"
330ifsr_str:
331 .asciz " IFSR = 0x"
332ifar_str:
333 .asciz " IFAR = 0x"
Yann Gautiere0b4fde2020-09-15 12:24:46 +0200334end_error_str:
335 .asciz "\n\r"
336#endif