1 /*
2  * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch.h>
8 #include <debug.h>
9 #include <gic_v3.h>
10 
gicv3_get_rdist(uintptr_t gicr_base,uint64_t mpidr)11 uintptr_t gicv3_get_rdist(uintptr_t gicr_base, uint64_t mpidr)
12 {
13 	uint32_t  cpu_aff, gicr_aff;
14 	uint64_t  gicr_typer;
15 	uintptr_t addr;
16 
17 	/* Construct the affinity as used by GICv3. MPIDR and GIC affinity level
18 	 * mask is the same.
19 	 */
20 	cpu_aff  = ((mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK) <<
21 			GICV3_AFF0_SHIFT;
22 	cpu_aff |= ((mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK) <<
23 			GICV3_AFF1_SHIFT;
24 	cpu_aff |= ((mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK) <<
25 			GICV3_AFF2_SHIFT;
26 	cpu_aff |= ((mpidr >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK) <<
27 			GICV3_AFF3_SHIFT;
28 
29 	addr = gicr_base;
30 	do {
31 		gicr_typer = gicr_read_typer(addr);
32 
33 		gicr_aff = (gicr_typer >> GICR_TYPER_AFF_SHIFT) &
34 				GICR_TYPER_AFF_MASK;
35 		if (cpu_aff == gicr_aff) {
36 			/* Disable this print for now as it appears every time
37 			 * when using PSCI CPU_SUSPEND.
38 			 * TODO: Print this only the first time for each CPU.
39 			 * INFO("GICv3 - Found RDIST for MPIDR(0x%lx) at %p\n",
40 			 *	mpidr, (void *) addr);
41 			 */
42 			return addr;
43 		}
44 
45 		/* TODO:
46 		 * For GICv4 we need to adjust the Base address based on
47 		 * GICR_TYPER.VLPIS
48 		 */
49 		addr += (1 << GICR_PCPUBASE_SHIFT);
50 
51 	} while (!(gicr_typer & GICR_TYPER_LAST));
52 
53 	/* If we get here we did not find a match. */
54 	ERROR("GICv3 - Did not find RDIST for CPU with MPIDR 0x%lx\n", mpidr);
55 	return (uintptr_t)NULL;
56 }
57