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