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

device.h (16411B)


      1/* SPDX-License-Identifier: GPL-2.0+ */
      2/*
      3 * Surface System Aggregator Module (SSAM) bus and client-device subsystem.
      4 *
      5 * Main interface for the surface-aggregator bus, surface-aggregator client
      6 * devices, and respective drivers building on top of the SSAM controller.
      7 * Provides support for non-platform/non-ACPI SSAM clients via dedicated
      8 * subsystem.
      9 *
     10 * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
     11 */
     12
     13#ifndef _LINUX_SURFACE_AGGREGATOR_DEVICE_H
     14#define _LINUX_SURFACE_AGGREGATOR_DEVICE_H
     15
     16#include <linux/device.h>
     17#include <linux/mod_devicetable.h>
     18#include <linux/types.h>
     19
     20#include <linux/surface_aggregator/controller.h>
     21
     22
     23/* -- Surface System Aggregator Module bus. --------------------------------- */
     24
     25/**
     26 * enum ssam_device_domain - SAM device domain.
     27 * @SSAM_DOMAIN_VIRTUAL:   Virtual device.
     28 * @SSAM_DOMAIN_SERIALHUB: Physical device connected via Surface Serial Hub.
     29 */
     30enum ssam_device_domain {
     31	SSAM_DOMAIN_VIRTUAL   = 0x00,
     32	SSAM_DOMAIN_SERIALHUB = 0x01,
     33};
     34
     35/**
     36 * enum ssam_virtual_tc - Target categories for the virtual SAM domain.
     37 * @SSAM_VIRTUAL_TC_HUB: Device hub category.
     38 */
     39enum ssam_virtual_tc {
     40	SSAM_VIRTUAL_TC_HUB = 0x00,
     41};
     42
     43/**
     44 * struct ssam_device_uid - Unique identifier for SSAM device.
     45 * @domain:   Domain of the device.
     46 * @category: Target category of the device.
     47 * @target:   Target ID of the device.
     48 * @instance: Instance ID of the device.
     49 * @function: Sub-function of the device. This field can be used to split a
     50 *            single SAM device into multiple virtual subdevices to separate
     51 *            different functionality of that device and allow one driver per
     52 *            such functionality.
     53 */
     54struct ssam_device_uid {
     55	u8 domain;
     56	u8 category;
     57	u8 target;
     58	u8 instance;
     59	u8 function;
     60};
     61
     62/*
     63 * Special values for device matching.
     64 *
     65 * These values are intended to be used with SSAM_DEVICE(), SSAM_VDEV(), and
     66 * SSAM_SDEV() exclusively. Specifically, they are used to initialize the
     67 * match_flags member of the device ID structure. Do not use them directly
     68 * with struct ssam_device_id or struct ssam_device_uid.
     69 */
     70#define SSAM_ANY_TID		0xffff
     71#define SSAM_ANY_IID		0xffff
     72#define SSAM_ANY_FUN		0xffff
     73
     74/**
     75 * SSAM_DEVICE() - Initialize a &struct ssam_device_id with the given
     76 * parameters.
     77 * @d:   Domain of the device.
     78 * @cat: Target category of the device.
     79 * @tid: Target ID of the device.
     80 * @iid: Instance ID of the device.
     81 * @fun: Sub-function of the device.
     82 *
     83 * Initializes a &struct ssam_device_id with the given parameters. See &struct
     84 * ssam_device_uid for details regarding the parameters. The special values
     85 * %SSAM_ANY_TID, %SSAM_ANY_IID, and %SSAM_ANY_FUN can be used to specify that
     86 * matching should ignore target ID, instance ID, and/or sub-function,
     87 * respectively. This macro initializes the ``match_flags`` field based on the
     88 * given parameters.
     89 *
     90 * Note: The parameters @d and @cat must be valid &u8 values, the parameters
     91 * @tid, @iid, and @fun must be either valid &u8 values or %SSAM_ANY_TID,
     92 * %SSAM_ANY_IID, or %SSAM_ANY_FUN, respectively. Other non-&u8 values are not
     93 * allowed.
     94 */
     95#define SSAM_DEVICE(d, cat, tid, iid, fun)					\
     96	.match_flags = (((tid) != SSAM_ANY_TID) ? SSAM_MATCH_TARGET : 0)	\
     97		     | (((iid) != SSAM_ANY_IID) ? SSAM_MATCH_INSTANCE : 0)	\
     98		     | (((fun) != SSAM_ANY_FUN) ? SSAM_MATCH_FUNCTION : 0),	\
     99	.domain   = d,								\
    100	.category = cat,							\
    101	.target   = __builtin_choose_expr((tid) != SSAM_ANY_TID, (tid), 0),	\
    102	.instance = __builtin_choose_expr((iid) != SSAM_ANY_IID, (iid), 0),	\
    103	.function = __builtin_choose_expr((fun) != SSAM_ANY_FUN, (fun), 0)
    104
    105/**
    106 * SSAM_VDEV() - Initialize a &struct ssam_device_id as virtual device with
    107 * the given parameters.
    108 * @cat: Target category of the device.
    109 * @tid: Target ID of the device.
    110 * @iid: Instance ID of the device.
    111 * @fun: Sub-function of the device.
    112 *
    113 * Initializes a &struct ssam_device_id with the given parameters in the
    114 * virtual domain. See &struct ssam_device_uid for details regarding the
    115 * parameters. The special values %SSAM_ANY_TID, %SSAM_ANY_IID, and
    116 * %SSAM_ANY_FUN can be used to specify that matching should ignore target ID,
    117 * instance ID, and/or sub-function, respectively. This macro initializes the
    118 * ``match_flags`` field based on the given parameters.
    119 *
    120 * Note: The parameter @cat must be a valid &u8 value, the parameters @tid,
    121 * @iid, and @fun must be either valid &u8 values or %SSAM_ANY_TID,
    122 * %SSAM_ANY_IID, or %SSAM_ANY_FUN, respectively. Other non-&u8 values are not
    123 * allowed.
    124 */
    125#define SSAM_VDEV(cat, tid, iid, fun) \
    126	SSAM_DEVICE(SSAM_DOMAIN_VIRTUAL, SSAM_VIRTUAL_TC_##cat, tid, iid, fun)
    127
    128/**
    129 * SSAM_SDEV() - Initialize a &struct ssam_device_id as physical SSH device
    130 * with the given parameters.
    131 * @cat: Target category of the device.
    132 * @tid: Target ID of the device.
    133 * @iid: Instance ID of the device.
    134 * @fun: Sub-function of the device.
    135 *
    136 * Initializes a &struct ssam_device_id with the given parameters in the SSH
    137 * domain. See &struct ssam_device_uid for details regarding the parameters.
    138 * The special values %SSAM_ANY_TID, %SSAM_ANY_IID, and %SSAM_ANY_FUN can be
    139 * used to specify that matching should ignore target ID, instance ID, and/or
    140 * sub-function, respectively. This macro initializes the ``match_flags``
    141 * field based on the given parameters.
    142 *
    143 * Note: The parameter @cat must be a valid &u8 value, the parameters @tid,
    144 * @iid, and @fun must be either valid &u8 values or %SSAM_ANY_TID,
    145 * %SSAM_ANY_IID, or %SSAM_ANY_FUN, respectively. Other non-&u8 values are not
    146 * allowed.
    147 */
    148#define SSAM_SDEV(cat, tid, iid, fun) \
    149	SSAM_DEVICE(SSAM_DOMAIN_SERIALHUB, SSAM_SSH_TC_##cat, tid, iid, fun)
    150
    151/**
    152 * struct ssam_device - SSAM client device.
    153 * @dev:  Driver model representation of the device.
    154 * @ctrl: SSAM controller managing this device.
    155 * @uid:  UID identifying the device.
    156 */
    157struct ssam_device {
    158	struct device dev;
    159	struct ssam_controller *ctrl;
    160
    161	struct ssam_device_uid uid;
    162};
    163
    164/**
    165 * struct ssam_device_driver - SSAM client device driver.
    166 * @driver:      Base driver model structure.
    167 * @match_table: Match table specifying which devices the driver should bind to.
    168 * @probe:       Called when the driver is being bound to a device.
    169 * @remove:      Called when the driver is being unbound from the device.
    170 */
    171struct ssam_device_driver {
    172	struct device_driver driver;
    173
    174	const struct ssam_device_id *match_table;
    175
    176	int  (*probe)(struct ssam_device *sdev);
    177	void (*remove)(struct ssam_device *sdev);
    178};
    179
    180extern struct bus_type ssam_bus_type;
    181extern const struct device_type ssam_device_type;
    182
    183/**
    184 * is_ssam_device() - Check if the given device is a SSAM client device.
    185 * @d: The device to test the type of.
    186 *
    187 * Return: Returns %true if the specified device is of type &struct
    188 * ssam_device, i.e. the device type points to %ssam_device_type, and %false
    189 * otherwise.
    190 */
    191static inline bool is_ssam_device(struct device *d)
    192{
    193	return d->type == &ssam_device_type;
    194}
    195
    196/**
    197 * to_ssam_device() - Casts the given device to a SSAM client device.
    198 * @d: The device to cast.
    199 *
    200 * Casts the given &struct device to a &struct ssam_device. The caller has to
    201 * ensure that the given device is actually enclosed in a &struct ssam_device,
    202 * e.g. by calling is_ssam_device().
    203 *
    204 * Return: Returns a pointer to the &struct ssam_device wrapping the given
    205 * device @d.
    206 */
    207static inline struct ssam_device *to_ssam_device(struct device *d)
    208{
    209	return container_of(d, struct ssam_device, dev);
    210}
    211
    212/**
    213 * to_ssam_device_driver() - Casts the given device driver to a SSAM client
    214 * device driver.
    215 * @d: The driver to cast.
    216 *
    217 * Casts the given &struct device_driver to a &struct ssam_device_driver. The
    218 * caller has to ensure that the given driver is actually enclosed in a
    219 * &struct ssam_device_driver.
    220 *
    221 * Return: Returns the pointer to the &struct ssam_device_driver wrapping the
    222 * given device driver @d.
    223 */
    224static inline
    225struct ssam_device_driver *to_ssam_device_driver(struct device_driver *d)
    226{
    227	return container_of(d, struct ssam_device_driver, driver);
    228}
    229
    230const struct ssam_device_id *ssam_device_id_match(const struct ssam_device_id *table,
    231						  const struct ssam_device_uid uid);
    232
    233const struct ssam_device_id *ssam_device_get_match(const struct ssam_device *dev);
    234
    235const void *ssam_device_get_match_data(const struct ssam_device *dev);
    236
    237struct ssam_device *ssam_device_alloc(struct ssam_controller *ctrl,
    238				      struct ssam_device_uid uid);
    239
    240int ssam_device_add(struct ssam_device *sdev);
    241void ssam_device_remove(struct ssam_device *sdev);
    242
    243/**
    244 * ssam_device_get() - Increment reference count of SSAM client device.
    245 * @sdev: The device to increment the reference count of.
    246 *
    247 * Increments the reference count of the given SSAM client device by
    248 * incrementing the reference count of the enclosed &struct device via
    249 * get_device().
    250 *
    251 * See ssam_device_put() for the counter-part of this function.
    252 *
    253 * Return: Returns the device provided as input.
    254 */
    255static inline struct ssam_device *ssam_device_get(struct ssam_device *sdev)
    256{
    257	return sdev ? to_ssam_device(get_device(&sdev->dev)) : NULL;
    258}
    259
    260/**
    261 * ssam_device_put() - Decrement reference count of SSAM client device.
    262 * @sdev: The device to decrement the reference count of.
    263 *
    264 * Decrements the reference count of the given SSAM client device by
    265 * decrementing the reference count of the enclosed &struct device via
    266 * put_device().
    267 *
    268 * See ssam_device_get() for the counter-part of this function.
    269 */
    270static inline void ssam_device_put(struct ssam_device *sdev)
    271{
    272	if (sdev)
    273		put_device(&sdev->dev);
    274}
    275
    276/**
    277 * ssam_device_get_drvdata() - Get driver-data of SSAM client device.
    278 * @sdev: The device to get the driver-data from.
    279 *
    280 * Return: Returns the driver-data of the given device, previously set via
    281 * ssam_device_set_drvdata().
    282 */
    283static inline void *ssam_device_get_drvdata(struct ssam_device *sdev)
    284{
    285	return dev_get_drvdata(&sdev->dev);
    286}
    287
    288/**
    289 * ssam_device_set_drvdata() - Set driver-data of SSAM client device.
    290 * @sdev: The device to set the driver-data of.
    291 * @data: The data to set the device's driver-data pointer to.
    292 */
    293static inline void ssam_device_set_drvdata(struct ssam_device *sdev, void *data)
    294{
    295	dev_set_drvdata(&sdev->dev, data);
    296}
    297
    298int __ssam_device_driver_register(struct ssam_device_driver *d, struct module *o);
    299void ssam_device_driver_unregister(struct ssam_device_driver *d);
    300
    301/**
    302 * ssam_device_driver_register() - Register a SSAM client device driver.
    303 * @drv: The driver to register.
    304 */
    305#define ssam_device_driver_register(drv) \
    306	__ssam_device_driver_register(drv, THIS_MODULE)
    307
    308/**
    309 * module_ssam_device_driver() - Helper macro for SSAM device driver
    310 * registration.
    311 * @drv: The driver managed by this module.
    312 *
    313 * Helper macro to register a SSAM device driver via module_init() and
    314 * module_exit(). This macro may only be used once per module and replaces the
    315 * aforementioned definitions.
    316 */
    317#define module_ssam_device_driver(drv)			\
    318	module_driver(drv, ssam_device_driver_register,	\
    319		      ssam_device_driver_unregister)
    320
    321
    322/* -- Helpers for controller and hub devices. ------------------------------- */
    323
    324#ifdef CONFIG_SURFACE_AGGREGATOR_BUS
    325void ssam_remove_clients(struct device *dev);
    326#else /* CONFIG_SURFACE_AGGREGATOR_BUS */
    327static inline void ssam_remove_clients(struct device *dev) {}
    328#endif /* CONFIG_SURFACE_AGGREGATOR_BUS */
    329
    330
    331/* -- Helpers for client-device requests. ----------------------------------- */
    332
    333/**
    334 * SSAM_DEFINE_SYNC_REQUEST_CL_N() - Define synchronous client-device SAM
    335 * request function with neither argument nor return value.
    336 * @name: Name of the generated function.
    337 * @spec: Specification (&struct ssam_request_spec_md) defining the request.
    338 *
    339 * Defines a function executing the synchronous SAM request specified by
    340 * @spec, with the request having neither argument nor return value. Device
    341 * specifying parameters are not hard-coded, but instead are provided via the
    342 * client device, specifically its UID, supplied when calling this function.
    343 * The generated function takes care of setting up the request struct, buffer
    344 * allocation, as well as execution of the request itself, returning once the
    345 * request has been fully completed. The required transport buffer will be
    346 * allocated on the stack.
    347 *
    348 * The generated function is defined as ``static int name(struct ssam_device
    349 * *sdev)``, returning the status of the request, which is zero on success and
    350 * negative on failure. The ``sdev`` parameter specifies both the target
    351 * device of the request and by association the controller via which the
    352 * request is sent.
    353 *
    354 * Refer to ssam_request_sync_onstack() for more details on the behavior of
    355 * the generated function.
    356 */
    357#define SSAM_DEFINE_SYNC_REQUEST_CL_N(name, spec...)			\
    358	SSAM_DEFINE_SYNC_REQUEST_MD_N(__raw_##name, spec)		\
    359	static int name(struct ssam_device *sdev)			\
    360	{								\
    361		return __raw_##name(sdev->ctrl, sdev->uid.target,	\
    362				    sdev->uid.instance);		\
    363	}
    364
    365/**
    366 * SSAM_DEFINE_SYNC_REQUEST_CL_W() - Define synchronous client-device SAM
    367 * request function with argument.
    368 * @name:  Name of the generated function.
    369 * @atype: Type of the request's argument.
    370 * @spec:  Specification (&struct ssam_request_spec_md) defining the request.
    371 *
    372 * Defines a function executing the synchronous SAM request specified by
    373 * @spec, with the request taking an argument of type @atype and having no
    374 * return value. Device specifying parameters are not hard-coded, but instead
    375 * are provided via the client device, specifically its UID, supplied when
    376 * calling this function. The generated function takes care of setting up the
    377 * request struct, buffer allocation, as well as execution of the request
    378 * itself, returning once the request has been fully completed. The required
    379 * transport buffer will be allocated on the stack.
    380 *
    381 * The generated function is defined as ``static int name(struct ssam_device
    382 * *sdev, const atype *arg)``, returning the status of the request, which is
    383 * zero on success and negative on failure. The ``sdev`` parameter specifies
    384 * both the target device of the request and by association the controller via
    385 * which the request is sent. The request's argument is specified via the
    386 * ``arg`` pointer.
    387 *
    388 * Refer to ssam_request_sync_onstack() for more details on the behavior of
    389 * the generated function.
    390 */
    391#define SSAM_DEFINE_SYNC_REQUEST_CL_W(name, atype, spec...)		\
    392	SSAM_DEFINE_SYNC_REQUEST_MD_W(__raw_##name, atype, spec)	\
    393	static int name(struct ssam_device *sdev, const atype *arg)	\
    394	{								\
    395		return __raw_##name(sdev->ctrl, sdev->uid.target,	\
    396				    sdev->uid.instance, arg);		\
    397	}
    398
    399/**
    400 * SSAM_DEFINE_SYNC_REQUEST_CL_R() - Define synchronous client-device SAM
    401 * request function with return value.
    402 * @name:  Name of the generated function.
    403 * @rtype: Type of the request's return value.
    404 * @spec:  Specification (&struct ssam_request_spec_md) defining the request.
    405 *
    406 * Defines a function executing the synchronous SAM request specified by
    407 * @spec, with the request taking no argument but having a return value of
    408 * type @rtype. Device specifying parameters are not hard-coded, but instead
    409 * are provided via the client device, specifically its UID, supplied when
    410 * calling this function. The generated function takes care of setting up the
    411 * request struct, buffer allocation, as well as execution of the request
    412 * itself, returning once the request has been fully completed. The required
    413 * transport buffer will be allocated on the stack.
    414 *
    415 * The generated function is defined as ``static int name(struct ssam_device
    416 * *sdev, rtype *ret)``, returning the status of the request, which is zero on
    417 * success and negative on failure. The ``sdev`` parameter specifies both the
    418 * target device of the request and by association the controller via which
    419 * the request is sent. The request's return value is written to the memory
    420 * pointed to by the ``ret`` parameter.
    421 *
    422 * Refer to ssam_request_sync_onstack() for more details on the behavior of
    423 * the generated function.
    424 */
    425#define SSAM_DEFINE_SYNC_REQUEST_CL_R(name, rtype, spec...)		\
    426	SSAM_DEFINE_SYNC_REQUEST_MD_R(__raw_##name, rtype, spec)	\
    427	static int name(struct ssam_device *sdev, rtype *ret)		\
    428	{								\
    429		return __raw_##name(sdev->ctrl, sdev->uid.target,	\
    430				    sdev->uid.instance, ret);		\
    431	}
    432
    433#endif /* _LINUX_SURFACE_AGGREGATOR_DEVICE_H */