blob: c535b222d3eece64fc73e4a830be6a85c5082a83 [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
10#include <arch_helpers.h>
11#include <assert.h>
dp-arm3cac7862016-09-19 11:18:44 +010012#include <bl_common.h>
Yatharth Kochar9518d022016-03-11 14:20:19 +000013#include <platform.h>
Yatharth Kochar9518d022016-03-11 14:20:19 +000014#include <stddef.h>
Isla Mitchell99305012017-07-11 14:54:08 +010015#include <stdint.h>
Yatharth Kochar9518d022016-03-11 14:20:19 +000016
17/*
18 * Prototype for PMF service functions.
19 */
20typedef int (*pmf_svc_init_t)(void);
21typedef unsigned long long (*pmf_svc_get_ts_t)(unsigned int tid,
22 u_register_t mpidr,
23 unsigned int flags);
24
25/*
26 * This is the definition of PMF service desc.
27 */
28typedef struct pmf_svc_desc {
29 /* Structure version information */
30 param_header_t h;
31
32 /* Name of the PMF service */
33 const char *name;
34
35 /* PMF service config: Implementer id, Service id and total id*/
36 unsigned int svc_config;
37
38 /* PMF service initialization handler */
39 pmf_svc_init_t init;
40
41 /* PMF service time-stamp retrieval handler */
42 pmf_svc_get_ts_t get_ts;
43} pmf_svc_desc_t;
44
45/*
46 * Convenience macro to allocate memory for a PMF service.
Roberto Vargas2ca18d92018-02-12 12:36:17 +000047 *
48 * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
Yatharth Kochar9518d022016-03-11 14:20:19 +000049 */
dp-arma97bd892016-08-15 10:35:54 +010050#define PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _total_id) \
Roberto Vargas2ca18d92018-02-12 12:36:17 +000051 extern unsigned long long pmf_ts_mem_ ## _name[_total_id]; \
dp-arma97bd892016-08-15 10:35:54 +010052 unsigned long long pmf_ts_mem_ ## _name[_total_id] \
dp-arm8810e832016-09-09 11:39:09 +010053 __aligned(CACHE_WRITEBACK_GRANULE) \
54 __section("pmf_timestamp_array") \
55 __used;
Yatharth Kochar9518d022016-03-11 14:20:19 +000056
57/*
58 * Convenience macro to validate tid index for the given TS array.
59 */
60#define PMF_VALIDATE_TID(_name, _tid) \
61 assert((_tid & PMF_TID_MASK) < (ARRAY_SIZE(pmf_ts_mem_ ## _name)))
62
63/*
64 * Convenience macros for capturing time-stamp.
Roberto Vargas2ca18d92018-02-12 12:36:17 +000065 *
66 * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
Yatharth Kochar9518d022016-03-11 14:20:19 +000067 */
68#define PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags) \
69 void pmf_capture_timestamp_ ## _name( \
70 unsigned int tid, \
Roberto Vargas2ca18d92018-02-12 12:36:17 +000071 unsigned long long ts); \
72 void pmf_capture_timestamp_ ## _name( \
73 unsigned int tid, \
Yatharth Kochar9518d022016-03-11 14:20:19 +000074 unsigned long long ts) \
75 { \
76 CASSERT(_flags, select_proper_config); \
77 PMF_VALIDATE_TID(_name, tid); \
78 uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
Antonio Nino Diaze89a4532018-07-18 13:26:25 +010079 if (((_flags) & PMF_STORE_ENABLE) != 0) \
Yatharth Kochar9518d022016-03-11 14:20:19 +000080 __pmf_store_timestamp(base_addr, tid, ts); \
Antonio Nino Diaze89a4532018-07-18 13:26:25 +010081 if (((_flags) & PMF_DUMP_ENABLE) != 0) \
Yatharth Kochar9518d022016-03-11 14:20:19 +000082 __pmf_dump_timestamp(tid, ts); \
83 } \
84 void pmf_capture_timestamp_with_cache_maint_ ## _name( \
85 unsigned int tid, \
Roberto Vargas2ca18d92018-02-12 12:36:17 +000086 unsigned long long ts); \
87 void pmf_capture_timestamp_with_cache_maint_ ## _name( \
88 unsigned int tid, \
Yatharth Kochar9518d022016-03-11 14:20:19 +000089 unsigned long long ts) \
90 { \
91 CASSERT(_flags, select_proper_config); \
92 PMF_VALIDATE_TID(_name, tid); \
93 uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
Antonio Nino Diaze89a4532018-07-18 13:26:25 +010094 if (((_flags) & PMF_STORE_ENABLE) != 0) \
Yatharth Kochar9518d022016-03-11 14:20:19 +000095 __pmf_store_timestamp_with_cache_maint(base_addr, tid, ts);\
Antonio Nino Diaze89a4532018-07-18 13:26:25 +010096 if (((_flags) & PMF_DUMP_ENABLE) != 0) \
Yatharth Kochar9518d022016-03-11 14:20:19 +000097 __pmf_dump_timestamp(tid, ts); \
98 }
99
100/*
101 * Convenience macros for retrieving time-stamp.
Roberto Vargas2ca18d92018-02-12 12:36:17 +0000102 *
103 * The extern declaration is there to satisfy MISRA C-2012 rule 8.4.
Yatharth Kochar9518d022016-03-11 14:20:19 +0000104 */
105#define PMF_DEFINE_GET_TIMESTAMP(_name) \
106 unsigned long long pmf_get_timestamp_by_index_ ## _name( \
Roberto Vargas2ca18d92018-02-12 12:36:17 +0000107 unsigned int tid, unsigned int cpuid, unsigned int flags);\
108 unsigned long long pmf_get_timestamp_by_index_ ## _name( \
Yatharth Kochar9518d022016-03-11 14:20:19 +0000109 unsigned int tid, unsigned int cpuid, unsigned int flags)\
110 { \
111 PMF_VALIDATE_TID(_name, tid); \
112 uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
113 return __pmf_get_timestamp(base_addr, tid, cpuid, flags);\
114 } \
115 unsigned long long pmf_get_timestamp_by_mpidr_ ## _name( \
Roberto Vargas2ca18d92018-02-12 12:36:17 +0000116 unsigned int tid, u_register_t mpidr, unsigned int flags);\
117 unsigned long long pmf_get_timestamp_by_mpidr_ ## _name( \
Yatharth Kochar9518d022016-03-11 14:20:19 +0000118 unsigned int tid, u_register_t mpidr, unsigned int flags)\
119 { \
120 PMF_VALIDATE_TID(_name, tid); \
121 uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
122 return __pmf_get_timestamp(base_addr, tid, \
123 plat_core_pos_by_mpidr(mpidr), flags); \
124 }
125
126/*
127 * Convenience macro to register a PMF service.
128 * This is needed for services that require SMC handling.
129 */
130#define PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid, \
131 _init, _getts_by_mpidr) \
132 static const pmf_svc_desc_t __pmf_desc_ ## _name \
133 __section("pmf_svc_descs") __used = { \
134 .h.type = PARAM_EP, \
135 .h.version = VERSION_1, \
136 .h.size = sizeof(pmf_svc_desc_t), \
137 .h.attr = 0, \
138 .name = #_name, \
139 .svc_config = ((((_implid) << PMF_IMPL_ID_SHIFT) & \
140 PMF_IMPL_ID_MASK) | \
141 (((_svcid) << PMF_SVC_ID_SHIFT) & \
142 PMF_SVC_ID_MASK) | \
143 (((_totalid) << PMF_TID_SHIFT) & \
144 PMF_TID_MASK)), \
145 .init = _init, \
146 .get_ts = _getts_by_mpidr \
147 };
148
149/* PMF internal functions */
150void __pmf_dump_timestamp(unsigned int tid, unsigned long long ts);
151void __pmf_store_timestamp(uintptr_t base_addr,
152 unsigned int tid,
153 unsigned long long ts);
154void __pmf_store_timestamp_with_cache_maint(uintptr_t base_addr,
155 unsigned int tid,
156 unsigned long long ts);
157unsigned long long __pmf_get_timestamp(uintptr_t base_addr,
158 unsigned int tid,
159 unsigned int cpuid,
160 unsigned int flags);
Antonio Nino Diaze89a4532018-07-18 13:26:25 +0100161#endif /* PMF_HELPERS_H */