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 */ 162int pmf_get_timestamp_smc(unsigned int tid, 163 u_register_t mpidr, 164 unsigned int flags, 165 unsigned long long *ts); 166int pmf_setup(void); 167uintptr_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