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 | |