]> git.saurik.com Git - apple/xnu.git/blob - iokit/IOKit/pwr_mgt/RootDomain.h
xnu-1504.9.17.tar.gz
[apple/xnu.git] / iokit / IOKit / pwr_mgt / RootDomain.h
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 #ifndef _IOKIT_ROOTDOMAIN_H
29 #define _IOKIT_ROOTDOMAIN_H
30
31 #include <IOKit/IOService.h>
32 #include <IOKit/pwr_mgt/IOPM.h>
33 #include "IOKit/pwr_mgt/IOPMPrivate.h"
34
35 #ifdef XNU_KERNEL_PRIVATE
36 #if defined(__i386__) || defined(__x86_64__)
37 #define ROOT_DOMAIN_RUN_STATES 1
38 #endif
39 struct AggressivesRecord;
40 class PMAssertionsTracker;
41 #endif /* XNU_KERNEL_PRIVATE */
42
43 class IOPMPowerStateQueue;
44 class RootDomainUserClient;
45 class PMTraceWorker;
46
47 /*!
48 * Types for PM Assertions
49 * For creating, releasing, and getting PM assertion levels.
50 */
51
52 /*! IOPMDriverAssertionType
53 * A bitfield describing a set of assertions. May be used to specify which assertions
54 * to set with <link>IOPMrootDomain::createPMAssertion</link>; or to query which
55 * assertions are set with <link>IOPMrootDomain::releasePMAssertion</link>.
56 */
57 typedef uint64_t IOPMDriverAssertionType;
58
59 /* IOPMDriverAssertionID
60 * Drivers may create PM assertions to request system behavior (keep the system awake,
61 * or keep the display awake). When a driver creates an assertion via
62 * <link>IOPMrootDomain::createPMAssertion</link>, PM returns a handle to
63 * the assertion of type IOPMDriverAssertionID.
64 */
65 typedef uint64_t IOPMDriverAssertionID;
66 #define kIOPMUndefinedDriverAssertionID 0
67
68 /* IOPMDriverAssertionLevel
69 * Possible values for IOPMDriverAssertionLevel are <link>kIOPMDriverAssertionLevelOff</link>
70 * and <link>kIOPMDriverAssertionLevelOn</link>
71 */
72 typedef uint32_t IOPMDriverAssertionLevel;
73 #define kIOPMDriverAssertionLevelOff 0
74 #define kIOPMDriverAssertionLevelOn 255
75
76 /*
77 * Flags for get/setSleepSupported()
78 */
79 enum {
80 kRootDomainSleepNotSupported = 0x00000000,
81 kRootDomainSleepSupported = 0x00000001,
82 kFrameBufferDeepSleepSupported = 0x00000002,
83 kPCICantSleep = 0x00000004
84 };
85
86 /*
87 *IOPMrootDomain registry property keys
88 */
89 #define kRootDomainSupportedFeatures "Supported Features"
90 #define kRootDomainSleepReasonKey "Last Sleep Reason"
91 #define kRootDomainSleepOptionsKey "Last Sleep Options"
92 #define kIOPMRootDomainWakeReasonKey "Wake Reason"
93 #define kIOPMRootDomainWakeTypeKey "Wake Type"
94 #define kIOPMRootDomainPowerStatusKey "Power Status"
95
96 /*
97 * Possible sleep reasons found under kRootDomainSleepReasonsKey
98 */
99 #define kIOPMClamshellSleepKey "Clamshell Sleep"
100 #define kIOPMPowerButtonSleepKey "Power Button Sleep"
101 #define kIOPMSoftwareSleepKey "Software Sleep"
102 #define kIOPMOSSwitchHibernationKey "OS Switch Sleep"
103 #define kIOPMIdleSleepKey "Idle Sleep"
104 #define kIOPMLowPowerSleepKey "Low Power Sleep"
105 #define kIOPMThermalEmergencySleepKey "Thermal Emergency Sleep"
106 #define kIOPMMaintenanceSleepKey "Maintenance Sleep"
107
108 enum
109 {
110 kIOPMSleepReasonClamshell = 1,
111 kIOPMSleepReasonPowerButton = 2,
112 kIOPMSleepReasonSoftware = 3,
113 kIOPMSleepReasonOSSwitchHibernation = 4,
114 kIOPMSleepReasonIdle = 5,
115 kIOPMSleepReasonLowPower = 6,
116 kIOPMSleepReasonThermalEmergency = 7,
117 kIOPMSleepReasonMaintenance = 8,
118 kIOPMSleepReasonMax
119 };
120
121 /*
122 * String constants for communication with PM CPU
123 */
124 #define kIOPMRootDomainLidCloseCString "LidClose"
125 #define kIOPMRootDomainBatPowerCString "BatPower"
126
127 /*
128 * Supported Feature bitfields for IOPMrootDomain::publishFeature()
129 */
130 enum {
131 kIOPMSupportedOnAC = (1<<0),
132 kIOPMSupportedOnBatt = (1<<1),
133 kIOPMSupportedOnUPS = (1<<2)
134 };
135
136 typedef IOReturn (*IOPMSettingControllerCallback)
137 (OSObject *target, const OSSymbol *type,
138 OSObject *val, uintptr_t refcon);
139
140 __BEGIN_DECLS
141 IONotifier * registerSleepWakeInterest(
142 IOServiceInterestHandler, void *, void * = 0);
143
144 IONotifier * registerPrioritySleepWakeInterest(
145 IOServiceInterestHandler handler,
146 void * self, void * ref = 0);
147
148 IOReturn acknowledgeSleepWakeNotification(void * );
149
150 IOReturn vetoSleepWakeNotification(void * PMrefcon);
151 __END_DECLS
152
153 #define IOPM_ROOTDOMAIN_REV 2
154
155 class IOPMrootDomain: public IOService
156 {
157 OSDeclareFinalStructors(IOPMrootDomain)
158
159 public:
160 static IOPMrootDomain * construct( void );
161
162 virtual bool start( IOService * provider );
163 virtual IOReturn setAggressiveness( unsigned long, unsigned long );
164 virtual IOReturn getAggressiveness( unsigned long, unsigned long * );
165
166 virtual IOReturn sleepSystem( void );
167 IOReturn sleepSystemOptions( OSDictionary *options );
168
169 virtual IOReturn setProperties( OSObject * );
170 virtual bool serializeProperties( OSSerialize * s ) const;
171
172 /*! @function systemPowerEventOccurred
173 @abstract Other drivers may inform IOPMrootDomain of system PM events
174 @discussion systemPowerEventOccurred is a richer alternative to receivePowerNotification()
175 Only Apple-owned kexts should have reason to call systemPowerEventOccurred.
176 @param event An OSSymbol describing the type of power event.
177 @param value A 32-bit integer value associated with the event.
178 @param shouldUpdate indicates whether the root domain should send a notification
179 to interested parties. Pass false if you're calling systemPowerEventOccurred
180 several times in succession; and pass true only on the last invocatino.
181 @result kIOReturnSuccess on success */
182
183 IOReturn systemPowerEventOccurred(
184 const OSSymbol *event,
185 uint32_t intValue );
186
187 IOReturn systemPowerEventOccurred(
188 const OSSymbol *event,
189 OSObject *value );
190
191 virtual IOReturn receivePowerNotification( UInt32 msg );
192
193 virtual void setSleepSupported( IOOptionBits flags );
194
195 virtual IOOptionBits getSleepSupported( void );
196
197 void wakeFromDoze( void );
198
199 // KEXT driver announces support of power management feature
200
201 void publishFeature( const char *feature );
202
203 // KEXT driver announces support of power management feature
204 // And specifies power sources with kIOPMSupportedOn{AC/Batt/UPS} bitfield.
205 // Returns a unique uint32_t identifier for later removing support for this
206 // feature.
207 // NULL is acceptable for uniqueFeatureID for kexts without plans to unload.
208
209 void publishFeature( const char *feature,
210 uint32_t supportedWhere,
211 uint32_t *uniqueFeatureID);
212
213 // KEXT driver announces removal of a previously published power management
214 // feature. Pass 'uniqueFeatureID' returned from publishFeature()
215
216 IOReturn removePublishedFeature( uint32_t removeFeatureID );
217
218 /*! @function copyPMSetting
219 @abstract Copy the current value for a PM setting. Returns an OSNumber or
220 OSData depending on the setting.
221 @param whichSetting Name of the desired setting.
222 @result OSObject value if valid, NULL otherwise. */
223
224 OSObject * copyPMSetting( OSSymbol *whichSetting );
225
226 /*! @function registerPMSettingController
227 @abstract Register for callbacks on changes to certain PM settings.
228 @param settings NULL terminated array of C strings, each string for a PM
229 setting that the caller is interested in and wants to get callbacks for.
230 @param callout C function ptr or member function cast as such.
231 @param target The target of the callback, usually 'this'
232 @param refcon Will be passed to caller in callback; for caller's use.
233 @param handle Caller should keep the OSObject * returned here. If non-NULL,
234 handle will have a retain count of 1 on return. To deregister, pass to
235 unregisterPMSettingController()
236 @result kIOReturnSuccess on success. */
237
238 IOReturn registerPMSettingController(
239 const OSSymbol *settings[],
240 IOPMSettingControllerCallback callout,
241 OSObject *target,
242 uintptr_t refcon,
243 OSObject **handle); // out param
244
245 /*! @function registerPMSettingController
246 @abstract Register for callbacks on changes to certain PM settings.
247 @param settings NULL terminated array of C strings, each string for a PM
248 setting that the caller is interested in and wants to get callbacks for.
249 @param supportedPowerSources bitfield indicating which power sources these
250 settings are supported for (kIOPMSupportedOnAC, etc.)
251 @param callout C function ptr or member function cast as such.
252 @param target The target of the callback, usually 'this'
253 @param refcon Will be passed to caller in callback; for caller's use.
254 @param handle Caller should keep the OSObject * returned here. If non-NULL,
255 handle will have a retain count of 1 on return. To deregister, pass to
256 unregisterPMSettingController()
257 @result kIOReturnSuccess on success. */
258
259 IOReturn registerPMSettingController(
260 const OSSymbol *settings[],
261 uint32_t supportedPowerSources,
262 IOPMSettingControllerCallback callout,
263 OSObject *target,
264 uintptr_t refcon,
265 OSObject **handle); // out param
266
267 virtual IONotifier * registerInterest(
268 const OSSymbol * typeOfInterest,
269 IOServiceInterestHandler handler,
270 void * target, void * ref = 0 );
271
272 void pmStatsRecordEvent(
273 int eventIndex,
274 AbsoluteTime timestamp);
275
276 void pmStatsRecordApplicationResponse(
277 const OSSymbol *response,
278 const char *name,
279 int messageType,
280 uint32_t delay_ms,
281 int app_pid);
282
283 virtual IOReturn callPlatformFunction(
284 const OSSymbol *functionName,
285 bool waitForFunction,
286 void *param1, void *param2,
287 void *param3, void *param4 );
288
289 /*! @function createPMAssertion
290 @abstract Creates an assertion to influence system power behavior.
291 @param whichAssertionBits A bitfield specify the assertion that the caller requests.
292 @param assertionLevel An integer detailing the initial assertion level, kIOPMDriverAssertionLevelOn
293 or kIOPMDriverAssertionLevelOff.
294 @param ownerService A pointer to the caller's IOService class, for tracking.
295 @param ownerDescription A reverse-DNS string describing the caller's identity and reason.
296 @result On success, returns a new assertion of type IOPMDriverAssertionID
297 */
298 IOPMDriverAssertionID createPMAssertion(
299 IOPMDriverAssertionType whichAssertionsBits,
300 IOPMDriverAssertionLevel assertionLevel,
301 IOService *ownerService,
302 const char *ownerDescription);
303
304 /* @function setPMAssertionLevel
305 @abstract Modify the level of a pre-existing assertion.
306 @discussion Change the value of a PM assertion to influence system behavior,
307 without undergoing the work required to create or destroy an assertion. Suggested
308 for clients who will assert and de-assert needs for PM behavior several times over
309 their lifespan.
310 @param assertionID An assertion ID previously returned by <link>createPMAssertion</link>
311 @param assertionLevel The new assertion level.
312 @result kIOReturnSuccess if it worked; kIOReturnNotFound or other IOReturn error on failure.
313 */
314 IOReturn setPMAssertionLevel(IOPMDriverAssertionID assertionID, IOPMDriverAssertionLevel assertionLevel);
315
316 /*! @function getPMAssertionLevel
317 @absract Returns the active level of the specified assertion(s).
318 @discussion Returns <link>kIOPMDriverAssertionLevelOff</link> or
319 <link>kIOPMDriverAssertionLevelOn</link>. If multiple assertions are specified
320 in the bitfield, only returns <link>kIOPMDriverAssertionLevelOn</link>
321 if all assertions are active.
322 @param whichAssertionBits Bits defining the assertion or assertions the caller is interested in
323 the level of. If in doubt, pass <link>kIOPMDriverAssertionCPUBit</link> as the argument.
324 @result Returns <link>kIOPMDriverAssertionLevelOff</link> or
325 <link>kIOPMDriverAssertionLevelOn</link> indicating the specified assertion's levels, if available.
326 If the assertions aren't supported on this machine, or aren't recognized by the OS, the
327 result is undefined.
328 */
329 IOPMDriverAssertionLevel getPMAssertionLevel(IOPMDriverAssertionType whichAssertionBits);
330
331 /*! @function releasePMAssertion
332 @abstract Removes an assertion to influence system power behavior.
333 @result On success, returns a new assertion of type IOPMDriverAssertionID *
334 */
335 IOReturn releasePMAssertion(IOPMDriverAssertionID releaseAssertion);
336
337 private:
338 virtual IOReturn changePowerStateTo( unsigned long ordinal );
339 virtual IOReturn changePowerStateToPriv( unsigned long ordinal );
340 virtual IOReturn requestPowerDomainState( IOPMPowerFlags, IOPowerConnection *, unsigned long );
341 virtual void powerChangeDone( unsigned long );
342 virtual bool tellChangeDown( unsigned long );
343 virtual bool askChangeDown( unsigned long );
344 virtual void tellChangeUp( unsigned long );
345 virtual void tellNoChangeDown( unsigned long );
346 #ifdef XNU_KERNEL_PRIVATE
347 /* Root Domain internals */
348 public:
349
350 #if HIBERNATION
351 bool getHibernateSettings(
352 uint32_t * hibernateMode,
353 uint32_t * hibernateFreeRatio,
354 uint32_t * hibernateFreeTime );
355 #endif
356
357 #if ROOT_DOMAIN_RUN_STATES
358 void tagPowerPlaneService(
359 IOService * service,
360 uint32_t * rdFlags );
361
362 void handleActivityTickleForService( IOService * service,
363 unsigned long type,
364 unsigned long currentPowerState,
365 uint32_t activityTickleCount );
366
367 void handlePowerChangeStartForService(
368 IOService * service,
369 uint32_t * rootDomainFlags,
370 uint32_t newPowerState,
371 uint32_t changeFlags );
372
373 void handlePowerChangeDoneForService(
374 IOService * service,
375 uint32_t * rootDomainFlags,
376 uint32_t newPowerState,
377 uint32_t changeFlags );
378
379 void overridePowerStateForService(
380 IOService * service,
381 uint32_t * rdFlags,
382 unsigned long * powerState,
383 uint32_t changeFlags );
384
385 IOReturn setMaintenanceWakeCalendar(
386 const IOPMCalendarStruct * calendar );
387 #endif /* ROOT_DOMAIN_RUN_STATES */
388
389 // Handle callbacks from IOService::systemWillShutdown()
390 void acknowledgeSystemWillShutdown( IOService * from );
391
392 // Handle platform halt and restart notifications
393 void handlePlatformHaltRestart( UInt32 pe_type );
394
395 IOReturn shutdownSystem( void );
396 IOReturn restartSystem( void );
397 void handleSleepTimerExpiration( void );
398 void handleForcedSleepTimerExpiration( void );
399 void stopIgnoringClamshellEventsDuringWakeup( void );
400 bool activitySinceSleep(void);
401 bool abortHibernation(void);
402
403 IOReturn joinAggressiveness( IOService * service );
404 void handleAggressivesRequests( void );
405
406 void tracePoint( uint8_t point );
407
408 private:
409 friend class PMSettingObject;
410 friend class PMAssertionsTracker;
411 friend class RootDomainUserClient;
412
413 // Points to our parent
414 IOService * wrangler;
415 class IORootParent * patriarch;
416
417 IOLock *featuresDictLock; // guards supportedFeatures
418 IOPMPowerStateQueue *pmPowerStateQueue;
419
420 OSArray *allowedPMSettings;
421 PMTraceWorker *pmTracer;
422 PMAssertionsTracker *pmAssertions;
423
424 // Settings controller info
425 IORecursiveLock *settingsCtrlLock;
426 OSDictionary *settingsCallbacks;
427 OSDictionary *fPMSettingsDict;
428
429 IONotifier *_batteryPublishNotifier;
430 IONotifier *_displayWranglerNotifier;
431
432 // Statistics
433 const OSSymbol *_statsNameKey;
434 const OSSymbol *_statsPIDKey;
435 const OSSymbol *_statsTimeMSKey;
436 const OSSymbol *_statsResponseTypeKey;
437 const OSSymbol *_statsMessageTypeKey;
438
439 OSString *queuedSleepWakeUUIDString;
440
441 OSArray *pmStatsAppResponses;
442
443 PMStatsStruct pmStats;
444
445 // Pref: idle time before idle sleep
446 unsigned long sleepSlider;
447 unsigned long idleSeconds;
448 uint64_t autoWakeStart;
449 uint64_t autoWakeEnd;
450
451 // Difference between sleepSlider and longestNonSleepSlider
452 unsigned long extraSleepDelay;
453
454 // Used to wait between say display idle and system idle
455 thread_call_t extraSleepTimer;
456
457 // Used to ignore clamshell close events while we're waking from sleep
458 thread_call_t clamshellWakeupIgnore;
459
460 thread_call_t diskSyncCalloutEntry;
461
462 uint32_t runStateIndex;
463 uint32_t runStateFlags;
464 uint32_t nextRunStateIndex;
465 uint32_t wranglerTickled;
466
467 unsigned int systemBooting :1;
468 unsigned int systemShutdown :1;
469 unsigned int clamshellExists :1;
470 unsigned int clamshellIsClosed :1;
471 unsigned int ignoringClamshell :1;
472 unsigned int ignoringClamshellOnWake :1;
473 unsigned int desktopMode :1;
474 unsigned int acAdaptorConnected :1;
475
476 unsigned int allowSleep :1;
477 unsigned int sleepIsSupported :1;
478 unsigned int canSleep :1;
479 unsigned int sleepASAP :1;
480 unsigned int idleSleepTimerPending :1;
481 unsigned int userDisabledAllSleep :1;
482 unsigned int ignoreChangeDown :1;
483 unsigned int wranglerAsleep :1;
484
485 unsigned int sleepTimerMaintenance :1;
486 unsigned int lowBatteryCondition :1;
487 unsigned int hibernateDisabled :1;
488 unsigned int hibernateNoDefeat :1;
489 unsigned int hibernateAborted :1;
490
491 uint32_t hibernateMode;
492 uint32_t userActivityCount;
493 uint32_t userActivityAtSleep;
494 uint32_t lastSleepReason;
495
496 // Info for communicating system state changes to PMCPU
497 int32_t idxPMCPUClamshell;
498 int32_t idxPMCPULimitedPower;
499
500 IOOptionBits platformSleepSupport;
501
502 queue_head_t aggressivesQueue;
503 thread_call_t aggressivesThreadCall;
504 OSData * aggressivesData;
505
506 AbsoluteTime wranglerSleepTime;
507
508 // PCI top-level PM trace
509 IOService * pciHostBridgeDevice;
510
511 // IOPMrootDomain internal sleep call
512 IOReturn privateSleepSystem( uint32_t sleepReason );
513 void announcePowerSourceChange( void );
514
515 void reportUserInput( void );
516 static IOReturn sysPowerDownHandler( void * target, void * refCon,
517 UInt32 messageType, IOService * service,
518 void * messageArgument, vm_size_t argSize );
519
520 static IOReturn displayWranglerNotification( void * target, void * refCon,
521 UInt32 messageType, IOService * service,
522 void * messageArgument, vm_size_t argSize );
523
524 static bool displayWranglerPublished( void * target, void * refCon,
525 IOService * newService);
526
527 static bool batteryPublished( void * target, void * refCon,
528 IOService * resourceService );
529
530 void adjustPowerState( void );
531 void setQuickSpinDownTimeout( void );
532 void restoreUserSpinDownTimeout( void );
533
534 bool shouldSleepOnClamshellClosed(void );
535 void sendClientClamshellNotification( void );
536
537 // Inform PMCPU of changes to state like lid, AC vs. battery
538 void informCPUStateChange( uint32_t type, uint32_t value );
539
540 void dispatchPowerEvent( uint32_t event, void * arg0, uint64_t arg1 );
541 void handlePowerNotification( UInt32 msg );
542
543 IOReturn setPMSetting(const OSSymbol *, OSObject *);
544
545 void startIdleSleepTimer( uint32_t inSeconds );
546 void cancelIdleSleepTimer( void );
547
548 void updateRunState( uint32_t inRunState );
549
550 IOReturn setAggressiveness(
551 unsigned long type,
552 unsigned long value,
553 IOOptionBits options );
554
555 void synchronizeAggressives(
556 queue_head_t * services,
557 const AggressivesRecord * array,
558 int count );
559
560 void broadcastAggressives(
561 const AggressivesRecord * array,
562 int count );
563
564 void aggressivenessChanged( void );
565
566 IOReturn setPMAssertionUserLevels(IOPMDriverAssertionType);
567
568 void publishSleepWakeUUID( bool shouldPublish );
569
570 #if HIBERNATION
571 bool getSleepOption( const char * key, uint32_t * option );
572 bool evaluateSystemSleepPolicy( IOPMSystemSleepParameters * p );
573 void evaluateSystemSleepPolicyEarly( void );
574 void evaluateSystemSleepPolicyFinal( void );
575 #endif /* HIBERNATION */
576
577 #endif /* XNU_KERNEL_PRIVATE */
578 };
579
580 #ifdef XNU_KERNEL_PRIVATE
581 class IORootParent: public IOService
582 {
583 OSDeclareFinalStructors(IORootParent)
584
585 private:
586 unsigned long mostRecentChange;
587
588 public:
589 bool start( IOService * nub );
590 void shutDownSystem( void );
591 void restartSystem( void );
592 void sleepSystem( void );
593 void dozeSystem( void );
594 void sleepToDoze( void );
595 void wakeSystem( void );
596 };
597 #endif /* XNU_KERNEL_PRIVATE */
598
599 #endif /* _IOKIT_ROOTDOMAIN_H */