xref: /rk3399_ARM-atf/plat/rpi/common/aarch64/plat_helpers.S (revision 07aa0c7e0e13db4b22de135247b4aa3a5b18f15b)
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 <arch.h>
8#include <asm_macros.S>
9#include <assert_macros.S>
10#include <platform_def.h>
11#include <cortex_a72.h>
12
13	.globl	plat_crash_console_flush
14	.globl	plat_crash_console_init
15	.globl	plat_crash_console_putc
16	.globl	platform_mem_init
17	.globl	plat_get_my_entrypoint
18	.globl	plat_is_my_cpu_primary
19	.globl	plat_my_core_pos
20	.globl	plat_reset_handler
21	.globl	plat_rpi3_calc_core_pos
22	.globl	plat_secondary_cold_boot_setup
23	.globl	plat_rpi_get_model
24
25	/* -----------------------------------------------------
26	 *  unsigned int plat_my_core_pos(void)
27	 *
28	 *  This function uses the plat_rpi3_calc_core_pos()
29	 *  definition to get the index of the calling CPU.
30	 * -----------------------------------------------------
31	 */
32func plat_my_core_pos
33	mrs	x0, mpidr_el1
34	b	plat_rpi3_calc_core_pos
35endfunc plat_my_core_pos
36
37	/* -----------------------------------------------------
38	 *  unsigned int plat_rpi3_calc_core_pos(u_register_t mpidr);
39	 *
40	 *  CorePos = (ClusterId * 4) + CoreId
41	 * -----------------------------------------------------
42	 */
43func plat_rpi3_calc_core_pos
44	and	x1, x0, #MPIDR_CPU_MASK
45	and	x0, x0, #MPIDR_CLUSTER_MASK
46	add	x0, x1, x0, LSR #6
47	ret
48endfunc plat_rpi3_calc_core_pos
49
50	/* -----------------------------------------------------
51	 * unsigned int plat_is_my_cpu_primary (void);
52	 *
53	 * Find out whether the current cpu is the primary
54	 * cpu.
55	 * -----------------------------------------------------
56	 */
57func plat_is_my_cpu_primary
58	mrs	x0, mpidr_el1
59	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
60	cmp	x0, #RPI_PRIMARY_CPU
61	cset	w0, eq
62	ret
63endfunc plat_is_my_cpu_primary
64
65	/* -----------------------------------------------------
66	 * void plat_secondary_cold_boot_setup (void);
67	 *
68	 * This function performs any platform specific actions
69	 * needed for a secondary cpu after a cold reset e.g
70	 * mark the cpu's presence, mechanism to place it in a
71	 * holding pen etc.
72	 * -----------------------------------------------------
73	 */
74func plat_secondary_cold_boot_setup
75	/* Calculate address of our hold entry */
76	bl	plat_my_core_pos
77	lsl	x0, x0, #3
78	mov_imm	x2, PLAT_RPI3_TM_HOLD_BASE
79	add	x0, x0, x2
80
81	/*
82	 * This code runs way before requesting the warmboot of this core,
83	 * so it is possible to clear the mailbox before getting a request
84	 * to boot.
85	 */
86	mov	x1, PLAT_RPI3_TM_HOLD_STATE_WAIT
87	str	x1,[x0]
88
89	/* Wait until we have a go */
90poll_mailbox:
91	wfe
92	ldr	x1, [x0]
93	cmp	x1, PLAT_RPI3_TM_HOLD_STATE_GO
94	bne	poll_mailbox
95
96	/* Jump to the provided entrypoint */
97	mov_imm	x0, PLAT_RPI3_TM_ENTRYPOINT
98	ldr	x1, [x0]
99	br	x1
100endfunc plat_secondary_cold_boot_setup
101
102	/* ---------------------------------------------------------------------
103	 * uintptr_t plat_get_my_entrypoint (void);
104	 *
105	 * Main job of this routine is to distinguish between a cold and a warm
106	 * boot.
107	 *
108	 * This functions returns:
109	 *  - 0 for a cold boot.
110	 *  - Any other value for a warm boot.
111	 * ---------------------------------------------------------------------
112	 */
113func plat_get_my_entrypoint
114	/* TODO: support warm boot */
115	mov	x0, #0
116	ret
117endfunc plat_get_my_entrypoint
118
119	/* ---------------------------------------------
120	 * void platform_mem_init (void);
121	 *
122	 * No need to carry out any memory initialization.
123	 * ---------------------------------------------
124	 */
125func platform_mem_init
126	ret
127endfunc platform_mem_init
128
129	/* ---------------------------------------------
130	 * int plat_crash_console_init(void)
131	 * Function to initialize the crash console
132	 * without a C Runtime to print crash report.
133	 * Clobber list : x0 - x3
134	 * ---------------------------------------------
135	 */
136func plat_crash_console_init
137	mov_imm	x0, PLAT_RPI_MINI_UART_BASE
138	mov	x1, xzr
139	mov	x2, xzr
140	b	console_16550_core_init
141endfunc plat_crash_console_init
142
143	/* ---------------------------------------------
144	 * int plat_crash_console_putc(int c)
145	 * Function to print a character on the crash
146	 * console without a C Runtime.
147	 * Clobber list : x1, x2
148	 * ---------------------------------------------
149	 */
150func plat_crash_console_putc
151	mov_imm	x1, PLAT_RPI_MINI_UART_BASE
152	b	console_16550_core_putc
153endfunc plat_crash_console_putc
154
155	/* ---------------------------------------------
156	 * int plat_crash_console_flush()
157	 * Function to force a write of all buffered
158	 * data that hasn't been output.
159	 * Out : return -1 on error else return 0.
160	 * Clobber list : x0, x1
161	 * ---------------------------------------------
162	 */
163func plat_crash_console_flush
164	mov_imm	x0, PLAT_RPI_MINI_UART_BASE
165	b	console_16550_core_flush
166endfunc plat_crash_console_flush
167
168	/* ---------------------------------------------
169	 * int plat_rpi_get_model()
170	 * Macro to determine whether we are running on
171	 * a Raspberry Pi 3 or 4. Just checks the MIDR for
172	 * being either a Cortex-A72 or a Cortex-A53.
173	 * Out : return 4 if RPi4, 3 otherwise.
174	 * Clobber list : x0
175	 * ---------------------------------------------
176	 */
177	.macro _plat_rpi_get_model
178	mrs	x0, midr_el1
179	and	x0, x0, #0xf0	/* Isolate low byte of part number */
180	cmp	w0, #0x80	/* Cortex-A72 (RPi4) is 0xd08, A53 is 0xd03 */
181	mov	w0, #3
182	csinc	w0, w0, w0, ne
183	.endm
184
185	func plat_rpi_get_model
186	_plat_rpi_get_model
187	ret
188	endfunc plat_rpi_get_model
189
190	/* ---------------------------------------------
191	 * void plat_reset_handler(void);
192	 * ---------------------------------------------
193	 */
194func plat_reset_handler
195	/* L2 cache setup only needed on RPi4 */
196	_plat_rpi_get_model
197	cmp	w0, #4
198	b.ne	1f
199
200	/* ------------------------------------------------
201	 * Set L2 read/write cache latency:
202	 * - L2 Data RAM latency: 3 cycles (0b010)
203	 * - L2 Data RAM setup: 1 cycle (bit 5)
204	 * ------------------------------------------------
205	 */
206	mrs	x0, CORTEX_A72_L2CTLR_EL1
207	mov	x1, #0x22
208	orr	x0, x0, x1
209	msr	CORTEX_A72_L2CTLR_EL1, x0
210	isb
211
2121:
213	ret
214endfunc plat_reset_handler
215