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 | |
41 | struct AggressivesRecord; |
42 | struct IOPMMessageFilterContext; |
43 | struct IOPMActions; |
44 | struct IOPMSystemSleepParameters; |
45 | class PMSettingObject; |
46 | class PMTraceWorker; |
47 | class IOPMPowerStateQueue; |
48 | class RootDomainUserClient; |
49 | class PMAssertionsTracker; |
50 | class 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 | */ |
66 | typedef 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 | */ |
74 | typedef 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 | */ |
81 | typedef uint32_t IOPMDriverAssertionLevel; |
82 | #define kIOPMDriverAssertionLevelOff 0 |
83 | #define kIOPMDriverAssertionLevelOn 255 |
84 | |
85 | /* |
86 | * Flags for get/setSleepSupported() |
87 | */ |
88 | enum { |
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 | */ |
126 | enum { |
127 | kIOPMSupportedOnAC = (1 << 0), |
128 | kIOPMSupportedOnBatt = (1 << 1), |
129 | kIOPMSupportedOnUPS = (1 << 2) |
130 | }; |
131 | |
132 | typedef IOReturn (*IOPMSettingControllerCallback) |
133 | (OSObject *target, const OSSymbol *type, |
134 | OSObject *val, uintptr_t refcon); |
135 | |
136 | __BEGIN_DECLS |
137 | IONotifier * registerSleepWakeInterest( |
138 | IOServiceInterestHandler, void *, void * = NULL); |
139 | |
140 | IONotifier * registerPrioritySleepWakeInterest( |
141 | IOServiceInterestHandler handler, |
142 | void * self, void * ref = NULL); |
143 | |
144 | IOReturn acknowledgeSleepWakeNotification(void * ); |
145 | |
146 | IOReturn vetoSleepWakeNotification(void * PMrefcon); |
147 | __END_DECLS |
148 | |
149 | #define IOPM_ROOTDOMAIN_REV 2 |
150 | |
151 | class IOPMrootDomain : public IOService |
152 | { |
153 | OSDeclareFinalStructors(IOPMrootDomain); |
154 | |
155 | public: |
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 | |
418 | private: |
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 */ |
447 | public: |
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 | |
608 | private: |
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; |
848 | public: |
849 | IOPMAOTMetrics * _aotMetrics; |
850 | uint8_t _aotMode; |
851 | private: |
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); |
868 | public: |
869 | bool isAOTMode(void); |
870 | private: |
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 |
981 | class IORootParent : public IOService |
982 | { |
983 | OSDeclareFinalStructors(IORootParent); |
984 | |
985 | public: |
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 | |