1/*
2 * Copyright (c) 1998-2016 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#ifndef _IOKIT_ROOTDOMAIN_H
29#define _IOKIT_ROOTDOMAIN_H
30
31#include <IOKit/IOService.h>
32#include <IOKit/pwr_mgt/IOPM.h>
33#include <IOKit/IOBufferMemoryDescriptor.h>
34#include <sys/vnode.h>
35
36#ifdef XNU_KERNEL_PRIVATE
37struct AggressivesRecord;
38struct IOPMMessageFilterContext;
39struct IOPMActions;
40struct IOPMSystemSleepParameters;
41class PMSettingObject;
42class PMTraceWorker;
43class IOPMPowerStateQueue;
44class RootDomainUserClient;
45class PMAssertionsTracker;
46
47#define OBFUSCATE(x) (void *)VM_KERNEL_UNSLIDE_OR_PERM(x)
48
49#endif
50
51/*!
52 * Types for PM Assertions
53 * For creating, releasing, and getting PM assertion levels.
54 */
55
56/*! IOPMDriverAssertionType
57 * A bitfield describing a set of assertions. May be used to specify which assertions
58 * to set with <link>IOPMrootDomain::createPMAssertion</link>; or to query which
59 * assertions are set with <link>IOPMrootDomain::releasePMAssertion</link>.
60 */
61typedef uint64_t IOPMDriverAssertionType;
62
63/* IOPMDriverAssertionID
64 * Drivers may create PM assertions to request system behavior (keep the system awake,
65 * or keep the display awake). When a driver creates an assertion via
66 * <link>IOPMrootDomain::createPMAssertion</link>, PM returns a handle to
67 * the assertion of type IOPMDriverAssertionID.
68 */
69typedef uint64_t IOPMDriverAssertionID;
70#define kIOPMUndefinedDriverAssertionID 0
71
72/* IOPMDriverAssertionLevel
73 * Possible values for IOPMDriverAssertionLevel are <link>kIOPMDriverAssertionLevelOff</link>
74 * and <link>kIOPMDriverAssertionLevelOn</link>
75 */
76typedef uint32_t IOPMDriverAssertionLevel;
77#define kIOPMDriverAssertionLevelOff 0
78#define kIOPMDriverAssertionLevelOn 255
79
80/*
81 * Flags for get/setSleepSupported()
82 */
83enum {
84 kRootDomainSleepNotSupported = 0x00000000,
85 kRootDomainSleepSupported = 0x00000001,
86 kFrameBufferDeepSleepSupported = 0x00000002,
87 kPCICantSleep = 0x00000004
88};
89
90/*
91 *IOPMrootDomain registry property keys
92 */
93#define kRootDomainSupportedFeatures "Supported Features"
94#define kRootDomainSleepReasonKey "Last Sleep Reason"
95#define kRootDomainSleepOptionsKey "Last Sleep Options"
96#define kIOPMRootDomainWakeReasonKey "Wake Reason"
97#define kIOPMRootDomainWakeTypeKey "Wake Type"
98#define kIOPMRootDomainPowerStatusKey "Power Status"
99
100/*
101 * Possible sleep reasons found under kRootDomainSleepReasonsKey
102 */
103#define kIOPMClamshellSleepKey "Clamshell Sleep"
104#define kIOPMPowerButtonSleepKey "Power Button Sleep"
105#define kIOPMSoftwareSleepKey "Software Sleep"
106#define kIOPMOSSwitchHibernationKey "OS Switch Sleep"
107#define kIOPMIdleSleepKey "Idle Sleep"
108#define kIOPMLowPowerSleepKey "Low Power Sleep"
109#define kIOPMThermalEmergencySleepKey "Thermal Emergency Sleep"
110#define kIOPMMaintenanceSleepKey "Maintenance Sleep"
111
112/*
113 * String constants for communication with PM CPU
114 */
115#define kIOPMRootDomainLidCloseCString "LidClose"
116#define kIOPMRootDomainBatPowerCString "BatPower"
117
118/*
119 * Supported Feature bitfields for IOPMrootDomain::publishFeature()
120 */
121enum {
122 kIOPMSupportedOnAC = (1<<0),
123 kIOPMSupportedOnBatt = (1<<1),
124 kIOPMSupportedOnUPS = (1<<2)
125};
126
127typedef IOReturn (*IOPMSettingControllerCallback)
128 (OSObject *target, const OSSymbol *type,
129 OSObject *val, uintptr_t refcon);
130
131__BEGIN_DECLS
132IONotifier * registerSleepWakeInterest(
133 IOServiceInterestHandler, void *, void * = 0);
134
135IONotifier * registerPrioritySleepWakeInterest(
136 IOServiceInterestHandler handler,
137 void * self, void * ref = 0);
138
139IOReturn acknowledgeSleepWakeNotification(void * );
140
141IOReturn vetoSleepWakeNotification(void * PMrefcon);
142__END_DECLS
143
144#define IOPM_ROOTDOMAIN_REV 2
145
146class IOPMrootDomain: public IOService
147{
148 OSDeclareFinalStructors(IOPMrootDomain)
149
150public:
151 static IOPMrootDomain * construct( void );
152
153 virtual bool start( IOService * provider ) APPLE_KEXT_OVERRIDE;
154 virtual IOReturn setAggressiveness( unsigned long, unsigned long ) APPLE_KEXT_OVERRIDE;
155 virtual IOReturn getAggressiveness( unsigned long, unsigned long * ) APPLE_KEXT_OVERRIDE;
156
157 virtual IOReturn sleepSystem( void );
158 IOReturn sleepSystemOptions( OSDictionary *options );
159
160 virtual IOReturn setProperties( OSObject * ) APPLE_KEXT_OVERRIDE;
161 virtual bool serializeProperties( OSSerialize * s ) const APPLE_KEXT_OVERRIDE;
162 virtual OSObject * copyProperty( const char * aKey ) const APPLE_KEXT_OVERRIDE;
163
164/*! @function systemPowerEventOccurred
165 @abstract Other drivers may inform IOPMrootDomain of system PM events
166 @discussion systemPowerEventOccurred is a richer alternative to receivePowerNotification()
167 Only Apple-owned kexts should have reason to call systemPowerEventOccurred.
168 @param event An OSSymbol describing the type of power event.
169 @param intValue A 32-bit integer value associated with the event.
170 @result kIOReturnSuccess on success */
171
172 IOReturn systemPowerEventOccurred(
173 const OSSymbol *event,
174 uint32_t intValue );
175
176 IOReturn systemPowerEventOccurred(
177 const OSSymbol *event,
178 OSObject *value );
179
180#ifdef XNU_KERNEL_PRIVATE // Hide doc from public headers
181/*! @function claimSystemWakeEvent
182 @abstract Apple-internal SPI to describe system wake events.
183 @discussion IOKit drivers may call claimSystemWakeEvent() during system wakeup to
184 provide human readable debug information describing the event(s) that
185 caused the system to wake.
186
187 - Drivers should call claimSystemWakeEvent before completing
188 their setPowerState() acknowledgement. IOPMrootDomain stops
189 collecting wake events when driver wake is complete.
190
191 - It is only appropriate to claim a wake event when the driver
192 can positively identify its hardware has generated an event
193 that can wake the system.
194
195 - This call tracks wake events from a non-S0 state (S0i, S3, S4) into S0.
196 - This call does not track wake events from DarkWake(S0) to FullWake(S0).
197
198 Examples:
199 (reason = "WiFi.TCPData",
200 details = "TCPKeepAlive packet arrived from IP 16.2.1.1")
201 (reason = "WiFi.ScanOffload",
202 details = "WiFi station 'AppleWiFi' signal dropped below threshold")
203 (reason = "Enet.LinkToggle",
204 details = "Ethernet attached")
205
206 @param device The device/nub that is associated with the wake event.
207
208 @param flags Pass kIOPMWakeEventSource if the device is the source
209 of the wake event. Pass zero if the device is forwarding or
210 aggregating wake events from multiple sources, e.g. an USB or
211 Thunderbolt host controller.
212
213 @param reason Caller should pass a human readable C string describing the
214 wake reason. Please use a string from the list below, or create
215 your own string matching this format:
216 [Hardware].[Event]
217 WiFi.MagicPacket
218 WiFi.ScanOffload
219 WiFi.mDNSConflict
220 WiFi.mDNSService
221 WiFi.TCPData
222 WiFi.TCPTimeout
223 WiFi.FirmwareCrash
224 Enet.MagicPacket
225 Enet.mDNSConflict
226 Enet.mDNSService
227 Enet.TCPData
228 Enet.TCPTimeout
229 Enet.Service
230 Enet.LinkToggle
231 Enet.ConflictResolution
232 Enet.PatternMatch
233 Enet.Timer
234 Enet.LinkUpTimeout
235 Enet.LinkDown
236 USB.DeviceAttach
237 USB.DeviceDetach
238
239 @param details Optional details further describing the wake event.
240 Please pass an OSString defining the event.
241 */
242#endif
243 void claimSystemWakeEvent( IOService *device,
244 IOOptionBits flags,
245 const char *reason,
246 OSObject *details = 0 );
247
248 virtual IOReturn receivePowerNotification( UInt32 msg );
249
250 virtual void setSleepSupported( IOOptionBits flags );
251
252 virtual IOOptionBits getSleepSupported( void );
253
254 void wakeFromDoze( void );
255
256 // KEXT driver announces support of power management feature
257
258 void publishFeature( const char *feature );
259
260 // KEXT driver announces support of power management feature
261 // And specifies power sources with kIOPMSupportedOn{AC/Batt/UPS} bitfield.
262 // Returns a unique uint32_t identifier for later removing support for this
263 // feature.
264 // NULL is acceptable for uniqueFeatureID for kexts without plans to unload.
265
266 void publishFeature( const char *feature,
267 uint32_t supportedWhere,
268 uint32_t *uniqueFeatureID);
269
270 // KEXT driver announces removal of a previously published power management
271 // feature. Pass 'uniqueFeatureID' returned from publishFeature()
272
273 IOReturn removePublishedFeature( uint32_t removeFeatureID );
274
275/*! @function copyPMSetting
276 @abstract Copy the current value for a PM setting. Returns an OSNumber or
277 OSData depending on the setting.
278 @param whichSetting Name of the desired setting.
279 @result OSObject value if valid, NULL otherwise. */
280
281 OSObject * copyPMSetting( OSSymbol *whichSetting );
282
283/*! @function registerPMSettingController
284 @abstract Register for callbacks on changes to certain PM settings.
285 @param settings NULL terminated array of C strings, each string for a PM
286 setting that the caller is interested in and wants to get callbacks for.
287 @param callout C function ptr or member function cast as such.
288 @param target The target of the callback, usually 'this'
289 @param refcon Will be passed to caller in callback; for caller's use.
290 @param handle Caller should keep the OSObject * returned here. If non-NULL,
291 handle will have a retain count of 1 on return. To deregister, pass to
292 unregisterPMSettingController()
293 @result kIOReturnSuccess on success. */
294
295 IOReturn registerPMSettingController(
296 const OSSymbol *settings[],
297 IOPMSettingControllerCallback callout,
298 OSObject *target,
299 uintptr_t refcon,
300 OSObject **handle); // out param
301
302/*! @function registerPMSettingController
303 @abstract Register for callbacks on changes to certain PM settings.
304 @param settings NULL terminated array of C strings, each string for a PM
305 setting that the caller is interested in and wants to get callbacks for.
306 @param supportedPowerSources bitfield indicating which power sources these
307 settings are supported for (kIOPMSupportedOnAC, etc.)
308 @param callout C function ptr or member function cast as such.
309 @param target The target of the callback, usually 'this'
310 @param refcon Will be passed to caller in callback; for caller's use.
311 @param handle Caller should keep the OSObject * returned here. If non-NULL,
312 handle will have a retain count of 1 on return. To deregister, pass to
313 unregisterPMSettingController()
314 @result kIOReturnSuccess on success. */
315
316 IOReturn registerPMSettingController(
317 const OSSymbol *settings[],
318 uint32_t supportedPowerSources,
319 IOPMSettingControllerCallback callout,
320 OSObject *target,
321 uintptr_t refcon,
322 OSObject **handle); // out param
323
324 virtual IONotifier * registerInterest(
325 const OSSymbol * typeOfInterest,
326 IOServiceInterestHandler handler,
327 void * target, void * ref = 0 ) APPLE_KEXT_OVERRIDE;
328
329 virtual IOReturn callPlatformFunction(
330 const OSSymbol *functionName,
331 bool waitForFunction,
332 void *param1, void *param2,
333 void *param3, void *param4 ) APPLE_KEXT_OVERRIDE;
334
335/*! @function createPMAssertion
336 @abstract Creates an assertion to influence system power behavior.
337 @param whichAssertionsBits A bitfield specify the assertion that the caller requests.
338 @param assertionLevel An integer detailing the initial assertion level, kIOPMDriverAssertionLevelOn
339 or kIOPMDriverAssertionLevelOff.
340 @param ownerService A pointer to the caller's IOService class, for tracking.
341 @param ownerDescription A reverse-DNS string describing the caller's identity and reason.
342 @result On success, returns a new assertion of type IOPMDriverAssertionID
343*/
344 IOPMDriverAssertionID createPMAssertion(
345 IOPMDriverAssertionType whichAssertionsBits,
346 IOPMDriverAssertionLevel assertionLevel,
347 IOService *ownerService,
348 const char *ownerDescription);
349
350/* @function setPMAssertionLevel
351 @abstract Modify the level of a pre-existing assertion.
352 @discussion Change the value of a PM assertion to influence system behavior,
353 without undergoing the work required to create or destroy an assertion. Suggested
354 for clients who will assert and de-assert needs for PM behavior several times over
355 their lifespan.
356 @param assertionID An assertion ID previously returned by <link>createPMAssertion</link>
357 @param assertionLevel The new assertion level.
358 @result kIOReturnSuccess if it worked; kIOReturnNotFound or other IOReturn error on failure.
359*/
360 IOReturn setPMAssertionLevel(IOPMDriverAssertionID assertionID, IOPMDriverAssertionLevel assertionLevel);
361
362/*! @function getPMAssertionLevel
363 @absract Returns the active level of the specified assertion(s).
364 @discussion Returns <link>kIOPMDriverAssertionLevelOff</link> or
365 <link>kIOPMDriverAssertionLevelOn</link>. If multiple assertions are specified
366 in the bitfield, only returns <link>kIOPMDriverAssertionLevelOn</link>
367 if all assertions are active.
368 @param whichAssertionBits Bits defining the assertion or assertions the caller is interested in
369 the level of. If in doubt, pass <link>kIOPMDriverAssertionCPUBit</link> as the argument.
370 @result Returns <link>kIOPMDriverAssertionLevelOff</link> or
371 <link>kIOPMDriverAssertionLevelOn</link> indicating the specified assertion's levels, if available.
372 If the assertions aren't supported on this machine, or aren't recognized by the OS, the
373 result is undefined.
374*/
375 IOPMDriverAssertionLevel getPMAssertionLevel(IOPMDriverAssertionType whichAssertionBits);
376
377/*! @function releasePMAssertion
378 @abstract Removes an assertion to influence system power behavior.
379 @result On success, returns a new assertion of type IOPMDriverAssertionID *
380*/
381 IOReturn releasePMAssertion(IOPMDriverAssertionID releaseAssertion);
382
383/*! @function restartWithStackshot
384 @abstract Take a stackshot of the system and restart the system.
385 @result Return kIOReturnSuccess if it work, kIOReturnError if the service is not available.
386*/
387 IOReturn restartWithStackshot();
388
389private:
390 virtual IOReturn changePowerStateTo( unsigned long ordinal ) APPLE_KEXT_COMPATIBILITY_OVERRIDE;
391 virtual IOReturn changePowerStateToPriv( unsigned long ordinal );
392 virtual IOReturn requestPowerDomainState( IOPMPowerFlags, IOPowerConnection *, unsigned long ) APPLE_KEXT_OVERRIDE;
393 virtual void powerChangeDone( unsigned long ) APPLE_KEXT_OVERRIDE;
394 virtual bool tellChangeDown( unsigned long ) APPLE_KEXT_OVERRIDE;
395 virtual bool askChangeDown( unsigned long ) APPLE_KEXT_OVERRIDE;
396 virtual void tellChangeUp( unsigned long ) APPLE_KEXT_OVERRIDE;
397 virtual void tellNoChangeDown( unsigned long ) APPLE_KEXT_OVERRIDE;
398 virtual IOReturn configureReport(IOReportChannelList *channels,
399 IOReportConfigureAction action,
400 void *result,
401 void *destination) APPLE_KEXT_OVERRIDE;
402 virtual IOReturn updateReport(IOReportChannelList *channels,
403 IOReportUpdateAction action,
404 void *result,
405 void *destination) APPLE_KEXT_OVERRIDE;
406
407 void configureReportGated(uint64_t channel_id,
408 uint64_t action,
409 void *result);
410 IOReturn updateReportGated(uint64_t ch_id,
411 void *result,
412 IOBufferMemoryDescriptor *dest);
413
414#ifdef XNU_KERNEL_PRIVATE
415 /* Root Domain internals */
416public:
417 void tagPowerPlaneService(
418 IOService * service,
419 IOPMActions * actions );
420
421 void overrideOurPowerChange(
422 IOService * service,
423 IOPMActions * actions,
424 IOPMPowerStateIndex * inOutPowerState,
425 IOPMPowerChangeFlags * inOutChangeFlags,
426 IOPMRequestTag requestTag );
427
428 void handleOurPowerChangeStart(
429 IOService * service,
430 IOPMActions * actions,
431 IOPMPowerStateIndex powerState,
432 IOPMPowerChangeFlags * inOutChangeFlags,
433 IOPMRequestTag requestTag );
434
435 void handleOurPowerChangeDone(
436 IOService * service,
437 IOPMActions * actions,
438 IOPMPowerStateIndex powerState,
439 IOPMPowerChangeFlags changeFlags,
440 IOPMRequestTag requestTag );
441
442 void overridePowerChangeForUIService(
443 IOService * service,
444 IOPMActions * actions,
445 IOPMPowerStateIndex * inOutPowerState,
446 IOPMPowerChangeFlags * inOutChangeFlags );
447
448 void handleActivityTickleForDisplayWrangler(
449 IOService * service,
450 IOPMActions * actions );
451
452 void handleUpdatePowerClientForDisplayWrangler(
453 IOService * service,
454 IOPMActions * actions,
455 const OSSymbol * powerClient,
456 IOPMPowerStateIndex oldPowerState,
457 IOPMPowerStateIndex newPowerState );
458
459 bool shouldDelayChildNotification(
460 IOService * service );
461
462 void handlePowerChangeStartForPCIDevice(
463 IOService * service,
464 IOPMActions * actions,
465 IOPMPowerStateIndex powerState,
466 IOPMPowerChangeFlags * inOutChangeFlags );
467
468 void handlePowerChangeDoneForPCIDevice(
469 IOService * service,
470 IOPMActions * actions,
471 IOPMPowerStateIndex powerState,
472 IOPMPowerChangeFlags changeFlags );
473
474 void askChangeDownDone(
475 IOPMPowerChangeFlags * inOutChangeFlags,
476 bool * cancel );
477
478 void handlePublishSleepWakeUUID(
479 bool shouldPublish);
480
481 void handleQueueSleepWakeUUID(
482 OSObject *obj);
483
484 void handleDisplayPowerOn( );
485
486 void willNotifyPowerChildren( IOPMPowerStateIndex newPowerState );
487
488 IOReturn setMaintenanceWakeCalendar(
489 const IOPMCalendarStruct * calendar );
490
491 IOReturn getSystemSleepType(uint32_t * sleepType, uint32_t * standbyTimer);
492
493 // Handle callbacks from IOService::systemWillShutdown()
494 void acknowledgeSystemWillShutdown( IOService * from );
495
496 // Handle platform halt and restart notifications
497 void handlePlatformHaltRestart( UInt32 pe_type );
498
499 IOReturn shutdownSystem( void );
500 IOReturn restartSystem( void );
501 void handleSleepTimerExpiration( void );
502
503 bool activitySinceSleep(void);
504 bool abortHibernation(void);
505 void updateConsoleUsers(void);
506
507 IOReturn joinAggressiveness( IOService * service );
508 void handleAggressivesRequests( void );
509
510 void kdebugTrace(uint32_t event, uint64_t regId,
511 uintptr_t param1, uintptr_t param2, uintptr_t param3 = 0);
512 void tracePoint(uint8_t point);
513 void traceDetail(uint32_t msgType, uint32_t msgIndex, uint32_t delay);
514 void traceDetail(OSObject *notifier, bool start);
515 void traceAckDelay(OSObject *notifier, uint32_t response, uint32_t delay_ms);
516
517 void startSpinDump(uint32_t spindumpKind);
518
519 bool systemMessageFilter(
520 void * object, void * arg1, void * arg2, void * arg3 );
521
522 bool updatePreventIdleSleepList(
523 IOService * service, bool addNotRemove );
524 void updatePreventSystemSleepList(
525 IOService * service, bool addNotRemove );
526
527 void publishPMSetting(
528 const OSSymbol * feature, uint32_t where, uint32_t * featureID );
529
530 void pmStatsRecordEvent(
531 int eventIndex,
532 AbsoluteTime timestamp);
533
534 void pmStatsRecordApplicationResponse(
535 const OSSymbol *response,
536 const char *name,
537 int messageType,
538 uint32_t delay_ms,
539 uint64_t id,
540 OSObject *object,
541 IOPMPowerStateIndex ps=0);
542
543 void copyWakeReasonString( char * outBuf, size_t bufSize );
544
545#if HIBERNATION
546 bool getHibernateSettings(
547 uint32_t * hibernateMode,
548 uint32_t * hibernateFreeRatio,
549 uint32_t * hibernateFreeTime );
550 bool mustHibernate( void );
551#endif
552 void takeStackshot(bool restart, bool isOSXWatchdog, bool isSpinDump);
553 void sleepWakeDebugTrig(bool restart);
554 void sleepWakeDebugEnableWdog();
555 bool sleepWakeDebugIsWdogEnabled();
556 void sleepWakeDebugSaveSpinDumpFile();
557 bool checkShutdownTimeout();
558 void panicWithShutdownLog(uint32_t timeoutInMs);
559 uint32_t getWatchdogTimeout();
560
561private:
562 friend class PMSettingObject;
563 friend class RootDomainUserClient;
564 friend class PMAssertionsTracker;
565
566 static IOReturn sysPowerDownHandler( void * target, void * refCon,
567 UInt32 messageType, IOService * service,
568 void * messageArgument, vm_size_t argSize );
569
570 static IOReturn displayWranglerNotification( void * target, void * refCon,
571 UInt32 messageType, IOService * service,
572 void * messageArgument, vm_size_t argSize );
573
574 static IOReturn rootBusyStateChangeHandler( void * target, void * refCon,
575 UInt32 messageType, IOService * service,
576 void * messageArgument, vm_size_t argSize );
577
578 static bool displayWranglerMatchPublished( void * target, void * refCon,
579 IOService * newService,
580 IONotifier * notifier);
581
582 static bool batteryPublished( void * target, void * refCon,
583 IOService * resourceService,
584 IONotifier * notifier);
585
586 void initializeBootSessionUUID( void );
587
588 void fullWakeDelayedWork( void );
589
590 IOService * wrangler;
591 OSDictionary * wranglerIdleSettings;
592
593 IOLock *featuresDictLock; // guards supportedFeatures
594 IOLock *wakeEventLock;
595 IOPMPowerStateQueue *pmPowerStateQueue;
596
597 OSArray *allowedPMSettings;
598 OSArray *noPublishPMSettings;
599 PMTraceWorker *pmTracer;
600 PMAssertionsTracker *pmAssertions;
601
602 // Settings controller info
603 IOLock *settingsCtrlLock;
604 OSDictionary *settingsCallbacks;
605 OSDictionary *fPMSettingsDict;
606
607 IONotifier *_batteryPublishNotifier;
608 IONotifier *_displayWranglerNotifier;
609
610 // Statistics
611 const OSSymbol *_statsNameKey;
612 const OSSymbol *_statsPIDKey;
613 const OSSymbol *_statsTimeMSKey;
614 const OSSymbol *_statsResponseTypeKey;
615 const OSSymbol *_statsMessageTypeKey;
616 const OSSymbol *_statsPowerCapsKey;
617 uint32_t sleepCnt;
618 uint32_t darkWakeCnt;
619 uint32_t displayWakeCnt;
620
621 OSString *queuedSleepWakeUUIDString;
622 OSArray *pmStatsAppResponses;
623 IOLock *pmStatsLock; // guards pmStatsAppResponses
624
625 void *sleepDelaysReport; // report to track time taken to go to sleep
626 uint32_t sleepDelaysClientCnt; // Number of interested clients in sleepDelaysReport
627 uint64_t ts_sleepStart;
628 uint64_t wake2DarkwakeDelay; // Time taken to change from full wake -> Dark wake
629
630
631 void *assertOnWakeReport; // report to track time spent without any assertions held after wake
632 uint32_t assertOnWakeClientCnt; // Number of clients interested in assertOnWakeReport
633 clock_sec_t assertOnWakeSecs; // Num of secs after wake for first assertion
634
635 bool uuidPublished;
636
637 // Pref: idle time before idle sleep
638 bool idleSleepEnabled;
639 unsigned long sleepSlider;
640 unsigned long idleSeconds;
641 uint64_t autoWakeStart;
642 uint64_t autoWakeEnd;
643
644 // Difference between sleepSlider and longestNonSleepSlider
645 unsigned long extraSleepDelay;
646
647 // Used to wait between say display idle and system idle
648 thread_call_t extraSleepTimer;
649 thread_call_t diskSyncCalloutEntry;
650 thread_call_t fullWakeThreadCall;
651 thread_call_t updateConsoleUsersEntry;
652
653 // Track system capabilities.
654 uint32_t _desiredCapability;
655 uint32_t _currentCapability;
656 uint32_t _pendingCapability;
657 uint32_t _highestCapability;
658 OSSet * _joinedCapabilityClients;
659 uint32_t _systemStateGeneration;
660
661 // Type of clients that can receive system messages.
662 enum {
663 kSystemMessageClientPowerd = 0x01,
664 kSystemMessageClientLegacyApp = 0x02,
665 kSystemMessageClientKernel = 0x04,
666 kSystemMessageClientAll = 0x07
667 };
668 uint32_t _systemMessageClientMask;
669
670 // Power state and capability change transitions.
671 enum {
672 kSystemTransitionNone = 0,
673 kSystemTransitionSleep = 1,
674 kSystemTransitionWake = 2,
675 kSystemTransitionCapability = 3,
676 kSystemTransitionNewCapClient = 4
677 } _systemTransitionType;
678
679 unsigned int systemBooting :1;
680 unsigned int systemShutdown :1;
681 unsigned int systemDarkWake :1;
682 unsigned int clamshellExists :1;
683 unsigned int clamshellClosed :1;
684 unsigned int clamshellDisabled :1;
685 unsigned int desktopMode :1;
686 unsigned int acAdaptorConnected :1;
687
688 unsigned int clamshellSleepDisabled :1;
689 unsigned int idleSleepTimerPending :1;
690 unsigned int userDisabledAllSleep :1;
691 unsigned int ignoreTellChangeDown :1;
692 unsigned int wranglerAsleep :1;
693 unsigned int wranglerTickled :1;
694 unsigned int _preventUserActive :1;
695 unsigned int graphicsSuppressed :1;
696
697 unsigned int capabilityLoss :1;
698 unsigned int pciCantSleepFlag :1;
699 unsigned int pciCantSleepValid :1;
700 unsigned int logGraphicsClamp :1;
701 unsigned int darkWakeToSleepASAP :1;
702 unsigned int darkWakeMaintenance :1;
703 unsigned int darkWakeSleepService :1;
704 unsigned int darkWakePostTickle :1;
705
706 unsigned int sleepTimerMaintenance :1;
707 unsigned int sleepToStandby :1;
708 unsigned int lowBatteryCondition :1;
709 unsigned int hibernateDisabled :1;
710 unsigned int hibernateRetry :1;
711 unsigned int wranglerTickleLatched :1;
712 unsigned int userIsActive :1;
713 unsigned int userWasActive :1;
714
715 unsigned int displayIdleForDemandSleep :1;
716 unsigned int darkWakeHibernateError :1;
717 unsigned int thermalWarningState:1;
718 unsigned int toldPowerdCapWillChange :1;
719 unsigned int displayPowerOnRequested:1;
720
721 uint8_t tasksSuspended;
722 uint32_t hibernateMode;
723 AbsoluteTime userActivityTime;
724 AbsoluteTime userActivityTime_prev;
725 uint32_t userActivityCount;
726 uint32_t userActivityAtSleep;
727 uint32_t lastSleepReason;
728 uint32_t fullToDarkReason;
729 uint32_t hibernateAborted;
730 uint8_t standbyNixed;
731 uint8_t resetTimers;
732
733 enum FullWakeReason {
734 kFullWakeReasonNone = 0,
735 kFullWakeReasonLocalUser = 1,
736 kFullWakeReasonDisplayOn = 2,
737 fFullWakeReasonDisplayOnAndLocalUser = 3
738 };
739 uint32_t fullWakeReason;
740
741 // Info for communicating system state changes to PMCPU
742 int32_t idxPMCPUClamshell;
743 int32_t idxPMCPULimitedPower;
744
745 IOOptionBits platformSleepSupport;
746 uint32_t _debugWakeSeconds;
747 uint32_t _lastDebugWakeSeconds;
748
749 queue_head_t aggressivesQueue;
750 thread_call_t aggressivesThreadCall;
751 OSData * aggressivesData;
752
753 AbsoluteTime userBecameInactiveTime;
754
755 // PCI top-level PM trace
756 IOService * pciHostBridgeDevice;
757 IOService * pciHostBridgeDriver;
758
759 IONotifier * systemCapabilityNotifier;
760
761 typedef struct {
762 uint32_t pid;
763 uint32_t refcount;
764 } PMNotifySuspendedStruct;
765
766 uint32_t pmSuspendedCapacity;
767 uint32_t pmSuspendedSize;
768 PMNotifySuspendedStruct *pmSuspendedPIDS;
769
770 OSSet * preventIdleSleepList;
771 OSSet * preventSystemSleepList;
772
773 UInt32 _scheduledAlarms;
774 UInt32 _userScheduledAlarm;
775
776#if HIBERNATION
777 clock_sec_t _standbyTimerResetSeconds;
778#endif
779 volatile uint32_t swd_lock; /* Lock to access swd_buffer & and its header */
780 void * swd_buffer; /* Memory allocated for dumping sleep/wake logs */
781 uint32_t swd_flags; /* Flags defined in IOPMPrivate.h */
782 void * swd_compressed_buffer;
783 void * swd_spindump_buffer;
784 thread_t notifierThread;
785 OSObject *notifierObject;
786
787 IOBufferMemoryDescriptor *swd_memDesc;
788
789 // Wake Event Reporting
790 OSArray * _systemWakeEventsArray;
791 bool _acceptSystemWakeEvents;
792
793 int findSuspendedPID(uint32_t pid, uint32_t *outRefCount);
794
795 // IOPMrootDomain internal sleep call
796 IOReturn privateSleepSystem( uint32_t sleepReason );
797 void reportUserInput( void );
798 void setDisableClamShellSleep( bool );
799 bool checkSystemSleepAllowed( IOOptionBits options,
800 uint32_t sleepReason );
801 bool checkSystemSleepEnabled( void );
802 bool checkSystemCanSleep( uint32_t sleepReason );
803 bool checkSystemCanSustainFullWake( void );
804
805 void adjustPowerState( bool sleepASAP = false );
806 void setQuickSpinDownTimeout( void );
807 void restoreUserSpinDownTimeout( void );
808
809 bool shouldSleepOnClamshellClosed(void );
810 void sendClientClamshellNotification( void );
811
812 // Inform PMCPU of changes to state like lid, AC vs. battery
813 void informCPUStateChange( uint32_t type, uint32_t value );
814
815 void dispatchPowerEvent( uint32_t event, void * arg0, uint64_t arg1 );
816 void handlePowerNotification( UInt32 msg );
817
818 IOReturn setPMSetting(const OSSymbol *, OSObject *);
819
820 void startIdleSleepTimer( uint32_t inSeconds );
821 void cancelIdleSleepTimer( void );
822 uint32_t getTimeToIdleSleep( void );
823
824 IOReturn setAggressiveness(
825 unsigned long type,
826 unsigned long value,
827 IOOptionBits options );
828
829 void synchronizeAggressives(
830 queue_head_t * services,
831 const AggressivesRecord * array,
832 int count );
833
834 void broadcastAggressives(
835 const AggressivesRecord * array,
836 int count );
837
838 IOReturn setPMAssertionUserLevels(IOPMDriverAssertionType);
839
840 void publishSleepWakeUUID( bool shouldPublish );
841
842 void evaluatePolicy( int stimulus, uint32_t arg = 0 );
843 void requestFullWake( FullWakeReason reason );
844 void willEnterFullWake( void );
845
846 void evaluateAssertions(IOPMDriverAssertionType newAssertions,
847 IOPMDriverAssertionType oldAssertions);
848
849 void deregisterPMSettingObject( PMSettingObject * pmso );
850
851 uint32_t checkForValidDebugData(const char *fname, vfs_context_t *ctx,
852 void *tmpBuf, struct vnode **vp);
853 void getFailureData(thread_t *thread, char *failureStr, size_t strLen);
854 void saveFailureData2File();
855 void tracePhase2String(uint32_t tracePhase, const char **phaseString, const char **description);
856 void sleepWakeDebugMemAlloc( );
857 void sleepWakeDebugSpinDumpMemAlloc( );
858 errno_t sleepWakeDebugSaveFile(const char *name, char *buf, int len);
859
860
861#if HIBERNATION
862 bool getSleepOption( const char * key, uint32_t * option );
863 bool evaluateSystemSleepPolicy( IOPMSystemSleepParameters * p,
864 int phase, uint32_t * hibMode );
865 void evaluateSystemSleepPolicyEarly( void );
866 void evaluateSystemSleepPolicyFinal( void );
867#endif /* HIBERNATION */
868
869 bool latchDisplayWranglerTickle( bool latch );
870 void setDisplayPowerOn( uint32_t options );
871
872 void acceptSystemWakeEvents( bool accept );
873 void systemDidNotSleep( void );
874 void preventTransitionToUserActive( bool prevent );
875 void setThermalState(OSObject *value);
876 void copySleepPreventersList(OSArray **idleSleepList, OSArray **systemSleepList);
877#endif /* XNU_KERNEL_PRIVATE */
878};
879
880#ifdef XNU_KERNEL_PRIVATE
881class IORootParent: public IOService
882{
883 OSDeclareFinalStructors(IORootParent)
884
885public:
886 static void initialize( void );
887 virtual OSObject * copyProperty( const char * aKey ) const APPLE_KEXT_OVERRIDE;
888 bool start( IOService * nub ) APPLE_KEXT_OVERRIDE;
889 void shutDownSystem( void );
890 void restartSystem( void );
891 void sleepSystem( void );
892 void dozeSystem( void );
893 void sleepToDoze( void );
894 void wakeSystem( void );
895};
896#endif /* XNU_KERNEL_PRIVATE */
897
898#endif /* _IOKIT_ROOTDOMAIN_H */
899