2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 #ifndef _IOKIT_ROOTDOMAIN_H
29 #define _IOKIT_ROOTDOMAIN_H
31 #include <IOKit/IOService.h>
32 #include <IOKit/pwr_mgt/IOPM.h>
33 #include "IOKit/pwr_mgt/IOPMPrivate.h"
35 #ifdef XNU_KERNEL_PRIVATE
36 #if defined(__i386__) || defined(__x86_64__)
37 #define ROOT_DOMAIN_RUN_STATES 1
39 struct AggressivesRecord
;
42 class IOPMPowerStateQueue
;
43 class RootDomainUserClient
;
47 * Flags for get/setSleepSupported()
50 kRootDomainSleepNotSupported
= 0x00000000,
51 kRootDomainSleepSupported
= 0x00000001,
52 kFrameBufferDeepSleepSupported
= 0x00000002,
53 kPCICantSleep
= 0x00000004
57 *IOPMrootDomain registry property keys
59 #define kRootDomainSupportedFeatures "Supported Features"
60 #define kRootDomainSleepReasonKey "Last Sleep Reason"
61 #define kRootDomainSleepOptionsKey "Last Sleep Options"
62 #define kIOPMRootDomainWakeReasonKey "Wake Reason"
63 #define kIOPMRootDomainWakeTypeKey "Wake Type"
64 #define kIOPMRootDomainPowerStatusKey "Power Status"
67 * Possible sleep reasons found under kRootDomainSleepReasonsKey
69 #define kIOPMClamshellSleepKey "Clamshell Sleep"
70 #define kIOPMPowerButtonSleepKey "Power Button Sleep"
71 #define kIOPMSoftwareSleepKey "Software Sleep"
72 #define kIOPMOSSwitchHibernationKey "OS Switch Sleep"
73 #define kIOPMIdleSleepKey "Idle Sleep"
74 #define kIOPMLowPowerSleepKey "Low Power Sleep"
75 #define kIOPMThermalEmergencySleepKey "Thermal Emergency Sleep"
76 #define kIOPMMaintenanceSleepKey "Maintenance Sleep"
79 * String constants for communication with PM CPU
81 #define kIOPMRootDomainLidCloseCString "LidClose"
82 #define kIOPMRootDomainBatPowerCString "BatPower"
85 * Supported Feature bitfields for IOPMrootDomain::publishFeature()
88 kIOPMSupportedOnAC
= (1<<0),
89 kIOPMSupportedOnBatt
= (1<<1),
90 kIOPMSupportedOnUPS
= (1<<2)
93 typedef IOReturn (*IOPMSettingControllerCallback
)
94 (OSObject
*target
, const OSSymbol
*type
,
95 OSObject
*val
, uintptr_t refcon
);
98 IONotifier
* registerSleepWakeInterest(
99 IOServiceInterestHandler
, void *, void * = 0);
101 IONotifier
* registerPrioritySleepWakeInterest(
102 IOServiceInterestHandler handler
,
103 void * self
, void * ref
= 0);
105 IOReturn
acknowledgeSleepWakeNotification(void * );
107 IOReturn
vetoSleepWakeNotification(void * PMrefcon
);
110 #define IOPM_ROOTDOMAIN_REV 2
112 class IOPMrootDomain
: public IOService
114 OSDeclareFinalStructors(IOPMrootDomain
)
117 static IOPMrootDomain
* construct( void );
119 virtual bool start( IOService
* provider
);
120 virtual IOReturn
setAggressiveness( unsigned long, unsigned long );
121 virtual IOReturn
getAggressiveness( unsigned long, unsigned long * );
123 virtual IOReturn
sleepSystem( void );
124 IOReturn
sleepSystemOptions( OSDictionary
*options
);
126 virtual IOReturn
setProperties( OSObject
* );
128 /*! @function systemPowerEventOccurred
129 @abstract Other drivers may inform IOPMrootDomain of system PM events
130 @discussion systemPowerEventOccurred is a richer alternative to receivePowerNotification()
131 Only Apple-owned kexts should have reason to call systemPowerEventOccurred.
132 @param event An OSSymbol describing the type of power event.
133 @param value A 32-bit integer value associated with the event.
134 @param shouldUpdate indicates whether the root domain should send a notification
135 to interested parties. Pass false if you're calling systemPowerEventOccurred
136 several times in succession; and pass true only on the last invocatino.
137 @result kIOReturnSuccess on success */
139 IOReturn
systemPowerEventOccurred(
140 const OSSymbol
*event
,
143 IOReturn
systemPowerEventOccurred(
144 const OSSymbol
*event
,
147 virtual IOReturn
receivePowerNotification( UInt32 msg
);
149 virtual void setSleepSupported( IOOptionBits flags
);
151 virtual IOOptionBits
getSleepSupported( void );
153 void wakeFromDoze( void );
155 // KEXT driver announces support of power management feature
157 void publishFeature( const char *feature
);
159 // KEXT driver announces support of power management feature
160 // And specifies power sources with kIOPMSupportedOn{AC/Batt/UPS} bitfield.
161 // Returns a unique uint32_t identifier for later removing support for this
163 // NULL is acceptable for uniqueFeatureID for kexts without plans to unload.
165 void publishFeature( const char *feature
,
166 uint32_t supportedWhere
,
167 uint32_t *uniqueFeatureID
);
169 // KEXT driver announces removal of a previously published power management
170 // feature. Pass 'uniqueFeatureID' returned from publishFeature()
172 IOReturn
removePublishedFeature( uint32_t removeFeatureID
);
174 /*! @function copyPMSetting
175 @abstract Copy the current value for a PM setting. Returns an OSNumber or
176 OSData depending on the setting.
177 @param whichSetting Name of the desired setting.
178 @result OSObject value if valid, NULL otherwise. */
180 OSObject
* copyPMSetting( OSSymbol
*whichSetting
);
182 /*! @function registerPMSettingController
183 @abstract Register for callbacks on changes to certain PM settings.
184 @param settings NULL terminated array of C strings, each string for a PM
185 setting that the caller is interested in and wants to get callbacks for.
186 @param callout C function ptr or member function cast as such.
187 @param target The target of the callback, usually 'this'
188 @param refcon Will be passed to caller in callback; for caller's use.
189 @param handle Caller should keep the OSObject * returned here. If non-NULL,
190 handle will have a retain count of 1 on return. To deregister, pass to
191 unregisterPMSettingController()
192 @result kIOReturnSuccess on success. */
194 IOReturn
registerPMSettingController(
195 const OSSymbol
*settings
[],
196 IOPMSettingControllerCallback callout
,
199 OSObject
**handle
); // out param
201 /*! @function registerPMSettingController
202 @abstract Register for callbacks on changes to certain PM settings.
203 @param settings NULL terminated array of C strings, each string for a PM
204 setting that the caller is interested in and wants to get callbacks for.
205 @param supportedPowerSources bitfield indicating which power sources these
206 settings are supported for (kIOPMSupportedOnAC, etc.)
207 @param callout C function ptr or member function cast as such.
208 @param target The target of the callback, usually 'this'
209 @param refcon Will be passed to caller in callback; for caller's use.
210 @param handle Caller should keep the OSObject * returned here. If non-NULL,
211 handle will have a retain count of 1 on return. To deregister, pass to
212 unregisterPMSettingController()
213 @result kIOReturnSuccess on success. */
215 IOReturn
registerPMSettingController(
216 const OSSymbol
*settings
[],
217 uint32_t supportedPowerSources
,
218 IOPMSettingControllerCallback callout
,
221 OSObject
**handle
); // out param
223 virtual IONotifier
* registerInterest(
224 const OSSymbol
* typeOfInterest
,
225 IOServiceInterestHandler handler
,
226 void * target
, void * ref
= 0 );
228 void pmStatsRecordEvent(
230 AbsoluteTime timestamp
);
232 void pmStatsRecordApplicationResponse(
233 const OSSymbol
*response
,
239 virtual IOReturn
callPlatformFunction(
240 const OSSymbol
*functionName
,
241 bool waitForFunction
,
242 void *param1
, void *param2
,
243 void *param3
, void *param4
);
246 virtual IOReturn
changePowerStateTo( unsigned long ordinal
);
247 virtual IOReturn
changePowerStateToPriv( unsigned long ordinal
);
248 virtual IOReturn
requestPowerDomainState( IOPMPowerFlags
, IOPowerConnection
*, unsigned long );
249 virtual void powerChangeDone( unsigned long );
250 virtual bool tellChangeDown( unsigned long );
251 virtual bool askChangeDown( unsigned long );
252 virtual void tellChangeUp( unsigned long );
253 virtual void tellNoChangeDown( unsigned long );
254 #ifdef XNU_KERNEL_PRIVATE
255 /* Root Domain internals */
258 #if ROOT_DOMAIN_RUN_STATES
259 void tagPowerPlaneService(
261 uint32_t * rdFlags
);
263 void handleActivityTickleForService(
264 IOService
* service
);
266 void handlePowerChangeStartForService(
268 uint32_t * rootDomainFlags
,
269 uint32_t newPowerState
,
270 uint32_t changeFlags
);
272 void handlePowerChangeDoneForService(
274 uint32_t * rootDomainFlags
,
275 uint32_t newPowerState
,
276 uint32_t changeFlags
);
278 void overridePowerStateForService(
281 unsigned long * powerState
,
282 uint32_t changeFlags
);
284 IOReturn
setMaintenanceWakeCalendar(
285 const IOPMCalendarStruct
* calendar
);
286 #endif /* ROOT_DOMAIN_RUN_STATES */
288 // Handle callbacks from IOService::systemWillShutdown()
289 void acknowledgeSystemWillShutdown( IOService
* from
);
291 // Handle platform halt and restart notifications
292 void handlePlatformHaltRestart( UInt32 pe_type
);
294 IOReturn
shutdownSystem( void );
295 IOReturn
restartSystem( void );
296 void handleSleepTimerExpiration( void );
297 void handleForcedSleepTimerExpiration( void );
298 void stopIgnoringClamshellEventsDuringWakeup( void );
300 IOReturn
joinAggressiveness( IOService
* service
);
301 void handleAggressivesRequests( void );
303 void tracePoint( uint8_t point
);
306 friend class PMSettingObject
;
308 // Points to our parent
309 IOService
* wrangler
;
310 class IORootParent
* patriarch
;
312 IOLock
*featuresDictLock
; // guards supportedFeatures
313 IOPMPowerStateQueue
*pmPowerStateQueue
;
315 OSArray
*allowedPMSettings
;
316 PMTraceWorker
*pmTracer
;
318 // Settings controller info
319 IORecursiveLock
*settingsCtrlLock
;
320 OSDictionary
*settingsCallbacks
;
321 OSDictionary
*fPMSettingsDict
;
323 IONotifier
*_batteryPublishNotifier
;
324 IONotifier
*_displayWranglerNotifier
;
327 const OSSymbol
*_statsNameKey
;
328 const OSSymbol
*_statsPIDKey
;
329 const OSSymbol
*_statsTimeMSKey
;
330 const OSSymbol
*_statsResponseTypeKey
;
331 const OSSymbol
*_statsMessageTypeKey
;
333 OSString
*queuedSleepWakeUUIDString
;
335 OSArray
*pmStatsAppResponses
;
337 PMStatsStruct pmStats
;
339 // Pref: idle time before idle sleep
340 unsigned long sleepSlider
;
341 unsigned long idleSeconds
;
342 uint64_t autoWakeStart
;
343 uint64_t autoWakeEnd
;
345 // Difference between sleepSlider and longestNonSleepSlider
346 unsigned long extraSleepDelay
;
348 // Used to wait between say display idle and system idle
349 thread_call_t extraSleepTimer
;
351 // Used to ignore clamshell close events while we're waking from sleep
352 thread_call_t clamshellWakeupIgnore
;
354 thread_call_t diskSyncCalloutEntry
;
356 uint32_t runStateIndex
;
357 uint32_t runStateFlags
;
358 uint32_t nextRunStateIndex
;
359 uint32_t wranglerTickled
;
361 unsigned int systemBooting
:1;
362 unsigned int systemShutdown
:1;
363 unsigned int clamshellExists
:1;
364 unsigned int clamshellIsClosed
:1;
365 unsigned int ignoringClamshell
:1;
366 unsigned int ignoringClamshellOnWake
:1;
367 unsigned int desktopMode
:1;
368 unsigned int acAdaptorConnected
:1;
370 unsigned int allowSleep
:1;
371 unsigned int sleepIsSupported
:1;
372 unsigned int canSleep
:1;
373 unsigned int sleepASAP
:1;
374 unsigned int idleSleepTimerPending
:1;
375 unsigned int userDisabledAllSleep
:1;
376 unsigned int ignoreChangeDown
:1;
377 unsigned int wranglerAsleep
:1;
379 // Info for communicating system state changes to PMCPU
380 int32_t idxPMCPUClamshell
;
381 int32_t idxPMCPULimitedPower
;
383 IOOptionBits platformSleepSupport
;
385 queue_head_t aggressivesQueue
;
386 thread_call_t aggressivesThreadCall
;
387 OSData
* aggressivesData
;
389 AbsoluteTime wranglerSleepTime
;
391 // PCI top-level PM trace
392 IOService
* pciHostBridgeDevice
;
394 // IOPMrootDomain internal sleep call
395 IOReturn
privateSleepSystem( const char *sleepReason
);
396 void announcePowerSourceChange( void );
398 void reportUserInput( void );
399 static IOReturn
sysPowerDownHandler( void * target
, void * refCon
,
400 UInt32 messageType
, IOService
* service
,
401 void * messageArgument
, vm_size_t argSize
);
403 static IOReturn
displayWranglerNotification( void * target
, void * refCon
,
404 UInt32 messageType
, IOService
* service
,
405 void * messageArgument
, vm_size_t argSize
);
407 static bool displayWranglerPublished( void * target
, void * refCon
,
408 IOService
* newService
);
410 static bool batteryPublished( void * target
, void * refCon
,
411 IOService
* resourceService
);
413 void adjustPowerState( void );
414 void setQuickSpinDownTimeout( void );
415 void restoreUserSpinDownTimeout( void );
417 bool shouldSleepOnClamshellClosed(void );
418 void sendClientClamshellNotification( void );
420 // Inform PMCPU of changes to state like lid, AC vs. battery
421 void informCPUStateChange( uint32_t type
, uint32_t value
);
423 void dispatchPowerEvent( uint32_t event
, void * arg0
, void * arg1
);
424 void handlePowerNotification( UInt32 msg
);
426 IOReturn
setPMSetting(const OSSymbol
*, OSObject
*);
428 void startIdleSleepTimer( uint32_t inSeconds
);
429 void cancelIdleSleepTimer( void );
431 void updateRunState( uint32_t inRunState
);
433 IOReturn
setAggressiveness(
436 IOOptionBits options
);
438 void synchronizeAggressives(
439 queue_head_t
* services
,
440 const AggressivesRecord
* array
,
443 void broadcastAggressives(
444 const AggressivesRecord
* array
,
447 void aggressivenessChanged( void );
450 void publishSleepWakeUUID( bool shouldPublish
);
452 #endif /* XNU_KERNEL_PRIVATE */
455 #ifdef XNU_KERNEL_PRIVATE
456 class IORootParent
: public IOService
458 OSDeclareFinalStructors(IORootParent
)
461 unsigned long mostRecentChange
;
464 bool start( IOService
* nub
);
465 void shutDownSystem( void );
466 void restartSystem( void );
467 void sleepSystem( void );
468 void dozeSystem( void );
469 void sleepToDoze( void );
470 void wakeSystem( void );
472 #endif /* XNU_KERNEL_PRIVATE */
474 #endif /* _IOKIT_ROOTDOMAIN_H */