xref: /arm-trusted-firmware/plat/arm/board/arm_fpga/aarch64/fpga_helpers.S (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu/*
2*91f16700Schasinglulu * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu *
4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu */
6*91f16700Schasinglulu
7*91f16700Schasinglulu#include <arch.h>
8*91f16700Schasinglulu#include <asm_macros.S>
9*91f16700Schasinglulu#include <common/bl_common.h>
10*91f16700Schasinglulu#include "../fpga_private.h"
11*91f16700Schasinglulu
12*91f16700Schasinglulu#include <platform_def.h>
13*91f16700Schasinglulu
14*91f16700Schasinglulu	.globl	plat_get_my_entrypoint
15*91f16700Schasinglulu	.globl	plat_secondary_cold_boot_setup
16*91f16700Schasinglulu	.globl	plat_is_my_cpu_primary
17*91f16700Schasinglulu	.globl	platform_mem_init
18*91f16700Schasinglulu	.globl	plat_my_core_pos
19*91f16700Schasinglulu	.globl	plat_crash_console_init
20*91f16700Schasinglulu	.globl	plat_crash_console_putc
21*91f16700Schasinglulu	.globl	plat_crash_console_flush
22*91f16700Schasinglulu	.globl	plat_fpga_calc_core_pos
23*91f16700Schasinglulu
24*91f16700Schasinglulu/* -----------------------------------------------------------------------
25*91f16700Schasinglulu * Indicate a cold boot for every CPU - warm boot is unsupported for the
26*91f16700Schasinglulu * holding pen PSCI implementation.
27*91f16700Schasinglulu * -----------------------------------------------------------------------
28*91f16700Schasinglulu */
29*91f16700Schasinglulufunc plat_get_my_entrypoint
30*91f16700Schasinglulu	mov	x0, #0
31*91f16700Schasinglulu	ret
32*91f16700Schasingluluendfunc plat_get_my_entrypoint
33*91f16700Schasinglulu
34*91f16700Schasinglulu/* -----------------------------------------------------------------------
35*91f16700Schasinglulu * void plat_secondary_cold_boot_setup (void);
36*91f16700Schasinglulu * -----------------------------------------------------------------------
37*91f16700Schasinglulu */
38*91f16700Schasinglulufunc plat_secondary_cold_boot_setup
39*91f16700Schasinglulu
40*91f16700Schasinglulu	/*
41*91f16700Schasinglulu	 * Wait for the primary processor to initialise the .BSS segment
42*91f16700Schasinglulu	 * to avoid a race condition that would erase fpga_valid_mpids
43*91f16700Schasinglulu	 * if it is populated before the C runtime is ready.
44*91f16700Schasinglulu	 *
45*91f16700Schasinglulu	 * We cannot use the current spin-lock implementation until the
46*91f16700Schasinglulu	 * runtime is up and we should not rely on sevl/wfe instructions as
47*91f16700Schasinglulu	 * it is optional whether they are implemented or not, so we use
48*91f16700Schasinglulu	 * a global variable as lock and wait for the primary processor to
49*91f16700Schasinglulu	 * finish the C runtime bring-up.
50*91f16700Schasinglulu	 */
51*91f16700Schasinglulu
52*91f16700Schasinglulu	ldr	w0, =C_RUNTIME_READY_KEY
53*91f16700Schasinglulu	adrp	x1, secondary_core_spinlock
54*91f16700Schasinglulu	add	x1, x1, :lo12:secondary_core_spinlock
55*91f16700Schasinglulu1:
56*91f16700Schasinglulu	wfe
57*91f16700Schasinglulu	ldr	w2, [x1]
58*91f16700Schasinglulu	cmp	w2, w0
59*91f16700Schasinglulu	b.ne	1b
60*91f16700Schasinglulu	/* Prevent reordering of the store into fpga_valid_mpids below */
61*91f16700Schasinglulu	dmb	ish
62*91f16700Schasinglulu
63*91f16700Schasinglulu	mov	x10, x30
64*91f16700Schasinglulu	bl	plat_my_core_pos
65*91f16700Schasinglulu	mov	x30, x10
66*91f16700Schasinglulu
67*91f16700Schasinglulu	adrp	x4, fpga_valid_mpids
68*91f16700Schasinglulu	add	x4, x4, :lo12:fpga_valid_mpids
69*91f16700Schasinglulu	mov	x5, #VALID_MPID
70*91f16700Schasinglulu	strb	w5, [x4, x0]
71*91f16700Schasinglulu
72*91f16700Schasinglulu	/*
73*91f16700Schasinglulu	 * Poll the CPU's hold entry until it indicates to jump
74*91f16700Schasinglulu	 * to the entrypoint address.
75*91f16700Schasinglulu	 */
76*91f16700Schasinglulu
77*91f16700Schasinglulu	adrp	x1, hold_base
78*91f16700Schasinglulu	add	x1, x1, :lo12:hold_base
79*91f16700Schasinglulupoll_hold_entry:
80*91f16700Schasinglulu	ldr	x3, [x1, x0, LSL #PLAT_FPGA_HOLD_ENTRY_SHIFT]
81*91f16700Schasinglulu	cmp	x3, #PLAT_FPGA_HOLD_STATE_GO
82*91f16700Schasinglulu	b.ne	1f
83*91f16700Schasinglulu
84*91f16700Schasinglulu	adrp	x2, fpga_sec_entrypoint
85*91f16700Schasinglulu	add	x2, x2, :lo12:fpga_sec_entrypoint
86*91f16700Schasinglulu	ldr	x3, [x2]
87*91f16700Schasinglulu	br	x3
88*91f16700Schasinglulu1:
89*91f16700Schasinglulu	wfe
90*91f16700Schasinglulu	b	poll_hold_entry
91*91f16700Schasinglulu
92*91f16700Schasingluluendfunc plat_secondary_cold_boot_setup
93*91f16700Schasinglulu
94*91f16700Schasinglulu/* -----------------------------------------------------------------------
95*91f16700Schasinglulu * unsigned int plat_is_my_cpu_primary (void);
96*91f16700Schasinglulu *
97*91f16700Schasinglulu * Find out whether the current cpu is the primary cpu
98*91f16700Schasinglulu * -----------------------------------------------------------------------
99*91f16700Schasinglulu */
100*91f16700Schasinglulufunc plat_is_my_cpu_primary
101*91f16700Schasinglulu	mrs	x0, mpidr_el1
102*91f16700Schasinglulu	mov_imm	x1, MPIDR_AFFINITY_MASK
103*91f16700Schasinglulu	and	x0, x0, x1
104*91f16700Schasinglulu	cmp	x0, #FPGA_PRIMARY_CPU
105*91f16700Schasinglulu	cset	w0, eq
106*91f16700Schasinglulu	ret
107*91f16700Schasingluluendfunc plat_is_my_cpu_primary
108*91f16700Schasinglulu
109*91f16700Schasinglulufunc platform_mem_init
110*91f16700Schasinglulu	ret
111*91f16700Schasingluluendfunc platform_mem_init
112*91f16700Schasinglulu
113*91f16700Schasinglulufunc plat_my_core_pos
114*91f16700Schasinglulu	ldr	x1, =(MPID_MASK & ~(MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT))
115*91f16700Schasinglulu	mrs	x0, mpidr_el1
116*91f16700Schasinglulu	and	x0, x0, x1
117*91f16700Schasinglulu	b	plat_fpga_calc_core_pos
118*91f16700Schasinglulu
119*91f16700Schasingluluendfunc plat_my_core_pos
120*91f16700Schasinglulu
121*91f16700Schasinglulu/* -----------------------------------------------------------------------
122*91f16700Schasinglulu * unsigned int plat_fpga_calc_core_pos (uint32_t mpid)
123*91f16700Schasinglulu * Clobber registers: x0 to x5
124*91f16700Schasinglulu * -----------------------------------------------------------------------
125*91f16700Schasinglulu */
126*91f16700Schasinglulufunc plat_fpga_calc_core_pos
127*91f16700Schasinglulu	/*
128*91f16700Schasinglulu	 * Check for MT bit in MPIDR, which may be either value for images
129*91f16700Schasinglulu	 * running on the FPGA.
130*91f16700Schasinglulu	 *
131*91f16700Schasinglulu	 * If not set, shift MPIDR to left to make it look as if in a
132*91f16700Schasinglulu	 * multi-threaded implementation.
133*91f16700Schasinglulu	 *
134*91f16700Schasinglulu	 */
135*91f16700Schasinglulu	tst	x0, #MPIDR_MT_MASK
136*91f16700Schasinglulu	lsl	x3, x0, #MPIDR_AFFINITY_BITS
137*91f16700Schasinglulu	csel	x3, x3, x0, eq
138*91f16700Schasinglulu
139*91f16700Schasinglulu	/* Extract individual affinity fields from MPIDR */
140*91f16700Schasinglulu	ubfx	x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
141*91f16700Schasinglulu	ubfx	x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
142*91f16700Schasinglulu	ubfx	x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
143*91f16700Schasinglulu
144*91f16700Schasinglulu	mov	x4, #FPGA_MAX_CPUS_PER_CLUSTER
145*91f16700Schasinglulu	mov	x5, #FPGA_MAX_PE_PER_CPU
146*91f16700Schasinglulu
147*91f16700Schasinglulu	/* Compute linear position */
148*91f16700Schasinglulu	madd	x1, x2, x4, x1
149*91f16700Schasinglulu	madd	x0, x1, x5, x0
150*91f16700Schasinglulu
151*91f16700Schasinglulu	ret
152*91f16700Schasingluluendfunc plat_fpga_calc_core_pos
153*91f16700Schasinglulu
154*91f16700Schasinglulufunc plat_crash_console_init
155*91f16700Schasinglulu	mov_imm	x0, PLAT_FPGA_CRASH_UART_BASE
156*91f16700Schasinglulu	b	console_pl011_core_init
157*91f16700Schasingluluendfunc plat_crash_console_init
158*91f16700Schasinglulu
159*91f16700Schasinglulufunc plat_crash_console_putc
160*91f16700Schasinglulu	mov_imm	x1, PLAT_FPGA_CRASH_UART_BASE
161*91f16700Schasinglulu	b	console_pl011_core_putc
162*91f16700Schasingluluendfunc plat_crash_console_putc
163*91f16700Schasinglulu
164*91f16700Schasinglulufunc plat_crash_console_flush
165*91f16700Schasinglulu	mov_imm	x0, PLAT_FPGA_CRASH_UART_BASE
166*91f16700Schasinglulu	b	console_pl011_core_flush
167*91f16700Schasingluluendfunc plat_crash_console_flush
168