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 
208 // Settle time after changing power state.
209 #if USE_SETTLE_TIMER
210 	uint32_t                SettleTimeUS;
211 #endif
212 	IOPMPowerStateIndex     IdleTimerGeneration;
213 
214 // The flags describing current change note.
215 	IOPMPowerChangeFlags    HeadNoteChangeFlags;
216 
217 // The new power state number being changed to.
218 	IOPMPowerStateIndex     HeadNotePowerState;
219 
220 // Points to the entry in the power state array.
221 	IOPMPSEntry *           HeadNotePowerArrayEntry;
222 
223 // Power flags supplied by all parents (domain).
224 	IOPMPowerFlags          HeadNoteDomainFlags;
225 
226 // Power flags supplied by domain accounting for parent changes.
227 	IOPMPowerFlags          HeadNoteDomainTargetFlags;
228 
229 // Connection attached to the changing parent.
230 	IOPowerConnection *     HeadNoteParentConnection;
231 
232 // Power flags supplied by the changing parent.
233 	IOPMPowerFlags          HeadNoteParentFlags;
234 
235 // Number of acks still outstanding.
236 	uint32_t                HeadNotePendingAcks;
237 
238 // PM state lock.
239 	IOLock *                PMLock;
240 
241 	unsigned int            InitialPowerChange          :1;
242 	unsigned int            InitialSetPowerState        :1;
243 	unsigned int            DeviceOverrideEnabled       :1;
244 	unsigned int            DoNotPowerDown              :1;
245 	unsigned int            ParentsKnowState            :1;
246 	unsigned int            StrictTreeOrder             :1;
247 	unsigned int            IdleTimerStopped            :1;
248 	unsigned int            AdjustPowerScheduled        :1;
249 
250 	unsigned int            IsPreChange                 :1;
251 	unsigned int            DriverCallBusy              :1;
252 	unsigned int            PCDFunctionOverride         :1;
253 	unsigned int            IdleTimerIgnored            :1;
254 	unsigned int            HasAdvisoryDesire           :1;
255 	unsigned int            AdvisoryTickleUsed          :1;
256 	unsigned int            ResetPowerStateOnWake       :1;
257 
258 // Time of last device activity.
259 	AbsoluteTime            DeviceActiveTimestamp;
260 	AbsoluteTime            MaxPowerStateEntryTime;
261 	AbsoluteTime            MaxPowerStateExitTime;
262 
263 // Used to protect activity flag.
264 	IOLock *                ActivityLock;
265 
266 // Idle timer's period in seconds.
267 	int                     IdleTimerPeriod;
268 	int                     NextIdleTimerPeriod;
269 	IOPMPowerStateIndex     IdleTimerMinPowerState;
270 	AbsoluteTime            IdleTimerStartTime;
271 
272 // Power state desired by a subclassed device object.
273 	IOPMPowerStateIndex     DeviceDesire;
274 
275 // This is the power state we desire currently.
276 	IOPMPowerStateIndex     DesiredPowerState;
277 
278 // This is what our parent thinks our need is.
279 	IOPMPowerFlags          PreviousRequestPowerFlags;
280 
281 // Cache result from getName(), used in logging.
282 	const char *            Name;
283 
284 // Number of power states in the power array.
285 	IOPMPowerStateIndex     NumberOfPowerStates;
286 
287 // Ordered highest power state in the power array.
288 	IOPMPowerStateIndex     HighestPowerState;
289 
290 // Power state array.
291 	IOPMPSEntry *           PowerStates;
292 
293 // The controlling driver.
294 	IOService *             ControllingDriver;
295 
296 // Our current power state.
297 	IOPMPowerStateIndex     CurrentPowerState;
298 
299 // Logical OR of power flags for each power domain parent.
300 	IOPMPowerFlags          ParentsCurrentPowerFlags;
301 
302 // The highest power state we can achieve in current power domain.
303 	IOPMPowerStateIndex     MaxPowerState;
304 
305 // Logical OR of all output power flags in the power state array.
306 	IOPMPowerFlags          MergedOutputPowerFlags;
307 
308 // OSArray which manages responses from notified apps and clients.
309 	OSArray *               ResponseArray;
310 	OSArray *               NotifyClientArray;
311 
312 // Used to uniquely identify power management notification to apps and clients.
313 	uint16_t                SerialNumber;
314 
315 // Used to communicate desired function to tellClientsWithResponse().
316 // This is used because it avoids changing the signatures of the affected virtual methods.
317 	int                     OutOfBandParameter;
318 
319 	AbsoluteTime            DriverCallStartTime;
320 	IOPMPowerFlags          CurrentCapabilityFlags;
321 	unsigned long           CurrentPowerConsumption;
322 	IOPMPowerStateIndex     TempClampPowerState;
323 	OSArray *               NotifyChildArray;
324 	OSDictionary *          PowerClients;
325 	thread_call_t           DriverCallEntry;
326 	void *                  DriverCallParamPtr;
327 	IOItemCount             DriverCallParamCount;
328 	IOItemCount             DriverCallParamSlots;
329 	uint32_t                DriverCallReason;
330 	uint32_t                OutOfBandMessage;
331 	uint32_t                TempClampCount;
332 	IOPMPowerStateIndex     OverrideMaxPowerState;
333 	IOPMPowerStateIndex     DeviceUsablePowerState;
334 
335 // Thread to be run alongside DriverCallEntry to provide logging.
336 	thread_call_t           DriverCallTimer;
337 
338 // Protected by ActivityLock - BEGIN
339 	IOPMPowerStateIndex     ActivityTicklePowerState;
340 	IOPMPowerStateIndex     AdvisoryTicklePowerState;
341 	uint32_t                ActivityTickleCount;
342 	uint32_t                DeviceWasActive     : 1;
343 	uint32_t                AdvisoryTickled     : 1;
344 // Protected by ActivityLock - END
345 
346 	uint32_t                WaitReason;
347 	uint32_t                SavedMachineState;
348 
349 // Protected by PMLock - BEGIN
350 	struct {
351 		uint32_t            PMStop              : 1;
352 		uint32_t            PMDriverCallWait    : 1;
353 	} LockedFlags;
354 
355 	queue_head_t            PMDriverCallQueue;
356 	OSSet *                 InsertInterestSet;
357 	OSSet *                 RemoveInterestSet;
358 
359 // IOReporter Data
360 	uint32_t                ReportClientCnt;
361 	void *                  ReportBuf;
362 // Protected by PMLock - END
363 
364 #if PM_VARS_SUPPORT
365 	IOPMprot *              PMVars;
366 #endif
367 
368 	IOPMActions             PMActions;
369 
370 // Serialize IOServicePM state for debug output.
371 	IOReturn gatedSerialize( OSSerialize * s ) const;
372 	virtual bool serialize( OSSerialize * s ) const APPLE_KEXT_OVERRIDE;
373 
374 // PM log and trace
375 	void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const;
376 	void pmTrace( uint32_t event, uint32_t eventFunc, uintptr_t param1, uintptr_t param2 ) const;
377 };
378 
379 #define fOwner                      pwrMgt->Owner
380 #define fInterestedDrivers          pwrMgt->InterestedDrivers
381 #define fDriverTimer                pwrMgt->DriverTimer
382 #define fMachineState               pwrMgt->MachineState
383 #define fAckTimer                   pwrMgt->AckTimer
384 #define fSettleTimer                pwrMgt->SettleTimer
385 #define fIdleTimer                  pwrMgt->IdleTimer
386 #define fWatchdogTimer              pwrMgt->WatchdogTimer
387 #define fWatchdogDeadline           pwrMgt->WatchdogDeadline
388 #define fWatchdogLock               pwrMgt->WatchdogLock
389 #define fBlockedArray               pwrMgt->BlockedArray
390 #define fPendingResponseDeadline    pwrMgt->PendingResponseDeadline
391 #define fSettleTimeUS               pwrMgt->SettleTimeUS
392 #define fIdleTimerGeneration        pwrMgt->IdleTimerGeneration
393 #define fHeadNoteChangeFlags        pwrMgt->HeadNoteChangeFlags
394 #define fHeadNotePowerState         pwrMgt->HeadNotePowerState
395 #define fHeadNotePowerArrayEntry    pwrMgt->HeadNotePowerArrayEntry
396 #define fHeadNoteDomainFlags        pwrMgt->HeadNoteDomainFlags
397 #define fHeadNoteDomainTargetFlags  pwrMgt->HeadNoteDomainTargetFlags
398 #define fHeadNoteParentConnection   pwrMgt->HeadNoteParentConnection
399 #define fHeadNoteParentFlags        pwrMgt->HeadNoteParentFlags
400 #define fHeadNotePendingAcks        pwrMgt->HeadNotePendingAcks
401 #define fPMLock                     pwrMgt->PMLock
402 #define fInitialPowerChange         pwrMgt->InitialPowerChange
403 #define fInitialSetPowerState       pwrMgt->InitialSetPowerState
404 #define fDeviceOverrideEnabled      pwrMgt->DeviceOverrideEnabled
405 #define fDoNotPowerDown             pwrMgt->DoNotPowerDown
406 #define fParentsKnowState           pwrMgt->ParentsKnowState
407 #define fStrictTreeOrder            pwrMgt->StrictTreeOrder
408 #define fIdleTimerStopped           pwrMgt->IdleTimerStopped
409 #define fAdjustPowerScheduled       pwrMgt->AdjustPowerScheduled
410 #define fIsPreChange                pwrMgt->IsPreChange
411 #define fDriverCallBusy             pwrMgt->DriverCallBusy
412 #define fPCDFunctionOverride        pwrMgt->PCDFunctionOverride
413 #define fIdleTimerIgnored           pwrMgt->IdleTimerIgnored
414 #define fHasAdvisoryDesire          pwrMgt->HasAdvisoryDesire
415 #define fAdvisoryTickleUsed         pwrMgt->AdvisoryTickleUsed
416 #define fResetPowerStateOnWake      pwrMgt->ResetPowerStateOnWake
417 #define fDeviceActiveTimestamp      pwrMgt->DeviceActiveTimestamp
418 #define fMaxPowerStateEntryTime     pwrMgt->MaxPowerStateEntryTime
419 #define fMaxPowerStateExitTime      pwrMgt->MaxPowerStateExitTime
420 #define fActivityLock               pwrMgt->ActivityLock
421 #define fIdleTimerPeriod            pwrMgt->IdleTimerPeriod
422 #define fIdleTimerMinPowerState     pwrMgt->IdleTimerMinPowerState
423 #define fNextIdleTimerPeriod        pwrMgt->NextIdleTimerPeriod
424 #define fIdleTimerStartTime         pwrMgt->IdleTimerStartTime
425 #define fDeviceDesire               pwrMgt->DeviceDesire
426 #define fDesiredPowerState          pwrMgt->DesiredPowerState
427 #define fPreviousRequestPowerFlags  pwrMgt->PreviousRequestPowerFlags
428 #define fName                       pwrMgt->Name
429 #define fNumberOfPowerStates        pwrMgt->NumberOfPowerStates
430 #define fHighestPowerState          pwrMgt->HighestPowerState
431 #define fPowerStates                pwrMgt->PowerStates
432 #define fControllingDriver          pwrMgt->ControllingDriver
433 #define fCurrentPowerState          pwrMgt->CurrentPowerState
434 #define fParentsCurrentPowerFlags   pwrMgt->ParentsCurrentPowerFlags
435 #define fMaxPowerState              pwrMgt->MaxPowerState
436 #define fMergedOutputPowerFlags     pwrMgt->MergedOutputPowerFlags
437 #define fResponseArray              pwrMgt->ResponseArray
438 #define fNotifyClientArray          pwrMgt->NotifyClientArray
439 #define fSerialNumber               pwrMgt->SerialNumber
440 #define fOutOfBandParameter         pwrMgt->OutOfBandParameter
441 #define fDriverCallStartTime        pwrMgt->DriverCallStartTime
442 #define fCurrentCapabilityFlags     pwrMgt->CurrentCapabilityFlags
443 #define fCurrentPowerConsumption    pwrMgt->CurrentPowerConsumption
444 #define fTempClampPowerState        pwrMgt->TempClampPowerState
445 #define fNotifyChildArray           pwrMgt->NotifyChildArray
446 #define fPowerClients               pwrMgt->PowerClients
447 #define fDriverCallEntry            pwrMgt->DriverCallEntry
448 #define fDriverCallParamPtr         pwrMgt->DriverCallParamPtr
449 #define fDriverCallParamCount       pwrMgt->DriverCallParamCount
450 #define fDriverCallParamSlots       pwrMgt->DriverCallParamSlots
451 #define fDriverCallReason           pwrMgt->DriverCallReason
452 #define fOutOfBandMessage           pwrMgt->OutOfBandMessage
453 #define fTempClampCount             pwrMgt->TempClampCount
454 #define fOverrideMaxPowerState      pwrMgt->OverrideMaxPowerState
455 #define fDeviceUsablePowerState     pwrMgt->DeviceUsablePowerState
456 #define fDriverCallTimer            pwrMgt->DriverCallTimer
457 #define fActivityTicklePowerState   pwrMgt->ActivityTicklePowerState
458 #define fAdvisoryTicklePowerState   pwrMgt->AdvisoryTicklePowerState
459 #define fActivityTickleCount        pwrMgt->ActivityTickleCount
460 #define fDeviceWasActive            pwrMgt->DeviceWasActive
461 #define fAdvisoryTickled            pwrMgt->AdvisoryTickled
462 #define fWaitReason                 pwrMgt->WaitReason
463 #define fSavedMachineState          pwrMgt->SavedMachineState
464 #define fLockedFlags                pwrMgt->LockedFlags
465 #define fPMDriverCallQueue          pwrMgt->PMDriverCallQueue
466 #define fInsertInterestSet          pwrMgt->InsertInterestSet
467 #define fRemoveInterestSet          pwrMgt->RemoveInterestSet
468 #define fReportClientCnt            pwrMgt->ReportClientCnt
469 #define fReportBuf                  pwrMgt->ReportBuf
470 #define fPMVars                     pwrMgt->PMVars
471 #define fPMActions                  pwrMgt->PMActions
472 
473 #define StateOrder(state)           (((state) < fNumberOfPowerStates)               \
474 	                            ? pwrMgt->PowerStates[(state)].stateOrder       \
475 	                            : (state))
476 #define StateMax(a, b)               (StateOrder((a)) < StateOrder((b)) ? (b) : (a))
477 #define StateMin(a, b)               (StateOrder((a)) < StateOrder((b)) ? (a) : (b))
478 
479 #define kPowerStateZero             (0)
480 
481 /*
482  *  When an IOService is waiting for acknowledgement to a power change
483  *  notification from an interested driver or the controlling driver,
484  *  the ack timer is ticking every tenth of a second.
485  *  (100000000 nanoseconds are one tenth of a second).
486  */
487 #define ACK_TIMER_PERIOD            100000000
488 
489 #if defined(__i386__) || defined(__x86_64__)
490 #define WATCHDOG_SLEEP_TIMEOUT      (180)   // 180 secs
491 #define WATCHDOG_WAKE_TIMEOUT       (180)   // 180  secs
492 #else
493 #define WATCHDOG_SLEEP_TIMEOUT      (35)   // 35 secs (kMaxTimeRequested + 5s)
494 #define WATCHDOG_WAKE_TIMEOUT       (35)   // 35 secs (kMaxTimeRequested + 5s)
495 #endif
496 // Slightly larger than the internal VM flush timeout
497 #define WATCHDOG_HIBERNATION_TIMEOUT (HIBERNATE_FLUSHING_SECS_TO_COMPLETE + 1)
498 
499 // Max wait time in microseconds for kernel priority and capability clients
500 // with async message handlers to acknowledge.
501 //
502 #define kPriorityClientMaxWait      (90 * 1000 * 1000)
503 #define kCapabilityClientMaxWait    (240 * 1000 * 1000)
504 
505 // Attributes describing a power state change.
506 // See IOPMPowerChangeFlags data type.
507 //
508 #define kIOPMParentInitiated        0x0001  // power change initiated by our  parent
509 #define kIOPMSelfInitiated          0x0002  // power change initiated by this device
510 #define kIOPMNotDone                0x0004  // we couldn't make this change
511 #define kIOPMDomainWillChange       0x0008  // change started by PowerDomainWillChangeTo
512 #define kIOPMDomainDidChange        0x0010  // change started by PowerDomainDidChangeTo
513 #define kIOPMDomainPowerDrop        0x0020  // Domain is lowering power
514 #define kIOPMIgnoreChildren         0x0040  // Ignore children and driver power desires
515 #define kIOPMSkipAskPowerDown       0x0080  // skip the ask app phase
516 #define kIOPMSynchronize            0x0100  // change triggered by power tree re-sync
517 #define kIOPMSyncNoChildNotify      0x0200  // sync root domain only, not entire tree
518 #define kIOPMSyncTellPowerDown      0x0400  // send the ask/will power off messages
519 #define kIOPMSyncCancelPowerDown    0x0800  // sleep cancel for maintenance wake
520 #define kIOPMInitialPowerChange     0x1000  // set for initial power change
521 #define kIOPMRootChangeUp           0x2000  // Root power domain change up
522 #define kIOPMRootChangeDown         0x4000  // Root power domain change down
523 #define kIOPMExpireIdleTimer        0x8000  // Accelerate idle timer expiration
524 
525 #define kIOPMRootBroadcastFlags     (kIOPMSynchronize  | \
526 	                             kIOPMRootChangeUp | kIOPMRootChangeDown)
527 
528 // Activity tickle request flags
529 #define kTickleTypePowerDrop        0x01
530 #define kTickleTypePowerRise        0x02
531 #define kTickleTypeActivity         0x04
532 #define kTickleTypeAdvisory         0x08
533 
534 enum {
535 	kDriverCallInformPreChange,
536 	kDriverCallInformPostChange,
537 	kDriverCallSetPowerState,
538 	kRootDomainInformPreChange
539 };
540 
541 struct DriverCallParam {
542 	OSObject *  Target;
543 	IOReturn    Result;
544 };
545 
546 // values of OutOfBandParameter
547 enum {
548 	kNotifyApps,
549 	kNotifyPriority,
550 	kNotifyCapabilityChangeApps,
551 	kNotifyCapabilityChangePriority
552 };
553 
554 typedef bool (*IOPMMessageFilter)(
555 	void * target, void * object, void * arg1, void * arg2, void * arg3 );
556 
557 // used for applyToInterested
558 struct IOPMInterestContext {
559 	OSArray *               responseArray;
560 	OSArray *               notifyClients;
561 	uint16_t                serialNumber;
562 	uint8_t                 isPreChange;
563 	uint8_t                 enableTracing;
564 	uint32_t                maxTimeRequested;
565 	uint32_t                messageType;
566 	uint32_t                notifyType;
567 	uint32_t                skippedInDark;
568 	uint32_t                notSkippedInDark;
569 	IOService *             us;
570 	IOPMPowerStateIndex     stateNumber;
571 	IOPMPowerFlags          stateFlags;
572 	IOPMPowerChangeFlags    changeFlags;
573 	IOPMMessageFilter       messageFilter;
574 };
575 
576 // track client ack requirements
577 class IOPMClientAck : public OSObject {
578 	OSDeclareDefaultStructors( IOPMClientAck );
579 public:
580 	uint64_t completionTimestamp;   // absolute time
581 	uint32_t maxTimeRequested;              // microseconds
582 };
583 
584 // assertPMDriverCall() options
585 enum {
586 	kIOPMDriverCallNoInactiveCheck = 1
587 };
588 
589 // assertPMDriverCall() method
590 enum {
591 	kIOPMDriverCallMethodUnknown                         = 0,
592 	kIOPMDriverCallMethodSetPowerState                   = 1,
593 	kIOPMDriverCallMethodWillChange                      = 2,
594 	kIOPMDriverCallMethodDidChange                       = 3,
595 	kIOPMDriverCallMethodChangeDone                      = 4,
596 	kIOPMDriverCallMethodSetAggressive                   = 5,
597 	kIOPMDriverCallMethodMaxCapabilityForDomainState     = 6,
598 	kIOPMDriverCallMethodInitialPowerStateForDomainState = 7
599 };
600 
601 //******************************************************************************
602 // PM Statistics & Diagnostics
603 //******************************************************************************
604 
605 extern OSPtr<const OSSymbol> gIOPMStatsResponseTimedOut;
606 extern OSPtr<const OSSymbol> gIOPMStatsResponseCancel;
607 extern OSPtr<const OSSymbol> gIOPMStatsResponseSlow;
608 extern OSPtr<const OSSymbol> gIOPMStatsResponsePrompt;
609 extern OSPtr<const OSSymbol> gIOPMStatsDriverPSChangeSlow;
610 
611 //******************************************************************************
612 // IOPMRequest
613 //******************************************************************************
614 
615 class IOPMRequest : public IOCommand
616 {
617 	OSDeclareDefaultStructors( IOPMRequest );
618 
619 protected:
620 	IOService *          fTarget;           // request target
621 	IOPMRequest *        fRequestNext;      // the next request in the chain
622 	IOPMRequest *        fRequestRoot;      // the root request in the call tree
623 	uint32_t             fWorkWaitCount;    // execution blocked if non-zero
624 	uint32_t             fFreeWaitCount;    // completion blocked if non-zero
625 	uint64_t             fTimestamp;        // MCTU
626 	uint32_t             fRequestType;      // request type
627 	bool                 fIsQuiesceBlocker;
628 
629 	IOPMCompletionAction fCompletionAction;
630 	void *               fCompletionTarget;
631 	void *               fCompletionParam;
632 
633 public:
634 	uint32_t             fTag;
635 	void *               fArg0;
636 	void *               fArg1;
637 	void *               fArg2;
638 
639 	inline bool
isWorkBlocked(void)640 	isWorkBlocked( void ) const
641 	{
642 		return fWorkWaitCount != 0;
643 	}
644 
645 	inline bool
isFreeBlocked(void)646 	isFreeBlocked( void ) const
647 	{
648 		return fFreeWaitCount != 0;
649 	}
650 
651 	inline IOPMRequest *
getNextRequest(void)652 	getNextRequest( void ) const
653 	{
654 		return fRequestNext;
655 	}
656 
657 	inline IOPMRequest *
getRootRequest(void)658 	getRootRequest( void ) const
659 	{
660 		if (fRequestRoot) {
661 			return fRequestRoot;
662 		}
663 #if NOT_READY
664 		if (fCompletionAction) {
665 			return (IOPMRequest *) this;
666 		}
667 #endif
668 		return NULL;
669 	}
670 
671 	inline uint32_t
getType(void)672 	getType( void ) const
673 	{
674 		return fRequestType;
675 	}
676 
677 	inline uint32_t
getTag(void)678 	getTag( void ) const
679 	{
680 		return fTag;
681 	}
682 
683 	inline bool
isReplyType(void)684 	isReplyType( void ) const
685 	{
686 		return fRequestType > kIOPMRequestTypeReplyStart;
687 	}
688 
689 	inline IOService *
getTarget(void)690 	getTarget( void ) const
691 	{
692 		return fTarget;
693 	}
694 
695 	inline bool
isQuiesceBlocker(void)696 	isQuiesceBlocker( void ) const
697 	{
698 		return fIsQuiesceBlocker;
699 	}
700 
701 	inline bool
isQuiesceType(void)702 	isQuiesceType( void ) const
703 	{
704 		return (kIOPMRequestTypeQuiescePowerTree == fRequestType) &&
705 		       (fCompletionAction != NULL) && (fCompletionTarget != NULL);
706 	}
707 
708 	inline void
installCompletionAction(void * target,IOPMCompletionAction action,void * param)709 	installCompletionAction(
710 		void *               target,
711 		IOPMCompletionAction action,
712 		void *               param )
713 	{
714 		fCompletionTarget = target;
715 		fCompletionAction = action;
716 		fCompletionParam  = param;
717 	}
718 
719 	inline void
setTimestamp(uint64_t time)720 	setTimestamp( uint64_t time )
721 	{
722 		fTimestamp = time;
723 	}
724 
725 	inline uint64_t
getTimestamp(void)726 	getTimestamp( void ) const
727 	{
728 		return fTimestamp;
729 	}
730 
731 	static IOPMRequest * create( void );
732 	bool   init( IOService * owner, IOOptionBits type );
733 	void   reset( void );
734 	bool   attachNextRequest( IOPMRequest * next );
735 	bool   detachNextRequest( void );
736 	bool   attachRootRequest( IOPMRequest * root );
737 	bool   detachRootRequest( void );
738 };
739 
740 //******************************************************************************
741 // IOPMRequestQueue
742 //******************************************************************************
743 
744 class IOPMRequestQueue : public IOEventSource
745 {
746 	OSDeclareDefaultStructors( IOPMRequestQueue );
747 
748 public:
749 	typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * );
750 
751 protected:
752 	queue_head_t    fQueue;
753 	IOLock *        fLock;
754 
755 	enum { kMaxDequeueCount = 256 };
756 
757 	virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE;
758 	virtual void free( void ) APPLE_KEXT_OVERRIDE;
759 	virtual bool init( IOService * inOwner, Action inAction );
760 
761 public:
762 	static  IOPMRequestQueue * create( IOService * inOwner, Action inAction );
763 	void    queuePMRequest( LIBKERN_CONSUMED IOPMRequest * request );
764 	void    queuePMRequestChain( IOPMRequest ** requests, IOItemCount count );
765 };
766 
767 //******************************************************************************
768 // IOPMWorkQueue
769 //******************************************************************************
770 
771 #define WORK_QUEUE_STATS    1
772 
773 class IOPMWorkQueue : public IOEventSource
774 {
775 	OSDeclareDefaultStructors( IOPMWorkQueue );
776 
777 public:
778 	typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * );
779 
780 #if WORK_QUEUE_STATS
781 	uint64_t            fStatCheckForWork;
782 	uint64_t            fStatScanEntries;
783 	uint64_t            fStatQueueEmpty;
784 	uint64_t            fStatNoWorkDone;
785 #endif
786 
787 protected:
788 	queue_head_t        fWorkQueue;
789 	Action              fInvokeAction;
790 	Action              fRetireAction;
791 	uint32_t            fQueueLength;
792 	uint32_t            fConsumerCount;
793 	volatile uint32_t   fProducerCount;
794 	IOPMRequest *       fQuiesceRequest;
795 	AbsoluteTime        fQuiesceStartTime;
796 	AbsoluteTime        fQuiesceFinishTime;
797 
798 	virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE;
799 	virtual bool init( IOService * inOwner, Action invoke, Action retire );
800 	bool    checkRequestQueue( queue_head_t * queue, bool * empty );
801 
802 public:
803 	static  IOPMWorkQueue * create( IOService * inOwner, Action invoke, Action retire );
804 	bool    queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt );
805 	void    signalWorkAvailable( void );
806 	void    incrementProducerCount( void );
807 	void    attachQuiesceRequest( IOPMRequest * quiesceRequest );
808 	void    finishQuiesceRequest( IOPMRequest * quiesceRequest );
809 };
810 
811 //******************************************************************************
812 // IOPMCompletionQueue
813 //******************************************************************************
814 
815 class IOPMCompletionQueue : public IOEventSource
816 {
817 	OSDeclareDefaultStructors( IOPMCompletionQueue );
818 
819 public:
820 	typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * );
821 
822 protected:
823 	queue_head_t    fQueue;
824 
825 	virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE;
826 	virtual bool init( IOService * inOwner, Action inAction );
827 
828 public:
829 	static  IOPMCompletionQueue * create( IOService * inOwner, Action inAction );
830 	bool    queuePMRequest( IOPMRequest * request );
831 };
832 
833 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */
834