blob: 1846b91739c1cafebc0b9a09239c02fdac189a32 [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef __PLAT_TOPOLOGY_H__
8#define __PLAT_TOPOLOGY_H__
9
10#include <arch.h>
11#include <platform_def.h>
12#include <stdint.h>
13
14/*
15 * This is the initial value of the power domain index when used
16 * as argument to the tftf topology helpers. They are also used
17 * to indicate the end of iterative topology navigation when returned
18 * by the tftf topology helpers.
19 */
20#define PWR_DOMAIN_INIT ((unsigned int) -1)
21
22/*
23 * Return the total number of clusters in the system.
24 * Currently there is correspondence between power level and affinity
25 * level and hence cluster power level corresponds to affinity level 1.
26 */
27#define tftf_get_total_clusters_count() tftf_get_total_aff_count(1)
28
29/*
30 * Return the total number of CPUs in the system (across all clusters).
31 * Currently there is correspondence between power level and affinity
32 * level and hence CPU power level correspond to affinity level 0.
33 */
34#define tftf_get_total_cpus_count() tftf_get_total_aff_count(0)
35
36/*
37 * Converts a 'core_pos' into an MPIDR. The 'core_pos' is a unique number
38 * corresponding to a CPU as returned by platform_get_core_pos() API
39 */
40#define tftf_core_pos_to_mpidr(core_pos) \
41 tftf_get_mpidr_from_node(core_pos + tftf_pwr_domain_start_idx[0])
42
43/*
44 * The following array stores the start index of each level in the power
45 * domain topology tree.
46 */
47extern unsigned int tftf_pwr_domain_start_idx[PLATFORM_MAX_AFFLVL + 1];
48
49/*
50 * The following data structure represents a TFTF power domain node.
51 */
52typedef struct tftf_pwr_domain_node {
53 /*
54 * Array index of the first CPU in the topology array for which this
55 * power domain is the parent. If this power domain is a CPU, then
56 * `cpu_start_node` will be its own index in the power domain
57 * topology array.
58 */
59 unsigned int cpu_start_node;
60
61 /*
62 * Number of CPU power domains which belong to this power domain.
63 * i.e. all the CPUs in the range 'cpu_start_node
64 * -> cpu_start_node + ncpus - 1 ' will belong to this power domain.
65 * If this power domain is a CPU then 'ncpus' will be 1.
66 */
67 unsigned int ncpus;
68
69 /* Valid only for CPU power domains */
70 unsigned int mpidr;
71
72 /* Index of the parent power domain node */
73 unsigned int parent_node;
74
75 /*
76 * The level of this power domain node in the power domain topology
77 * tree. It could correspond to the affinity level but the platform
78 * could have power levels which do not match affinity levels.
79 */
80 unsigned int level;
81
82 /*
83 * The 'is_present' field is used to cater for power domains
84 * which are absent.
85 */
86 unsigned char is_present;
87} tftf_pwr_domain_node_t;
88
89/*
90 * Detect and store the platform topology so that test cases can query it later.
91 */
92void tftf_init_topology(void);
93
94/*
95 * Return the number of affinity instances implemented at the affinity level
96 * passed as an argument. This function returns 0 for any other affinity
97 * level higher than that supported by the platform.
98 */
99unsigned int tftf_get_total_aff_count(unsigned int aff_lvl);
100
101/*
102 * Returns the index of the next power domain after `pwr_domain_idx`
103 * in the topology tree at the same `aff_lvl`. The `pwr_domain_idx`
104 * has to be initialized to PWR_DOMAIN_INIT to get the first entry.
105 * It returns PWR_DOMAIN_INIT if none is found.
106 */
107unsigned int tftf_get_next_peer_domain(unsigned int pwr_domain_idx,
108 unsigned int pwr_lvl);
109
110/*
111 * Returns the index of the next CPU after the current CPU `cpu_node`
112 * which belongs to the power domain `pwr_domain_idx`. The `cpu_node`
113 * has to be initialized to PWR_DOMAIN_INIT to get the first entry.
114 * It returns PWR_DOMAIN_INIT if none is found.
115 */
116unsigned int tftf_get_next_cpu_in_pwr_domain(unsigned int pwr_domain_idx,
117 unsigned int cpu_node);
118
119/*
120 * Return the node index of the next CPU after 'cpu_node' in the topology tree.
121 * Skip absent CPUs.
122 * cpu_node: Node index of the current CPU.
123 */
124unsigned int tftf_topology_next_cpu(unsigned int cpu_node);
125
126/*
127 * Iterate over every CPU. Skip absent CPUs.
128 * cpu: unsigned integer corresponding to the index of the cpu in
129 * the topology array. After the loop, cpu is equal to PWR_DOMAIN_INIT.
130 */
131#define for_each_cpu(cpu) \
132 for ((cpu) = PWR_DOMAIN_INIT; \
133 (cpu) = tftf_topology_next_cpu(cpu), \
134 (cpu) != PWR_DOMAIN_INIT;)
135
136/*
137 * Iterate over every power domain idx for a given level.
138 * - idx: unsigned integer corresponding to the power domain index. After the
139 * loop, idx is equal to PWR_DOMAIN_INIT.
140 * - lvl: level
141 */
142#define for_each_power_domain_idx(idx, lvl) \
143 for (idx = PWR_DOMAIN_INIT; \
144 idx = tftf_get_next_peer_domain(idx, lvl), \
145 idx != PWR_DOMAIN_INIT;)
146
147/*
148 * Iterate over every CPU in a power domain idx.
149 * - pwr_domain_idx: unsigned integer corresponding to the power domain index.
150 * After the loop, idx is equal to PWR_DOMAIN_INIT.
151 * - cpu_idx: CPU index
152 */
153#define for_each_cpu_in_power_domain(pwr_domain_idx, cpu_idx) \
154 for (cpu_idx = PWR_DOMAIN_INIT; \
155 cpu_idx = tftf_get_next_cpu_in_pwr_domain(pwr_domain_idx, cpu_idx),\
156 cpu_idx != PWR_DOMAIN_INIT;)
157
158/*
159 * Returns the MPIDR of the CPU power domain node indexed by `cpu_node`
160 * or INVALID_MPID if it is absent.
161 */
162unsigned int tftf_get_mpidr_from_node(unsigned int cpu_node);
163
164/*
165 * Query the platform topology to find another CPU than the one specified
166 * as an argument.
167 * Return the MPID of this other CPU, or INVALID_MPID if none could be found.
168 */
169unsigned int tftf_find_any_cpu_other_than(unsigned int exclude_mpid);
170
171/*
172 * Query the platform topology to find a random CPU other than the one specified
173 * as an argument.
174 * The difference between this function and tftf_find_any_cpu_other_than is
175 * the randomness in selecting a CPU.
176 * Return the MPID of this other CPU, or INVALID_MPID if none could be found.
177 */
178unsigned int tftf_find_random_cpu_other_than(unsigned int exclude_mpid);
179
180#endif /* __PLAT_TOPOLOGY_H__ */