xref: /rk3399_ARM-atf/plat/amd/versal2/aarch64/helpers.S (revision 744b070b49bb804893a77742b1aa386b830ed498)
1/*
2 * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
3 * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
4 * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9#include <arch.h>
10#include <asm_macros.S>
11#include <drivers/arm/gicv3.h>
12
13#include <platform_def.h>
14
15	.globl	plat_secondary_cold_boot_setup
16	.globl	plat_is_my_cpu_primary
17	.globl	platform_mem_init
18	.globl	plat_my_core_pos
19	.globl	plat_core_pos_by_mpidr
20	.extern plat_primary_cpu_core
21
22	/* -----------------------------------------------------
23	 * void plat_secondary_cold_boot_setup (void);
24	 *
25	 * This function performs any platform specific actions
26	 * needed for a secondary cpu after a cold reset e.g
27	 * mark the cpu's presence, mechanism to place it in a
28	 * holding pen etc.
29	 * TODO: Should we read the PSYS register to make sure
30	 * that the request has gone through.
31	 * -----------------------------------------------------
32	 */
33func plat_secondary_cold_boot_setup
34	mrs	x0, mpidr_el1
35
36	/*
37	 * There is no sane reason to come out of this wfi. This
38	 * cpu will be powered on and reset by the cpu_on pm api
39	 */
40	dsb	sy
41	bl	plat_panic_handler
42endfunc plat_secondary_cold_boot_setup
43
44func plat_is_my_cpu_primary
45	mov	x9, x30
46	bl	plat_my_core_pos
47
48	/* Load address of var into x2. */
49	ldr	x2, =plat_primary_cpu_core
50	/* Load var value into x3 */
51	ldr	w3, [x2]
52	mov	w4, #PLAT_INVALID_CPU_CORE
53	cmp	w3, w4
54	/* On first instance (as it equals) primary core pos is updated. */
55	b.ne	skip_var_update
56
57	str     w0, [x2]
58	mov	x3, x0
59
60skip_var_update:
61	cmp	x0, x3
62	cset	x0, eq
63	ret	x9
64endfunc plat_is_my_cpu_primary
65
66	/* -----------------------------------------------------
67	 *  unsigned int plat_my_core_pos(void)
68	 *  This function uses the plat_core_pos_by_mpidr()
69	 *  definition to get the index of the calling CPU.
70	 * -----------------------------------------------------
71	 */
72func plat_my_core_pos
73	mrs	x0, mpidr_el1
74	b	plat_core_pos_by_mpidr
75endfunc plat_my_core_pos
76
77       /*----------------------------------------------------------------------
78	* unsigned int plat_core_pos_by_mpidr(u_register_t mpid)
79	*
80	* Function to calculate the core position
81	*
82	* clobbers: x0 - x3
83	* ---------------------------------------------------------------------
84	*/
85func plat_core_pos_by_mpidr
86
87	/* Extract individual affinity fields from MPIDR */
88	ubfx	x1, x0, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
89	ubfx	x2, x0, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
90
91	/* check if cpu_id valid */
92	cmp     x2, #PLATFORM_CORE_COUNT_PER_CLUSTER
93	b.hi    error_invalid_core
94
95	/* check if cluster valid */
96	cmp	x1, #PLATFORM_CLUSTER_COUNT
97	b.hi    error_invalid_cluster
98
99	/* Compute linear position */
100	mov	x3, #PLATFORM_CORE_COUNT_PER_CLUSTER
101	madd	x0, x1, x3, x2
102	ret
103error_invalid_cluster:
104	mov     x0, #E_INVALID_CLUSTER_COUNT
105	ret
106error_invalid_core:
107        mov     x0, #E_INVALID_CORE_COUNT
108        ret
109endfunc plat_core_pos_by_mpidr
110
111	/* ---------------------------------------------------------------------
112	 * We don't need to carry out any memory initialization on platform
113	 * The Secure RAM is accessible straight away.
114	 * ---------------------------------------------------------------------
115	 */
116func platform_mem_init
117	ret
118endfunc platform_mem_init
119