xref: /rk3399_ARM-atf/plat/st/stm32mp1/stm32mp1_helper.S (revision 4f2c4ecfb087dd32b277000dc1578837dee1fd71)
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