xref: /arm-trusted-firmware/plat/arm/board/a5ds/aarch32/a5ds_helpers.S (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu/*
2*91f16700Schasinglulu * Copyright (c) 2019, Arm Limited. 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 <platform_def.h>
10*91f16700Schasinglulu
11*91f16700Schasinglulu	.globl	plat_secondary_cold_boot_setup
12*91f16700Schasinglulu	.globl	plat_get_my_entrypoint
13*91f16700Schasinglulu	.globl	plat_is_my_cpu_primary
14*91f16700Schasinglulu
15*91f16700Schasinglulu	/* -----------------------------------------------------
16*91f16700Schasinglulu	 * void plat_secondary_cold_boot_setup (void);
17*91f16700Schasinglulu	 *
18*91f16700Schasinglulu	 * This function performs any platform specific actions
19*91f16700Schasinglulu	 * needed for a secondary cpu after a cold reset e.g
20*91f16700Schasinglulu	 * mark the cpu's presence, mechanism to place it in a
21*91f16700Schasinglulu	 * holding pen etc.
22*91f16700Schasinglulu	 * -----------------------------------------------------
23*91f16700Schasinglulu	 */
24*91f16700Schasinglulufunc plat_secondary_cold_boot_setup
25*91f16700Schasinglulu	/* Calculate address of our hold entry */
26*91f16700Schasinglulu	bl	plat_my_core_pos
27*91f16700Schasinglulu	lsl	r0, r0, #A5DS_HOLD_ENTRY_SHIFT
28*91f16700Schasinglulu	mov_imm	r2, A5DS_HOLD_BASE
29*91f16700Schasinglulu	/* Clear the value stored in the hold address for the specific core */
30*91f16700Schasinglulu	mov_imm	r3, A5DS_HOLD_STATE_WAIT
31*91f16700Schasinglulu	str	r3, [r2, r0]
32*91f16700Schasinglulu	dmb	ish
33*91f16700Schasinglulu
34*91f16700Schasinglulu	/* Wait until we have a go */
35*91f16700Schasinglulupoll_mailbox:
36*91f16700Schasinglulu	ldr	r1, [r2, r0]
37*91f16700Schasinglulu	cmp	r1, #A5DS_HOLD_STATE_WAIT
38*91f16700Schasinglulu	beq	1f
39*91f16700Schasinglulu	mov_imm	r0, A5DS_TRUSTED_MAILBOX_BASE
40*91f16700Schasinglulu	ldr	r1, [r0]
41*91f16700Schasinglulu	bx	r1
42*91f16700Schasinglulu1:
43*91f16700Schasinglulu	wfe
44*91f16700Schasinglulu	b	poll_mailbox
45*91f16700Schasingluluendfunc plat_secondary_cold_boot_setup
46*91f16700Schasinglulu
47*91f16700Schasinglulu	/* ---------------------------------------------------------------------
48*91f16700Schasinglulu	 * unsigned long plat_get_my_entrypoint (void);
49*91f16700Schasinglulu	 *
50*91f16700Schasinglulu	 * Main job of this routine is to distinguish between a cold and warm
51*91f16700Schasinglulu	 * boot.
52*91f16700Schasinglulu	 * ---------------------------------------------------------------------
53*91f16700Schasinglulu	 */
54*91f16700Schasinglulufunc plat_get_my_entrypoint
55*91f16700Schasinglulu	/* TODO support warm boot */
56*91f16700Schasinglulu	/* Cold reset */
57*91f16700Schasinglulu	mov	r0, #0
58*91f16700Schasinglulu	bx	lr
59*91f16700Schasinglulu
60*91f16700Schasingluluendfunc plat_get_my_entrypoint
61*91f16700Schasinglulu
62*91f16700Schasinglulu	/* -----------------------------------------------------
63*91f16700Schasinglulu	 * unsigned int plat_is_my_cpu_primary (void);
64*91f16700Schasinglulu	 *
65*91f16700Schasinglulu	 * Find out whether the current cpu is the primary
66*91f16700Schasinglulu	 * cpu.
67*91f16700Schasinglulu	 * -----------------------------------------------------
68*91f16700Schasinglulu	 */
69*91f16700Schasinglulufunc plat_is_my_cpu_primary
70*91f16700Schasinglulu	ldcopr	r0, MPIDR
71*91f16700Schasinglulu	ldr	r1, =MPIDR_AFFINITY_MASK
72*91f16700Schasinglulu	and	r0, r1
73*91f16700Schasinglulu	cmp	r0, #0
74*91f16700Schasinglulu	moveq	r0, #1
75*91f16700Schasinglulu	movne	r0, #0
76*91f16700Schasinglulu	bx	lr
77*91f16700Schasingluluendfunc plat_is_my_cpu_primary
78*91f16700Schasinglulu
79*91f16700Schasinglulu	/* ---------------------------------------------------------------------
80*91f16700Schasinglulu	 * Loads MPIDR in r0 and calls plat_arm_calc_core_pos
81*91f16700Schasinglulu	 * ---------------------------------------------------------------------
82*91f16700Schasinglulu	 */
83*91f16700Schasinglulufunc plat_my_core_pos
84*91f16700Schasinglulu	ldcopr	r0, MPIDR
85*91f16700Schasinglulu	b	plat_arm_calc_core_pos
86*91f16700Schasinglulu
87*91f16700Schasingluluendfunc plat_my_core_pos
88*91f16700Schasinglulu
89*91f16700Schasinglulu	/* ---------------------------------------------------------------------
90*91f16700Schasinglulu	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
91*91f16700Schasinglulu	 *
92*91f16700Schasinglulu	 * Function to calculate the core position on A5DS.
93*91f16700Schasinglulu	 *
94*91f16700Schasinglulu	 * (ClusterId * A5DS_MAX_CPUS_PER_CLUSTER * A5DS_MAX_PE_PER_CPU) +
95*91f16700Schasinglulu	 * (CPUId * A5DS_MAX_PE_PER_CPU) +
96*91f16700Schasinglulu	 * ThreadId
97*91f16700Schasinglulu	 *
98*91f16700Schasinglulu	 * which can be simplified as:
99*91f16700Schasinglulu	 *
100*91f16700Schasinglulu	 * ((ClusterId * A5DS_MAX_CPUS_PER_CLUSTER + CPUId) * A5DS_MAX_PE_PER_CPU)
101*91f16700Schasinglulu	 * + ThreadId
102*91f16700Schasinglulu	 * ---------------------------------------------------------------------
103*91f16700Schasinglulu	 */
104*91f16700Schasinglulufunc plat_arm_calc_core_pos
105*91f16700Schasinglulu	mov	r3, r0
106*91f16700Schasinglulu
107*91f16700Schasinglulu	/*
108*91f16700Schasinglulu	 * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
109*91f16700Schasinglulu	 * look as if in a multi-threaded implementation
110*91f16700Schasinglulu	 */
111*91f16700Schasinglulu	tst	r0, #MPIDR_MT_MASK
112*91f16700Schasinglulu	lsleq	r3, r0, #MPIDR_AFFINITY_BITS
113*91f16700Schasinglulu
114*91f16700Schasinglulu	/* Extract individual affinity fields from MPIDR */
115*91f16700Schasinglulu	ubfx	r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
116*91f16700Schasinglulu	ubfx	r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
117*91f16700Schasinglulu	ubfx	r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
118*91f16700Schasinglulu
119*91f16700Schasinglulu	/* Compute linear position */
120*91f16700Schasinglulu	mov	r3, #A5DS_MAX_CPUS_PER_CLUSTER
121*91f16700Schasinglulu	mla	r1, r2, r3, r1
122*91f16700Schasinglulu	mov	r3, #A5DS_MAX_PE_PER_CPU
123*91f16700Schasinglulu	mla	r0, r1, r3, r0
124*91f16700Schasinglulu
125*91f16700Schasinglulu	bx	lr
126*91f16700Schasingluluendfunc plat_arm_calc_core_pos
127