xref: /xnu-11417.140.69/iokit/Kernel/IOServicePMPrivate.h (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
1 /*
2  * Copyright (c) 2019-2020 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #ifndef _IOKIT_IOSERVICEPMPRIVATE_H
30 #define _IOKIT_IOSERVICEPMPRIVATE_H
31 
32 #include <IOKit/IOCommand.h>
33 #include <IOKit/IOEventSource.h>
34 
35 #include <vm/vm_compressor_xnu.h>
36 
37 #define USE_SETTLE_TIMER    0
38 
39 //******************************************************************************
40 // PM command types
41 //******************************************************************************
42 
43 enum {
44 	/* Command Types */
45 	kIOPMRequestTypeInvalid                     = 0x00,
46 	kIOPMRequestTypePMStop                      = 0x01,
47 	kIOPMRequestTypeAddPowerChild1              = 0x02,
48 	kIOPMRequestTypeAddPowerChild2              = 0x03,
49 	kIOPMRequestTypeAddPowerChild3              = 0x04,
50 	kIOPMRequestTypeRegisterPowerDriver         = 0x05,
51 	kIOPMRequestTypeAdjustPowerState            = 0x06,
52 	kIOPMRequestTypePowerDomainWillChange       = 0x07,
53 	kIOPMRequestTypePowerDomainDidChange        = 0x08,
54 	kIOPMRequestTypePowerOverrideOnPriv         = 0x09,
55 	kIOPMRequestTypePowerOverrideOffPriv        = 0x0A,
56 	kIOPMRequestTypeActivityTickle              = 0x0B,
57 	kIOPMRequestTypeRequestPowerState           = 0x0C,
58 	kIOPMRequestTypeSynchronizePowerTree        = 0x0D,
59 	kIOPMRequestTypeRequestPowerStateOverride   = 0x0E,
60 	kIOPMRequestTypeSetIdleTimerPeriod          = 0x0F,
61 	kIOPMRequestTypeIgnoreIdleTimer             = 0x10,
62 	kIOPMRequestTypeQuiescePowerTree            = 0x11,
63 	kIOPMRequestTypeDeferredActivityTickle      = 0x12,
64 
65 	/* Reply Types */
66 	kIOPMRequestTypeReplyStart                  = 0x80,
67 	kIOPMRequestTypeAckPowerChange              = 0x81,
68 	kIOPMRequestTypeAckSetPowerState            = 0x82,
69 	kIOPMRequestTypeAllowPowerChange            = 0x83,
70 	kIOPMRequestTypeCancelPowerChange           = 0x84,
71 	kIOPMRequestTypeInterestChanged             = 0x85,
72 	kIOPMRequestTypeIdleCancel                  = 0x86,
73 	kIOPMRequestTypeChildNotifyDelayCancel      = 0x87
74 };
75 
76 //******************************************************************************
77 // PM actions - For root domain only
78 //******************************************************************************
79 
80 struct IOPMActions;
81 
82 typedef void
83 (*IOPMActionPowerChangeStart)(
84 	void *                  target,
85 	IOService *             service,
86 	IOPMActions *           actions,
87 	const IOPMRequest *     request,
88 	IOPMPowerStateIndex     powerState,
89 	IOPMPowerChangeFlags *  changeFlagsPtr );
90 
91 typedef void
92 (*IOPMActionPowerChangeDone)(
93 	void *                  target,
94 	IOService *             service,
95 	IOPMActions *           actions,
96 	const IOPMRequest *     request,
97 	IOPMPowerStateIndex     powerState,
98 	IOPMPowerChangeFlags    changeFlags );
99 
100 typedef void
101 (*IOPMActionPowerChangeOverride)(
102 	void *                  target,
103 	IOService *             service,
104 	IOPMActions *           actions,
105 	const IOPMRequest *     request,
106 	IOPMPowerStateIndex *   powerStatePtr,
107 	IOPMPowerChangeFlags *  changeFlagsPtr );
108 
109 typedef void
110 (*IOPMActionActivityTickle)(
111 	void *                  target,
112 	IOService *             service,
113 	IOPMActions *           actions );
114 
115 typedef void
116 (*IOPMActionUpdatePowerClient)(
117 	void *                  target,
118 	IOService *             service,
119 	IOPMActions *           actions,
120 	const OSSymbol *        powerClient,
121 	IOPMPowerStateIndex     oldPowerState,
122 	IOPMPowerStateIndex     newPowerState );
123 
124 struct IOPMActions {
125 	void *                          target;
126 	IOPMActionPowerChangeStart      actionPowerChangeStart;
127 	IOPMActionPowerChangeDone       actionPowerChangeDone;
128 	IOPMActionPowerChangeOverride   actionPowerChangeOverride;
129 	IOPMActionActivityTickle        actionActivityTickle;
130 	IOPMActionUpdatePowerClient     actionUpdatePowerClient;
131 	uint32_t                        darkWakePowerState;
132 	uint16_t                        flags;
133 	uint16_t                        state;
134 };
135 
136 // IOPMActions flags
137 enum {
138 	kPMActionsPCIBitNumberMask           = 0x00ff,
139 	kPMActionsFlagIsDisplayWrangler      = 0x0100,
140 	kPMActionsFlagIsGraphicsDriver       = 0x0200,
141 	kPMActionsFlagIsAudioDriver          = 0x0400,
142 	kPMActionsFlagHasDarkWakePowerState  = 0x0800
143 };
144 
145 // IOPMActions state
146 enum {
147 	kPMActionsStatePowerClamped          = 0x0001
148 };
149 
150 //******************************************************************************
151 // Internal concise representation of IOPMPowerState
152 struct IOPMPSEntry {
153 	IOPMPowerFlags      capabilityFlags;
154 	IOPMPowerFlags      outputPowerFlags;
155 	IOPMPowerFlags      inputPowerFlags;
156 	unsigned long       staticPower;
157 #if USE_SETTLE_TIMER
158 	uint32_t            settleUpTime;
159 	uint32_t            settleDownTime;
160 #endif
161 	IOPMPowerStateIndex stateOrder;
162 	IOPMPowerStateIndex stateOrderToIndex;
163 };
164 
165 //******************************************************************************
166 // IOServicePM
167 //******************************************************************************
168 
169 class IOServicePM : public OSObject
170 {
171 	friend class IOService;
172 	friend class IOPMWorkQueue;
173 
174 	OSDeclareDefaultStructors( IOServicePM );
175 
176 private:
177 // Link IOServicePM objects on IOPMWorkQueue.
178 	queue_chain_t           WorkChain;
179 
180 // Queue of IOPMRequest objects.
181 	queue_head_t            RequestHead;
182 
183 // IOService creator and owner.
184 	IOService *             Owner;
185 
186 // List of interested drivers (protected by PMLock).
187 	IOPMinformeeList *      InterestedDrivers;
188 
189 // How long to wait for controlling driver to acknowledge.
190 	IOReturn                DriverTimer;
191 
192 // Current power management machine state.
193 	uint32_t                MachineState;
194 
195 	thread_call_t           AckTimer;
196 #if USE_SETTLE_TIMER
197 	thread_call_t           SettleTimer;
198 #endif
199 	thread_call_t           IdleTimer;
200 	thread_call_t           WatchdogTimer;
201 	thread_call_t           SpinDumpTimer;
202 
203 	IOLock  *               WatchdogLock;
204 	OSArray *               BlockedArray;
205 	uint64_t                PendingResponseDeadline;
206 	uint64_t                WatchdogDeadline;
207 	uint64_t                WatchdogStart;
208 
209 // Settle time after changing power state.
210 #if USE_SETTLE_TIMER
211 	uint32_t                SettleTimeUS;
212 #endif
213 	IOPMPowerStateIndex     IdleTimerGeneration;
214 
215 // The flags describing current change note.
216 	IOPMPowerChangeFlags    HeadNoteChangeFlags;
217 
218 // The new power state number being changed to.
219 	IOPMPowerStateIndex     HeadNotePowerState;
220 
221 // Points to the entry in the power state array.
222 	IOPMPSEntry *           HeadNotePowerArrayEntry;
223 
224 // Power flags supplied by all parents (domain).
225 	IOPMPowerFlags          HeadNoteDomainFlags;
226 
227 // Power flags supplied by domain accounting for parent changes.
228 	IOPMPowerFlags          HeadNoteDomainTargetFlags;
229 
230 // Connection attached to the changing parent.
231 	IOPowerConnection *     HeadNoteParentConnection;
232 
233 // Power flags supplied by the changing parent.
234 	IOPMPowerFlags          HeadNoteParentFlags;
235 
236 // Number of acks still outstanding.
237 	uint32_t                HeadNotePendingAcks;
238 
239 // PM state lock.
240 	IOLock *                PMLock;
241 
242 	unsigned int            InitialPowerChange          :1;
243 	unsigned int            InitialSetPowerState        :1;
244 	unsigned int            DeviceOverrideEnabled       :1;
245 	unsigned int            DoNotPowerDown              :1;
246 	unsigned int            ParentsKnowState            :1;
247 	unsigned int            StrictTreeOrder             :1;
248 	unsigned int            IdleTimerStopped            :1;
249 	unsigned int            AdjustPowerScheduled        :1;
250 
251 	unsigned int            IsPreChange                 :1;
252 	unsigned int            DriverCallBusy              :1;
253 	unsigned int            PCDFunctionOverride         :1;
254 	unsigned int            IdleTimerIgnored            :1;
255 	unsigned int            HasAdvisoryDesire           :1;
256 	unsigned int            AdvisoryTickleUsed          :1;
257 	unsigned int            ResetPowerStateOnWake       :1;
258 
259 // Time of last device activity.
260 	AbsoluteTime            DeviceActiveTimestamp;
261 	AbsoluteTime            MaxPowerStateEntryTime;
262 	AbsoluteTime            MaxPowerStateExitTime;
263 
264 // Used to protect activity flag.
265 	IOLock *                ActivityLock;
266 
267 // Idle timer's period in seconds.
268 	int                     IdleTimerPeriod;
269 	int                     NextIdleTimerPeriod;
270 	IOPMPowerStateIndex     IdleTimerMinPowerState;
271 	AbsoluteTime            IdleTimerStartTime;
272 
273 // Power state desired by a subclassed device object.
274 	IOPMPowerStateIndex     DeviceDesire;
275 
276 // This is the power state we desire currently.
277 	IOPMPowerStateIndex     DesiredPowerState;
278 
279 // This is what our parent thinks our need is.
280 	IOPMPowerFlags          PreviousRequestPowerFlags;
281 
282 // Cache result from getName(), used in logging.
283 	const char *            Name;
284 
285 // Number of power states in the power array.
286 	IOPMPowerStateIndex     NumberOfPowerStates;
287 
288 // Ordered highest power state in the power array.
289 	IOPMPowerStateIndex     HighestPowerState;
290 
291 // Power state array.
292 	IOPMPSEntry *           PowerStates;
293 
294 // The controlling driver.
295 	IOService *             ControllingDriver;
296 
297 // Our current power state.
298 	IOPMPowerStateIndex     CurrentPowerState;
299 
300 // Logical OR of power flags for each power domain parent.
301 	IOPMPowerFlags          ParentsCurrentPowerFlags;
302 
303 // The highest power state we can achieve in current power domain.
304 	IOPMPowerStateIndex     MaxPowerState;
305 
306 // Logical OR of all output power flags in the power state array.
307 	IOPMPowerFlags          MergedOutputPowerFlags;
308 
309 // OSArray which manages responses from notified apps and clients.
310 	OSArray *               ResponseArray;
311 	OSArray *               NotifyClientArray;
312 
313 // Used to uniquely identify power management notification to apps and clients.
314 	uint16_t                SerialNumber;
315 
316 // Used to communicate desired function to tellClientsWithResponse().
317 // This is used because it avoids changing the signatures of the affected virtual methods.
318 	int                     OutOfBandParameter;
319 
320 	AbsoluteTime            DriverCallStartTime;
321 	IOPMPowerFlags          CurrentCapabilityFlags;
322 	unsigned long           CurrentPowerConsumption;
323 	IOPMPowerStateIndex     TempClampPowerState;
324 	OSArray *               NotifyChildArray;
325 	OSDictionary *          PowerClients;
326 	thread_call_t           DriverCallEntry;
327 	void *                  DriverCallParamPtr;
328 	IOItemCount             DriverCallParamCount;
329 	IOItemCount             DriverCallParamSlots;
330 	uint32_t                DriverCallReason;
331 	uint32_t                OutOfBandMessage;
332 	uint32_t                TempClampCount;
333 	IOPMPowerStateIndex     OverrideMaxPowerState;
334 	IOPMPowerStateIndex     DeviceUsablePowerState;
335 
336 // Thread to be run alongside DriverCallEntry to provide logging.
337 	thread_call_t           DriverCallTimer;
338 
339 // Protected by ActivityLock - BEGIN
340 	IOPMPowerStateIndex     ActivityTicklePowerState;
341 	IOPMPowerStateIndex     AdvisoryTicklePowerState;
342 	uint32_t                ActivityTickleCount;
343 	uint32_t                DeviceWasActive     : 1;
344 	uint32_t                AdvisoryTickled     : 1;
345 // Protected by ActivityLock - END
346 
347 	uint32_t                WaitReason;
348 	uint32_t                SavedMachineState;
349 
350 // Protected by PMLock - BEGIN
351 	struct {
352 		uint32_t            PMStop              : 1;
353 		uint32_t            PMDriverCallWait    : 1;
354 	} LockedFlags;
355 
356 	queue_head_t            PMDriverCallQueue;
357 	OSSet *                 InsertInterestSet;
358 	OSSet *                 RemoveInterestSet;
359 
360 // IOReporter Data
361 	uint32_t                ReportClientCnt;
362 	void *                  ReportBuf;
363 // Protected by PMLock - END
364 
365 #if PM_VARS_SUPPORT
366 	IOPMprot *              PMVars;
367 #endif
368 
369 	IOPMActions             PMActions;
370 
371 // Serialize IOServicePM state for debug output.
372 	IOReturn gatedSerialize( OSSerialize * s ) const;
373 	virtual bool serialize( OSSerialize * s ) const APPLE_KEXT_OVERRIDE;
374 
375 // PM log and trace
376 	void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const;
377 	void pmTrace( uint32_t event, uint32_t eventFunc, uintptr_t param1, uintptr_t param2 ) const;
378 };
379 
380 #define fOwner                      pwrMgt->Owner
381 #define fInterestedDrivers          pwrMgt->InterestedDrivers
382 #define fDriverTimer                pwrMgt->DriverTimer
383 #define fMachineState               pwrMgt->MachineState
384 #define fAckTimer                   pwrMgt->AckTimer
385 #define fSettleTimer                pwrMgt->SettleTimer
386 #define fIdleTimer                  pwrMgt->IdleTimer
387 #define fWatchdogTimer              pwrMgt->WatchdogTimer
388 #define fWatchdogDeadline           pwrMgt->WatchdogDeadline
389 #define fWatchdogStart              pwrMgt->WatchdogStart
390 #define fWatchdogLock               pwrMgt->WatchdogLock
391 #define fBlockedArray               pwrMgt->BlockedArray
392 #define fPendingResponseDeadline    pwrMgt->PendingResponseDeadline
393 #define fSettleTimeUS               pwrMgt->SettleTimeUS
394 #define fIdleTimerGeneration        pwrMgt->IdleTimerGeneration
395 #define fHeadNoteChangeFlags        pwrMgt->HeadNoteChangeFlags
396 #define fHeadNotePowerState         pwrMgt->HeadNotePowerState
397 #define fHeadNotePowerArrayEntry    pwrMgt->HeadNotePowerArrayEntry
398 #define fHeadNoteDomainFlags        pwrMgt->HeadNoteDomainFlags
399 #define fHeadNoteDomainTargetFlags  pwrMgt->HeadNoteDomainTargetFlags
400 #define fHeadNoteParentConnection   pwrMgt->HeadNoteParentConnection
401 #define fHeadNoteParentFlags        pwrMgt->HeadNoteParentFlags
402 #define fHeadNotePendingAcks        pwrMgt->HeadNotePendingAcks
403 #define fPMLock                     pwrMgt->PMLock
404 #define fInitialPowerChange         pwrMgt->InitialPowerChange
405 #define fInitialSetPowerState       pwrMgt->InitialSetPowerState
406 #define fDeviceOverrideEnabled      pwrMgt->DeviceOverrideEnabled
407 #define fDoNotPowerDown             pwrMgt->DoNotPowerDown
408 #define fParentsKnowState           pwrMgt->ParentsKnowState
409 #define fStrictTreeOrder            pwrMgt->StrictTreeOrder
410 #define fIdleTimerStopped           pwrMgt->IdleTimerStopped
411 #define fAdjustPowerScheduled       pwrMgt->AdjustPowerScheduled
412 #define fIsPreChange                pwrMgt->IsPreChange
413 #define fDriverCallBusy             pwrMgt->DriverCallBusy
414 #define fPCDFunctionOverride        pwrMgt->PCDFunctionOverride
415 #define fIdleTimerIgnored           pwrMgt->IdleTimerIgnored
416 #define fHasAdvisoryDesire          pwrMgt->HasAdvisoryDesire
417 #define fAdvisoryTickleUsed         pwrMgt->AdvisoryTickleUsed
418 #define fResetPowerStateOnWake      pwrMgt->ResetPowerStateOnWake
419 #define fDeviceActiveTimestamp      pwrMgt->DeviceActiveTimestamp
420 #define fMaxPowerStateEntryTime     pwrMgt->MaxPowerStateEntryTime
421 #define fMaxPowerStateExitTime      pwrMgt->MaxPowerStateExitTime
422 #define fActivityLock               pwrMgt->ActivityLock
423 #define fIdleTimerPeriod            pwrMgt->IdleTimerPeriod
424 #define fIdleTimerMinPowerState     pwrMgt->IdleTimerMinPowerState
425 #define fNextIdleTimerPeriod        pwrMgt->NextIdleTimerPeriod
426 #define fIdleTimerStartTime         pwrMgt->IdleTimerStartTime
427 #define fDeviceDesire               pwrMgt->DeviceDesire
428 #define fDesiredPowerState          pwrMgt->DesiredPowerState
429 #define fPreviousRequestPowerFlags  pwrMgt->PreviousRequestPowerFlags
430 #define fName                       pwrMgt->Name
431 #define fNumberOfPowerStates        pwrMgt->NumberOfPowerStates
432 #define fHighestPowerState          pwrMgt->HighestPowerState
433 #define fPowerStates                pwrMgt->PowerStates
434 #define fControllingDriver          pwrMgt->ControllingDriver
435 #define fCurrentPowerState          pwrMgt->CurrentPowerState
436 #define fParentsCurrentPowerFlags   pwrMgt->ParentsCurrentPowerFlags
437 #define fMaxPowerState              pwrMgt->MaxPowerState
438 #define fMergedOutputPowerFlags     pwrMgt->MergedOutputPowerFlags
439 #define fResponseArray              pwrMgt->ResponseArray
440 #define fNotifyClientArray          pwrMgt->NotifyClientArray
441 #define fSerialNumber               pwrMgt->SerialNumber
442 #define fOutOfBandParameter         pwrMgt->OutOfBandParameter
443 #define fDriverCallStartTime        pwrMgt->DriverCallStartTime
444 #define fCurrentCapabilityFlags     pwrMgt->CurrentCapabilityFlags
445 #define fCurrentPowerConsumption    pwrMgt->CurrentPowerConsumption
446 #define fTempClampPowerState        pwrMgt->TempClampPowerState
447 #define fNotifyChildArray           pwrMgt->NotifyChildArray
448 #define fPowerClients               pwrMgt->PowerClients
449 #define fDriverCallEntry            pwrMgt->DriverCallEntry
450 #define fDriverCallParamPtr         pwrMgt->DriverCallParamPtr
451 #define fDriverCallParamCount       pwrMgt->DriverCallParamCount
452 #define fDriverCallParamSlots       pwrMgt->DriverCallParamSlots
453 #define fDriverCallReason           pwrMgt->DriverCallReason
454 #define fOutOfBandMessage           pwrMgt->OutOfBandMessage
455 #define fTempClampCount             pwrMgt->TempClampCount
456 #define fOverrideMaxPowerState      pwrMgt->OverrideMaxPowerState
457 #define fDeviceUsablePowerState     pwrMgt->DeviceUsablePowerState
458 #define fDriverCallTimer            pwrMgt->DriverCallTimer
459 #define fActivityTicklePowerState   pwrMgt->ActivityTicklePowerState
460 #define fAdvisoryTicklePowerState   pwrMgt->AdvisoryTicklePowerState
461 #define fActivityTickleCount        pwrMgt->ActivityTickleCount
462 #define fDeviceWasActive            pwrMgt->DeviceWasActive
463 #define fAdvisoryTickled            pwrMgt->AdvisoryTickled
464 #define fWaitReason                 pwrMgt->WaitReason
465 #define fSavedMachineState          pwrMgt->SavedMachineState
466 #define fLockedFlags                pwrMgt->LockedFlags
467 #define fPMDriverCallQueue          pwrMgt->PMDriverCallQueue
468 #define fInsertInterestSet          pwrMgt->InsertInterestSet
469 #define fRemoveInterestSet          pwrMgt->RemoveInterestSet
470 #define fReportClientCnt            pwrMgt->ReportClientCnt
471 #define fReportBuf                  pwrMgt->ReportBuf
472 #define fPMVars                     pwrMgt->PMVars
473 #define fPMActions                  pwrMgt->PMActions
474 
475 #define StateOrder(state)           (((state) < fNumberOfPowerStates)               \
476 	                            ? pwrMgt->PowerStates[(state)].stateOrder       \
477 	                            : (state))
478 #define StateMax(a, b)               (StateOrder((a)) < StateOrder((b)) ? (b) : (a))
479 #define StateMin(a, b)               (StateOrder((a)) < StateOrder((b)) ? (a) : (b))
480 
481 #define kPowerStateZero             (0)
482 
483 /*
484  *  When an IOService is waiting for acknowledgement to a power change
485  *  notification from an interested driver or the controlling driver,
486  *  the ack timer is ticking every tenth of a second.
487  *  (100000000 nanoseconds are one tenth of a second).
488  */
489 #define ACK_TIMER_PERIOD            100000000
490 
491 #if defined(__i386__) || defined(__x86_64__)
492 #define WATCHDOG_SLEEP_TIMEOUT      (180)   // 180 secs
493 #define WATCHDOG_WAKE_TIMEOUT       (180)   // 180  secs
494 #else
495 #define WATCHDOG_SLEEP_TIMEOUT      (35)   // 35 secs (kMaxTimeRequested + 5s)
496 #define WATCHDOG_WAKE_TIMEOUT       (35)   // 35 secs (kMaxTimeRequested + 5s)
497 #endif
498 #define WATCHDOG_HIBERNATION_TIMEOUT (180)
499 
500 // Max wait time in microseconds for kernel priority and capability clients
501 // with async message handlers to acknowledge.
502 //
503 #define kPriorityClientMaxWait      (90 * 1000 * 1000)
504 #define kCapabilityClientMaxWait    (240 * 1000 * 1000)
505 
506 // Attributes describing a power state change.
507 // See IOPMPowerChangeFlags data type.
508 //
509 #define kIOPMParentInitiated        0x0001  // power change initiated by our  parent
510 #define kIOPMSelfInitiated          0x0002  // power change initiated by this device
511 #define kIOPMNotDone                0x0004  // we couldn't make this change
512 #define kIOPMDomainWillChange       0x0008  // change started by PowerDomainWillChangeTo
513 #define kIOPMDomainDidChange        0x0010  // change started by PowerDomainDidChangeTo
514 #define kIOPMDomainPowerDrop        0x0020  // Domain is lowering power
515 #define kIOPMIgnoreChildren         0x0040  // Ignore children and driver power desires
516 #define kIOPMSkipAskPowerDown       0x0080  // skip the ask app phase
517 #define kIOPMSynchronize            0x0100  // change triggered by power tree re-sync
518 #define kIOPMSyncNoChildNotify      0x0200  // sync root domain only, not entire tree
519 #define kIOPMSyncTellPowerDown      0x0400  // send the ask/will power off messages
520 #define kIOPMSyncCancelPowerDown    0x0800  // sleep cancel for maintenance wake
521 #define kIOPMInitialPowerChange     0x1000  // set for initial power change
522 #define kIOPMRootChangeUp           0x2000  // Root power domain change up
523 #define kIOPMRootChangeDown         0x4000  // Root power domain change down
524 #define kIOPMExpireIdleTimer        0x8000  // Accelerate idle timer expiration
525 
526 #define kIOPMRootBroadcastFlags     (kIOPMSynchronize  | \
527 	                             kIOPMRootChangeUp | kIOPMRootChangeDown)
528 
529 // Activity tickle request flags
530 #define kTickleTypePowerDrop        0x01
531 #define kTickleTypePowerRise        0x02
532 #define kTickleTypeActivity         0x04
533 #define kTickleTypeAdvisory         0x08
534 
535 enum {
536 	kDriverCallInformPreChange,
537 	kDriverCallInformPostChange,
538 	kDriverCallSetPowerState,
539 	kRootDomainInformPreChange
540 };
541 
542 struct DriverCallParam {
543 	OSObject *  Target;
544 	IOReturn    Result;
545 };
546 
547 // values of OutOfBandParameter
548 enum {
549 	kNotifyApps,
550 	kNotifyPriority,
551 	kNotifyCapabilityChangeApps,
552 	kNotifyCapabilityChangePriority
553 };
554 
555 typedef bool (*IOPMMessageFilter)(
556 	void * target, void * object, void * arg1, void * arg2, void * arg3 );
557 
558 // used for applyToInterested
559 struct IOPMInterestContext {
560 	OSArray *               responseArray;
561 	OSArray *               notifyClients;
562 	uint16_t                serialNumber;
563 	uint8_t                 isPreChange;
564 	uint8_t                 enableTracing;
565 	uint32_t                maxTimeRequested;
566 	uint32_t                messageType;
567 	uint32_t                notifyType;
568 	uint32_t                skippedInDark;
569 	uint32_t                notSkippedInDark;
570 	IOService *             us;
571 	IOPMPowerStateIndex     stateNumber;
572 	IOPMPowerFlags          stateFlags;
573 	IOPMPowerChangeFlags    changeFlags;
574 	IOPMMessageFilter       messageFilter;
575 };
576 
577 // track client ack requirements
578 class IOPMClientAck : public OSObject {
579 	OSDeclareDefaultStructors( IOPMClientAck );
580 public:
581 	uint64_t completionTimestamp;   // absolute time
582 	uint32_t maxTimeRequested;              // microseconds
583 };
584 
585 // assertPMDriverCall() options
586 enum {
587 	kIOPMDriverCallNoInactiveCheck = 1
588 };
589 
590 // assertPMDriverCall() method
591 enum {
592 	kIOPMDriverCallMethodUnknown                         = 0,
593 	kIOPMDriverCallMethodSetPowerState                   = 1,
594 	kIOPMDriverCallMethodWillChange                      = 2,
595 	kIOPMDriverCallMethodDidChange                       = 3,
596 	kIOPMDriverCallMethodChangeDone                      = 4,
597 	kIOPMDriverCallMethodSetAggressive                   = 5,
598 	kIOPMDriverCallMethodMaxCapabilityForDomainState     = 6,
599 	kIOPMDriverCallMethodInitialPowerStateForDomainState = 7
600 };
601 
602 //******************************************************************************
603 // PM Statistics & Diagnostics
604 //******************************************************************************
605 
606 extern OSPtr<const OSSymbol> gIOPMStatsResponseTimedOut;
607 extern OSPtr<const OSSymbol> gIOPMStatsResponseCancel;
608 extern OSPtr<const OSSymbol> gIOPMStatsResponseSlow;
609 extern OSPtr<const OSSymbol> gIOPMStatsResponsePrompt;
610 extern OSPtr<const OSSymbol> gIOPMStatsDriverPSChangeSlow;
611 
612 //******************************************************************************
613 // IOPMRequest
614 //******************************************************************************
615 
616 class IOPMRequest : public IOCommand
617 {
618 	OSDeclareDefaultStructors( IOPMRequest );
619 
620 protected:
621 	IOService *          fTarget;           // request target
622 	IOPMRequest *        fRequestNext;      // the next request in the chain
623 	IOPMRequest *        fRequestRoot;      // the root request in the call tree
624 	uint32_t             fWorkWaitCount;    // execution blocked if non-zero
625 	uint32_t             fFreeWaitCount;    // completion blocked if non-zero
626 	uint64_t             fTimestamp;        // MCTU
627 	uint32_t             fRequestType;      // request type
628 	bool                 fIsQuiesceBlocker;
629 
630 	IOPMCompletionAction fCompletionAction;
631 	void *               fCompletionTarget;
632 	void *               fCompletionParam;
633 
634 public:
635 	uint32_t             fTag;
636 	void *               fArg0;
637 	void *               fArg1;
638 	void *               fArg2;
639 
640 	inline bool
isWorkBlocked(void)641 	isWorkBlocked( void ) const
642 	{
643 		return fWorkWaitCount != 0;
644 	}
645 
646 	inline bool
isFreeBlocked(void)647 	isFreeBlocked( void ) const
648 	{
649 		return fFreeWaitCount != 0;
650 	}
651 
652 	inline IOPMRequest *
getNextRequest(void)653 	getNextRequest( void ) const
654 	{
655 		return fRequestNext;
656 	}
657 
658 	inline IOPMRequest *
getRootRequest(void)659 	getRootRequest( void ) const
660 	{
661 		if (fRequestRoot) {
662 			return fRequestRoot;
663 		}
664 #if NOT_READY
665 		if (fCompletionAction) {
666 			return (IOPMRequest *) this;
667 		}
668 #endif
669 		return NULL;
670 	}
671 
672 	inline uint32_t
getType(void)673 	getType( void ) const
674 	{
675 		return fRequestType;
676 	}
677 
678 	inline uint32_t
getTag(void)679 	getTag( void ) const
680 	{
681 		return fTag;
682 	}
683 
684 	inline bool
isReplyType(void)685 	isReplyType( void ) const
686 	{
687 		return fRequestType > kIOPMRequestTypeReplyStart;
688 	}
689 
690 	inline IOService *
getTarget(void)691 	getTarget( void ) const
692 	{
693 		return fTarget;
694 	}
695 
696 	inline bool
isQuiesceBlocker(void)697 	isQuiesceBlocker( void ) const
698 	{
699 		return fIsQuiesceBlocker;
700 	}
701 
702 	inline bool
isQuiesceType(void)703 	isQuiesceType( void ) const
704 	{
705 		return (kIOPMRequestTypeQuiescePowerTree == fRequestType) &&
706 		       (fCompletionAction != NULL) && (fCompletionTarget != NULL);
707 	}
708 
709 	inline void
installCompletionAction(void * target,IOPMCompletionAction action,void * param)710 	installCompletionAction(
711 		void *               target,
712 		IOPMCompletionAction action,
713 		void *               param )
714 	{
715 		fCompletionTarget = target;
716 		fCompletionAction = action;
717 		fCompletionParam  = param;
718 	}
719 
720 	inline void
setTimestamp(uint64_t time)721 	setTimestamp( uint64_t time )
722 	{
723 		fTimestamp = time;
724 	}
725 
726 	inline uint64_t
getTimestamp(void)727 	getTimestamp( void ) const
728 	{
729 		return fTimestamp;
730 	}
731 
732 	static IOPMRequest * create( void );
733 	bool   init( IOService * owner, IOOptionBits type );
734 	void   reset( void );
735 	bool   attachNextRequest( IOPMRequest * next );
736 	bool   detachNextRequest( void );
737 	bool   attachRootRequest( IOPMRequest * root );
738 	bool   detachRootRequest( void );
739 };
740 
741 //******************************************************************************
742 // IOPMRequestQueue
743 //******************************************************************************
744 
745 class IOPMRequestQueue : public IOEventSource
746 {
747 	OSDeclareDefaultStructors( IOPMRequestQueue );
748 
749 public:
750 	typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * );
751 
752 protected:
753 	queue_head_t    fQueue;
754 	IOLock *        fLock;
755 
756 	enum { kMaxDequeueCount = 256 };
757 
758 	virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE;
759 	virtual void free( void ) APPLE_KEXT_OVERRIDE;
760 	virtual bool init( IOService * inOwner, Action inAction );
761 
762 public:
763 	static  IOPMRequestQueue * create( IOService * inOwner, Action inAction );
764 	void    queuePMRequest( LIBKERN_CONSUMED IOPMRequest * request );
765 	void    queuePMRequestChain( IOPMRequest ** requests, IOItemCount count );
766 };
767 
768 //******************************************************************************
769 // IOPMWorkQueue
770 //******************************************************************************
771 
772 #define WORK_QUEUE_STATS    1
773 
774 class IOPMWorkQueue : public IOEventSource
775 {
776 	OSDeclareDefaultStructors( IOPMWorkQueue );
777 
778 public:
779 	typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * );
780 
781 #if WORK_QUEUE_STATS
782 	uint64_t            fStatCheckForWork;
783 	uint64_t            fStatScanEntries;
784 	uint64_t            fStatQueueEmpty;
785 	uint64_t            fStatNoWorkDone;
786 #endif
787 
788 protected:
789 	queue_head_t        fWorkQueue;
790 	Action              fInvokeAction;
791 	Action              fRetireAction;
792 	uint32_t            fQueueLength;
793 	uint32_t            fConsumerCount;
794 	volatile uint32_t   fProducerCount;
795 	IOPMRequest *       fQuiesceRequest;
796 	AbsoluteTime        fQuiesceStartTime;
797 	AbsoluteTime        fQuiesceFinishTime;
798 
799 	virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE;
800 	virtual bool init( IOService * inOwner, Action invoke, Action retire );
801 	bool    checkRequestQueue( queue_head_t * queue, bool * empty );
802 
803 public:
804 	static  IOPMWorkQueue * create( IOService * inOwner, Action invoke, Action retire );
805 	bool    queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt );
806 	void    signalWorkAvailable( void );
807 	void    incrementProducerCount( void );
808 	void    attachQuiesceRequest( IOPMRequest * quiesceRequest );
809 	void    finishQuiesceRequest( IOPMRequest * quiesceRequest );
810 };
811 
812 //******************************************************************************
813 // IOPMCompletionQueue
814 //******************************************************************************
815 
816 class IOPMCompletionQueue : public IOEventSource
817 {
818 	OSDeclareDefaultStructors( IOPMCompletionQueue );
819 
820 public:
821 	typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * );
822 
823 protected:
824 	queue_head_t    fQueue;
825 
826 	virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE;
827 	virtual bool init( IOService * inOwner, Action inAction );
828 
829 public:
830 	static  IOPMCompletionQueue * create( IOService * inOwner, Action inAction );
831 	bool    queuePMRequest( IOPMRequest * request );
832 };
833 
834 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */
835