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