/* * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef __PMF_H__ #define __PMF_H__ #include <cassert.h> #include <pmf_helpers.h> /* * Constants used for/by PMF services. */ #define PMF_ARM_TIF_IMPL_ID 0x41 #define PMF_TID_SHIFT 0 #define PMF_TID_MASK (0xFF << PMF_TID_SHIFT) #define PMF_SVC_ID_SHIFT 10 #define PMF_SVC_ID_MASK (0x3F << PMF_SVC_ID_SHIFT) #define PMF_IMPL_ID_SHIFT 24 #define PMF_IMPL_ID_MASK (0xFFU << PMF_IMPL_ID_SHIFT) /* * Flags passed to PMF_REGISTER_SERVICE */ #define PMF_STORE_ENABLE (1 << 0) #define PMF_DUMP_ENABLE (1 << 1) /* * Flags passed to PMF_GET_TIMESTAMP_XXX * and PMF_CAPTURE_TIMESTAMP */ #define PMF_CACHE_MAINT (1 << 0) #define PMF_NO_CACHE_MAINT 0 /* * Defines for PMF SMC function ids. */ #define PMF_SMC_GET_TIMESTAMP_32 0x82000010 #define PMF_SMC_GET_TIMESTAMP_64 0xC2000010 #define PMF_NUM_SMC_CALLS 2 /* * The macros below are used to identify * PMF calls from the SMC function ID. */ #define PMF_FID_MASK 0xffe0u #define PMF_FID_VALUE 0u #define is_pmf_fid(_fid) (((_fid) & PMF_FID_MASK) == PMF_FID_VALUE) /* Following are the supported PMF service IDs */ #define PMF_PSCI_STAT_SVC_ID 0 #define PMF_RT_INSTR_SVC_ID 1 #if ENABLE_PMF /* * Convenience macros for capturing time-stamp. */ #define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) \ void pmf_capture_timestamp_with_cache_maint_ ## _name( \ unsigned int tid, \ unsigned long long ts); \ void pmf_capture_timestamp_ ## _name( \ unsigned int tid, \ unsigned long long ts); #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) \ do { \ unsigned long long ts = read_cntpct_el0(); \ if ((_flags) & PMF_CACHE_MAINT) \ pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\ else \ pmf_capture_timestamp_ ## _name((_tid), ts); \ } while (0) #define PMF_CAPTURE_AND_GET_TIMESTAMP(_name, _tid, _flags, _tsval) \ do { \ (_tsval) = read_cntpct_el0(); \ CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\ if ((_flags) & PMF_CACHE_MAINT) \ pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\ else \ pmf_capture_timestamp_ ## _name((_tid), (_tsval));\ } while (0) #define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval) \ do { \ CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\ if ((_flags) & PMF_CACHE_MAINT) \ pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\ else \ pmf_capture_timestamp_ ## _name((_tid), (_wrval));\ } while (0) /* * Convenience macros for retrieving time-stamp. */ #define PMF_DECLARE_GET_TIMESTAMP(_name) \ unsigned long long pmf_get_timestamp_by_index_ ## _name(\ unsigned int tid, \ unsigned int cpuid, \ unsigned int flags); \ unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(\ unsigned int tid, \ u_register_t mpidr, \ unsigned int flags); #define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)\ _tsval = pmf_get_timestamp_by_mpidr_ ## _name(_tid, _mpidr, _flags) #define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)\ _tsval = pmf_get_timestamp_by_index_ ## _name(_tid, _cpuid, _flags) /* Convenience macros to register a PMF service.*/ /* * This macro is used to register a PMF Service. It allocates PMF memory * and defines default service-specific PMF functions. */ #define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \ PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _totalid) \ PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags) \ PMF_DEFINE_GET_TIMESTAMP(_name) /* * This macro is used to register a PMF service, including an * SMC interface to that service. */ #define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)\ PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \ PMF_DEFINE_SERVICE_DESC(_name, PMF_ARM_TIF_IMPL_ID, \ _svcid, _totalid, NULL, \ pmf_get_timestamp_by_mpidr_ ## _name) /* * This macro is used to register a PMF service that has an SMC interface * but provides its own service-specific PMF functions. */ #define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \ _init, _getts) \ PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid, \ _init, _getts) #else #define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) #define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags) #define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \ _init, _getts) #define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) #define PMF_DECLARE_GET_TIMESTAMP(_name) #define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) #define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval) #define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval) #endif /* ENABLE_PMF */ /******************************************************************************* * Function & variable prototypes ******************************************************************************/ /* PMF common functions */ int pmf_get_timestamp_smc(unsigned int tid, u_register_t mpidr, unsigned int flags, unsigned long long *ts); int pmf_setup(void); uintptr_t pmf_smc_handler(unsigned int smc_fid, u_register_t x1, u_register_t x2, u_register_t x3, u_register_t x4, void *cookie, void *handle, u_register_t flags); #endif /* __PMF_H__ */