1 /* 2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef __PMF_H__ 8 #define __PMF_H__ 9 10 #include <cassert.h> 11 #include <pmf_helpers.h> 12 13 /* 14 * Constants used for/by PMF services. 15 */ 16 #define PMF_ARM_TIF_IMPL_ID 0x41 17 #define PMF_TID_SHIFT 0 18 #define PMF_TID_MASK (0xFF << PMF_TID_SHIFT) 19 #define PMF_SVC_ID_SHIFT 10 20 #define PMF_SVC_ID_MASK (0x3F << PMF_SVC_ID_SHIFT) 21 #define PMF_IMPL_ID_SHIFT 24 22 #define PMF_IMPL_ID_MASK (0xFFU << PMF_IMPL_ID_SHIFT) 23 24 /* 25 * Flags passed to PMF_REGISTER_SERVICE 26 */ 27 #define PMF_STORE_ENABLE (1 << 0) 28 #define PMF_DUMP_ENABLE (1 << 1) 29 30 /* 31 * Flags passed to PMF_GET_TIMESTAMP_XXX 32 * and PMF_CAPTURE_TIMESTAMP 33 */ 34 #define PMF_CACHE_MAINT (1 << 0) 35 #define PMF_NO_CACHE_MAINT 0 36 37 /* 38 * Defines for PMF SMC function ids. 39 */ 40 #define PMF_SMC_GET_TIMESTAMP_32 0x82000010 41 #define PMF_SMC_GET_TIMESTAMP_64 0xC2000010 42 #define PMF_NUM_SMC_CALLS 2 43 44 /* 45 * The macros below are used to identify 46 * PMF calls from the SMC function ID. 47 */ 48 #define PMF_FID_MASK 0xffe0u 49 #define PMF_FID_VALUE 0u 50 #define is_pmf_fid(_fid) (((_fid) & PMF_FID_MASK) == PMF_FID_VALUE) 51 52 /* Following are the supported PMF service IDs */ 53 #define PMF_PSCI_STAT_SVC_ID 0 54 #define PMF_RT_INSTR_SVC_ID 1 55 56 #if ENABLE_PMF 57 /* 58 * Convenience macros for capturing time-stamp. 59 */ 60 #define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) \ 61 void pmf_capture_timestamp_with_cache_maint_ ## _name( \ 62 unsigned int tid, \ 63 unsigned long long ts); \ 64 void pmf_capture_timestamp_ ## _name( \ 65 unsigned int tid, \ 66 unsigned long long ts); 67 68 #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) \ 69 do { \ 70 unsigned long long ts = read_cntpct_el0(); \ 71 if ((_flags) & PMF_CACHE_MAINT) \ 72 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\ 73 else \ 74 pmf_capture_timestamp_ ## _name((_tid), ts); \ 75 } while (0) 76 77 #define PMF_CAPTURE_AND_GET_TIMESTAMP(_name, _tid, _flags, _tsval) \ 78 do { \ 79 (_tsval) = read_cntpct_el0(); \ 80 CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\ 81 if ((_flags) & PMF_CACHE_MAINT) \ 82 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\ 83 else \ 84 pmf_capture_timestamp_ ## _name((_tid), (_tsval));\ 85 } while (0) 86 87 #define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval) \ 88 do { \ 89 CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\ 90 if ((_flags) & PMF_CACHE_MAINT) \ 91 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\ 92 else \ 93 pmf_capture_timestamp_ ## _name((_tid), (_wrval));\ 94 } while (0) 95 96 /* 97 * Convenience macros for retrieving time-stamp. 98 */ 99 #define PMF_DECLARE_GET_TIMESTAMP(_name) \ 100 unsigned long long pmf_get_timestamp_by_index_ ## _name(\ 101 unsigned int tid, \ 102 unsigned int cpuid, \ 103 unsigned int flags); \ 104 unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(\ 105 unsigned int tid, \ 106 u_register_t mpidr, \ 107 unsigned int flags); 108 109 #define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)\ 110 _tsval = pmf_get_timestamp_by_mpidr_ ## _name(_tid, _mpidr, _flags) 111 112 #define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)\ 113 _tsval = pmf_get_timestamp_by_index_ ## _name(_tid, _cpuid, _flags) 114 115 /* Convenience macros to register a PMF service.*/ 116 /* 117 * This macro is used to register a PMF Service. It allocates PMF memory 118 * and defines default service-specific PMF functions. 119 */ 120 #define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \ 121 PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _totalid) \ 122 PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags) \ 123 PMF_DEFINE_GET_TIMESTAMP(_name) 124 125 /* 126 * This macro is used to register a PMF service, including an 127 * SMC interface to that service. 128 */ 129 #define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)\ 130 PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \ 131 PMF_DEFINE_SERVICE_DESC(_name, PMF_ARM_TIF_IMPL_ID, \ 132 _svcid, _totalid, NULL, \ 133 pmf_get_timestamp_by_mpidr_ ## _name) 134 135 /* 136 * This macro is used to register a PMF service that has an SMC interface 137 * but provides its own service-specific PMF functions. 138 */ 139 #define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \ 140 _init, _getts) \ 141 PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid, \ 142 _init, _getts) 143 144 #else 145 146 #define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) 147 #define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags) 148 #define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \ 149 _init, _getts) 150 #define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) 151 #define PMF_DECLARE_GET_TIMESTAMP(_name) 152 #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) 153 #define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval) 154 #define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval) 155 156 #endif /* ENABLE_PMF */ 157 158 /******************************************************************************* 159 * Function & variable prototypes 160 ******************************************************************************/ 161 /* PMF common functions */ 162 int pmf_get_timestamp_smc(unsigned int tid, 163 u_register_t mpidr, 164 unsigned int flags, 165 unsigned long long *ts); 166 int pmf_setup(void); 167 uintptr_t pmf_smc_handler(unsigned int smc_fid, 168 u_register_t x1, 169 u_register_t x2, 170 u_register_t x3, 171 u_register_t x4, 172 void *cookie, 173 void *handle, 174 u_register_t flags); 175 176 #endif /* __PMF_H__ */ 177