blob: db38e556a9b7f9a648c0ce680cd93da1a94f4b65 [file] [log] [blame]
Yatharth Kochar9518d022016-03-11 14:20:19 +00001/*
Roberto Vargas2ca18d92018-02-12 12:36:17 +00002 * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
Yatharth Kochar9518d022016-03-11 14:20:19 +00003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Yatharth Kochar9518d022016-03-11 14:20:19 +00005 */
6
Antonio Nino Diaze89a4532018-07-18 13:26:25 +01007#ifndef PMF_HELPERS_H
8#define PMF_HELPERS_H
Yatharth Kochar9518d022016-03-11 14:20:19 +00009
Yatharth Kochar9518d022016-03-11 14:20:19 +000010#include <assert.h>
Yatharth Kochar9518d022016-03-11 14:20:19 +000011#include <stddef.h>
Isla Mitchell99305012017-07-11 14:54:08 +010012#include <stdint.h>
Yatharth Kochar9518d022016-03-11 14:20:19 +000013
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000014#include <arch_helpers.h>
15#include <common/bl_common.h>
16#include <plat/common/platform.h>
17
Yatharth Kochar9518d022016-03-11 14:20:19 +000018/*
19 * Prototype for PMF service functions.
20 */
21typedef int (*pmf_svc_init_t)(void);
22typedef unsigned long long (*pmf_svc_get_ts_t)(unsigned int tid,
23 u_register_t mpidr,
24 unsigned int flags);
25
26/*
27 * This is the definition of PMF service desc.
28 */
29typedef struct pmf_svc_desc {
30 /* Structure version information */
31 param_header_t h;
32
33 /* Name of the PMF service */
34 const char *name;
35
36 /* PMF service config: Implementer id, Service id and total id*/
37 unsigned int svc_config;
38
39 /* PMF service initialization handler */
40 pmf_svc_init_t init;
41
42 /* PMF service time-stamp retrieval handler */
43 pmf_svc_get_ts_t get_ts;
44} pmf_svc_desc_t;
45
Madhukar Pappireddya091d042020-01-06 14:42:30 -060046#if ENABLE_PMF
47/*
48 * Convenience macros for capturing time-stamp.
49 */
50#define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) \
51 void pmf_capture_timestamp_with_cache_maint_ ## _name( \
52 unsigned int tid, \
53 unsigned long long ts); \
54 void pmf_capture_timestamp_ ## _name( \
55 unsigned int tid, \
56 unsigned long long ts);
57
58#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) \
59 do { \
60 unsigned long long ts = read_cntpct_el0(); \
61 if (((_flags) & PMF_CACHE_MAINT) != 0U) \
62 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\
63 else \
64 pmf_capture_timestamp_ ## _name((_tid), ts); \
65 } while (0)
66
67#define PMF_CAPTURE_AND_GET_TIMESTAMP(_name, _tid, _flags, _tsval) \
68 do { \
69 (_tsval) = read_cntpct_el0(); \
70 CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\
71 if (((_flags) & PMF_CACHE_MAINT) != 0U) \
72 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\
73 else \
74 pmf_capture_timestamp_ ## _name((_tid), (_tsval));\
75 } while (0)
76
77#define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval) \
78 do { \
79 CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\
80 if (((_flags) & PMF_CACHE_MAINT) != 0U) \
81 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\
82 else \
83 pmf_capture_timestamp_ ## _name((_tid), (_wrval));\
84 } while (0)
85
86/*
87 * Convenience macros for retrieving time-stamp.
88 */
89#define PMF_DECLARE_GET_TIMESTAMP(_name) \
90 unsigned long long pmf_get_timestamp_by_index_ ## _name(\
91 unsigned int tid, \
92 unsigned int cpuid, \
93 unsigned int flags); \
94 unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(\
95 unsigned int tid, \
96 u_register_t mpidr, \
97 unsigned int flags);
98
99#define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)\
100 _tsval = pmf_get_timestamp_by_mpidr_ ## _name(_tid, _mpidr, _flags)
101
102#define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)\
103 _tsval = pmf_get_timestamp_by_index_ ## _name(_tid, _cpuid, _flags)
104
105/* Convenience macros to register a PMF service.*/
106/*
107 * This macro is used to register a PMF Service. It allocates PMF memory
108 * and defines default service-specific PMF functions.
109 */
110#define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \
111 PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _totalid) \
112 PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags) \
113 PMF_DEFINE_GET_TIMESTAMP(_name)
114
115/*
116 * This macro is used to register a PMF service, including an
117 * SMC interface to that service.
118 */
119#define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)\
120 PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \
121 PMF_DEFINE_SERVICE_DESC(_name, PMF_ARM_TIF_IMPL_ID, \
122 _svcid, _totalid, NULL, \
123 pmf_get_timestamp_by_mpidr_ ## _name)
124
125/*
126 * This macro is used to register a PMF service that has an SMC interface
127 * but provides its own service-specific PMF functions.
128 */
129#define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \
130 _init, _getts) \
131 PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid, \
132 _init, _getts)
133
134#else
135
136#define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)
137#define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)
138#define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \
139 _init, _getts)
140#define PMF_DECLARE_CAPTURE_TIMESTAMP(_name)
141#define PMF_DECLARE_GET_TIMESTAMP(_name)
142#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags)
143#define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)
144#define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)
145
146#endif /* ENABLE_PMF */
147
Yatharth Kochar9518d022016-03-11 14:20:19 +0000148/*
149 * Convenience macro to allocate memory for a PMF service.
Roberto Vargas2ca18d92018-02-12 12:36:17 +0000150 *
151 * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
Yatharth Kochar9518d022016-03-11 14:20:19 +0000152 */
dp-arma97bd892016-08-15 10:35:54 +0100153#define PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _total_id) \
Roberto Vargas2ca18d92018-02-12 12:36:17 +0000154 extern unsigned long long pmf_ts_mem_ ## _name[_total_id]; \
dp-arma97bd892016-08-15 10:35:54 +0100155 unsigned long long pmf_ts_mem_ ## _name[_total_id] \
dp-arm8810e832016-09-09 11:39:09 +0100156 __aligned(CACHE_WRITEBACK_GRANULE) \
157 __section("pmf_timestamp_array") \
158 __used;
Yatharth Kochar9518d022016-03-11 14:20:19 +0000159
160/*
161 * Convenience macro to validate tid index for the given TS array.
162 */
163#define PMF_VALIDATE_TID(_name, _tid) \
164 assert((_tid & PMF_TID_MASK) < (ARRAY_SIZE(pmf_ts_mem_ ## _name)))
165
166/*
167 * Convenience macros for capturing time-stamp.
Roberto Vargas2ca18d92018-02-12 12:36:17 +0000168 *
169 * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
Yatharth Kochar9518d022016-03-11 14:20:19 +0000170 */
171#define PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags) \
172 void pmf_capture_timestamp_ ## _name( \
173 unsigned int tid, \
174 unsigned long long ts) \
175 { \
176 CASSERT(_flags, select_proper_config); \
177 PMF_VALIDATE_TID(_name, tid); \
178 uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
Antonio Nino Diaze89a4532018-07-18 13:26:25 +0100179 if (((_flags) & PMF_STORE_ENABLE) != 0) \
Yatharth Kochar9518d022016-03-11 14:20:19 +0000180 __pmf_store_timestamp(base_addr, tid, ts); \
Antonio Nino Diaze89a4532018-07-18 13:26:25 +0100181 if (((_flags) & PMF_DUMP_ENABLE) != 0) \
Yatharth Kochar9518d022016-03-11 14:20:19 +0000182 __pmf_dump_timestamp(tid, ts); \
183 } \
184 void pmf_capture_timestamp_with_cache_maint_ ## _name( \
185 unsigned int tid, \
186 unsigned long long ts) \
187 { \
188 CASSERT(_flags, select_proper_config); \
189 PMF_VALIDATE_TID(_name, tid); \
190 uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
Antonio Nino Diaze89a4532018-07-18 13:26:25 +0100191 if (((_flags) & PMF_STORE_ENABLE) != 0) \
Yatharth Kochar9518d022016-03-11 14:20:19 +0000192 __pmf_store_timestamp_with_cache_maint(base_addr, tid, ts);\
Antonio Nino Diaze89a4532018-07-18 13:26:25 +0100193 if (((_flags) & PMF_DUMP_ENABLE) != 0) \
Yatharth Kochar9518d022016-03-11 14:20:19 +0000194 __pmf_dump_timestamp(tid, ts); \
195 }
196
197/*
198 * Convenience macros for retrieving time-stamp.
Roberto Vargas2ca18d92018-02-12 12:36:17 +0000199 *
200 * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
Yatharth Kochar9518d022016-03-11 14:20:19 +0000201 */
202#define PMF_DEFINE_GET_TIMESTAMP(_name) \
203 unsigned long long pmf_get_timestamp_by_index_ ## _name( \
204 unsigned int tid, unsigned int cpuid, unsigned int flags)\
205 { \
206 PMF_VALIDATE_TID(_name, tid); \
207 uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
208 return __pmf_get_timestamp(base_addr, tid, cpuid, flags);\
209 } \
210 unsigned long long pmf_get_timestamp_by_mpidr_ ## _name( \
Yatharth Kochar9518d022016-03-11 14:20:19 +0000211 unsigned int tid, u_register_t mpidr, unsigned int flags)\
212 { \
213 PMF_VALIDATE_TID(_name, tid); \
214 uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
215 return __pmf_get_timestamp(base_addr, tid, \
216 plat_core_pos_by_mpidr(mpidr), flags); \
217 }
218
219/*
220 * Convenience macro to register a PMF service.
221 * This is needed for services that require SMC handling.
222 */
223#define PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid, \
224 _init, _getts_by_mpidr) \
225 static const pmf_svc_desc_t __pmf_desc_ ## _name \
226 __section("pmf_svc_descs") __used = { \
227 .h.type = PARAM_EP, \
228 .h.version = VERSION_1, \
229 .h.size = sizeof(pmf_svc_desc_t), \
230 .h.attr = 0, \
231 .name = #_name, \
232 .svc_config = ((((_implid) << PMF_IMPL_ID_SHIFT) & \
233 PMF_IMPL_ID_MASK) | \
234 (((_svcid) << PMF_SVC_ID_SHIFT) & \
235 PMF_SVC_ID_MASK) | \
236 (((_totalid) << PMF_TID_SHIFT) & \
237 PMF_TID_MASK)), \
238 .init = _init, \
239 .get_ts = _getts_by_mpidr \
240 };
241
242/* PMF internal functions */
243void __pmf_dump_timestamp(unsigned int tid, unsigned long long ts);
244void __pmf_store_timestamp(uintptr_t base_addr,
245 unsigned int tid,
246 unsigned long long ts);
247void __pmf_store_timestamp_with_cache_maint(uintptr_t base_addr,
248 unsigned int tid,
249 unsigned long long ts);
250unsigned long long __pmf_get_timestamp(uintptr_t base_addr,
251 unsigned int tid,
252 unsigned int cpuid,
253 unsigned int flags);
Antonio Nino Diaze89a4532018-07-18 13:26:25 +0100254#endif /* PMF_HELPERS_H */