]> git.saurik.com Git - apple/xnu.git/blob - iokit/IOKit/pwr_mgt/RootDomain.h
xnu-1456.1.26.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 #endif
41
42 class IOPMPowerStateQueue;
43 class RootDomainUserClient;
44 class PMTraceWorker;
45
46 /*
47 * Flags for get/setSleepSupported()
48 */
49 enum {
50 kRootDomainSleepNotSupported = 0x00000000,
51 kRootDomainSleepSupported = 0x00000001,
52 kFrameBufferDeepSleepSupported = 0x00000002,
53 kPCICantSleep = 0x00000004
54 };
55
56 /*
57 *IOPMrootDomain registry property keys
58 */
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"
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"
76 #define kIOPMMaintenanceSleepKey "Maintenance Sleep"
77
78 /*
79 * String constants for communication with PM CPU
80 */
81 #define kIOPMRootDomainLidCloseCString "LidClose"
82 #define kIOPMRootDomainBatPowerCString "BatPower"
83
84 /*
85 * Supported Feature bitfields for IOPMrootDomain::publishFeature()
86 */
87 enum {
88 kIOPMSupportedOnAC = (1<<0),
89 kIOPMSupportedOnBatt = (1<<1),
90 kIOPMSupportedOnUPS = (1<<2)
91 };
92
93 typedef IOReturn (*IOPMSettingControllerCallback)
94 (OSObject *target, const OSSymbol *type,
95 OSObject *val, uintptr_t refcon);
96
97 __BEGIN_DECLS
98 IONotifier * registerSleepWakeInterest(
99 IOServiceInterestHandler, void *, void * = 0);
100
101 IONotifier * registerPrioritySleepWakeInterest(
102 IOServiceInterestHandler handler,
103 void * self, void * ref = 0);
104
105 IOReturn acknowledgeSleepWakeNotification(void * );
106
107 IOReturn vetoSleepWakeNotification(void * PMrefcon);
108 __END_DECLS
109
110 #define IOPM_ROOTDOMAIN_REV 2
111
112 class IOPMrootDomain: public IOService
113 {
114 OSDeclareFinalStructors(IOPMrootDomain)
115
116 public:
117 static IOPMrootDomain * construct( void );
118
119 virtual bool start( IOService * provider );
120 virtual IOReturn setAggressiveness( unsigned long, unsigned long );
121 virtual IOReturn getAggressiveness( unsigned long, unsigned long * );
122
123 virtual IOReturn sleepSystem( void );
124 IOReturn sleepSystemOptions( OSDictionary *options );
125
126 virtual IOReturn setProperties( OSObject * );
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 */
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 );
154
155 // KEXT driver announces support of power management feature
156
157 void publishFeature( const char *feature );
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.
164
165 void publishFeature( const char *feature,
166 uint32_t supportedWhere,
167 uint32_t *uniqueFeatureID);
168
169 // KEXT driver announces removal of a previously published power management
170 // feature. Pass 'uniqueFeatureID' returned from publishFeature()
171
172 IOReturn removePublishedFeature( uint32_t removeFeatureID );
173
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. */
179
180 OSObject * copyPMSetting( OSSymbol *whichSetting );
181
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. */
193
194 IOReturn registerPMSettingController(
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. */
214
215 IOReturn registerPMSettingController(
216 const OSSymbol *settings[],
217 uint32_t supportedPowerSources,
218 IOPMSettingControllerCallback callout,
219 OSObject *target,
220 uintptr_t refcon,
221 OSObject **handle); // out param
222
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()
289 void acknowledgeSystemWillShutdown( IOService * from );
290
291 // Handle platform halt and restart notifications
292 void handlePlatformHaltRestart( UInt32 pe_type );
293
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
305 private:
306 friend class PMSettingObject;
307
308 // Points to our parent
309 IOService * wrangler;
310 class IORootParent * patriarch;
311
312 IOLock *featuresDictLock; // guards supportedFeatures
313 IOPMPowerStateQueue *pmPowerStateQueue;
314
315 OSArray *allowedPMSettings;
316 PMTraceWorker *pmTracer;
317
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;
344
345 // Difference between sleepSlider and longestNonSleepSlider
346 unsigned long extraSleepDelay;
347
348 // Used to wait between say display idle and system idle
349 thread_call_t extraSleepTimer;
350
351 // Used to ignore clamshell close events while we're waking from sleep
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;
390
391 // PCI top-level PM trace
392 IOService * pciHostBridgeDevice;
393
394 // IOPMrootDomain internal sleep call
395 IOReturn privateSleepSystem( const char *sleepReason );
396 void announcePowerSourceChange( void );
397
398 void reportUserInput( void );
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
410 static bool batteryPublished( void * target, void * refCon,
411 IOService * resourceService );
412
413 void adjustPowerState( void );
414 void setQuickSpinDownTimeout( void );
415 void restoreUserSpinDownTimeout( void );
416
417 bool shouldSleepOnClamshellClosed(void );
418 void sendClientClamshellNotification( void );
419
420 // Inform PMCPU of changes to state like lid, AC vs. battery
421 void informCPUStateChange( uint32_t type, uint32_t value );
422
423 void dispatchPowerEvent( uint32_t event, void * arg0, void * arg1 );
424 void handlePowerNotification( UInt32 msg );
425
426 IOReturn setPMSetting(const OSSymbol *, OSObject *);
427
428 void startIdleSleepTimer( uint32_t inSeconds );
429 void cancelIdleSleepTimer( void );
430
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 );
448
449
450 void publishSleepWakeUUID( bool shouldPublish );
451
452 #endif /* XNU_KERNEL_PRIVATE */
453 };
454
455 #ifdef XNU_KERNEL_PRIVATE
456 class IORootParent: public IOService
457 {
458 OSDeclareFinalStructors(IORootParent)
459
460 private:
461 unsigned long mostRecentChange;
462
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 );
471 };
472 #endif /* XNU_KERNEL_PRIVATE */
473
474 #endif /* _IOKIT_ROOTDOMAIN_H */