xref: /arm-trusted-firmware/lib/extensions/amu/aarch32/amu.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <cdefs.h>
9*91f16700Schasinglulu #include <stdbool.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include "../amu_private.h"
12*91f16700Schasinglulu #include <arch.h>
13*91f16700Schasinglulu #include <arch_features.h>
14*91f16700Schasinglulu #include <arch_helpers.h>
15*91f16700Schasinglulu #include <common/debug.h>
16*91f16700Schasinglulu #include <lib/el3_runtime/pubsub_events.h>
17*91f16700Schasinglulu #include <lib/extensions/amu.h>
18*91f16700Schasinglulu 
19*91f16700Schasinglulu #include <plat/common/platform.h>
20*91f16700Schasinglulu 
21*91f16700Schasinglulu struct amu_ctx {
22*91f16700Schasinglulu 	uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS];
23*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
24*91f16700Schasinglulu 	uint64_t group1_cnts[AMU_GROUP1_MAX_COUNTERS];
25*91f16700Schasinglulu #endif
26*91f16700Schasinglulu 
27*91f16700Schasinglulu 	uint16_t group0_enable;
28*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
29*91f16700Schasinglulu 	uint16_t group1_enable;
30*91f16700Schasinglulu #endif
31*91f16700Schasinglulu };
32*91f16700Schasinglulu 
33*91f16700Schasinglulu static struct amu_ctx amu_ctxs_[PLATFORM_CORE_COUNT];
34*91f16700Schasinglulu 
35*91f16700Schasinglulu CASSERT((sizeof(amu_ctxs_[0].group0_enable) * CHAR_BIT) <= AMU_GROUP0_MAX_COUNTERS,
36*91f16700Schasinglulu 	amu_ctx_group0_enable_cannot_represent_all_group0_counters);
37*91f16700Schasinglulu 
38*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
39*91f16700Schasinglulu CASSERT((sizeof(amu_ctxs_[0].group1_enable) * CHAR_BIT) <= AMU_GROUP1_MAX_COUNTERS,
40*91f16700Schasinglulu 	amu_ctx_group1_enable_cannot_represent_all_group1_counters);
41*91f16700Schasinglulu #endif
42*91f16700Schasinglulu 
43*91f16700Schasinglulu static inline __unused void write_hcptr_tam(uint32_t value)
44*91f16700Schasinglulu {
45*91f16700Schasinglulu 	write_hcptr((read_hcptr() & ~TAM_BIT) |
46*91f16700Schasinglulu 		((value << TAM_SHIFT) & TAM_BIT));
47*91f16700Schasinglulu }
48*91f16700Schasinglulu 
49*91f16700Schasinglulu static inline __unused void write_amcr_cg1rz(uint32_t value)
50*91f16700Schasinglulu {
51*91f16700Schasinglulu 	write_amcr((read_amcr() & ~AMCR_CG1RZ_BIT) |
52*91f16700Schasinglulu 		((value << AMCR_CG1RZ_SHIFT) & AMCR_CG1RZ_BIT));
53*91f16700Schasinglulu }
54*91f16700Schasinglulu 
55*91f16700Schasinglulu static inline __unused uint32_t read_amcfgr_ncg(void)
56*91f16700Schasinglulu {
57*91f16700Schasinglulu 	return (read_amcfgr() >> AMCFGR_NCG_SHIFT) &
58*91f16700Schasinglulu 		AMCFGR_NCG_MASK;
59*91f16700Schasinglulu }
60*91f16700Schasinglulu 
61*91f16700Schasinglulu static inline __unused uint32_t read_amcgcr_cg0nc(void)
62*91f16700Schasinglulu {
63*91f16700Schasinglulu 	return (read_amcgcr() >> AMCGCR_CG0NC_SHIFT) &
64*91f16700Schasinglulu 		AMCGCR_CG0NC_MASK;
65*91f16700Schasinglulu }
66*91f16700Schasinglulu 
67*91f16700Schasinglulu static inline __unused uint32_t read_amcgcr_cg1nc(void)
68*91f16700Schasinglulu {
69*91f16700Schasinglulu 	return (read_amcgcr() >> AMCGCR_CG1NC_SHIFT) &
70*91f16700Schasinglulu 		AMCGCR_CG1NC_MASK;
71*91f16700Schasinglulu }
72*91f16700Schasinglulu 
73*91f16700Schasinglulu static inline __unused uint32_t read_amcntenset0_px(void)
74*91f16700Schasinglulu {
75*91f16700Schasinglulu 	return (read_amcntenset0() >> AMCNTENSET0_Pn_SHIFT) &
76*91f16700Schasinglulu 		AMCNTENSET0_Pn_MASK;
77*91f16700Schasinglulu }
78*91f16700Schasinglulu 
79*91f16700Schasinglulu static inline __unused uint32_t read_amcntenset1_px(void)
80*91f16700Schasinglulu {
81*91f16700Schasinglulu 	return (read_amcntenset1() >> AMCNTENSET1_Pn_SHIFT) &
82*91f16700Schasinglulu 		AMCNTENSET1_Pn_MASK;
83*91f16700Schasinglulu }
84*91f16700Schasinglulu 
85*91f16700Schasinglulu static inline __unused void write_amcntenset0_px(uint32_t px)
86*91f16700Schasinglulu {
87*91f16700Schasinglulu 	uint32_t value = read_amcntenset0();
88*91f16700Schasinglulu 
89*91f16700Schasinglulu 	value &= ~AMCNTENSET0_Pn_MASK;
90*91f16700Schasinglulu 	value |= (px << AMCNTENSET0_Pn_SHIFT) &
91*91f16700Schasinglulu 		AMCNTENSET0_Pn_MASK;
92*91f16700Schasinglulu 
93*91f16700Schasinglulu 	write_amcntenset0(value);
94*91f16700Schasinglulu }
95*91f16700Schasinglulu 
96*91f16700Schasinglulu static inline __unused void write_amcntenset1_px(uint32_t px)
97*91f16700Schasinglulu {
98*91f16700Schasinglulu 	uint32_t value = read_amcntenset1();
99*91f16700Schasinglulu 
100*91f16700Schasinglulu 	value &= ~AMCNTENSET1_Pn_MASK;
101*91f16700Schasinglulu 	value |= (px << AMCNTENSET1_Pn_SHIFT) &
102*91f16700Schasinglulu 		AMCNTENSET1_Pn_MASK;
103*91f16700Schasinglulu 
104*91f16700Schasinglulu 	write_amcntenset1(value);
105*91f16700Schasinglulu }
106*91f16700Schasinglulu 
107*91f16700Schasinglulu static inline __unused void write_amcntenclr0_px(uint32_t px)
108*91f16700Schasinglulu {
109*91f16700Schasinglulu 	uint32_t value = read_amcntenclr0();
110*91f16700Schasinglulu 
111*91f16700Schasinglulu 	value &= ~AMCNTENCLR0_Pn_MASK;
112*91f16700Schasinglulu 	value |= (px << AMCNTENCLR0_Pn_SHIFT) & AMCNTENCLR0_Pn_MASK;
113*91f16700Schasinglulu 
114*91f16700Schasinglulu 	write_amcntenclr0(value);
115*91f16700Schasinglulu }
116*91f16700Schasinglulu 
117*91f16700Schasinglulu static inline __unused void write_amcntenclr1_px(uint32_t px)
118*91f16700Schasinglulu {
119*91f16700Schasinglulu 	uint32_t value = read_amcntenclr1();
120*91f16700Schasinglulu 
121*91f16700Schasinglulu 	value &= ~AMCNTENCLR1_Pn_MASK;
122*91f16700Schasinglulu 	value |= (px << AMCNTENCLR1_Pn_SHIFT) & AMCNTENCLR1_Pn_MASK;
123*91f16700Schasinglulu 
124*91f16700Schasinglulu 	write_amcntenclr1(value);
125*91f16700Schasinglulu }
126*91f16700Schasinglulu 
127*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
128*91f16700Schasinglulu static __unused bool amu_group1_supported(void)
129*91f16700Schasinglulu {
130*91f16700Schasinglulu 	return read_amcfgr_ncg() > 0U;
131*91f16700Schasinglulu }
132*91f16700Schasinglulu #endif
133*91f16700Schasinglulu 
134*91f16700Schasinglulu /*
135*91f16700Schasinglulu  * Enable counters. This function is meant to be invoked by the context
136*91f16700Schasinglulu  * management library before exiting from EL3.
137*91f16700Schasinglulu  */
138*91f16700Schasinglulu void amu_enable(bool el2_unused)
139*91f16700Schasinglulu {
140*91f16700Schasinglulu 	uint32_t amcfgr_ncg;		/* Number of counter groups */
141*91f16700Schasinglulu 	uint32_t amcgcr_cg0nc;		/* Number of group 0 counters */
142*91f16700Schasinglulu 
143*91f16700Schasinglulu 	uint32_t amcntenset0_px = 0x0;	/* Group 0 enable mask */
144*91f16700Schasinglulu 	uint32_t amcntenset1_px = 0x0;	/* Group 1 enable mask */
145*91f16700Schasinglulu 
146*91f16700Schasinglulu 	if (el2_unused) {
147*91f16700Schasinglulu 		/*
148*91f16700Schasinglulu 		 * HCPTR.TAM: Set to zero so any accesses to the Activity
149*91f16700Schasinglulu 		 * Monitor registers do not trap to EL2.
150*91f16700Schasinglulu 		 */
151*91f16700Schasinglulu 		write_hcptr_tam(0U);
152*91f16700Schasinglulu 	}
153*91f16700Schasinglulu 
154*91f16700Schasinglulu 	/*
155*91f16700Schasinglulu 	 * Retrieve the number of architected counters. All of these counters
156*91f16700Schasinglulu 	 * are enabled by default.
157*91f16700Schasinglulu 	 */
158*91f16700Schasinglulu 
159*91f16700Schasinglulu 	amcgcr_cg0nc = read_amcgcr_cg0nc();
160*91f16700Schasinglulu 	amcntenset0_px = (UINT32_C(1) << (amcgcr_cg0nc)) - 1U;
161*91f16700Schasinglulu 
162*91f16700Schasinglulu 	assert(amcgcr_cg0nc <= AMU_AMCGCR_CG0NC_MAX);
163*91f16700Schasinglulu 
164*91f16700Schasinglulu 	/*
165*91f16700Schasinglulu 	 * The platform may opt to enable specific auxiliary counters. This can
166*91f16700Schasinglulu 	 * be done via the common FCONF getter, or via the platform-implemented
167*91f16700Schasinglulu 	 * function.
168*91f16700Schasinglulu 	 */
169*91f16700Schasinglulu 
170*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
171*91f16700Schasinglulu 	const struct amu_topology *topology;
172*91f16700Schasinglulu 
173*91f16700Schasinglulu #if ENABLE_AMU_FCONF
174*91f16700Schasinglulu 	topology = FCONF_GET_PROPERTY(amu, config, topology);
175*91f16700Schasinglulu #else
176*91f16700Schasinglulu 	topology = plat_amu_topology();
177*91f16700Schasinglulu #endif /* ENABLE_AMU_FCONF */
178*91f16700Schasinglulu 
179*91f16700Schasinglulu 	if (topology != NULL) {
180*91f16700Schasinglulu 		unsigned int core_pos = plat_my_core_pos();
181*91f16700Schasinglulu 
182*91f16700Schasinglulu 		amcntenset1_el0_px = topology->cores[core_pos].enable;
183*91f16700Schasinglulu 	} else {
184*91f16700Schasinglulu 		ERROR("AMU: failed to generate AMU topology\n");
185*91f16700Schasinglulu 	}
186*91f16700Schasinglulu #endif /* ENABLE_AMU_AUXILIARY_COUNTERS */
187*91f16700Schasinglulu 
188*91f16700Schasinglulu 	/*
189*91f16700Schasinglulu 	 * Enable the requested counters.
190*91f16700Schasinglulu 	 */
191*91f16700Schasinglulu 
192*91f16700Schasinglulu 	write_amcntenset0_px(amcntenset0_px);
193*91f16700Schasinglulu 
194*91f16700Schasinglulu 	amcfgr_ncg = read_amcfgr_ncg();
195*91f16700Schasinglulu 	if (amcfgr_ncg > 0U) {
196*91f16700Schasinglulu 		write_amcntenset1_px(amcntenset1_px);
197*91f16700Schasinglulu 
198*91f16700Schasinglulu #if !ENABLE_AMU_AUXILIARY_COUNTERS
199*91f16700Schasinglulu 		VERBOSE("AMU: auxiliary counters detected but support is disabled\n");
200*91f16700Schasinglulu #endif
201*91f16700Schasinglulu 	}
202*91f16700Schasinglulu 
203*91f16700Schasinglulu 	/* Bail out if FEAT_AMUv1p1 features are not present. */
204*91f16700Schasinglulu 	if (!is_feat_amuv1p1_supported()) {
205*91f16700Schasinglulu 		return;
206*91f16700Schasinglulu 	}
207*91f16700Schasinglulu 
208*91f16700Schasinglulu #if AMU_RESTRICT_COUNTERS
209*91f16700Schasinglulu 	/*
210*91f16700Schasinglulu 	 * FEAT_AMUv1p1 adds a register field to restrict access to group 1
211*91f16700Schasinglulu 	 * counters at all but the highest implemented EL.  This is controlled
212*91f16700Schasinglulu 	 * with the AMU_RESTRICT_COUNTERS compile time flag, when set, system
213*91f16700Schasinglulu 	 * register reads at lower ELs return zero.  Reads from the memory
214*91f16700Schasinglulu 	 * mapped view are unaffected.
215*91f16700Schasinglulu 	 */
216*91f16700Schasinglulu 	VERBOSE("AMU group 1 counter access restricted.\n");
217*91f16700Schasinglulu 	write_amcr_cg1rz(1U);
218*91f16700Schasinglulu #else
219*91f16700Schasinglulu 	write_amcr_cg1rz(0U);
220*91f16700Schasinglulu #endif
221*91f16700Schasinglulu }
222*91f16700Schasinglulu 
223*91f16700Schasinglulu /* Read the group 0 counter identified by the given `idx`. */
224*91f16700Schasinglulu static uint64_t amu_group0_cnt_read(unsigned int idx)
225*91f16700Schasinglulu {
226*91f16700Schasinglulu 	assert(is_feat_amu_supported());
227*91f16700Schasinglulu 	assert(idx < read_amcgcr_cg0nc());
228*91f16700Schasinglulu 
229*91f16700Schasinglulu 	return amu_group0_cnt_read_internal(idx);
230*91f16700Schasinglulu }
231*91f16700Schasinglulu 
232*91f16700Schasinglulu /* Write the group 0 counter identified by the given `idx` with `val` */
233*91f16700Schasinglulu static void amu_group0_cnt_write(unsigned  int idx, uint64_t val)
234*91f16700Schasinglulu {
235*91f16700Schasinglulu 	assert(is_feat_amu_supported());
236*91f16700Schasinglulu 	assert(idx < read_amcgcr_cg0nc());
237*91f16700Schasinglulu 
238*91f16700Schasinglulu 	amu_group0_cnt_write_internal(idx, val);
239*91f16700Schasinglulu 	isb();
240*91f16700Schasinglulu }
241*91f16700Schasinglulu 
242*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
243*91f16700Schasinglulu /* Read the group 1 counter identified by the given `idx` */
244*91f16700Schasinglulu static uint64_t amu_group1_cnt_read(unsigned  int idx)
245*91f16700Schasinglulu {
246*91f16700Schasinglulu 	assert(is_feat_amu_supported());
247*91f16700Schasinglulu 	assert(amu_group1_supported());
248*91f16700Schasinglulu 	assert(idx < read_amcgcr_cg1nc());
249*91f16700Schasinglulu 
250*91f16700Schasinglulu 	return amu_group1_cnt_read_internal(idx);
251*91f16700Schasinglulu }
252*91f16700Schasinglulu 
253*91f16700Schasinglulu /* Write the group 1 counter identified by the given `idx` with `val` */
254*91f16700Schasinglulu static void amu_group1_cnt_write(unsigned  int idx, uint64_t val)
255*91f16700Schasinglulu {
256*91f16700Schasinglulu 	assert(is_feat_amu_supported());
257*91f16700Schasinglulu 	assert(amu_group1_supported());
258*91f16700Schasinglulu 	assert(idx < read_amcgcr_cg1nc());
259*91f16700Schasinglulu 
260*91f16700Schasinglulu 	amu_group1_cnt_write_internal(idx, val);
261*91f16700Schasinglulu 	isb();
262*91f16700Schasinglulu }
263*91f16700Schasinglulu #endif
264*91f16700Schasinglulu 
265*91f16700Schasinglulu static void *amu_context_save(const void *arg)
266*91f16700Schasinglulu {
267*91f16700Schasinglulu 	uint32_t i;
268*91f16700Schasinglulu 
269*91f16700Schasinglulu 	unsigned int core_pos;
270*91f16700Schasinglulu 	struct amu_ctx *ctx;
271*91f16700Schasinglulu 
272*91f16700Schasinglulu 	uint32_t amcgcr_cg0nc;	/* Number of group 0 counters */
273*91f16700Schasinglulu 
274*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
275*91f16700Schasinglulu 	uint32_t amcfgr_ncg;	/* Number of counter groups */
276*91f16700Schasinglulu 	uint32_t amcgcr_cg1nc;	/* Number of group 1 counters */
277*91f16700Schasinglulu #endif
278*91f16700Schasinglulu 
279*91f16700Schasinglulu 	if (!is_feat_amu_supported()) {
280*91f16700Schasinglulu 		return (void *)0;
281*91f16700Schasinglulu 	}
282*91f16700Schasinglulu 
283*91f16700Schasinglulu 	core_pos = plat_my_core_pos();
284*91f16700Schasinglulu 	ctx = &amu_ctxs_[core_pos];
285*91f16700Schasinglulu 
286*91f16700Schasinglulu 	amcgcr_cg0nc = read_amcgcr_cg0nc();
287*91f16700Schasinglulu 
288*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
289*91f16700Schasinglulu 	amcfgr_ncg = read_amcfgr_ncg();
290*91f16700Schasinglulu 	amcgcr_cg1nc = (amcfgr_ncg > 0U) ? read_amcgcr_cg1nc() : 0U;
291*91f16700Schasinglulu #endif
292*91f16700Schasinglulu 
293*91f16700Schasinglulu 	/*
294*91f16700Schasinglulu 	 * Disable all AMU counters.
295*91f16700Schasinglulu 	 */
296*91f16700Schasinglulu 
297*91f16700Schasinglulu 	ctx->group0_enable = read_amcntenset0_px();
298*91f16700Schasinglulu 	write_amcntenclr0_px(ctx->group0_enable);
299*91f16700Schasinglulu 
300*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
301*91f16700Schasinglulu 	if (amcfgr_ncg > 0U) {
302*91f16700Schasinglulu 		ctx->group1_enable = read_amcntenset1_px();
303*91f16700Schasinglulu 		write_amcntenclr1_px(ctx->group1_enable);
304*91f16700Schasinglulu 	}
305*91f16700Schasinglulu #endif
306*91f16700Schasinglulu 
307*91f16700Schasinglulu 	/*
308*91f16700Schasinglulu 	 * Save the counters to the local context.
309*91f16700Schasinglulu 	 */
310*91f16700Schasinglulu 
311*91f16700Schasinglulu 	isb(); /* Ensure counters have been stopped */
312*91f16700Schasinglulu 
313*91f16700Schasinglulu 	for (i = 0U; i < amcgcr_cg0nc; i++) {
314*91f16700Schasinglulu 		ctx->group0_cnts[i] = amu_group0_cnt_read(i);
315*91f16700Schasinglulu 	}
316*91f16700Schasinglulu 
317*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
318*91f16700Schasinglulu 	for (i = 0U; i < amcgcr_cg1nc; i++) {
319*91f16700Schasinglulu 		ctx->group1_cnts[i] = amu_group1_cnt_read(i);
320*91f16700Schasinglulu 	}
321*91f16700Schasinglulu #endif
322*91f16700Schasinglulu 
323*91f16700Schasinglulu 	return (void *)0;
324*91f16700Schasinglulu }
325*91f16700Schasinglulu 
326*91f16700Schasinglulu static void *amu_context_restore(const void *arg)
327*91f16700Schasinglulu {
328*91f16700Schasinglulu 	uint32_t i;
329*91f16700Schasinglulu 
330*91f16700Schasinglulu 	unsigned int core_pos;
331*91f16700Schasinglulu 	struct amu_ctx *ctx;
332*91f16700Schasinglulu 
333*91f16700Schasinglulu 	uint32_t amcfgr_ncg;	/* Number of counter groups */
334*91f16700Schasinglulu 	uint32_t amcgcr_cg0nc;	/* Number of group 0 counters */
335*91f16700Schasinglulu 
336*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
337*91f16700Schasinglulu 	uint32_t amcgcr_cg1nc;	/* Number of group 1 counters */
338*91f16700Schasinglulu #endif
339*91f16700Schasinglulu 
340*91f16700Schasinglulu 	if (!is_feat_amu_supported()) {
341*91f16700Schasinglulu 		return (void *)0;
342*91f16700Schasinglulu 	}
343*91f16700Schasinglulu 
344*91f16700Schasinglulu 	core_pos = plat_my_core_pos();
345*91f16700Schasinglulu 	ctx = &amu_ctxs_[core_pos];
346*91f16700Schasinglulu 
347*91f16700Schasinglulu 	amcfgr_ncg = read_amcfgr_ncg();
348*91f16700Schasinglulu 	amcgcr_cg0nc = read_amcgcr_cg0nc();
349*91f16700Schasinglulu 
350*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
351*91f16700Schasinglulu 	amcgcr_cg1nc = (amcfgr_ncg > 0U) ? read_amcgcr_cg1nc() : 0U;
352*91f16700Schasinglulu #endif
353*91f16700Schasinglulu 
354*91f16700Schasinglulu 	/*
355*91f16700Schasinglulu 	 * Sanity check that all counters were disabled when the context was
356*91f16700Schasinglulu 	 * previously saved.
357*91f16700Schasinglulu 	 */
358*91f16700Schasinglulu 
359*91f16700Schasinglulu 	assert(read_amcntenset0_px() == 0U);
360*91f16700Schasinglulu 
361*91f16700Schasinglulu 	if (amcfgr_ncg > 0U) {
362*91f16700Schasinglulu 		assert(read_amcntenset1_px() == 0U);
363*91f16700Schasinglulu 	}
364*91f16700Schasinglulu 
365*91f16700Schasinglulu 	/*
366*91f16700Schasinglulu 	 * Restore the counter values from the local context.
367*91f16700Schasinglulu 	 */
368*91f16700Schasinglulu 
369*91f16700Schasinglulu 	for (i = 0U; i < amcgcr_cg0nc; i++) {
370*91f16700Schasinglulu 		amu_group0_cnt_write(i, ctx->group0_cnts[i]);
371*91f16700Schasinglulu 	}
372*91f16700Schasinglulu 
373*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
374*91f16700Schasinglulu 	for (i = 0U; i < amcgcr_cg1nc; i++) {
375*91f16700Schasinglulu 		amu_group1_cnt_write(i, ctx->group1_cnts[i]);
376*91f16700Schasinglulu 	}
377*91f16700Schasinglulu #endif
378*91f16700Schasinglulu 
379*91f16700Schasinglulu 	/*
380*91f16700Schasinglulu 	 * Re-enable counters that were disabled during context save.
381*91f16700Schasinglulu 	 */
382*91f16700Schasinglulu 
383*91f16700Schasinglulu 	write_amcntenset0_px(ctx->group0_enable);
384*91f16700Schasinglulu 
385*91f16700Schasinglulu #if ENABLE_AMU_AUXILIARY_COUNTERS
386*91f16700Schasinglulu 	if (amcfgr_ncg > 0U) {
387*91f16700Schasinglulu 		write_amcntenset1_px(ctx->group1_enable);
388*91f16700Schasinglulu 	}
389*91f16700Schasinglulu #endif
390*91f16700Schasinglulu 
391*91f16700Schasinglulu 	return (void *)0;
392*91f16700Schasinglulu }
393*91f16700Schasinglulu 
394*91f16700Schasinglulu SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_start, amu_context_save);
395*91f16700Schasinglulu SUBSCRIBE_TO_EVENT(psci_suspend_pwrdown_finish, amu_context_restore);
396