1*f6217f89SApple OSS Distributions /* 2*f6217f89SApple OSS Distributions * Copyright (c) 2017 Apple Inc. All rights reserved. 3*f6217f89SApple OSS Distributions */ 4*f6217f89SApple OSS Distributions 5*f6217f89SApple OSS Distributions #pragma once 6*f6217f89SApple OSS Distributions 7*f6217f89SApple OSS Distributions #ifdef KERNEL_PRIVATE 8*f6217f89SApple OSS Distributions #ifdef __cplusplus 9*f6217f89SApple OSS Distributions 10*f6217f89SApple OSS Distributions #include <IOKit/IOService.h> 11*f6217f89SApple OSS Distributions #include <stdatomic.h> 12*f6217f89SApple OSS Distributions #include <kern/bits.h> 13*f6217f89SApple OSS Distributions #include <libkern/c++/OSPtr.h> 14*f6217f89SApple OSS Distributions 15*f6217f89SApple OSS Distributions struct thread_group; 16*f6217f89SApple OSS Distributions 17*f6217f89SApple OSS Distributions enum{ 18*f6217f89SApple OSS Distributions kIOPerfControlClientWorkUntracked = 0, 19*f6217f89SApple OSS Distributions }; 20*f6217f89SApple OSS Distributions 21*f6217f89SApple OSS Distributions /*! 22*f6217f89SApple OSS Distributions * @class IOPerfControlClient : public OSObject 23*f6217f89SApple OSS Distributions * @abstract Class which implements an interface allowing device drivers to participate in performance control. 24*f6217f89SApple OSS Distributions * @discussion TODO 25*f6217f89SApple OSS Distributions */ 26*f6217f89SApple OSS Distributions class IOPerfControlClient final : public OSObject 27*f6217f89SApple OSS Distributions { 28*f6217f89SApple OSS Distributions OSDeclareDefaultStructors(IOPerfControlClient); 29*f6217f89SApple OSS Distributions 30*f6217f89SApple OSS Distributions protected: 31*f6217f89SApple OSS Distributions virtual bool init(IOService *driver, uint64_t maxWorkCapacity); 32*f6217f89SApple OSS Distributions virtual void free() APPLE_KEXT_OVERRIDE; 33*f6217f89SApple OSS Distributions 34*f6217f89SApple OSS Distributions public: 35*f6217f89SApple OSS Distributions /*! 36*f6217f89SApple OSS Distributions * @function copyClient 37*f6217f89SApple OSS Distributions * @abstract Return a retained reference to a client object, to be released by the driver. It may be 38*f6217f89SApple OSS Distributions * shared with other drivers in the system. 39*f6217f89SApple OSS Distributions * @param driver The device driver that will be using this interface. 40*f6217f89SApple OSS Distributions * @param maxWorkCapacity The maximum number of concurrent work items supported by the device driver. 41*f6217f89SApple OSS Distributions * @returns An instance of IOPerfControlClient. 42*f6217f89SApple OSS Distributions */ 43*f6217f89SApple OSS Distributions static IOPerfControlClient *copyClient(IOService *driver, uint64_t maxWorkCapacity); 44*f6217f89SApple OSS Distributions 45*f6217f89SApple OSS Distributions __enum_decl(IOPCDeviceType, uint8_t, { 46*f6217f89SApple OSS Distributions IOPCDeviceTypeUnknown = 0x0, 47*f6217f89SApple OSS Distributions IOPCDeviceTypeGPU = 0x1, 48*f6217f89SApple OSS Distributions IOPCDeviceTypeANE = 0x2, 49*f6217f89SApple OSS Distributions IOPCDeviceTypeMSR = 0x3, 50*f6217f89SApple OSS Distributions IOPCDeviceTypeStorage = 0x4, 51*f6217f89SApple OSS Distributions IOPCDeviceTypeMax = 0x5, 52*f6217f89SApple OSS Distributions }); 53*f6217f89SApple OSS Distributions /*! 54*f6217f89SApple OSS Distributions * @function copyClientForDeviceType 55*f6217f89SApple OSS Distributions * @abstract Return a retained reference to a client object, to be released by the driver. It may be 56*f6217f89SApple OSS Distributions * shared with other drivers in the system. 57*f6217f89SApple OSS Distributions * @param driver The device driver that will be using this interface. 58*f6217f89SApple OSS Distributions * @param maxWorkCapacity The maximum number of concurrent work items supported by the device driver. 59*f6217f89SApple OSS Distributions * @param deviceType The type of device that this driver controls. Unknown is fine to use for devices not listed. 60*f6217f89SApple OSS Distributions * @returns An instance of IOPerfControlClient. 61*f6217f89SApple OSS Distributions */ 62*f6217f89SApple OSS Distributions static IOPerfControlClient *copyClientForDeviceType(IOService *driver, uint64_t maxWorkCapacity, IOPCDeviceType deviceType); 63*f6217f89SApple OSS Distributions 64*f6217f89SApple OSS Distributions /*! 65*f6217f89SApple OSS Distributions * @function registerDevice 66*f6217f89SApple OSS Distributions * @abstract Inform the system that work will be dispatched to a device in the future. 67*f6217f89SApple OSS Distributions * @discussion The system will do some one-time setup work associated with the device, and may block the 68*f6217f89SApple OSS Distributions * current thread during the setup. Devices should not be passed to work workSubmit, workSubmitAndBegin, 69*f6217f89SApple OSS Distributions * workBegin, or workEnd until they have been successfully registered. The unregistration process happens 70*f6217f89SApple OSS Distributions * automatically when the device object is deallocated. 71*f6217f89SApple OSS Distributions * @param device The device object. Some platforms require device to be a specific subclass of IOService. 72*f6217f89SApple OSS Distributions * @returns kIOReturnSuccess or an IOReturn error code 73*f6217f89SApple OSS Distributions */ 74*f6217f89SApple OSS Distributions virtual IOReturn registerDevice(IOService *driver, IOService *device); 75*f6217f89SApple OSS Distributions 76*f6217f89SApple OSS Distributions /*! 77*f6217f89SApple OSS Distributions * @function unregisterDevice 78*f6217f89SApple OSS Distributions * @abstract Inform the system that work will be no longer be dispatched to a device in the future. 79*f6217f89SApple OSS Distributions * @discussion This call is optional as the unregistration process happens automatically when the device 80*f6217f89SApple OSS Distributions * object is deallocated. This call may block the current thread and/or acquire locks. It should not be 81*f6217f89SApple OSS Distributions * called until after all submitted work has been ended using workEnd. 82*f6217f89SApple OSS Distributions * @param device The device object. Some platforms require device to be a specific subclass of IOService. 83*f6217f89SApple OSS Distributions */ 84*f6217f89SApple OSS Distributions virtual void unregisterDevice(IOService *driver, IOService *device); 85*f6217f89SApple OSS Distributions 86*f6217f89SApple OSS Distributions /*! 87*f6217f89SApple OSS Distributions * @struct WorkSubmitArgs 88*f6217f89SApple OSS Distributions * @discussion Drivers may submit additional device-specific arguments related to the submission of a work item 89*f6217f89SApple OSS Distributions * by passing a struct with WorkSubmitArgs as its first member. Note: Drivers are responsible for publishing 90*f6217f89SApple OSS Distributions * a header file describing these arguments. 91*f6217f89SApple OSS Distributions */ 92*f6217f89SApple OSS Distributions struct WorkSubmitArgs { 93*f6217f89SApple OSS Distributions uint32_t version; 94*f6217f89SApple OSS Distributions uint32_t size; 95*f6217f89SApple OSS Distributions uint64_t submit_time; 96*f6217f89SApple OSS Distributions uint64_t reserved[4]; 97*f6217f89SApple OSS Distributions void *driver_data; 98*f6217f89SApple OSS Distributions }; 99*f6217f89SApple OSS Distributions 100*f6217f89SApple OSS Distributions /*! 101*f6217f89SApple OSS Distributions * @function workSubmit 102*f6217f89SApple OSS Distributions * @abstract Tell the performance controller that work was submitted. 103*f6217f89SApple OSS Distributions * @param device The device that will execute the work. Some platforms require device to be a 104*f6217f89SApple OSS Distributions * specific subclass of IOService. 105*f6217f89SApple OSS Distributions * @param args Optional device-specific arguments related to the submission of this work item. 106*f6217f89SApple OSS Distributions * @returns A token representing this work item, which must be passed to workEnd when the work is finished 107*f6217f89SApple OSS Distributions * unless the token equals kIOPerfControlClientWorkUntracked. Failure to do this will result in memory leaks 108*f6217f89SApple OSS Distributions * and a degradation of system performance. 109*f6217f89SApple OSS Distributions */ 110*f6217f89SApple OSS Distributions virtual uint64_t workSubmit(IOService *device, WorkSubmitArgs *args = nullptr); 111*f6217f89SApple OSS Distributions 112*f6217f89SApple OSS Distributions /*! 113*f6217f89SApple OSS Distributions * @struct WorkBeginArgs 114*f6217f89SApple OSS Distributions * @discussion Drivers may submit additional device-specific arguments related to the start of a work item 115*f6217f89SApple OSS Distributions * by passing a struct with WorkBeginArgs as its first member. Note: Drivers are responsible for publishing 116*f6217f89SApple OSS Distributions * a header file describing these arguments. 117*f6217f89SApple OSS Distributions */ 118*f6217f89SApple OSS Distributions struct WorkBeginArgs { 119*f6217f89SApple OSS Distributions uint32_t version; 120*f6217f89SApple OSS Distributions uint32_t size; 121*f6217f89SApple OSS Distributions uint64_t begin_time; 122*f6217f89SApple OSS Distributions uint64_t reserved[4]; 123*f6217f89SApple OSS Distributions void *driver_data; 124*f6217f89SApple OSS Distributions }; 125*f6217f89SApple OSS Distributions 126*f6217f89SApple OSS Distributions /*! 127*f6217f89SApple OSS Distributions * @function workSubmitAndBegin 128*f6217f89SApple OSS Distributions * @abstract Tell the performance controller that work was submitted and immediately began executing. 129*f6217f89SApple OSS Distributions * @param device The device that is executing the work. Some platforms require device to be a 130*f6217f89SApple OSS Distributions * specific subclass of IOService. 131*f6217f89SApple OSS Distributions * @param submitArgs Optional device-specific arguments related to the submission of this work item. 132*f6217f89SApple OSS Distributions * @param beginArgs Optional device-specific arguments related to the start of this work item. 133*f6217f89SApple OSS Distributions * @returns A token representing this work item, which must be passed to workEnd when the work is finished 134*f6217f89SApple OSS Distributions * unless the token equals kIOPerfControlClientWorkUntracked. Failure to do this will result in memory leaks 135*f6217f89SApple OSS Distributions * and a degradation of system performance. 136*f6217f89SApple OSS Distributions */ 137*f6217f89SApple OSS Distributions virtual uint64_t workSubmitAndBegin(IOService *device, WorkSubmitArgs *submitArgs = nullptr, 138*f6217f89SApple OSS Distributions WorkBeginArgs *beginArgs = nullptr); 139*f6217f89SApple OSS Distributions 140*f6217f89SApple OSS Distributions /*! 141*f6217f89SApple OSS Distributions * @function workBegin 142*f6217f89SApple OSS Distributions * @abstract Tell the performance controller that previously submitted work began executing. 143*f6217f89SApple OSS Distributions * @param device The device that is executing the work. Some platforms require device to be a 144*f6217f89SApple OSS Distributions * specific subclass of IOService. 145*f6217f89SApple OSS Distributions * @param args Optional device-specific arguments related to the start of this work item. 146*f6217f89SApple OSS Distributions */ 147*f6217f89SApple OSS Distributions virtual void workBegin(IOService *device, uint64_t token, WorkBeginArgs *args = nullptr); 148*f6217f89SApple OSS Distributions 149*f6217f89SApple OSS Distributions /*! 150*f6217f89SApple OSS Distributions * @struct WorkEndArgs 151*f6217f89SApple OSS Distributions * @discussion Drivers may submit additional device-specific arguments related to the end of a work item 152*f6217f89SApple OSS Distributions * by passing a struct with WorkEndArgs as its first member. Note: Drivers are responsible for publishing 153*f6217f89SApple OSS Distributions * a header file describing these arguments. 154*f6217f89SApple OSS Distributions */ 155*f6217f89SApple OSS Distributions struct WorkEndArgs { 156*f6217f89SApple OSS Distributions uint32_t version; 157*f6217f89SApple OSS Distributions uint32_t size; 158*f6217f89SApple OSS Distributions uint64_t end_time; 159*f6217f89SApple OSS Distributions uint64_t reserved[4]; 160*f6217f89SApple OSS Distributions void *driver_data; 161*f6217f89SApple OSS Distributions }; 162*f6217f89SApple OSS Distributions 163*f6217f89SApple OSS Distributions /*! 164*f6217f89SApple OSS Distributions * @function workEnd 165*f6217f89SApple OSS Distributions * @abstract Tell the performance controller that previously started work finished executing. 166*f6217f89SApple OSS Distributions * @param device The device that executed the work. Some platforms require device to be a 167*f6217f89SApple OSS Distributions * specific subclass of IOService. 168*f6217f89SApple OSS Distributions * @param args Optional device-specific arguments related to the end of this work item. 169*f6217f89SApple OSS Distributions * @param done Optional Set to false if the work has not yet completed. Drivers are then responsible for 170*f6217f89SApple OSS Distributions * calling workBegin when the work resumes and workEnd with done set to True when it has completed. A workEnd() call 171*f6217f89SApple OSS Distributions * without a corresponding workBegin() call is a way to cancel a work item and return token to IOPerfControl. 172*f6217f89SApple OSS Distributions */ 173*f6217f89SApple OSS Distributions virtual void workEnd(IOService *device, uint64_t token, WorkEndArgs *args = nullptr, bool done = true); 174*f6217f89SApple OSS Distributions 175*f6217f89SApple OSS Distributions /*! 176*f6217f89SApple OSS Distributions * @function copyWorkContext 177*f6217f89SApple OSS Distributions * @abstract Return a retained reference to an opaque OSObject, to be released by the driver. This object can 178*f6217f89SApple OSS Distributions * be used by IOPerfControl to track a work item. This may perform dynamic memory allocation. 179*f6217f89SApple OSS Distributions * @returns A pointer to an OSObject 180*f6217f89SApple OSS Distributions */ 181*f6217f89SApple OSS Distributions OSPtr<OSObject> copyWorkContext(); 182*f6217f89SApple OSS Distributions 183*f6217f89SApple OSS Distributions /*! 184*f6217f89SApple OSS Distributions * @function workSubmitAndBeginWithContext 185*f6217f89SApple OSS Distributions * @abstract Tell the performance controller that work was submitted and immediately began executing 186*f6217f89SApple OSS Distributions * @param device The device that is executing the work. Some platforms require device to be a 187*f6217f89SApple OSS Distributions * specific subclass of IOService. 188*f6217f89SApple OSS Distributions * @param context An OSObject returned by copyWorkContext(). The context object will be used by IOPerfControl to track 189*f6217f89SApple OSS Distributions * this work item. 190*f6217f89SApple OSS Distributions * @param submitArgs Optional device-specific arguments related to the submission of this work item. 191*f6217f89SApple OSS Distributions * @param beginArgs Optional device-specific arguments related to the start of this work item. 192*f6217f89SApple OSS Distributions * @returns true if IOPerfControl is tracking this work item, else false. 193*f6217f89SApple OSS Distributions * @note The workEndWithContext() call is optional if the corresponding workSubmitWithContext() call returned false. 194*f6217f89SApple OSS Distributions */ 195*f6217f89SApple OSS Distributions bool workSubmitAndBeginWithContext(IOService *device, OSObject *context, WorkSubmitArgs *submitArgs = nullptr, 196*f6217f89SApple OSS Distributions WorkBeginArgs *beginArgs = nullptr); 197*f6217f89SApple OSS Distributions 198*f6217f89SApple OSS Distributions /*! 199*f6217f89SApple OSS Distributions * @function workSubmitWithContext 200*f6217f89SApple OSS Distributions * @abstract Tell the performance controller that work was submitted. 201*f6217f89SApple OSS Distributions * @param device The device that will execute the work. Some platforms require device to be a 202*f6217f89SApple OSS Distributions * specific subclass of IOService. 203*f6217f89SApple OSS Distributions * @param context An OSObject returned by copyWorkContext(). The context object will be used by IOPerfControl to track 204*f6217f89SApple OSS Distributions * this work item. 205*f6217f89SApple OSS Distributions * @param args Optional device-specific arguments related to the submission of this work item. 206*f6217f89SApple OSS Distributions * @returns true if IOPerfControl is tracking this work item, else false. 207*f6217f89SApple OSS Distributions */ 208*f6217f89SApple OSS Distributions bool workSubmitWithContext(IOService *device, OSObject *context, WorkSubmitArgs *args = nullptr); 209*f6217f89SApple OSS Distributions 210*f6217f89SApple OSS Distributions /*! 211*f6217f89SApple OSS Distributions * @function workBeginWithContext 212*f6217f89SApple OSS Distributions * @abstract Tell the performance controller that previously submitted work began executing. 213*f6217f89SApple OSS Distributions * @param device The device that is executing the work. Some platforms require device to be a 214*f6217f89SApple OSS Distributions * specific subclass of IOService. 215*f6217f89SApple OSS Distributions * @param context An OSObject returned by copyWorkContext() and provided to the previous call to workSubmitWithContext(). 216*f6217f89SApple OSS Distributions * @param args Optional device-specific arguments related to the start of this work item. 217*f6217f89SApple OSS Distributions * @note The workBeginWithContext() and workEndWithContext() calls are optional if the corresponding workSubmitWithContext() call returned false. 218*f6217f89SApple OSS Distributions */ 219*f6217f89SApple OSS Distributions void workBeginWithContext(IOService *device, OSObject *context, WorkBeginArgs *args = nullptr); 220*f6217f89SApple OSS Distributions 221*f6217f89SApple OSS Distributions /*! 222*f6217f89SApple OSS Distributions * @function workEndWithContext 223*f6217f89SApple OSS Distributions * @abstract Tell the performance controller that previously started work finished executing. 224*f6217f89SApple OSS Distributions * @param device The device that executed the work. Some platforms require device to be a 225*f6217f89SApple OSS Distributions * specific subclass of IOService. 226*f6217f89SApple OSS Distributions * @param context An OSObject returned by copyWorkContext() and provided to the previous call to workSubmitWithContext(). 227*f6217f89SApple OSS Distributions * @param args Optional device-specific arguments related to the end of this work item. 228*f6217f89SApple OSS Distributions * @param done Optional Set to false if the work has not yet completed. Drivers are then responsible for 229*f6217f89SApple OSS Distributions * calling workBegin when the work resumes and workEnd with done set to True when it has completed. 230*f6217f89SApple OSS Distributions * @note The workEndWithContext() call is optional if the corresponding workSubmitWithContext() call returned false. A workEndWithContext() 231*f6217f89SApple OSS Distributions * call without a corresponding workBeginWithContext() call is a way to cancel a work item. 232*f6217f89SApple OSS Distributions */ 233*f6217f89SApple OSS Distributions void workEndWithContext(IOService *device, OSObject *context, WorkEndArgs *args = nullptr, bool done = true); 234*f6217f89SApple OSS Distributions 235*f6217f89SApple OSS Distributions /*! 236*f6217f89SApple OSS Distributions * @struct WorkUpdateArgs 237*f6217f89SApple OSS Distributions * @discussion Drivers may submit additional device-specific arguments related to a work item by passing a 238*f6217f89SApple OSS Distributions * struct with WorkUpdateArgs as its first member. Note: Drivers are responsible for publishing 239*f6217f89SApple OSS Distributions * a header file describing these arguments. 240*f6217f89SApple OSS Distributions */ 241*f6217f89SApple OSS Distributions struct WorkUpdateArgs { 242*f6217f89SApple OSS Distributions uint32_t version; 243*f6217f89SApple OSS Distributions uint32_t size; 244*f6217f89SApple OSS Distributions uint64_t update_time; 245*f6217f89SApple OSS Distributions uint64_t reserved[4]; 246*f6217f89SApple OSS Distributions void *driver_data; 247*f6217f89SApple OSS Distributions }; 248*f6217f89SApple OSS Distributions 249*f6217f89SApple OSS Distributions /*! 250*f6217f89SApple OSS Distributions * @function workUpdateWithContext 251*f6217f89SApple OSS Distributions * @abstract Provide and receive additional information from the performance controller. If this call is 252*f6217f89SApple OSS Distributions * made at all, it should be between workSubmit and workEnd. The purpose and implementation of this call are 253*f6217f89SApple OSS Distributions * device specific, and may do nothing on some devices. 254*f6217f89SApple OSS Distributions * @param device The device that submitted the work. Some platforms require device to be a 255*f6217f89SApple OSS Distributions * specific subclass of IOService. 256*f6217f89SApple OSS Distributions * @param context An OSObject returned by copyWorkContext() and provided to the previous call to workSubmitWithContext(). 257*f6217f89SApple OSS Distributions * @param args Optional device-specific arguments. 258*f6217f89SApple OSS Distributions */ 259*f6217f89SApple OSS Distributions void workUpdateWithContext(IOService *device, OSObject *context, WorkUpdateArgs *args = nullptr); 260*f6217f89SApple OSS Distributions 261*f6217f89SApple OSS Distributions /*! 262*f6217f89SApple OSS Distributions * @function querySubmitterRole 263*f6217f89SApple OSS Distributions * @abstract Reports the current role configured on the submitting task by app lifecycle management policy 264*f6217f89SApple OSS Distributions * for this type of device. May be queried before submit to inform which policies should apply to this work. 265*f6217f89SApple OSS Distributions * @param device The device that will submit the work. Some platforms require device to be a 266*f6217f89SApple OSS Distributions * specific subclass of IOService. 267*f6217f89SApple OSS Distributions * @note Must use the copyClientForDeviceType init to convey the type of device to query the role of. 268*f6217f89SApple OSS Distributions * GPU role enums are found in sys/resource_private.h and are configured via PRIO_DARWIN_GPU. 269*f6217f89SApple OSS Distributions */ 270*f6217f89SApple OSS Distributions IOReturn querySubmitterRole(IOService *device, task_t submitting_task, uint32_t* role_out); 271*f6217f89SApple OSS Distributions 272*f6217f89SApple OSS Distributions #define PERFCONTROL_SUPPORTS_SUBMITTER_ROLE 1 273*f6217f89SApple OSS Distributions 274*f6217f89SApple OSS Distributions /* 275*f6217f89SApple OSS Distributions * Callers should always use the CURRENT version so that the kernel can detect both older 276*f6217f89SApple OSS Distributions * and newer structure layouts. New callbacks should always be added at the end of the 277*f6217f89SApple OSS Distributions * structure, and xnu should expect existing source recompiled against newer headers 278*f6217f89SApple OSS Distributions * to pass NULL for unimplemented callbacks. 279*f6217f89SApple OSS Distributions */ 280*f6217f89SApple OSS Distributions 281*f6217f89SApple OSS Distributions #define PERFCONTROL_INTERFACE_VERSION_NONE (0) /* no interface */ 282*f6217f89SApple OSS Distributions #define PERFCONTROL_INTERFACE_VERSION_1 (1) /* up-to workEnd */ 283*f6217f89SApple OSS Distributions #define PERFCONTROL_INTERFACE_VERSION_2 (2) /* up-to workUpdate */ 284*f6217f89SApple OSS Distributions #define PERFCONTROL_INTERFACE_VERSION_3 (3) /* up-to (un)registerDriverDevice */ 285*f6217f89SApple OSS Distributions #define PERFCONTROL_INTERFACE_VERSION_4 (4) /* up-to workEndWithResources */ 286*f6217f89SApple OSS Distributions #define PERFCONTROL_INTERFACE_VERSION_CURRENT PERFCONTROL_INTERFACE_VERSION_4 287*f6217f89SApple OSS Distributions 288*f6217f89SApple OSS Distributions /*! 289*f6217f89SApple OSS Distributions * @struct PerfControllerInterface 290*f6217f89SApple OSS Distributions * @discussion Function pointers necessary to register a performance controller. Not for general driver use. 291*f6217f89SApple OSS Distributions */ 292*f6217f89SApple OSS Distributions struct PerfControllerInterface { 293*f6217f89SApple OSS Distributions enum struct PerfDeviceID : uint32_t{ 294*f6217f89SApple OSS Distributions kInvalid = 0, 295*f6217f89SApple OSS Distributions kCPU = 0, 296*f6217f89SApple OSS Distributions kANE = 0x4, 297*f6217f89SApple OSS Distributions kGPU, 298*f6217f89SApple OSS Distributions kMSR, 299*f6217f89SApple OSS Distributions kStorage, 300*f6217f89SApple OSS Distributions }; 301*f6217f89SApple OSS Distributions 302*f6217f89SApple OSS Distributions struct DriverState { 303*f6217f89SApple OSS Distributions uint32_t has_target_thread_group : 1; 304*f6217f89SApple OSS Distributions uint32_t has_device_info : 1; 305*f6217f89SApple OSS Distributions uint32_t reserved : 30; 306*f6217f89SApple OSS Distributions 307*f6217f89SApple OSS Distributions uint64_t target_thread_group_id; 308*f6217f89SApple OSS Distributions void *target_thread_group_data; 309*f6217f89SApple OSS Distributions 310*f6217f89SApple OSS Distributions PerfDeviceID device_type; /* device-type determined by CLPC */ 311*f6217f89SApple OSS Distributions uint32_t instance_id; 312*f6217f89SApple OSS Distributions bool resource_accounting; 313*f6217f89SApple OSS Distributions }; 314*f6217f89SApple OSS Distributions 315*f6217f89SApple OSS Distributions struct WorkState { 316*f6217f89SApple OSS Distributions uint64_t thread_group_id; 317*f6217f89SApple OSS Distributions void *thread_group_data; 318*f6217f89SApple OSS Distributions void *work_data; 319*f6217f89SApple OSS Distributions uint32_t work_data_size; 320*f6217f89SApple OSS Distributions uint32_t started : 1; 321*f6217f89SApple OSS Distributions uint32_t reserved : 31; 322*f6217f89SApple OSS Distributions const DriverState* driver_state; 323*f6217f89SApple OSS Distributions }; 324*f6217f89SApple OSS Distributions 325*f6217f89SApple OSS Distributions struct ResourceAccounting { 326*f6217f89SApple OSS Distributions uint64_t mach_time_delta; 327*f6217f89SApple OSS Distributions uint64_t energy_nj_delta; 328*f6217f89SApple OSS Distributions }; 329*f6217f89SApple OSS Distributions 330*f6217f89SApple OSS Distributions using RegisterDeviceFunction = IOReturn (*)(IOService *); 331*f6217f89SApple OSS Distributions using RegisterDriverDeviceFunction = IOReturn (*)(IOService *, IOService *, DriverState *); 332*f6217f89SApple OSS Distributions using WorkCanSubmitFunction = bool (*)(IOService *, WorkState *, WorkSubmitArgs *); 333*f6217f89SApple OSS Distributions using WorkSubmitFunction = void (*)(IOService *, uint64_t, WorkState *, WorkSubmitArgs *); 334*f6217f89SApple OSS Distributions using WorkBeginFunction = void (*)(IOService *, uint64_t, WorkState *, WorkBeginArgs *); 335*f6217f89SApple OSS Distributions using WorkEndFunction = void (*)(IOService *, uint64_t, WorkState *, WorkEndArgs *, bool); 336*f6217f89SApple OSS Distributions using WorkEndWithResourcesFunction = void (*)(IOService *, uint64_t, WorkState *, WorkEndArgs *, ResourceAccounting *, bool); 337*f6217f89SApple OSS Distributions using WorkUpdateFunction = void (*)(IOService *, uint64_t, WorkState *, WorkUpdateArgs *); 338*f6217f89SApple OSS Distributions 339*f6217f89SApple OSS Distributions uint64_t version; 340*f6217f89SApple OSS Distributions RegisterDeviceFunction registerDevice; 341*f6217f89SApple OSS Distributions RegisterDeviceFunction unregisterDevice; 342*f6217f89SApple OSS Distributions WorkCanSubmitFunction workCanSubmit; 343*f6217f89SApple OSS Distributions WorkSubmitFunction workSubmit; 344*f6217f89SApple OSS Distributions WorkBeginFunction workBegin; 345*f6217f89SApple OSS Distributions WorkEndFunction workEnd; 346*f6217f89SApple OSS Distributions WorkUpdateFunction workUpdate; 347*f6217f89SApple OSS Distributions RegisterDriverDeviceFunction registerDriverDevice; 348*f6217f89SApple OSS Distributions RegisterDriverDeviceFunction unregisterDriverDevice; 349*f6217f89SApple OSS Distributions WorkEndWithResourcesFunction workEndWithResources; 350*f6217f89SApple OSS Distributions }; 351*f6217f89SApple OSS Distributions 352*f6217f89SApple OSS Distributions struct IOPerfControlClientShared { 353*f6217f89SApple OSS Distributions atomic_uint_fast8_t maxDriverIndex; 354*f6217f89SApple OSS Distributions PerfControllerInterface interface; 355*f6217f89SApple OSS Distributions IOLock *interfaceLock; 356*f6217f89SApple OSS Distributions OSSet *deviceRegistrationList; 357*f6217f89SApple OSS Distributions }; 358*f6217f89SApple OSS Distributions 359*f6217f89SApple OSS Distributions struct IOPerfControlClientData { 360*f6217f89SApple OSS Distributions struct thread_group *target_thread_group; 361*f6217f89SApple OSS Distributions PerfControllerInterface::DriverState driverState; 362*f6217f89SApple OSS Distributions IOService* device; 363*f6217f89SApple OSS Distributions }; 364*f6217f89SApple OSS Distributions /*! 365*f6217f89SApple OSS Distributions * @function registerPerformanceController 366*f6217f89SApple OSS Distributions * @abstract Register a performance controller to receive callbacks. Not for general driver use. 367*f6217f89SApple OSS Distributions * @param interface Struct containing callback functions implemented by the performance controller. 368*f6217f89SApple OSS Distributions * @returns kIOReturnSuccess or kIOReturnError if the interface was already registered. 369*f6217f89SApple OSS Distributions */ 370*f6217f89SApple OSS Distributions virtual IOReturn registerPerformanceController(PerfControllerInterface *interface); 371*f6217f89SApple OSS Distributions 372*f6217f89SApple OSS Distributions /*! 373*f6217f89SApple OSS Distributions * @function getClientData 374*f6217f89SApple OSS Distributions * @abstract Not for general driver use. Only used by registerPerformanceController(). Allows performanceController to register existing IOPerfControlClient. 375*f6217f89SApple OSS Distributions * @returns IOPerfControlData associated with a IOPerfControlClient 376*f6217f89SApple OSS Distributions */ 377*f6217f89SApple OSS Distributions IOPerfControlClientData * getClientData()378*f6217f89SApple OSS Distributions getClientData() 379*f6217f89SApple OSS Distributions { 380*f6217f89SApple OSS Distributions return &clientData; 381*f6217f89SApple OSS Distributions } 382*f6217f89SApple OSS Distributions 383*f6217f89SApple OSS Distributions private: 384*f6217f89SApple OSS Distributions 385*f6217f89SApple OSS Distributions void setDeviceType(IOPCDeviceType deviceType); 386*f6217f89SApple OSS Distributions 387*f6217f89SApple OSS Distributions struct WorkTableEntry { 388*f6217f89SApple OSS Distributions struct thread_group *thread_group; 389*f6217f89SApple OSS Distributions coalition_t coal; 390*f6217f89SApple OSS Distributions bool started; 391*f6217f89SApple OSS Distributions uint8_t perfcontrol_data[32]; 392*f6217f89SApple OSS Distributions }; 393*f6217f89SApple OSS Distributions 394*f6217f89SApple OSS Distributions static constexpr size_t kMaxWorkTableNumEntries = 1024; 395*f6217f89SApple OSS Distributions static constexpr size_t kWorkTableIndexBits = 24; 396*f6217f89SApple OSS Distributions static constexpr size_t kWorkTableMaxSize = (1 << kWorkTableIndexBits) - 1; // - 1 since 397*f6217f89SApple OSS Distributions // kIOPerfControlClientWorkUntracked takes number 0 398*f6217f89SApple OSS Distributions static constexpr size_t kWorkTableIndexMask = (const size_t)mask(kWorkTableIndexBits); 399*f6217f89SApple OSS Distributions 400*f6217f89SApple OSS Distributions uint64_t allocateToken(thread_group *thread_group); 401*f6217f89SApple OSS Distributions void deallocateToken(uint64_t token); 402*f6217f89SApple OSS Distributions WorkTableEntry *getEntryForToken(uint64_t token); 403*f6217f89SApple OSS Distributions void markEntryStarted(uint64_t token, bool started); 404*f6217f89SApple OSS Distributions inline uint64_t tokenToGlobalUniqueToken(uint64_t token); 405*f6217f89SApple OSS Distributions void accountResources(coalition_t coal, PerfControllerInterface::PerfDeviceID device_type, PerfControllerInterface::ResourceAccounting *resources); 406*f6217f89SApple OSS Distributions 407*f6217f89SApple OSS Distributions IOPCDeviceType deviceType; /* device-type provided by client via copyClientForDeviceType */ 408*f6217f89SApple OSS Distributions uint8_t driverIndex; 409*f6217f89SApple OSS Distributions IOPerfControlClientShared *shared; 410*f6217f89SApple OSS Distributions WorkTableEntry *workTable; 411*f6217f89SApple OSS Distributions size_t workTableLength; 412*f6217f89SApple OSS Distributions size_t workTableNextIndex; 413*f6217f89SApple OSS Distributions IOSimpleLock *workTableLock; 414*f6217f89SApple OSS Distributions 415*f6217f89SApple OSS Distributions IOPerfControlClientData clientData; 416*f6217f89SApple OSS Distributions }; 417*f6217f89SApple OSS Distributions 418*f6217f89SApple OSS Distributions #endif /* __cplusplus */ 419*f6217f89SApple OSS Distributions #endif /* KERNEL_PRIVATE */ 420