| 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 |
| 37 | struct AggressivesRecord; |
| 38 | struct IOPMMessageFilterContext; |
| 39 | struct IOPMActions; |
| 40 | struct IOPMSystemSleepParameters; |
| 41 | class PMSettingObject; |
| 42 | class PMTraceWorker; |
| 43 | class IOPMPowerStateQueue; |
| 44 | class RootDomainUserClient; |
| 45 | class 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 | */ |
| 61 | typedef 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 | */ |
| 69 | typedef 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 | */ |
| 76 | typedef uint32_t IOPMDriverAssertionLevel; |
| 77 | #define kIOPMDriverAssertionLevelOff 0 |
| 78 | #define kIOPMDriverAssertionLevelOn 255 |
| 79 | |
| 80 | /* |
| 81 | * Flags for get/setSleepSupported() |
| 82 | */ |
| 83 | enum { |
| 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 | */ |
| 121 | enum { |
| 122 | kIOPMSupportedOnAC = (1<<0), |
| 123 | kIOPMSupportedOnBatt = (1<<1), |
| 124 | kIOPMSupportedOnUPS = (1<<2) |
| 125 | }; |
| 126 | |
| 127 | typedef IOReturn (*IOPMSettingControllerCallback) |
| 128 | (OSObject *target, const OSSymbol *type, |
| 129 | OSObject *val, uintptr_t refcon); |
| 130 | |
| 131 | __BEGIN_DECLS |
| 132 | IONotifier * registerSleepWakeInterest( |
| 133 | IOServiceInterestHandler, void *, void * = 0); |
| 134 | |
| 135 | IONotifier * registerPrioritySleepWakeInterest( |
| 136 | IOServiceInterestHandler handler, |
| 137 | void * self, void * ref = 0); |
| 138 | |
| 139 | IOReturn acknowledgeSleepWakeNotification(void * ); |
| 140 | |
| 141 | IOReturn vetoSleepWakeNotification(void * PMrefcon); |
| 142 | __END_DECLS |
| 143 | |
| 144 | #define IOPM_ROOTDOMAIN_REV 2 |
| 145 | |
| 146 | class IOPMrootDomain: public IOService |
| 147 | { |
| 148 | OSDeclareFinalStructors(IOPMrootDomain) |
| 149 | |
| 150 | public: |
| 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 | |
| 389 | private: |
| 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 */ |
| 416 | public: |
| 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 | |
| 561 | private: |
| 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 |
| 881 | class IORootParent: public IOService |
| 882 | { |
| 883 | OSDeclareFinalStructors(IORootParent) |
| 884 | |
| 885 | public: |
| 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 | |