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