xref: /rk3399_ARM-atf/plat/intel/soc/common/aarch64/plat_helpers.S (revision 5cef096e4c7238b397ebd9661d61daecf6464283)
13f7b1490SHadi Asyrafi/*
26197dc98SJit Loon Lim * Copyright (c) 2019-2023, ARM Limited and Contributors. All rights reserved.
37ac7dadbSSieu Mun Tang * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
47ac7dadbSSieu Mun Tang * Copyright (c) 2024, Altera Corporation. All rights reserved.
53f7b1490SHadi Asyrafi *
63f7b1490SHadi Asyrafi * SPDX-License-Identifier: BSD-3-Clause
73f7b1490SHadi Asyrafi */
83f7b1490SHadi Asyrafi
93f7b1490SHadi Asyrafi#include <arch.h>
103f7b1490SHadi Asyrafi#include <asm_macros.S>
113f7b1490SHadi Asyrafi#include <cpu_macros.S>
123f7b1490SHadi Asyrafi#include <platform_def.h>
132db1e766SHadi Asyrafi#include <el3_common_macros.S>
143f7b1490SHadi Asyrafi
153f7b1490SHadi Asyrafi	.globl	plat_secondary_cold_boot_setup
163f7b1490SHadi Asyrafi	.globl	platform_is_primary_cpu
173f7b1490SHadi Asyrafi	.globl	plat_is_my_cpu_primary
183f7b1490SHadi Asyrafi	.globl	plat_my_core_pos
193f7b1490SHadi Asyrafi	.globl	plat_crash_console_init
203f7b1490SHadi Asyrafi	.globl	plat_crash_console_putc
213f7b1490SHadi Asyrafi	.globl  plat_crash_console_flush
223f7b1490SHadi Asyrafi	.globl	platform_mem_init
232db1e766SHadi Asyrafi	.globl	plat_secondary_cpus_bl31_entry
243f7b1490SHadi Asyrafi
253f7b1490SHadi Asyrafi	.globl plat_get_my_entrypoint
263f7b1490SHadi Asyrafi
273f7b1490SHadi Asyrafi	/* -----------------------------------------------------
283f7b1490SHadi Asyrafi	 * void plat_secondary_cold_boot_setup (void);
293f7b1490SHadi Asyrafi	 *
303f7b1490SHadi Asyrafi	 * This function performs any platform specific actions
313f7b1490SHadi Asyrafi	 * needed for a secondary cpu after a cold reset e.g
323f7b1490SHadi Asyrafi	 * mark the cpu's presence, mechanism to place it in a
333f7b1490SHadi Asyrafi	 * holding pen etc.
343f7b1490SHadi Asyrafi	 * -----------------------------------------------------
353f7b1490SHadi Asyrafi	 */
363f7b1490SHadi Asyrafifunc plat_secondary_cold_boot_setup
373f7b1490SHadi Asyrafi	/* Wait until the it gets reset signal from rstmgr gets populated */
383f7b1490SHadi Asyrafipoll_mailbox:
397931d332SJit Loon Lim#if	PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
407931d332SJit Loon Lim	mov_imm x0, PLAT_SEC_ENTRY
417931d332SJit Loon Lim	cbz	x0, poll_mailbox
427931d332SJit Loon Lim	br      x0
437931d332SJit Loon Lim#else
443f7b1490SHadi Asyrafi	wfi
453f7b1490SHadi Asyrafi	mov_imm	x0, PLAT_SEC_ENTRY
463f7b1490SHadi Asyrafi	ldr	x1, [x0]
473f7b1490SHadi Asyrafi	mov_imm	x2, PLAT_CPUID_RELEASE
483f7b1490SHadi Asyrafi	ldr	x3, [x2]
493f7b1490SHadi Asyrafi	mrs	x4, mpidr_el1
503f7b1490SHadi Asyrafi	and	x4, x4, #0xff
513f7b1490SHadi Asyrafi	cmp	x3, x4
523f7b1490SHadi Asyrafi	b.ne	poll_mailbox
533f7b1490SHadi Asyrafi	br	x1
547931d332SJit Loon Lim#endif
553f7b1490SHadi Asyrafiendfunc plat_secondary_cold_boot_setup
563f7b1490SHadi Asyrafi
577931d332SJit Loon Lim#if	((PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10) || \
587931d332SJit Loon Lim	(PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX) || \
597931d332SJit Loon Lim	(PLATFORM_MODEL == PLAT_SOCFPGA_N5X))
607931d332SJit Loon Lim
613f7b1490SHadi Asyrafifunc platform_is_primary_cpu
623f7b1490SHadi Asyrafi	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
633f7b1490SHadi Asyrafi	cmp	x0, #PLAT_PRIMARY_CPU
643f7b1490SHadi Asyrafi	cset	x0, eq
653f7b1490SHadi Asyrafi	ret
663f7b1490SHadi Asyrafiendfunc platform_is_primary_cpu
673f7b1490SHadi Asyrafi
687931d332SJit Loon Lim#else
697931d332SJit Loon Lim
707931d332SJit Loon Limfunc platform_is_primary_cpu
717931d332SJit Loon Lim	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
727931d332SJit Loon Lim	cmp x0, #(PLAT_PRIMARY_CPU_A76)
737931d332SJit Loon Lim	b.eq primary_cpu
747931d332SJit Loon Lim	cmp x0, #(PLAT_PRIMARY_CPU_A55)
757931d332SJit Loon Lim	b.eq primary_cpu
767931d332SJit Loon Limprimary_cpu:
777931d332SJit Loon Lim	cset	x0, eq
787931d332SJit Loon Lim	ret
797931d332SJit Loon Limendfunc platform_is_primary_cpu
807931d332SJit Loon Lim
817931d332SJit Loon Lim#endif
827931d332SJit Loon Lim
833f7b1490SHadi Asyrafifunc plat_is_my_cpu_primary
843f7b1490SHadi Asyrafi	mrs	x0, mpidr_el1
853f7b1490SHadi Asyrafi	b   platform_is_primary_cpu
863f7b1490SHadi Asyrafiendfunc plat_is_my_cpu_primary
873f7b1490SHadi Asyrafi
883f7b1490SHadi Asyrafifunc plat_my_core_pos
893f7b1490SHadi Asyrafi	mrs	x0, mpidr_el1
903f7b1490SHadi Asyrafi	and	x1, x0, #MPIDR_CPU_MASK
913f7b1490SHadi Asyrafi	and	x0, x0, #MPIDR_CLUSTER_MASK
927931d332SJit Loon Lim#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
937931d332SJit Loon Lim	add	x0, x1, x0, LSR #8
947931d332SJit Loon Lim#else
953f7b1490SHadi Asyrafi	add	x0, x1, x0, LSR #6
967931d332SJit Loon Lim#endif
973f7b1490SHadi Asyrafi	ret
983f7b1490SHadi Asyrafiendfunc plat_my_core_pos
993f7b1490SHadi Asyrafi
10032cf34acSHadi Asyrafifunc warm_reset_req
101*646a9a16SJit Loon Lim#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
102*646a9a16SJit Loon Lim	/* Clear the markup before going for warm reset */
103*646a9a16SJit Loon Lim	bic	x2, x2, #BS_REG_MAGIC_KEYS_MASK
104*646a9a16SJit Loon Lim	/* Check if the address is 64 bit aligned or not */
105*646a9a16SJit Loon Lim	ldr	x4, =L2_RESET_DONE_REG
106*646a9a16SJit Loon Lim	tst	x4, #ALIGN_CHECK_64BIT_MASK
107*646a9a16SJit Loon Lim	b.ne	unaligned_store
108*646a9a16SJit Loon Lim	/* Device memory address is aligned, store the value directly */
109*646a9a16SJit Loon Lim	str	x2, [x4]
110*646a9a16SJit Loon Lim	b	continue_warm_reset
111*646a9a16SJit Loon Lim
112*646a9a16SJit Loon Lim	/* Unaligned store, use byte by byte method to store */
113*646a9a16SJit Loon Limunaligned_store:
114*646a9a16SJit Loon Lim	strb	w2, [x4]
115*646a9a16SJit Loon Lim	lsr	x2, x2, #8
116*646a9a16SJit Loon Lim	add	x4, x4, #1
117*646a9a16SJit Loon Lim	strb	w2, [x4]
118*646a9a16SJit Loon Lim	lsr	x2, x2, #8
119*646a9a16SJit Loon Lim	add	x4, x4, #1
120*646a9a16SJit Loon Lim	strb	w2, [x4]
121*646a9a16SJit Loon Lim	lsr	x2, x2, #8
122*646a9a16SJit Loon Lim	add	x4, x4, #1
123*646a9a16SJit Loon Lim	strb	w2, [x4]
124*646a9a16SJit Loon Lim#else
125*646a9a16SJit Loon Lim	/* Clear the markup before going for warm reset */
126*646a9a16SJit Loon Lim	bic	x2, x2, #BS_REG_MAGIC_KEYS_MASK
127*646a9a16SJit Loon Lim	str	x2, [x4]
128*646a9a16SJit Loon Lim#endif
129*646a9a16SJit Loon Lim
130*646a9a16SJit Loon Limcontinue_warm_reset:
13132cf34acSHadi Asyrafi	bl	plat_is_my_cpu_primary
13232cf34acSHadi Asyrafi	cbz	x0, cpu_in_wfi
13332cf34acSHadi Asyrafi	mov_imm x1, PLAT_SEC_ENTRY
13432cf34acSHadi Asyrafi	str	xzr, [x1]
13532cf34acSHadi Asyrafi	mrs	x1, rmr_el3
13632cf34acSHadi Asyrafi	orr	x1, x1, #0x02
13732cf34acSHadi Asyrafi	msr	rmr_el3, x1
13832cf34acSHadi Asyrafi	isb
13932cf34acSHadi Asyrafi	dsb	sy
14032cf34acSHadi Asyraficpu_in_wfi:
14132cf34acSHadi Asyrafi	wfi
14232cf34acSHadi Asyrafi	b	cpu_in_wfi
14332cf34acSHadi Asyrafiendfunc warm_reset_req
14432cf34acSHadi Asyrafi
1457931d332SJit Loon Lim#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX5
1467931d332SJit Loon Limfunc plat_get_my_entrypoint
1477931d332SJit Loon Lim	ldr	x4, =L2_RESET_DONE_REG
148*646a9a16SJit Loon Lim
149*646a9a16SJit Loon Lim	/* Check if the address is 64 bit aligned or not */
150*646a9a16SJit Loon Lim	tst	x4, #ALIGN_CHECK_64BIT_MASK
151*646a9a16SJit Loon Lim	b.ne	unaligned_load
152*646a9a16SJit Loon Lim
153*646a9a16SJit Loon Lim	/* Device memory address is aligned, load the value directly */
154*646a9a16SJit Loon Lim	ldr	x1, [x4]
155*646a9a16SJit Loon Lim	b	events_check
156*646a9a16SJit Loon Lim
157*646a9a16SJit Loon Lim	/*
158*646a9a16SJit Loon Lim	 * It is unaligned device memory access. Read only LSB 32 bits
159*646a9a16SJit Loon Lim	 * byte by byte and combine them to get the 32 bit value.
160*646a9a16SJit Loon Lim	 */
161*646a9a16SJit Loon Limunaligned_load:
162*646a9a16SJit Loon Lim	ldrb	w1, [x4]
163*646a9a16SJit Loon Lim	ldrb	w2, [x4, #1]
164*646a9a16SJit Loon Lim	ldrb	w3, [x4, #2]
165*646a9a16SJit Loon Lim	ldrb	w4, [x4, #3]
166*646a9a16SJit Loon Lim	orr	x1, x1, x2, lsl #8
167*646a9a16SJit Loon Lim	orr	x1, x1, x3, lsl #16
168*646a9a16SJit Loon Lim	orr	x1, x1, x4, lsl #24
169*646a9a16SJit Loon Lim
170*646a9a16SJit Loon Limevents_check:
171*646a9a16SJit Loon Lim	/* Keep a backup of the boot scratch register contents */
172*646a9a16SJit Loon Lim	mov	x2, x1
173*646a9a16SJit Loon Lim
174*646a9a16SJit Loon Lim	/* Mask and get the required bits */
175*646a9a16SJit Loon Lim	and	x1, x1, #BS_REG_MAGIC_KEYS_MASK
176c1253b24SSieu Mun Tang
177c1253b24SSieu Mun Tang	/* Check for warm reset request */
178*646a9a16SJit Loon Lim	ldr	x5, =L2_RESET_DONE_STATUS
1797931d332SJit Loon Lim	cmp	x1, x5
180c1253b24SSieu Mun Tang	b.eq	warm_reset_req
181c1253b24SSieu Mun Tang
182c1253b24SSieu Mun Tang	/* Check for SMP secondary cores boot request */
183*646a9a16SJit Loon Lim	ldr	x5, =SMP_SEC_CORE_BOOT_REQ
184c1253b24SSieu Mun Tang	cmp	x1, x5
185c1253b24SSieu Mun Tang	b.eq	smp_request
186c1253b24SSieu Mun Tang
187*646a9a16SJit Loon Lim	/* Otherwise it is a cold reset request */
188c1253b24SSieu Mun Tang	mov	x0, #0
189c1253b24SSieu Mun Tang	ret
190*646a9a16SJit Loon Lim
191c1253b24SSieu Mun Tangsmp_request:
192c1253b24SSieu Mun Tang	/*
193*646a9a16SJit Loon Lim	 * On the SMP boot request, return the address 'bl31_warm_entrypoint',
194*646a9a16SJit Loon Lim	 * which is passed to 'psci_setup' routine as part of BL31
195*646a9a16SJit Loon Lim	 * initialization.
196c1253b24SSieu Mun Tang	 */
197*646a9a16SJit Loon Lim	ldr	x1, =PLAT_SEC_ENTRY
1987931d332SJit Loon Lim	ldr	x0, [x1]
1997931d332SJit Loon Lim	ret
2007931d332SJit Loon Limendfunc plat_get_my_entrypoint
2017931d332SJit Loon Lim#else
2023f7b1490SHadi Asyrafifunc plat_get_my_entrypoint
20332cf34acSHadi Asyrafi	ldr	x4, =L2_RESET_DONE_REG
20432cf34acSHadi Asyrafi	ldr	x5, [x4]
205*646a9a16SJit Loon Lim
206*646a9a16SJit Loon Lim	/* Keep a backup of the boot scratch register contents */
207*646a9a16SJit Loon Lim	mov	x2, x5
208*646a9a16SJit Loon Lim
209*646a9a16SJit Loon Lim	/* Mask and get only the required bits */
210*646a9a16SJit Loon Lim	and	x5, x5, #BS_REG_MAGIC_KEYS_MASK
211*646a9a16SJit Loon Lim
212*646a9a16SJit Loon Lim	/* Check for warm reset request */
21332cf34acSHadi Asyrafi	ldr	x1, =L2_RESET_DONE_STATUS
21432cf34acSHadi Asyrafi	cmp	x1, x5
21532cf34acSHadi Asyrafi	b.eq	warm_reset_req
2163f7b1490SHadi Asyrafi	mov_imm	x1, PLAT_SEC_ENTRY
2173f7b1490SHadi Asyrafi	ldr	x0, [x1]
2183f7b1490SHadi Asyrafi	ret
2193f7b1490SHadi Asyrafiendfunc plat_get_my_entrypoint
2207931d332SJit Loon Lim#endif
22132cf34acSHadi Asyrafi
2223f7b1490SHadi Asyrafi	/* ---------------------------------------------
2233f7b1490SHadi Asyrafi	 * int plat_crash_console_init(void)
2243f7b1490SHadi Asyrafi	 * Function to initialize the crash console
2253f7b1490SHadi Asyrafi	 * without a C Runtime to print crash report.
2263f7b1490SHadi Asyrafi	 * Clobber list : x0, x1, x2
2273f7b1490SHadi Asyrafi	 * ---------------------------------------------
2283f7b1490SHadi Asyrafi	 */
2293f7b1490SHadi Asyrafifunc plat_crash_console_init
230447e699fSBoon Khai Ng	mov_imm	x0, CRASH_CONSOLE_BASE
2313f7b1490SHadi Asyrafi	mov_imm	x1, PLAT_UART_CLOCK
2323f7b1490SHadi Asyrafi	mov_imm	x2, PLAT_BAUDRATE
2333f7b1490SHadi Asyrafi	b	console_16550_core_init
2343f7b1490SHadi Asyrafiendfunc plat_crash_console_init
2353f7b1490SHadi Asyrafi
2363f7b1490SHadi Asyrafi	/* ---------------------------------------------
2373f7b1490SHadi Asyrafi	 * int plat_crash_console_putc(void)
2383f7b1490SHadi Asyrafi	 * Function to print a character on the crash
2393f7b1490SHadi Asyrafi	 * console without a C Runtime.
2403f7b1490SHadi Asyrafi	 * Clobber list : x1, x2
2413f7b1490SHadi Asyrafi	 * ---------------------------------------------
2423f7b1490SHadi Asyrafi	 */
2433f7b1490SHadi Asyrafifunc plat_crash_console_putc
244447e699fSBoon Khai Ng	mov_imm x1, CRASH_CONSOLE_BASE
2453f7b1490SHadi Asyrafi	b	console_16550_core_putc
2463f7b1490SHadi Asyrafiendfunc plat_crash_console_putc
2473f7b1490SHadi Asyrafi
2483f7b1490SHadi Asyrafifunc plat_crash_console_flush
2493f7b1490SHadi Asyrafi	mov_imm x0, CRASH_CONSOLE_BASE
2503f7b1490SHadi Asyrafi	b	console_16550_core_flush
2513f7b1490SHadi Asyrafiendfunc plat_crash_console_flush
2523f7b1490SHadi Asyrafi
2533f7b1490SHadi Asyrafi
2543f7b1490SHadi Asyrafi	/* --------------------------------------------------------
2553f7b1490SHadi Asyrafi	 * void platform_mem_init (void);
2563f7b1490SHadi Asyrafi	 *
2573f7b1490SHadi Asyrafi	 * Any memory init, relocation to be done before the
2583f7b1490SHadi Asyrafi	 * platform boots. Called very early in the boot process.
2593f7b1490SHadi Asyrafi	 * --------------------------------------------------------
2603f7b1490SHadi Asyrafi	 */
2613f7b1490SHadi Asyrafifunc platform_mem_init
2623f7b1490SHadi Asyrafi	mov	x0, #0
2633f7b1490SHadi Asyrafi	ret
2643f7b1490SHadi Asyrafiendfunc platform_mem_init
2652db1e766SHadi Asyrafi
2667931d332SJit Loon Lim	/* --------------------------------------------------------
2677931d332SJit Loon Lim	 * macro plat_secondary_cpus_bl31_entry;
2687931d332SJit Loon Lim	 *
2697931d332SJit Loon Lim	 * el3_entrypoint_common init param configuration.
2707931d332SJit Loon Lim	 * Called very early in the secondary cores boot process.
2717931d332SJit Loon Lim	 * --------------------------------------------------------
2727931d332SJit Loon Lim	 */
2732db1e766SHadi Asyrafifunc plat_secondary_cpus_bl31_entry
2742db1e766SHadi Asyrafi	el3_entrypoint_common                                   \
2752db1e766SHadi Asyrafi		_init_sctlr=0                                   \
2762db1e766SHadi Asyrafi		_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS  \
2772db1e766SHadi Asyrafi		_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU      \
2782db1e766SHadi Asyrafi		_init_memory=1                                  \
2792db1e766SHadi Asyrafi		_init_c_runtime=1                               \
2802db1e766SHadi Asyrafi		_exception_vectors=runtime_exceptions		\
2812db1e766SHadi Asyrafi		_pie_fixup_size=BL31_LIMIT - BL31_BASE
2822db1e766SHadi Asyrafiendfunc plat_secondary_cpus_bl31_entry
283