xref: /rk3399_ARM-atf/include/lib/pmf/pmf_helpers.h (revision 4c700c1563aff7b51df95f17e952e050b9b4e37f)
1afdda571Sdp-arm /*
2*4c700c15SGovindraj Raja  * Copyright (c) 2016-2020, Arm Limited and Contributors. All rights reserved.
3afdda571Sdp-arm  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
5afdda571Sdp-arm  */
6afdda571Sdp-arm 
7bef9a10fSAntonio Nino Diaz #ifndef PMF_HELPERS_H
8bef9a10fSAntonio Nino Diaz #define PMF_HELPERS_H
9afdda571Sdp-arm 
10afdda571Sdp-arm #include <assert.h>
11afdda571Sdp-arm #include <stddef.h>
122a4b4b71SIsla Mitchell #include <stdint.h>
13afdda571Sdp-arm 
1409d40e0eSAntonio Nino Diaz #include <arch_helpers.h>
1509d40e0eSAntonio Nino Diaz #include <common/bl_common.h>
1609d40e0eSAntonio Nino Diaz #include <plat/common/platform.h>
1709d40e0eSAntonio Nino Diaz 
18afdda571Sdp-arm /*
19afdda571Sdp-arm  * Prototype for PMF service functions.
20afdda571Sdp-arm  */
21afdda571Sdp-arm typedef int (*pmf_svc_init_t)(void);
22afdda571Sdp-arm typedef unsigned long long (*pmf_svc_get_ts_t)(unsigned int tid,
23afdda571Sdp-arm 		 u_register_t mpidr,
24afdda571Sdp-arm 		 unsigned int flags);
25afdda571Sdp-arm 
26afdda571Sdp-arm /*
27afdda571Sdp-arm  * This is the definition of PMF service desc.
28afdda571Sdp-arm  */
29afdda571Sdp-arm typedef struct pmf_svc_desc {
30afdda571Sdp-arm 	/* Structure version information */
31afdda571Sdp-arm 	param_header_t h;
32afdda571Sdp-arm 
33afdda571Sdp-arm 	/* Name of the PMF service */
34afdda571Sdp-arm 	const char *name;
35afdda571Sdp-arm 
36afdda571Sdp-arm 	/* PMF service config: Implementer id, Service id and total id*/
37afdda571Sdp-arm 	unsigned int svc_config;
38afdda571Sdp-arm 
39afdda571Sdp-arm 	/* PMF service initialization handler */
40afdda571Sdp-arm 	pmf_svc_init_t init;
41afdda571Sdp-arm 
42afdda571Sdp-arm 	/* PMF service time-stamp retrieval handler */
43afdda571Sdp-arm 	pmf_svc_get_ts_t get_ts;
44afdda571Sdp-arm } pmf_svc_desc_t;
45afdda571Sdp-arm 
46daa9b6eaSMadhukar Pappireddy #if ENABLE_PMF
47daa9b6eaSMadhukar Pappireddy /*
48daa9b6eaSMadhukar Pappireddy  * Convenience macros for capturing time-stamp.
49daa9b6eaSMadhukar Pappireddy  */
50daa9b6eaSMadhukar Pappireddy #define PMF_DECLARE_CAPTURE_TIMESTAMP(_name)			\
51daa9b6eaSMadhukar Pappireddy 	void pmf_capture_timestamp_with_cache_maint_ ## _name(	\
52daa9b6eaSMadhukar Pappireddy 				unsigned int tid,		\
53daa9b6eaSMadhukar Pappireddy 				unsigned long long ts);		\
54daa9b6eaSMadhukar Pappireddy 	void pmf_capture_timestamp_ ## _name(			\
55daa9b6eaSMadhukar Pappireddy 				unsigned int tid,		\
56daa9b6eaSMadhukar Pappireddy 				unsigned long long ts);
57daa9b6eaSMadhukar Pappireddy 
58daa9b6eaSMadhukar Pappireddy #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags)			\
59daa9b6eaSMadhukar Pappireddy 	do {								\
60daa9b6eaSMadhukar Pappireddy 		unsigned long long ts = read_cntpct_el0();		\
61daa9b6eaSMadhukar Pappireddy 		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
62daa9b6eaSMadhukar Pappireddy 			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\
63daa9b6eaSMadhukar Pappireddy 		else							\
64daa9b6eaSMadhukar Pappireddy 			pmf_capture_timestamp_ ## _name((_tid), ts);	\
65daa9b6eaSMadhukar Pappireddy 	} while (0)
66daa9b6eaSMadhukar Pappireddy 
67daa9b6eaSMadhukar Pappireddy #define PMF_CAPTURE_AND_GET_TIMESTAMP(_name, _tid, _flags, _tsval)	\
68daa9b6eaSMadhukar Pappireddy 	do {								\
69daa9b6eaSMadhukar Pappireddy 		(_tsval) = read_cntpct_el0();				\
70daa9b6eaSMadhukar Pappireddy 		CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\
71daa9b6eaSMadhukar Pappireddy 		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
72daa9b6eaSMadhukar Pappireddy 			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\
73daa9b6eaSMadhukar Pappireddy 		else							\
74daa9b6eaSMadhukar Pappireddy 			pmf_capture_timestamp_ ## _name((_tid), (_tsval));\
75daa9b6eaSMadhukar Pappireddy 	} while (0)
76daa9b6eaSMadhukar Pappireddy 
77daa9b6eaSMadhukar Pappireddy #define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval)		\
78daa9b6eaSMadhukar Pappireddy 	do {								\
79daa9b6eaSMadhukar Pappireddy 		CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\
80daa9b6eaSMadhukar Pappireddy 		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
81daa9b6eaSMadhukar Pappireddy 			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\
82daa9b6eaSMadhukar Pappireddy 		else							\
83daa9b6eaSMadhukar Pappireddy 			pmf_capture_timestamp_ ## _name((_tid), (_wrval));\
84daa9b6eaSMadhukar Pappireddy 	} while (0)
85daa9b6eaSMadhukar Pappireddy 
86daa9b6eaSMadhukar Pappireddy /*
87daa9b6eaSMadhukar Pappireddy  * Convenience macros for retrieving time-stamp.
88daa9b6eaSMadhukar Pappireddy  */
89daa9b6eaSMadhukar Pappireddy #define PMF_DECLARE_GET_TIMESTAMP(_name)			\
90daa9b6eaSMadhukar Pappireddy 	unsigned long long pmf_get_timestamp_by_index_ ## _name(\
91daa9b6eaSMadhukar Pappireddy 		unsigned int tid,				\
92daa9b6eaSMadhukar Pappireddy 		unsigned int cpuid,				\
93daa9b6eaSMadhukar Pappireddy 		unsigned int flags);				\
94daa9b6eaSMadhukar Pappireddy 	unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(\
95daa9b6eaSMadhukar Pappireddy 		unsigned int tid,				\
96daa9b6eaSMadhukar Pappireddy 		u_register_t mpidr,				\
97daa9b6eaSMadhukar Pappireddy 		unsigned int flags);
98daa9b6eaSMadhukar Pappireddy 
99daa9b6eaSMadhukar Pappireddy #define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)\
100daa9b6eaSMadhukar Pappireddy 	_tsval = pmf_get_timestamp_by_mpidr_ ## _name(_tid, _mpidr, _flags)
101daa9b6eaSMadhukar Pappireddy 
102daa9b6eaSMadhukar Pappireddy #define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)\
103daa9b6eaSMadhukar Pappireddy 	_tsval = pmf_get_timestamp_by_index_ ## _name(_tid, _cpuid, _flags)
104daa9b6eaSMadhukar Pappireddy 
105daa9b6eaSMadhukar Pappireddy /* Convenience macros to register a PMF service.*/
106daa9b6eaSMadhukar Pappireddy /*
107daa9b6eaSMadhukar Pappireddy  * This macro is used to register a PMF Service. It allocates PMF memory
108daa9b6eaSMadhukar Pappireddy  * and defines default service-specific PMF functions.
109daa9b6eaSMadhukar Pappireddy  */
110daa9b6eaSMadhukar Pappireddy #define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)	\
111daa9b6eaSMadhukar Pappireddy 	PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _totalid)		\
112daa9b6eaSMadhukar Pappireddy 	PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags)		\
113daa9b6eaSMadhukar Pappireddy 	PMF_DEFINE_GET_TIMESTAMP(_name)
114daa9b6eaSMadhukar Pappireddy 
115daa9b6eaSMadhukar Pappireddy /*
116daa9b6eaSMadhukar Pappireddy  * This macro is used to register a PMF service, including an
117daa9b6eaSMadhukar Pappireddy  * SMC interface to that service.
118daa9b6eaSMadhukar Pappireddy  */
119daa9b6eaSMadhukar Pappireddy #define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)\
120daa9b6eaSMadhukar Pappireddy 	PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)	\
121daa9b6eaSMadhukar Pappireddy 	PMF_DEFINE_SERVICE_DESC(_name, PMF_ARM_TIF_IMPL_ID,	\
122daa9b6eaSMadhukar Pappireddy 			_svcid, _totalid, NULL,			\
123daa9b6eaSMadhukar Pappireddy 			pmf_get_timestamp_by_mpidr_ ## _name)
124daa9b6eaSMadhukar Pappireddy 
125daa9b6eaSMadhukar Pappireddy /*
126daa9b6eaSMadhukar Pappireddy  * This macro is used to register a PMF service that has an SMC interface
127daa9b6eaSMadhukar Pappireddy  * but provides its own service-specific PMF functions.
128daa9b6eaSMadhukar Pappireddy  */
129daa9b6eaSMadhukar Pappireddy #define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid,	\
130daa9b6eaSMadhukar Pappireddy 		 _init, _getts)						\
131daa9b6eaSMadhukar Pappireddy 	PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid,	\
132daa9b6eaSMadhukar Pappireddy 		 _init, _getts)
133daa9b6eaSMadhukar Pappireddy 
134daa9b6eaSMadhukar Pappireddy #else
135daa9b6eaSMadhukar Pappireddy 
136daa9b6eaSMadhukar Pappireddy #define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)
137daa9b6eaSMadhukar Pappireddy #define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)
138daa9b6eaSMadhukar Pappireddy #define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid,	\
139daa9b6eaSMadhukar Pappireddy 				_init, _getts)
140daa9b6eaSMadhukar Pappireddy #define PMF_DECLARE_CAPTURE_TIMESTAMP(_name)
141daa9b6eaSMadhukar Pappireddy #define PMF_DECLARE_GET_TIMESTAMP(_name)
142daa9b6eaSMadhukar Pappireddy #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags)
143daa9b6eaSMadhukar Pappireddy #define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)
144daa9b6eaSMadhukar Pappireddy #define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)
145daa9b6eaSMadhukar Pappireddy 
146daa9b6eaSMadhukar Pappireddy #endif /* ENABLE_PMF */
147daa9b6eaSMadhukar Pappireddy 
148afdda571Sdp-arm /*
149afdda571Sdp-arm  * Convenience macro to allocate memory for a PMF service.
1501af540efSRoberto Vargas  *
1511af540efSRoberto Vargas  * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
152afdda571Sdp-arm  */
153afdda571Sdp-arm #define PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _total_id)		\
1541af540efSRoberto Vargas 	extern unsigned long long pmf_ts_mem_ ## _name[_total_id];	\
1555695cfe7Sdp-arm 	unsigned long long pmf_ts_mem_ ## _name[_total_id]	\
1562d84b46eSdp-arm 	__aligned(CACHE_WRITEBACK_GRANULE)			\
157da04341eSChris Kay 	__section(".pmf_timestamp_array")			\
1582d84b46eSdp-arm 	__used;
159afdda571Sdp-arm 
160afdda571Sdp-arm /*
161afdda571Sdp-arm  * Convenience macro to validate tid index for the given TS array.
162afdda571Sdp-arm  */
163afdda571Sdp-arm #define PMF_VALIDATE_TID(_name, _tid)	\
164afdda571Sdp-arm 	assert((_tid & PMF_TID_MASK) < (ARRAY_SIZE(pmf_ts_mem_ ## _name)))
165afdda571Sdp-arm 
166afdda571Sdp-arm /*
167afdda571Sdp-arm  * Convenience macros for capturing time-stamp.
1681af540efSRoberto Vargas  *
1691af540efSRoberto Vargas  * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
170afdda571Sdp-arm  */
171afdda571Sdp-arm #define PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags)			\
172afdda571Sdp-arm 	void pmf_capture_timestamp_ ## _name(				\
173afdda571Sdp-arm 			unsigned int tid,				\
174afdda571Sdp-arm 			unsigned long long ts)				\
175afdda571Sdp-arm 	{								\
1764c4a1327SManish V Badarkhe 		CASSERT(_flags != 0, select_proper_config);		\
177d7b5f408SJimmy Brisson 		PMF_VALIDATE_TID(_name, (uint64_t)tid);			\
178afdda571Sdp-arm 		uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name;	\
179bef9a10fSAntonio Nino Diaz 		if (((_flags) & PMF_STORE_ENABLE) != 0)			\
180d7b5f408SJimmy Brisson 			__pmf_store_timestamp(base_addr,		\
181d7b5f408SJimmy Brisson 				(uint64_t)tid, ts);			\
182bef9a10fSAntonio Nino Diaz 		if (((_flags) & PMF_DUMP_ENABLE) != 0)			\
183d7b5f408SJimmy Brisson 			__pmf_dump_timestamp((uint64_t)tid, ts);	\
184afdda571Sdp-arm 	}								\
185afdda571Sdp-arm 	void pmf_capture_timestamp_with_cache_maint_ ## _name(		\
186afdda571Sdp-arm 			unsigned int tid,				\
187afdda571Sdp-arm 			unsigned long long ts)				\
188afdda571Sdp-arm 	{								\
1894c4a1327SManish V Badarkhe 		CASSERT(_flags != 0, select_proper_config);		\
190d7b5f408SJimmy Brisson 		PMF_VALIDATE_TID(_name, (uint64_t)tid);			\
191afdda571Sdp-arm 		uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name;	\
192bef9a10fSAntonio Nino Diaz 		if (((_flags) & PMF_STORE_ENABLE) != 0)			\
193d7b5f408SJimmy Brisson 			__pmf_store_timestamp_with_cache_maint(		\
194d7b5f408SJimmy Brisson 				base_addr, (uint64_t)tid, ts);		\
195bef9a10fSAntonio Nino Diaz 		if (((_flags) & PMF_DUMP_ENABLE) != 0)			\
196d7b5f408SJimmy Brisson 			__pmf_dump_timestamp((uint64_t)tid, ts);	\
197afdda571Sdp-arm 	}
198afdda571Sdp-arm 
199afdda571Sdp-arm /*
200afdda571Sdp-arm  * Convenience macros for retrieving time-stamp.
2011af540efSRoberto Vargas  *
2021af540efSRoberto Vargas  * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
203afdda571Sdp-arm  */
204afdda571Sdp-arm #define PMF_DEFINE_GET_TIMESTAMP(_name)					\
205afdda571Sdp-arm 	unsigned long long pmf_get_timestamp_by_index_ ## _name(	\
206afdda571Sdp-arm 		unsigned int tid, unsigned int cpuid, unsigned int flags)\
207afdda571Sdp-arm 	{								\
208afdda571Sdp-arm 		PMF_VALIDATE_TID(_name, tid);				\
209afdda571Sdp-arm 		uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name;	\
210afdda571Sdp-arm 		return __pmf_get_timestamp(base_addr, tid, cpuid, flags);\
211afdda571Sdp-arm 	}								\
212afdda571Sdp-arm 	unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(	\
213afdda571Sdp-arm 		unsigned int tid, u_register_t mpidr, unsigned int flags)\
214afdda571Sdp-arm 	{								\
215afdda571Sdp-arm 		PMF_VALIDATE_TID(_name, tid);				\
216afdda571Sdp-arm 		uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name;	\
217afdda571Sdp-arm 		return __pmf_get_timestamp(base_addr, tid,		\
218afdda571Sdp-arm 			plat_core_pos_by_mpidr(mpidr), flags);		\
219afdda571Sdp-arm 	}
220afdda571Sdp-arm 
221afdda571Sdp-arm /*
222afdda571Sdp-arm  * Convenience macro to register a PMF service.
223afdda571Sdp-arm  * This is needed for services that require SMC handling.
224afdda571Sdp-arm  */
225afdda571Sdp-arm #define PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid,	\
226afdda571Sdp-arm 		_init, _getts_by_mpidr) 				\
227afdda571Sdp-arm 	static const pmf_svc_desc_t __pmf_desc_ ## _name 		\
228da04341eSChris Kay 	__section(".pmf_svc_descs") __used = {		 		\
229afdda571Sdp-arm 		.h.type = PARAM_EP, 					\
230afdda571Sdp-arm 		.h.version = VERSION_1, 				\
231afdda571Sdp-arm 		.h.size = sizeof(pmf_svc_desc_t),			\
232afdda571Sdp-arm 		.h.attr = 0,						\
233afdda571Sdp-arm 		.name = #_name, 					\
234afdda571Sdp-arm 		.svc_config = ((((_implid) << PMF_IMPL_ID_SHIFT) &	\
235afdda571Sdp-arm 						PMF_IMPL_ID_MASK) |	\
236afdda571Sdp-arm 				(((_svcid) << PMF_SVC_ID_SHIFT) &	\
237afdda571Sdp-arm 						PMF_SVC_ID_MASK) |	\
238afdda571Sdp-arm 				(((_totalid) << PMF_TID_SHIFT) &	\
239afdda571Sdp-arm 						PMF_TID_MASK)),		\
240afdda571Sdp-arm 		.init = _init,						\
241afdda571Sdp-arm 		.get_ts = _getts_by_mpidr				\
242afdda571Sdp-arm 	};
243afdda571Sdp-arm 
244afdda571Sdp-arm /* PMF internal functions */
245afdda571Sdp-arm void __pmf_dump_timestamp(unsigned int tid, unsigned long long ts);
246afdda571Sdp-arm void __pmf_store_timestamp(uintptr_t base_addr,
247afdda571Sdp-arm 		unsigned int tid,
248afdda571Sdp-arm 		unsigned long long ts);
249afdda571Sdp-arm void __pmf_store_timestamp_with_cache_maint(uintptr_t base_addr,
250afdda571Sdp-arm 		unsigned int tid,
251afdda571Sdp-arm 		unsigned long long ts);
252afdda571Sdp-arm unsigned long long __pmf_get_timestamp(uintptr_t base_addr,
253afdda571Sdp-arm 		unsigned int tid,
254afdda571Sdp-arm 		unsigned int cpuid,
255afdda571Sdp-arm 		unsigned int flags);
256bef9a10fSAntonio Nino Diaz #endif /* PMF_HELPERS_H */
257