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 (0x41000000) 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 (0xFF << 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 79 #if ENABLE_PMF 80 /* 81 * Convenience macros for capturing time-stamp. 82 */ 83 #define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) \ 84 void pmf_capture_timestamp_with_cache_maint_ ## _name( \ 85 unsigned int tid, \ 86 unsigned long long ts); \ 87 void pmf_capture_timestamp_ ## _name( \ 88 unsigned int tid, \ 89 unsigned long long ts); 90 91 #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) \ 92 do { \ 93 unsigned long long ts = read_cntpct_el0(); \ 94 if ((_flags) & PMF_CACHE_MAINT) \ 95 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\ 96 else \ 97 pmf_capture_timestamp_ ## _name((_tid), ts); \ 98 } while (0) 99 100 #define PMF_CAPTURE_AND_GET_TIMESTAMP(_name, _tid, _flags, _tsval) \ 101 do { \ 102 (_tsval) = read_cntpct_el0(); \ 103 CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\ 104 if ((_flags) & PMF_CACHE_MAINT) \ 105 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\ 106 else \ 107 pmf_capture_timestamp_ ## _name((_tid), (_tsval));\ 108 } while (0) 109 110 #define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval) \ 111 do { \ 112 CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\ 113 if ((_flags) & PMF_CACHE_MAINT) \ 114 pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\ 115 else \ 116 pmf_capture_timestamp_ ## _name((_tid), (_wrval));\ 117 } while (0) 118 119 /* 120 * Convenience macros for retrieving time-stamp. 121 */ 122 #define PMF_DECLARE_GET_TIMESTAMP(_name) \ 123 unsigned long long pmf_get_timestamp_by_index_ ## _name(\ 124 unsigned int tid, \ 125 unsigned int cpuid, \ 126 unsigned int flags); \ 127 unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(\ 128 unsigned int tid, \ 129 u_register_t mpidr, \ 130 unsigned int flags); 131 132 #define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)\ 133 _tsval = pmf_get_timestamp_by_mpidr_ ## _name(_tid, _mpidr, _flags) 134 135 #define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)\ 136 _tsval = pmf_get_timestamp_by_index_ ## _name(_tid, _cpuid, _flags) 137 138 /* Convenience macros to register a PMF service.*/ 139 /* 140 * This macro is used to register a PMF Service. It allocates PMF memory 141 * and defines default service-specific PMF functions. 142 */ 143 #define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \ 144 PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _totalid) \ 145 PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags) \ 146 PMF_DEFINE_GET_TIMESTAMP(_name) 147 148 /* 149 * This macro is used to register a PMF service, including an 150 * SMC interface to that service. 151 */ 152 #define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)\ 153 PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \ 154 PMF_DEFINE_SERVICE_DESC(_name, PMF_ARM_TIF_IMPL_ID, \ 155 _svcid, _totalid, NULL, \ 156 pmf_get_timestamp_by_mpidr_ ## _name) 157 158 /* 159 * This macro is used to register a PMF service that has an SMC interface 160 * but provides its own service-specific PMF functions. 161 */ 162 #define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \ 163 _init, _getts) \ 164 PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid, \ 165 _init, _getts) 166 167 #else 168 169 #define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) 170 #define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags) 171 #define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \ 172 _init, _getts) 173 #define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) 174 #define PMF_DECLARE_GET_TIMESTAMP(_name) 175 #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) 176 #define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval) 177 #define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval) 178 179 #endif /* ENABLE_PMF */ 180 181 /******************************************************************************* 182 * Function & variable prototypes 183 ******************************************************************************/ 184 /* PMF common functions */ 185 int pmf_get_timestamp_smc(unsigned int tid, 186 u_register_t mpidr, 187 unsigned int flags, 188 unsigned long long *ts); 189 int pmf_setup(void); 190 uintptr_t pmf_smc_handler(unsigned int smc_fid, 191 u_register_t x1, 192 u_register_t x2, 193 u_register_t x3, 194 u_register_t x4, 195 void *cookie, 196 void *handle, 197 u_register_t flags); 198 199 #endif /* __PMF_H__ */ 200