1 /* 2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef __PMF_H__ 32 #define __PMF_H__ 33 34 #include <cassert.h> 35 #include <pmf_helpers.h> 36 37 /* 38 * Constants used for/by PMF services. 39 */ 40 #define PMF_ARM_TIF_IMPL_ID 0x41 41 #define PMF_TID_SHIFT 0 42 #define PMF_TID_MASK (0xFF << PMF_TID_SHIFT) 43 #define PMF_SVC_ID_SHIFT 10 44 #define PMF_SVC_ID_MASK (0x3F << PMF_SVC_ID_SHIFT) 45 #define PMF_IMPL_ID_SHIFT 24 46 #define PMF_IMPL_ID_MASK (0xFFU << PMF_IMPL_ID_SHIFT) 47 48 /* 49 * Flags passed to PMF_REGISTER_SERVICE 50 */ 51 #define PMF_STORE_ENABLE (1 << 0) 52 #define PMF_DUMP_ENABLE (1 << 1) 53 54 /* 55 * Flags passed to PMF_GET_TIMESTAMP_XXX 56 * and PMF_CAPTURE_TIMESTAMP 57 */ 58 #define PMF_CACHE_MAINT (1 << 0) 59 #define PMF_NO_CACHE_MAINT 0 60 61 /* 62 * Defines for PMF SMC function ids. 63 */ 64 #define PMF_SMC_GET_TIMESTAMP_32 0x82000010 65 #define PMF_SMC_GET_TIMESTAMP_64 0xC2000010 66 #define PMF_NUM_SMC_CALLS 2 67 68 /* 69 * The macros below are used to identify 70 * PMF calls from the SMC function ID. 71 */ 72 #define PMF_FID_MASK 0xffe0u 73 #define PMF_FID_VALUE 0u 74 #define is_pmf_fid(_fid) (((_fid) & PMF_FID_MASK) == PMF_FID_VALUE) 75 76 /* Following are the supported PMF service IDs */ 77 #define PMF_PSCI_STAT_SVC_ID 0 78 #define PMF_RT_INSTR_SVC_ID 1 79 80 #if ENABLE_PMF 81 /* 82 * Convenience macros for capturing time-stamp. 83 */ 84 #define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) \ 85 void pmf_capture_timestamp_with_cache_maint_ ## _name( \ 86 unsigned int tid, \ 87 unsigned long long ts); \ 88 void pmf_capture_timestamp_ ## _name( \ 89 unsigned int tid, \ 90 unsigned long long ts); 91 92 #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) \ 93 do { \ 94 unsigned long long ts = read_cntpct_el0(); \ 95 if ((_flags) & PMF_CACHE_MAINT) \ 96 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\ 97 else \ 98 pmf_capture_timestamp_ ## _name((_tid), ts); \ 99 } while (0) 100 101 #define PMF_CAPTURE_AND_GET_TIMESTAMP(_name, _tid, _flags, _tsval) \ 102 do { \ 103 (_tsval) = read_cntpct_el0(); \ 104 CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\ 105 if ((_flags) & PMF_CACHE_MAINT) \ 106 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\ 107 else \ 108 pmf_capture_timestamp_ ## _name((_tid), (_tsval));\ 109 } while (0) 110 111 #define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval) \ 112 do { \ 113 CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\ 114 if ((_flags) & PMF_CACHE_MAINT) \ 115 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\ 116 else \ 117 pmf_capture_timestamp_ ## _name((_tid), (_wrval));\ 118 } while (0) 119 120 /* 121 * Convenience macros for retrieving time-stamp. 122 */ 123 #define PMF_DECLARE_GET_TIMESTAMP(_name) \ 124 unsigned long long pmf_get_timestamp_by_index_ ## _name(\ 125 unsigned int tid, \ 126 unsigned int cpuid, \ 127 unsigned int flags); \ 128 unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(\ 129 unsigned int tid, \ 130 u_register_t mpidr, \ 131 unsigned int flags); 132 133 #define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)\ 134 _tsval = pmf_get_timestamp_by_mpidr_ ## _name(_tid, _mpidr, _flags) 135 136 #define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)\ 137 _tsval = pmf_get_timestamp_by_index_ ## _name(_tid, _cpuid, _flags) 138 139 /* Convenience macros to register a PMF service.*/ 140 /* 141 * This macro is used to register a PMF Service. It allocates PMF memory 142 * and defines default service-specific PMF functions. 143 */ 144 #define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \ 145 PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _totalid) \ 146 PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags) \ 147 PMF_DEFINE_GET_TIMESTAMP(_name) 148 149 /* 150 * This macro is used to register a PMF service, including an 151 * SMC interface to that service. 152 */ 153 #define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)\ 154 PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \ 155 PMF_DEFINE_SERVICE_DESC(_name, PMF_ARM_TIF_IMPL_ID, \ 156 _svcid, _totalid, NULL, \ 157 pmf_get_timestamp_by_mpidr_ ## _name) 158 159 /* 160 * This macro is used to register a PMF service that has an SMC interface 161 * but provides its own service-specific PMF functions. 162 */ 163 #define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \ 164 _init, _getts) \ 165 PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid, \ 166 _init, _getts) 167 168 #else 169 170 #define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) 171 #define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags) 172 #define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \ 173 _init, _getts) 174 #define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) 175 #define PMF_DECLARE_GET_TIMESTAMP(_name) 176 #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) 177 #define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval) 178 #define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval) 179 180 #endif /* ENABLE_PMF */ 181 182 /******************************************************************************* 183 * Function & variable prototypes 184 ******************************************************************************/ 185 /* PMF common functions */ 186 int pmf_get_timestamp_smc(unsigned int tid, 187 u_register_t mpidr, 188 unsigned int flags, 189 unsigned long long *ts); 190 int pmf_setup(void); 191 uintptr_t pmf_smc_handler(unsigned int smc_fid, 192 u_register_t x1, 193 u_register_t x2, 194 u_register_t x3, 195 u_register_t x4, 196 void *cookie, 197 void *handle, 198 u_register_t flags); 199 200 #endif /* __PMF_H__ */ 201