xref: /xnu-12377.1.9/iokit/IOKit/perfcontrol/IOPerfControl.h (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
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