]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* |
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
1c79356b | 5 | * |
2d21ac55 A |
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. | |
8f6c56a5 | 14 | * |
2d21ac55 A |
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 | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
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. | |
8f6c56a5 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
1c79356b A |
27 | */ |
28 | #ifndef _IOKIT_ROOTDOMAIN_H | |
29 | #define _IOKIT_ROOTDOMAIN_H | |
30 | ||
31 | #include <IOKit/IOService.h> | |
32 | #include <IOKit/pwr_mgt/IOPM.h> | |
b0d623f7 A |
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 | #endif | |
1c79356b | 41 | |
55e303ae | 42 | class IOPMPowerStateQueue; |
1c79356b | 43 | class RootDomainUserClient; |
b0d623f7 | 44 | class PMTraceWorker; |
1c79356b | 45 | |
b0d623f7 A |
46 | /* |
47 | * Flags for get/setSleepSupported() | |
48 | */ | |
1c79356b A |
49 | enum { |
50 | kRootDomainSleepNotSupported = 0x00000000, | |
51 | kRootDomainSleepSupported = 0x00000001, | |
0b4e3aa0 | 52 | kFrameBufferDeepSleepSupported = 0x00000002, |
b0d623f7 | 53 | kPCICantSleep = 0x00000004 |
1c79356b A |
54 | }; |
55 | ||
2d21ac55 A |
56 | /* |
57 | *IOPMrootDomain registry property keys | |
58 | */ | |
59 | #define kRootDomainSupportedFeatures "Supported Features" | |
60 | #define kRootDomainSleepReasonKey "Last Sleep Reason" | |
61 | #define kRootDomainSleepOptionsKey "Last Sleep Options" | |
b0d623f7 A |
62 | #define kIOPMRootDomainWakeReasonKey "Wake Reason" |
63 | #define kIOPMRootDomainWakeTypeKey "Wake Type" | |
4a3eedf9 | 64 | #define kIOPMRootDomainPowerStatusKey "Power Status" |
2d21ac55 A |
65 | |
66 | /* | |
67 | * Possible sleep reasons found under kRootDomainSleepReasonsKey | |
68 | */ | |
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" | |
b0d623f7 | 76 | #define kIOPMMaintenanceSleepKey "Maintenance Sleep" |
2d21ac55 A |
77 | |
78 | /* | |
79 | * String constants for communication with PM CPU | |
80 | */ | |
81 | #define kIOPMRootDomainLidCloseCString "LidClose" | |
82 | #define kIOPMRootDomainBatPowerCString "BatPower" | |
0c530ab8 | 83 | |
b0d623f7 A |
84 | /* |
85 | * Supported Feature bitfields for IOPMrootDomain::publishFeature() | |
86 | */ | |
e5568f75 | 87 | enum { |
b0d623f7 A |
88 | kIOPMSupportedOnAC = (1<<0), |
89 | kIOPMSupportedOnBatt = (1<<1), | |
90 | kIOPMSupportedOnUPS = (1<<2) | |
e5568f75 | 91 | }; |
4452a7af | 92 | |
b0d623f7 A |
93 | typedef IOReturn (*IOPMSettingControllerCallback) |
94 | (OSObject *target, const OSSymbol *type, | |
0c530ab8 | 95 | OSObject *val, uintptr_t refcon); |
4452a7af | 96 | |
b0d623f7 A |
97 | __BEGIN_DECLS |
98 | IONotifier * registerSleepWakeInterest( | |
99 | IOServiceInterestHandler, void *, void * = 0); | |
0c530ab8 | 100 | |
b0d623f7 A |
101 | IONotifier * registerPrioritySleepWakeInterest( |
102 | IOServiceInterestHandler handler, | |
103 | void * self, void * ref = 0); | |
0c530ab8 | 104 | |
b0d623f7 | 105 | IOReturn acknowledgeSleepWakeNotification(void * ); |
0c530ab8 | 106 | |
b0d623f7 A |
107 | IOReturn vetoSleepWakeNotification(void * PMrefcon); |
108 | __END_DECLS | |
1c79356b | 109 | |
d52fe63f | 110 | #define IOPM_ROOTDOMAIN_REV 2 |
1c79356b A |
111 | |
112 | class IOPMrootDomain: public IOService | |
113 | { | |
b0d623f7 | 114 | OSDeclareFinalStructors(IOPMrootDomain) |
0b4e3aa0 | 115 | |
b0d623f7 | 116 | public: |
0b4e3aa0 | 117 | static IOPMrootDomain * construct( void ); |
2d21ac55 | 118 | |
b0d623f7 A |
119 | virtual bool start( IOService * provider ); |
120 | virtual IOReturn setAggressiveness( unsigned long, unsigned long ); | |
121 | virtual IOReturn getAggressiveness( unsigned long, unsigned long * ); | |
2d21ac55 | 122 | |
b0d623f7 A |
123 | virtual IOReturn sleepSystem( void ); |
124 | IOReturn sleepSystemOptions( OSDictionary *options ); | |
125 | ||
126 | virtual IOReturn setProperties( OSObject * ); | |
4a3eedf9 A |
127 | |
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 */ | |
b0d623f7 A |
138 | |
139 | IOReturn systemPowerEventOccurred( | |
140 | const OSSymbol *event, | |
141 | uint32_t intValue ); | |
142 | ||
143 | IOReturn systemPowerEventOccurred( | |
144 | const OSSymbol *event, | |
145 | OSObject *value ); | |
146 | ||
147 | virtual IOReturn receivePowerNotification( UInt32 msg ); | |
148 | ||
149 | virtual void setSleepSupported( IOOptionBits flags ); | |
150 | ||
151 | virtual IOOptionBits getSleepSupported( void ); | |
152 | ||
153 | void wakeFromDoze( void ); | |
0c530ab8 A |
154 | |
155 | // KEXT driver announces support of power management feature | |
b0d623f7 A |
156 | |
157 | void publishFeature( const char *feature ); | |
0c530ab8 A |
158 | |
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 | |
162 | // feature. | |
163 | // NULL is acceptable for uniqueFeatureID for kexts without plans to unload. | |
b0d623f7 A |
164 | |
165 | void publishFeature( const char *feature, | |
166 | uint32_t supportedWhere, | |
167 | uint32_t *uniqueFeatureID); | |
0c530ab8 A |
168 | |
169 | // KEXT driver announces removal of a previously published power management | |
170 | // feature. Pass 'uniqueFeatureID' returned from publishFeature() | |
0c530ab8 | 171 | |
b0d623f7 | 172 | IOReturn removePublishedFeature( uint32_t removeFeatureID ); |
9bccf70c | 173 | |
0c530ab8 | 174 | /*! @function copyPMSetting |
b0d623f7 | 175 | @abstract Copy the current value for a PM setting. Returns an OSNumber or |
0c530ab8 | 176 | OSData depending on the setting. |
b0d623f7 A |
177 | @param whichSetting Name of the desired setting. |
178 | @result OSObject value if valid, NULL otherwise. */ | |
179 | ||
180 | OSObject * copyPMSetting( OSSymbol *whichSetting ); | |
181 | ||
0c530ab8 A |
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. */ | |
b0d623f7 A |
193 | |
194 | IOReturn registerPMSettingController( | |
0c530ab8 A |
195 | const OSSymbol *settings[], |
196 | IOPMSettingControllerCallback callout, | |
197 | OSObject *target, | |
198 | uintptr_t refcon, | |
199 | OSObject **handle); // out param | |
200 | ||
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. */ | |
b0d623f7 A |
214 | |
215 | IOReturn registerPMSettingController( | |
0c530ab8 A |
216 | const OSSymbol *settings[], |
217 | uint32_t supportedPowerSources, | |
218 | IOPMSettingControllerCallback callout, | |
219 | OSObject *target, | |
220 | uintptr_t refcon, | |
221 | OSObject **handle); // out param | |
e5568f75 | 222 | |
b0d623f7 A |
223 | virtual IONotifier * registerInterest( |
224 | const OSSymbol * typeOfInterest, | |
225 | IOServiceInterestHandler handler, | |
226 | void * target, void * ref = 0 ); | |
227 | ||
228 | void pmStatsRecordEvent( | |
229 | int eventIndex, | |
230 | AbsoluteTime timestamp); | |
231 | ||
232 | void pmStatsRecordApplicationResponse( | |
233 | const OSSymbol *response, | |
234 | const char *name, | |
235 | int messageType, | |
236 | uint32_t delay_ms, | |
237 | int app_pid); | |
238 | ||
239 | virtual IOReturn callPlatformFunction( | |
240 | const OSSymbol *functionName, | |
241 | bool waitForFunction, | |
242 | void *param1, void *param2, | |
243 | void *param3, void *param4 ); | |
244 | ||
245 | private: | |
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 */ | |
256 | public: | |
257 | ||
258 | #if ROOT_DOMAIN_RUN_STATES | |
259 | void tagPowerPlaneService( | |
260 | IOService * service, | |
261 | uint32_t * rdFlags ); | |
262 | ||
263 | void handleActivityTickleForService( | |
264 | IOService * service ); | |
265 | ||
266 | void handlePowerChangeStartForService( | |
267 | IOService * service, | |
268 | uint32_t * rootDomainFlags, | |
269 | uint32_t newPowerState, | |
270 | uint32_t changeFlags ); | |
271 | ||
272 | void handlePowerChangeDoneForService( | |
273 | IOService * service, | |
274 | uint32_t * rootDomainFlags, | |
275 | uint32_t newPowerState, | |
276 | uint32_t changeFlags ); | |
277 | ||
278 | void overridePowerStateForService( | |
279 | IOService * service, | |
280 | uint32_t * rdFlags, | |
281 | unsigned long * powerState, | |
282 | uint32_t changeFlags ); | |
283 | ||
284 | IOReturn setMaintenanceWakeCalendar( | |
285 | const IOPMCalendarStruct * calendar ); | |
286 | #endif /* ROOT_DOMAIN_RUN_STATES */ | |
287 | ||
288 | // Handle callbacks from IOService::systemWillShutdown() | |
2d21ac55 A |
289 | void acknowledgeSystemWillShutdown( IOService * from ); |
290 | ||
b0d623f7 | 291 | // Handle platform halt and restart notifications |
2d21ac55 A |
292 | void handlePlatformHaltRestart( UInt32 pe_type ); |
293 | ||
b0d623f7 A |
294 | IOReturn shutdownSystem( void ); |
295 | IOReturn restartSystem( void ); | |
296 | void handleSleepTimerExpiration( void ); | |
297 | void handleForcedSleepTimerExpiration( void ); | |
298 | void stopIgnoringClamshellEventsDuringWakeup( void ); | |
299 | ||
300 | IOReturn joinAggressiveness( IOService * service ); | |
301 | void handleAggressivesRequests( void ); | |
302 | ||
303 | void tracePoint( uint8_t point ); | |
304 | ||
1c79356b | 305 | private: |
b0d623f7 | 306 | friend class PMSettingObject; |
1c79356b | 307 | |
0c530ab8 | 308 | // Points to our parent |
b0d623f7 A |
309 | IOService * wrangler; |
310 | class IORootParent * patriarch; | |
0c530ab8 | 311 | |
b0d623f7 A |
312 | IOLock *featuresDictLock; // guards supportedFeatures |
313 | IOPMPowerStateQueue *pmPowerStateQueue; | |
314 | ||
315 | OSArray *allowedPMSettings; | |
316 | PMTraceWorker *pmTracer; | |
0c530ab8 | 317 | |
b0d623f7 A |
318 | // Settings controller info |
319 | IORecursiveLock *settingsCtrlLock; | |
320 | OSDictionary *settingsCallbacks; | |
321 | OSDictionary *fPMSettingsDict; | |
322 | ||
323 | IONotifier *_batteryPublishNotifier; | |
324 | IONotifier *_displayWranglerNotifier; | |
325 | ||
326 | // Statistics | |
327 | const OSSymbol *_statsNameKey; | |
328 | const OSSymbol *_statsPIDKey; | |
329 | const OSSymbol *_statsTimeMSKey; | |
330 | const OSSymbol *_statsResponseTypeKey; | |
331 | const OSSymbol *_statsMessageTypeKey; | |
332 | ||
333 | OSString *queuedSleepWakeUUIDString; | |
334 | ||
335 | OSArray *pmStatsAppResponses; | |
336 | ||
337 | PMStatsStruct pmStats; | |
338 | ||
339 | // Pref: idle time before idle sleep | |
340 | unsigned long sleepSlider; | |
341 | unsigned long idleSeconds; | |
342 | uint64_t autoWakeStart; | |
343 | uint64_t autoWakeEnd; | |
0c530ab8 A |
344 | |
345 | // Difference between sleepSlider and longestNonSleepSlider | |
b0d623f7 | 346 | unsigned long extraSleepDelay; |
0c530ab8 A |
347 | |
348 | // Used to wait between say display idle and system idle | |
b0d623f7 | 349 | thread_call_t extraSleepTimer; |
0c530ab8 A |
350 | |
351 | // Used to ignore clamshell close events while we're waking from sleep | |
b0d623f7 A |
352 | thread_call_t clamshellWakeupIgnore; |
353 | ||
354 | thread_call_t diskSyncCalloutEntry; | |
355 | ||
356 | uint32_t runStateIndex; | |
357 | uint32_t runStateFlags; | |
358 | uint32_t nextRunStateIndex; | |
359 | uint32_t wranglerTickled; | |
360 | ||
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; | |
369 | ||
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; | |
378 | ||
379 | // Info for communicating system state changes to PMCPU | |
380 | int32_t idxPMCPUClamshell; | |
381 | int32_t idxPMCPULimitedPower; | |
382 | ||
383 | IOOptionBits platformSleepSupport; | |
384 | ||
385 | queue_head_t aggressivesQueue; | |
386 | thread_call_t aggressivesThreadCall; | |
387 | OSData * aggressivesData; | |
388 | ||
389 | AbsoluteTime wranglerSleepTime; | |
d52fe63f | 390 | |
b0d623f7 A |
391 | // PCI top-level PM trace |
392 | IOService * pciHostBridgeDevice; | |
393 | ||
2d21ac55 | 394 | // IOPMrootDomain internal sleep call |
b0d623f7 A |
395 | IOReturn privateSleepSystem( const char *sleepReason ); |
396 | void announcePowerSourceChange( void ); | |
2d21ac55 | 397 | |
b0d623f7 | 398 | void reportUserInput( void ); |
0b4e3aa0 A |
399 | static IOReturn sysPowerDownHandler( void * target, void * refCon, |
400 | UInt32 messageType, IOService * service, | |
401 | void * messageArgument, vm_size_t argSize ); | |
402 | ||
403 | static IOReturn displayWranglerNotification( void * target, void * refCon, | |
404 | UInt32 messageType, IOService * service, | |
405 | void * messageArgument, vm_size_t argSize ); | |
406 | ||
407 | static bool displayWranglerPublished( void * target, void * refCon, | |
408 | IOService * newService); | |
409 | ||
0c530ab8 | 410 | static bool batteryPublished( void * target, void * refCon, |
483a1d10 A |
411 | IOService * resourceService ); |
412 | ||
b0d623f7 A |
413 | void adjustPowerState( void ); |
414 | void setQuickSpinDownTimeout( void ); | |
415 | void restoreUserSpinDownTimeout( void ); | |
0c530ab8 | 416 | |
b0d623f7 A |
417 | bool shouldSleepOnClamshellClosed(void ); |
418 | void sendClientClamshellNotification( void ); | |
0c530ab8 | 419 | |
2d21ac55 A |
420 | // Inform PMCPU of changes to state like lid, AC vs. battery |
421 | void informCPUStateChange( uint32_t type, uint32_t value ); | |
b0d623f7 A |
422 | |
423 | void dispatchPowerEvent( uint32_t event, void * arg0, void * arg1 ); | |
424 | void handlePowerNotification( UInt32 msg ); | |
425 | ||
0c530ab8 A |
426 | IOReturn setPMSetting(const OSSymbol *, OSObject *); |
427 | ||
b0d623f7 A |
428 | void startIdleSleepTimer( uint32_t inSeconds ); |
429 | void cancelIdleSleepTimer( void ); | |
e5568f75 | 430 | |
b0d623f7 A |
431 | void updateRunState( uint32_t inRunState ); |
432 | ||
433 | IOReturn setAggressiveness( | |
434 | unsigned long type, | |
435 | unsigned long value, | |
436 | IOOptionBits options ); | |
437 | ||
438 | void synchronizeAggressives( | |
439 | queue_head_t * services, | |
440 | const AggressivesRecord * array, | |
441 | int count ); | |
442 | ||
443 | void broadcastAggressives( | |
444 | const AggressivesRecord * array, | |
445 | int count ); | |
446 | ||
447 | void aggressivenessChanged( void ); | |
2d21ac55 | 448 | |
0c530ab8 | 449 | |
b0d623f7 A |
450 | void publishSleepWakeUUID( bool shouldPublish ); |
451 | ||
452 | #endif /* XNU_KERNEL_PRIVATE */ | |
1c79356b A |
453 | }; |
454 | ||
b0d623f7 | 455 | #ifdef XNU_KERNEL_PRIVATE |
1c79356b A |
456 | class IORootParent: public IOService |
457 | { | |
b0d623f7 | 458 | OSDeclareFinalStructors(IORootParent) |
0b4e3aa0 A |
459 | |
460 | private: | |
461 | unsigned long mostRecentChange; | |
0c530ab8 | 462 | |
b0d623f7 A |
463 | public: |
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 ); | |
1c79356b | 471 | }; |
b0d623f7 | 472 | #endif /* XNU_KERNEL_PRIVATE */ |
1c79356b | 473 | |
b0d623f7 | 474 | #endif /* _IOKIT_ROOTDOMAIN_H */ |