cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

core.c (12937B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Intel SoC Core Telemetry Driver
      4 * Copyright (C) 2015, Intel Corporation.
      5 * All Rights Reserved.
      6 *
      7 * Telemetry Framework provides platform related PM and performance statistics.
      8 * This file provides the core telemetry API implementation.
      9 */
     10#include <linux/device.h>
     11#include <linux/module.h>
     12
     13#include <asm/intel_telemetry.h>
     14
     15#define DRIVER_NAME "intel_telemetry_core"
     16
     17struct telemetry_core_config {
     18	struct telemetry_plt_config *plt_config;
     19	const struct telemetry_core_ops *telem_ops;
     20};
     21
     22static struct telemetry_core_config telm_core_conf;
     23
     24static int telemetry_def_update_events(struct telemetry_evtconfig pss_evtconfig,
     25				      struct telemetry_evtconfig ioss_evtconfig)
     26{
     27	return 0;
     28}
     29
     30static int telemetry_def_set_sampling_period(u8 pss_period, u8 ioss_period)
     31{
     32	return 0;
     33}
     34
     35static int telemetry_def_get_sampling_period(u8 *pss_min_period,
     36					     u8 *pss_max_period,
     37					     u8 *ioss_min_period,
     38					     u8 *ioss_max_period)
     39{
     40	return 0;
     41}
     42
     43static int telemetry_def_get_eventconfig(
     44			struct telemetry_evtconfig *pss_evtconfig,
     45			struct telemetry_evtconfig *ioss_evtconfig,
     46			int pss_len, int ioss_len)
     47{
     48	return 0;
     49}
     50
     51static int telemetry_def_get_trace_verbosity(enum telemetry_unit telem_unit,
     52					     u32 *verbosity)
     53{
     54	return 0;
     55}
     56
     57
     58static int telemetry_def_set_trace_verbosity(enum telemetry_unit telem_unit,
     59					     u32 verbosity)
     60{
     61	return 0;
     62}
     63
     64static int telemetry_def_raw_read_eventlog(enum telemetry_unit telem_unit,
     65					   struct telemetry_evtlog *evtlog,
     66					   int len, int log_all_evts)
     67{
     68	return 0;
     69}
     70
     71static int telemetry_def_read_eventlog(enum telemetry_unit telem_unit,
     72				       struct telemetry_evtlog *evtlog,
     73				       int len, int log_all_evts)
     74{
     75	return 0;
     76}
     77
     78static int telemetry_def_add_events(u8 num_pss_evts, u8 num_ioss_evts,
     79				    u32 *pss_evtmap, u32 *ioss_evtmap)
     80{
     81	return 0;
     82}
     83
     84static int telemetry_def_reset_events(void)
     85{
     86	return 0;
     87}
     88
     89static const struct telemetry_core_ops telm_defpltops = {
     90	.set_sampling_period = telemetry_def_set_sampling_period,
     91	.get_sampling_period = telemetry_def_get_sampling_period,
     92	.get_trace_verbosity = telemetry_def_get_trace_verbosity,
     93	.set_trace_verbosity = telemetry_def_set_trace_verbosity,
     94	.raw_read_eventlog = telemetry_def_raw_read_eventlog,
     95	.get_eventconfig = telemetry_def_get_eventconfig,
     96	.read_eventlog = telemetry_def_read_eventlog,
     97	.update_events = telemetry_def_update_events,
     98	.reset_events = telemetry_def_reset_events,
     99	.add_events = telemetry_def_add_events,
    100};
    101
    102/**
    103 * telemetry_update_events() - Update telemetry Configuration
    104 * @pss_evtconfig: PSS related config. No change if num_evts = 0.
    105 * @pss_evtconfig: IOSS related config. No change if num_evts = 0.
    106 *
    107 * This API updates the IOSS & PSS Telemetry configuration. Old config
    108 * is overwritten. Call telemetry_reset_events when logging is over
    109 * All sample period values should be in the form of:
    110 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
    111 *
    112 * Return: 0 success, < 0 for failure
    113 */
    114int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig,
    115			    struct telemetry_evtconfig ioss_evtconfig)
    116{
    117	return telm_core_conf.telem_ops->update_events(pss_evtconfig,
    118						       ioss_evtconfig);
    119}
    120EXPORT_SYMBOL_GPL(telemetry_update_events);
    121
    122
    123/**
    124 * telemetry_set_sampling_period() - Sets the IOSS & PSS sampling period
    125 * @pss_period:  placeholder for PSS Period to be set.
    126 *		 Set to 0 if not required to be updated
    127 * @ioss_period: placeholder for IOSS Period to be set
    128 *		 Set to 0 if not required to be updated
    129 *
    130 * All values should be in the form of:
    131 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
    132 *
    133 * Return: 0 success, < 0 for failure
    134 */
    135int telemetry_set_sampling_period(u8 pss_period, u8 ioss_period)
    136{
    137	return telm_core_conf.telem_ops->set_sampling_period(pss_period,
    138							     ioss_period);
    139}
    140EXPORT_SYMBOL_GPL(telemetry_set_sampling_period);
    141
    142/**
    143 * telemetry_get_sampling_period() - Get IOSS & PSS min & max sampling period
    144 * @pss_min_period:  placeholder for PSS Min Period supported
    145 * @pss_max_period:  placeholder for PSS Max Period supported
    146 * @ioss_min_period: placeholder for IOSS Min Period supported
    147 * @ioss_max_period: placeholder for IOSS Max Period supported
    148 *
    149 * All values should be in the form of:
    150 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
    151 *
    152 * Return: 0 success, < 0 for failure
    153 */
    154int telemetry_get_sampling_period(u8 *pss_min_period, u8 *pss_max_period,
    155				  u8 *ioss_min_period, u8 *ioss_max_period)
    156{
    157	return telm_core_conf.telem_ops->get_sampling_period(pss_min_period,
    158							     pss_max_period,
    159							     ioss_min_period,
    160							     ioss_max_period);
    161}
    162EXPORT_SYMBOL_GPL(telemetry_get_sampling_period);
    163
    164
    165/**
    166 * telemetry_reset_events() - Restore the IOSS & PSS configuration to default
    167 *
    168 * Return: 0 success, < 0 for failure
    169 */
    170int telemetry_reset_events(void)
    171{
    172	return telm_core_conf.telem_ops->reset_events();
    173}
    174EXPORT_SYMBOL_GPL(telemetry_reset_events);
    175
    176/**
    177 * telemetry_get_eventconfig() - Returns the pss and ioss events enabled
    178 * @pss_evtconfig: Pointer to PSS related configuration.
    179 * @pss_evtconfig: Pointer to IOSS related configuration.
    180 * @pss_len:	   Number of u32 elements allocated for pss_evtconfig array
    181 * @ioss_len:	   Number of u32 elements allocated for ioss_evtconfig array
    182 *
    183 * Return: 0 success, < 0 for failure
    184 */
    185int telemetry_get_eventconfig(struct telemetry_evtconfig *pss_evtconfig,
    186			      struct telemetry_evtconfig *ioss_evtconfig,
    187			      int pss_len, int ioss_len)
    188{
    189	return telm_core_conf.telem_ops->get_eventconfig(pss_evtconfig,
    190							 ioss_evtconfig,
    191							 pss_len, ioss_len);
    192}
    193EXPORT_SYMBOL_GPL(telemetry_get_eventconfig);
    194
    195/**
    196 * telemetry_add_events() - Add IOSS & PSS configuration to existing settings.
    197 * @num_pss_evts:  Number of PSS Events (<29) in pss_evtmap. Can be 0.
    198 * @num_ioss_evts: Number of IOSS Events (<29) in ioss_evtmap. Can be 0.
    199 * @pss_evtmap:    Array of PSS Event-IDs to Enable
    200 * @ioss_evtmap:   Array of PSS Event-IDs to Enable
    201 *
    202 * Events are appended to Old Configuration. In case of total events > 28, it
    203 * returns error. Call telemetry_reset_events to reset after eventlog done
    204 *
    205 * Return: 0 success, < 0 for failure
    206 */
    207int telemetry_add_events(u8 num_pss_evts, u8 num_ioss_evts,
    208			 u32 *pss_evtmap, u32 *ioss_evtmap)
    209{
    210	return telm_core_conf.telem_ops->add_events(num_pss_evts,
    211						    num_ioss_evts, pss_evtmap,
    212						    ioss_evtmap);
    213}
    214EXPORT_SYMBOL_GPL(telemetry_add_events);
    215
    216/**
    217 * telemetry_read_events() - Fetches samples as specified by evtlog.telem_evt_id
    218 * @telem_unit: Specify whether IOSS or PSS Read
    219 * @evtlog:     Array of telemetry_evtlog structs to fill data
    220 *		evtlog.telem_evt_id specifies the ids to read
    221 * @len:	Length of array of evtlog
    222 *
    223 * Return: number of eventlogs read for success, < 0 for failure
    224 */
    225int telemetry_read_events(enum telemetry_unit telem_unit,
    226			  struct telemetry_evtlog *evtlog, int len)
    227{
    228	return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
    229						       len, 0);
    230}
    231EXPORT_SYMBOL_GPL(telemetry_read_events);
    232
    233/**
    234 * telemetry_raw_read_events() - Fetch samples specified by evtlog.telem_evt_id
    235 * @telem_unit: Specify whether IOSS or PSS Read
    236 * @evtlog:	Array of telemetry_evtlog structs to fill data
    237 *		evtlog.telem_evt_id specifies the ids to read
    238 * @len:	Length of array of evtlog
    239 *
    240 * The caller must take care of locking in this case.
    241 *
    242 * Return: number of eventlogs read for success, < 0 for failure
    243 */
    244int telemetry_raw_read_events(enum telemetry_unit telem_unit,
    245			      struct telemetry_evtlog *evtlog, int len)
    246{
    247	return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
    248							   len, 0);
    249}
    250EXPORT_SYMBOL_GPL(telemetry_raw_read_events);
    251
    252/**
    253 * telemetry_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
    254 * @telem_unit: Specify whether IOSS or PSS Read
    255 * @evtlog:	Array of telemetry_evtlog structs to fill data
    256 * @len:	Length of array of evtlog
    257 *
    258 * Return: number of eventlogs read for success, < 0 for failure
    259 */
    260int telemetry_read_eventlog(enum telemetry_unit telem_unit,
    261			    struct telemetry_evtlog *evtlog, int len)
    262{
    263	return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
    264						       len, 1);
    265}
    266EXPORT_SYMBOL_GPL(telemetry_read_eventlog);
    267
    268/**
    269 * telemetry_raw_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
    270 * @telem_unit: Specify whether IOSS or PSS Read
    271 * @evtlog:	Array of telemetry_evtlog structs to fill data
    272 * @len:	Length of array of evtlog
    273 *
    274 * The caller must take care of locking in this case.
    275 *
    276 * Return: number of eventlogs read for success, < 0 for failure
    277 */
    278int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit,
    279				struct telemetry_evtlog *evtlog, int len)
    280{
    281	return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
    282							   len, 1);
    283}
    284EXPORT_SYMBOL_GPL(telemetry_raw_read_eventlog);
    285
    286
    287/**
    288 * telemetry_get_trace_verbosity() - Get the IOSS & PSS Trace verbosity
    289 * @telem_unit: Specify whether IOSS or PSS Read
    290 * @verbosity:	Pointer to return Verbosity
    291 *
    292 * Return: 0 success, < 0 for failure
    293 */
    294int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit,
    295				  u32 *verbosity)
    296{
    297	return telm_core_conf.telem_ops->get_trace_verbosity(telem_unit,
    298							     verbosity);
    299}
    300EXPORT_SYMBOL_GPL(telemetry_get_trace_verbosity);
    301
    302
    303/**
    304 * telemetry_set_trace_verbosity() - Update the IOSS & PSS Trace verbosity
    305 * @telem_unit: Specify whether IOSS or PSS Read
    306 * @verbosity:	Verbosity to set
    307 *
    308 * Return: 0 success, < 0 for failure
    309 */
    310int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit, u32 verbosity)
    311{
    312	return telm_core_conf.telem_ops->set_trace_verbosity(telem_unit,
    313							     verbosity);
    314}
    315EXPORT_SYMBOL_GPL(telemetry_set_trace_verbosity);
    316
    317/**
    318 * telemetry_set_pltdata() - Set the platform specific Data
    319 * @ops:	Pointer to ops structure
    320 * @pltconfig:	Platform config data
    321 *
    322 * Usage by other than telemetry pltdrv module is invalid
    323 *
    324 * Return: 0 success, < 0 for failure
    325 */
    326int telemetry_set_pltdata(const struct telemetry_core_ops *ops,
    327			  struct telemetry_plt_config *pltconfig)
    328{
    329	if (ops)
    330		telm_core_conf.telem_ops = ops;
    331
    332	if (pltconfig)
    333		telm_core_conf.plt_config = pltconfig;
    334
    335	return 0;
    336}
    337EXPORT_SYMBOL_GPL(telemetry_set_pltdata);
    338
    339/**
    340 * telemetry_clear_pltdata() - Clear the platform specific Data
    341 *
    342 * Usage by other than telemetry pltdrv module is invalid
    343 *
    344 * Return: 0 success, < 0 for failure
    345 */
    346int telemetry_clear_pltdata(void)
    347{
    348	telm_core_conf.telem_ops = &telm_defpltops;
    349	telm_core_conf.plt_config = NULL;
    350
    351	return 0;
    352}
    353EXPORT_SYMBOL_GPL(telemetry_clear_pltdata);
    354
    355/**
    356 * telemetry_get_pltdata() - Return telemetry platform config
    357 *
    358 * May be used by other telemetry modules to get platform specific
    359 * configuration.
    360 */
    361struct telemetry_plt_config *telemetry_get_pltdata(void)
    362{
    363	return telm_core_conf.plt_config;
    364}
    365EXPORT_SYMBOL_GPL(telemetry_get_pltdata);
    366
    367static inline int telemetry_get_pssevtname(enum telemetry_unit telem_unit,
    368					   const char **name, int len)
    369{
    370	struct telemetry_unit_config psscfg;
    371	int i;
    372
    373	if (!telm_core_conf.plt_config)
    374		return -EINVAL;
    375
    376	psscfg = telm_core_conf.plt_config->pss_config;
    377
    378	if (len > psscfg.ssram_evts_used)
    379		len = psscfg.ssram_evts_used;
    380
    381	for (i = 0; i < len; i++)
    382		name[i] = psscfg.telem_evts[i].name;
    383
    384	return 0;
    385}
    386
    387static inline int telemetry_get_iossevtname(enum telemetry_unit telem_unit,
    388					    const char **name, int len)
    389{
    390	struct telemetry_unit_config iosscfg;
    391	int i;
    392
    393	if (!(telm_core_conf.plt_config))
    394		return -EINVAL;
    395
    396	iosscfg = telm_core_conf.plt_config->ioss_config;
    397
    398	if (len > iosscfg.ssram_evts_used)
    399		len = iosscfg.ssram_evts_used;
    400
    401	for (i = 0; i < len; i++)
    402		name[i] = iosscfg.telem_evts[i].name;
    403
    404	return 0;
    405
    406}
    407
    408/**
    409 * telemetry_get_evtname() - Checkif platform config is valid
    410 * @telem_unit:	Telemetry Unit to check
    411 * @name:	Array of character pointers to contain name
    412 * @len:	length of array name provided by user
    413 *
    414 * Usage by other than telemetry debugfs module is invalid
    415 *
    416 * Return: 0 success, < 0 for failure
    417 */
    418int telemetry_get_evtname(enum telemetry_unit telem_unit,
    419			  const char **name, int len)
    420{
    421	int ret = -EINVAL;
    422
    423	if (telem_unit == TELEM_PSS)
    424		ret = telemetry_get_pssevtname(telem_unit, name, len);
    425
    426	else if (telem_unit == TELEM_IOSS)
    427		ret = telemetry_get_iossevtname(telem_unit, name, len);
    428
    429	return ret;
    430}
    431EXPORT_SYMBOL_GPL(telemetry_get_evtname);
    432
    433static int __init telemetry_module_init(void)
    434{
    435	pr_info(pr_fmt(DRIVER_NAME) " Init\n");
    436
    437	telm_core_conf.telem_ops = &telm_defpltops;
    438	return 0;
    439}
    440
    441static void __exit telemetry_module_exit(void)
    442{
    443}
    444
    445module_init(telemetry_module_init);
    446module_exit(telemetry_module_exit);
    447
    448MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
    449MODULE_DESCRIPTION("Intel SoC Telemetry Interface");
    450MODULE_LICENSE("GPL v2");