1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
/*
* Copyright (c) 2023, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
#include <drivers/st/stm32_gpio.h>
#include <platform_def.h>
#define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1)
.globl platform_mem_init
.globl plat_secondary_cold_boot_setup
.globl plat_is_my_cpu_primary
.globl plat_crash_console_init
.globl plat_crash_console_flush
.globl plat_crash_console_putc
.globl plat_report_exception
func platform_mem_init
/* Nothing to do, don't need to init SYSRAM */
ret
endfunc platform_mem_init
/* ---------------------------------------------
* void plat_secondary_cold_boot_setup (void);
*
* Set secondary core in WFI waiting for core reset.
* ---------------------------------------------
*/
func plat_secondary_cold_boot_setup
dsb sy
wfi
/* This shouldn't be reached */
b .
endfunc plat_secondary_cold_boot_setup
/* ----------------------------------------------
* unsigned int plat_is_my_cpu_primary(void);
* This function checks if this is the primary CPU
* ----------------------------------------------
*/
func plat_is_my_cpu_primary
mrs x0, mpidr_el1
and x0, x0, #(MPIDR_CPU_MASK)
cmp x0, #STM32MP_PRIMARY_CPU
cset x0, eq
ret
endfunc plat_is_my_cpu_primary
/* ---------------------------------------------
* int plat_crash_console_init(void)
*
* Initialize the crash console without a C Runtime stack.
* ---------------------------------------------
*/
func plat_crash_console_init
/* Reset UART peripheral */
mov_imm x1, (RCC_BASE + DEBUG_UART_RST_REG)
ldr x2, =DEBUG_UART_RST_BIT
ldr x0, [x1]
orr x0, x0, x2
str x0, [x1]
1:
ldr x0, [x1]
ands x2, x0, x2
beq 1b
bic x2, x2, #DEBUG_UART_RST_BIT
str x2, [x1]
2:
ldr x0, [x1]
ands x2, x0, x2
bne 2b
/* Enable GPIOs for UART TX */
mov_imm x1, (RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
ldr w2, [x1]
/* Configure GPIO */
orr w2, w2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
str w2, [x1]
mov_imm x1, DEBUG_UART_TX_GPIO_BANK_ADDRESS
/* Set GPIO mode alternate */
ldr w2, [x1, #GPIO_MODE_OFFSET]
bic w2, w2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
orr w2, w2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT)
str w2, [x1, #GPIO_MODE_OFFSET]
/* Set GPIO speed low */
ldr w2, [x1, #GPIO_SPEED_OFFSET]
bic w2, w2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT)
str w2, [x1, #GPIO_SPEED_OFFSET]
/* Set no-pull */
ldr w2, [x1, #GPIO_PUPD_OFFSET]
bic w2, w2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
str w2, [x1, #GPIO_PUPD_OFFSET]
/* Set alternate */
#if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT
ldr w2, [x1, #GPIO_AFRH_OFFSET]
bic w2, w2, #(GPIO_ALTERNATE_MASK << \
((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
orr w2, w2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \
((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
str w2, [x1, #GPIO_AFRH_OFFSET]
#else
ldr w2, [x1, #GPIO_AFRL_OFFSET]
bic w2, w2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2))
orr w2, w2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2))
str w2, [x1, #GPIO_AFRL_OFFSET]
#endif
/* Clear UART clock flexgen divisors, keep enable bit */
mov_imm x1, (RCC_BASE + DEBUG_UART_PREDIV_CFGR)
mov x2, #0
str w2, [x1]
mov_imm x1, (RCC_BASE + DEBUG_UART_FINDIV_CFGR)
mov x2, #0x40
str w2, [x1]
/* Enable UART clock, with its source */
mov_imm x1, (RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
mov_imm w2, (DEBUG_UART_TX_CLKSRC | RCC_XBARxCFGR_XBARxEN)
str w2, [x1]
mov_imm x1, (RCC_BASE + DEBUG_UART_TX_EN_REG)
ldr w2, [x1]
orr w2, w2, #DEBUG_UART_TX_EN
str w2, [x1]
mov_imm x0, STM32MP_DEBUG_USART_BASE
mov_imm x1, STM32MP_DEBUG_USART_CLK_FRQ
mov_imm x2, STM32MP_UART_BAUDRATE
b console_stm32_core_init
endfunc plat_crash_console_init
func plat_crash_console_flush
mov_imm x0, STM32MP_DEBUG_USART_BASE
b console_stm32_core_flush
endfunc plat_crash_console_flush
func plat_crash_console_putc
mov_imm x1, STM32MP_DEBUG_USART_BASE
cmp x0, #'\n'
b.ne 1f
mov x15, x30
mov x0, #'\r'
bl console_stm32_core_putc
mov x30, x15
mov x0, #'\n'
1:
b console_stm32_core_putc
endfunc plat_crash_console_putc
#ifdef IMAGE_BL2
/* ---------------------------------------------
* void plat_report_exception(unsigned int type)
* Function to report an unhandled exception
* with platform-specific means.
* ---------------------------------------------
*/
func plat_report_exception
mov x8, x30
adr x4, plat_err_str
bl asm_print_str
adr x4, esr_el3_str
bl asm_print_str
mrs x4, esr_el3
bl asm_print_hex
adr x4, elr_el3_str
bl asm_print_str
mrs x4, elr_el3
bl asm_print_hex
adr x4, far_el3_str
bl asm_print_str
mrs x4, far_el3
bl asm_print_hex
mov x30, x8
ret
endfunc plat_report_exception
.section .rodata.rev_err_str, "aS"
plat_err_str:
.asciz "\nPlatform exception reporting:"
esr_el3_str:
.asciz "\nESR_EL3: "
elr_el3_str:
.asciz "\nELR_EL3: "
far_el3_str:
.asciz "\nFAR_EL3: "
#endif /* IMAGE_BL2 */
|