1 /* 2 * Copyright (c) 2019-2020 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 29 #ifndef _IOKIT_IOSERVICEPMPRIVATE_H 30 #define _IOKIT_IOSERVICEPMPRIVATE_H 31 32 #include <IOKit/IOCommand.h> 33 #include <IOKit/IOEventSource.h> 34 35 #include <vm/vm_compressor_xnu.h> 36 37 #define USE_SETTLE_TIMER 0 38 39 //****************************************************************************** 40 // PM command types 41 //****************************************************************************** 42 43 enum { 44 /* Command Types */ 45 kIOPMRequestTypeInvalid = 0x00, 46 kIOPMRequestTypePMStop = 0x01, 47 kIOPMRequestTypeAddPowerChild1 = 0x02, 48 kIOPMRequestTypeAddPowerChild2 = 0x03, 49 kIOPMRequestTypeAddPowerChild3 = 0x04, 50 kIOPMRequestTypeRegisterPowerDriver = 0x05, 51 kIOPMRequestTypeAdjustPowerState = 0x06, 52 kIOPMRequestTypePowerDomainWillChange = 0x07, 53 kIOPMRequestTypePowerDomainDidChange = 0x08, 54 kIOPMRequestTypePowerOverrideOnPriv = 0x09, 55 kIOPMRequestTypePowerOverrideOffPriv = 0x0A, 56 kIOPMRequestTypeActivityTickle = 0x0B, 57 kIOPMRequestTypeRequestPowerState = 0x0C, 58 kIOPMRequestTypeSynchronizePowerTree = 0x0D, 59 kIOPMRequestTypeRequestPowerStateOverride = 0x0E, 60 kIOPMRequestTypeSetIdleTimerPeriod = 0x0F, 61 kIOPMRequestTypeIgnoreIdleTimer = 0x10, 62 kIOPMRequestTypeQuiescePowerTree = 0x11, 63 kIOPMRequestTypeDeferredActivityTickle = 0x12, 64 65 /* Reply Types */ 66 kIOPMRequestTypeReplyStart = 0x80, 67 kIOPMRequestTypeAckPowerChange = 0x81, 68 kIOPMRequestTypeAckSetPowerState = 0x82, 69 kIOPMRequestTypeAllowPowerChange = 0x83, 70 kIOPMRequestTypeCancelPowerChange = 0x84, 71 kIOPMRequestTypeInterestChanged = 0x85, 72 kIOPMRequestTypeIdleCancel = 0x86, 73 kIOPMRequestTypeChildNotifyDelayCancel = 0x87 74 }; 75 76 //****************************************************************************** 77 // PM actions - For root domain only 78 //****************************************************************************** 79 80 struct IOPMActions; 81 82 typedef void 83 (*IOPMActionPowerChangeStart)( 84 void * target, 85 IOService * service, 86 IOPMActions * actions, 87 const IOPMRequest * request, 88 IOPMPowerStateIndex powerState, 89 IOPMPowerChangeFlags * changeFlagsPtr ); 90 91 typedef void 92 (*IOPMActionPowerChangeDone)( 93 void * target, 94 IOService * service, 95 IOPMActions * actions, 96 const IOPMRequest * request, 97 IOPMPowerStateIndex powerState, 98 IOPMPowerChangeFlags changeFlags ); 99 100 typedef void 101 (*IOPMActionPowerChangeOverride)( 102 void * target, 103 IOService * service, 104 IOPMActions * actions, 105 const IOPMRequest * request, 106 IOPMPowerStateIndex * powerStatePtr, 107 IOPMPowerChangeFlags * changeFlagsPtr ); 108 109 typedef void 110 (*IOPMActionActivityTickle)( 111 void * target, 112 IOService * service, 113 IOPMActions * actions ); 114 115 typedef void 116 (*IOPMActionUpdatePowerClient)( 117 void * target, 118 IOService * service, 119 IOPMActions * actions, 120 const OSSymbol * powerClient, 121 IOPMPowerStateIndex oldPowerState, 122 IOPMPowerStateIndex newPowerState ); 123 124 struct IOPMActions { 125 void * target; 126 IOPMActionPowerChangeStart actionPowerChangeStart; 127 IOPMActionPowerChangeDone actionPowerChangeDone; 128 IOPMActionPowerChangeOverride actionPowerChangeOverride; 129 IOPMActionActivityTickle actionActivityTickle; 130 IOPMActionUpdatePowerClient actionUpdatePowerClient; 131 uint32_t darkWakePowerState; 132 uint16_t flags; 133 uint16_t state; 134 }; 135 136 // IOPMActions flags 137 enum { 138 kPMActionsPCIBitNumberMask = 0x00ff, 139 kPMActionsFlagIsDisplayWrangler = 0x0100, 140 kPMActionsFlagIsGraphicsDriver = 0x0200, 141 kPMActionsFlagIsAudioDriver = 0x0400, 142 kPMActionsFlagHasDarkWakePowerState = 0x0800 143 }; 144 145 // IOPMActions state 146 enum { 147 kPMActionsStatePowerClamped = 0x0001 148 }; 149 150 //****************************************************************************** 151 // Internal concise representation of IOPMPowerState 152 struct IOPMPSEntry { 153 IOPMPowerFlags capabilityFlags; 154 IOPMPowerFlags outputPowerFlags; 155 IOPMPowerFlags inputPowerFlags; 156 unsigned long staticPower; 157 #if USE_SETTLE_TIMER 158 uint32_t settleUpTime; 159 uint32_t settleDownTime; 160 #endif 161 IOPMPowerStateIndex stateOrder; 162 IOPMPowerStateIndex stateOrderToIndex; 163 }; 164 165 //****************************************************************************** 166 // IOServicePM 167 //****************************************************************************** 168 169 class IOServicePM : public OSObject 170 { 171 friend class IOService; 172 friend class IOPMWorkQueue; 173 174 OSDeclareDefaultStructors( IOServicePM ); 175 176 private: 177 // Link IOServicePM objects on IOPMWorkQueue. 178 queue_chain_t WorkChain; 179 180 // Queue of IOPMRequest objects. 181 queue_head_t RequestHead; 182 183 // IOService creator and owner. 184 IOService * Owner; 185 186 // List of interested drivers (protected by PMLock). 187 IOPMinformeeList * InterestedDrivers; 188 189 // How long to wait for controlling driver to acknowledge. 190 IOReturn DriverTimer; 191 192 // Current power management machine state. 193 uint32_t MachineState; 194 195 thread_call_t AckTimer; 196 #if USE_SETTLE_TIMER 197 thread_call_t SettleTimer; 198 #endif 199 thread_call_t IdleTimer; 200 thread_call_t WatchdogTimer; 201 thread_call_t SpinDumpTimer; 202 203 IOLock * WatchdogLock; 204 OSArray * BlockedArray; 205 uint64_t PendingResponseDeadline; 206 uint64_t WatchdogDeadline; 207 208 // Settle time after changing power state. 209 #if USE_SETTLE_TIMER 210 uint32_t SettleTimeUS; 211 #endif 212 IOPMPowerStateIndex IdleTimerGeneration; 213 214 // The flags describing current change note. 215 IOPMPowerChangeFlags HeadNoteChangeFlags; 216 217 // The new power state number being changed to. 218 IOPMPowerStateIndex HeadNotePowerState; 219 220 // Points to the entry in the power state array. 221 IOPMPSEntry * HeadNotePowerArrayEntry; 222 223 // Power flags supplied by all parents (domain). 224 IOPMPowerFlags HeadNoteDomainFlags; 225 226 // Power flags supplied by domain accounting for parent changes. 227 IOPMPowerFlags HeadNoteDomainTargetFlags; 228 229 // Connection attached to the changing parent. 230 IOPowerConnection * HeadNoteParentConnection; 231 232 // Power flags supplied by the changing parent. 233 IOPMPowerFlags HeadNoteParentFlags; 234 235 // Number of acks still outstanding. 236 uint32_t HeadNotePendingAcks; 237 238 // PM state lock. 239 IOLock * PMLock; 240 241 unsigned int InitialPowerChange :1; 242 unsigned int InitialSetPowerState :1; 243 unsigned int DeviceOverrideEnabled :1; 244 unsigned int DoNotPowerDown :1; 245 unsigned int ParentsKnowState :1; 246 unsigned int StrictTreeOrder :1; 247 unsigned int IdleTimerStopped :1; 248 unsigned int AdjustPowerScheduled :1; 249 250 unsigned int IsPreChange :1; 251 unsigned int DriverCallBusy :1; 252 unsigned int PCDFunctionOverride :1; 253 unsigned int IdleTimerIgnored :1; 254 unsigned int HasAdvisoryDesire :1; 255 unsigned int AdvisoryTickleUsed :1; 256 unsigned int ResetPowerStateOnWake :1; 257 258 // Time of last device activity. 259 AbsoluteTime DeviceActiveTimestamp; 260 AbsoluteTime MaxPowerStateEntryTime; 261 AbsoluteTime MaxPowerStateExitTime; 262 263 // Used to protect activity flag. 264 IOLock * ActivityLock; 265 266 // Idle timer's period in seconds. 267 int IdleTimerPeriod; 268 int NextIdleTimerPeriod; 269 IOPMPowerStateIndex IdleTimerMinPowerState; 270 AbsoluteTime IdleTimerStartTime; 271 272 // Power state desired by a subclassed device object. 273 IOPMPowerStateIndex DeviceDesire; 274 275 // This is the power state we desire currently. 276 IOPMPowerStateIndex DesiredPowerState; 277 278 // This is what our parent thinks our need is. 279 IOPMPowerFlags PreviousRequestPowerFlags; 280 281 // Cache result from getName(), used in logging. 282 const char * Name; 283 284 // Number of power states in the power array. 285 IOPMPowerStateIndex NumberOfPowerStates; 286 287 // Ordered highest power state in the power array. 288 IOPMPowerStateIndex HighestPowerState; 289 290 // Power state array. 291 IOPMPSEntry * PowerStates; 292 293 // The controlling driver. 294 IOService * ControllingDriver; 295 296 // Our current power state. 297 IOPMPowerStateIndex CurrentPowerState; 298 299 // Logical OR of power flags for each power domain parent. 300 IOPMPowerFlags ParentsCurrentPowerFlags; 301 302 // The highest power state we can achieve in current power domain. 303 IOPMPowerStateIndex MaxPowerState; 304 305 // Logical OR of all output power flags in the power state array. 306 IOPMPowerFlags MergedOutputPowerFlags; 307 308 // OSArray which manages responses from notified apps and clients. 309 OSArray * ResponseArray; 310 OSArray * NotifyClientArray; 311 312 // Used to uniquely identify power management notification to apps and clients. 313 uint16_t SerialNumber; 314 315 // Used to communicate desired function to tellClientsWithResponse(). 316 // This is used because it avoids changing the signatures of the affected virtual methods. 317 int OutOfBandParameter; 318 319 AbsoluteTime DriverCallStartTime; 320 IOPMPowerFlags CurrentCapabilityFlags; 321 unsigned long CurrentPowerConsumption; 322 IOPMPowerStateIndex TempClampPowerState; 323 OSArray * NotifyChildArray; 324 OSDictionary * PowerClients; 325 thread_call_t DriverCallEntry; 326 void * DriverCallParamPtr; 327 IOItemCount DriverCallParamCount; 328 IOItemCount DriverCallParamSlots; 329 uint32_t DriverCallReason; 330 uint32_t OutOfBandMessage; 331 uint32_t TempClampCount; 332 IOPMPowerStateIndex OverrideMaxPowerState; 333 IOPMPowerStateIndex DeviceUsablePowerState; 334 335 // Thread to be run alongside DriverCallEntry to provide logging. 336 thread_call_t DriverCallTimer; 337 338 // Protected by ActivityLock - BEGIN 339 IOPMPowerStateIndex ActivityTicklePowerState; 340 IOPMPowerStateIndex AdvisoryTicklePowerState; 341 uint32_t ActivityTickleCount; 342 uint32_t DeviceWasActive : 1; 343 uint32_t AdvisoryTickled : 1; 344 // Protected by ActivityLock - END 345 346 uint32_t WaitReason; 347 uint32_t SavedMachineState; 348 349 // Protected by PMLock - BEGIN 350 struct { 351 uint32_t PMStop : 1; 352 uint32_t PMDriverCallWait : 1; 353 } LockedFlags; 354 355 queue_head_t PMDriverCallQueue; 356 OSSet * InsertInterestSet; 357 OSSet * RemoveInterestSet; 358 359 // IOReporter Data 360 uint32_t ReportClientCnt; 361 void * ReportBuf; 362 // Protected by PMLock - END 363 364 #if PM_VARS_SUPPORT 365 IOPMprot * PMVars; 366 #endif 367 368 IOPMActions PMActions; 369 370 // Serialize IOServicePM state for debug output. 371 IOReturn gatedSerialize( OSSerialize * s ) const; 372 virtual bool serialize( OSSerialize * s ) const APPLE_KEXT_OVERRIDE; 373 374 // PM log and trace 375 void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; 376 void pmTrace( uint32_t event, uint32_t eventFunc, uintptr_t param1, uintptr_t param2 ) const; 377 }; 378 379 #define fOwner pwrMgt->Owner 380 #define fInterestedDrivers pwrMgt->InterestedDrivers 381 #define fDriverTimer pwrMgt->DriverTimer 382 #define fMachineState pwrMgt->MachineState 383 #define fAckTimer pwrMgt->AckTimer 384 #define fSettleTimer pwrMgt->SettleTimer 385 #define fIdleTimer pwrMgt->IdleTimer 386 #define fWatchdogTimer pwrMgt->WatchdogTimer 387 #define fWatchdogDeadline pwrMgt->WatchdogDeadline 388 #define fWatchdogLock pwrMgt->WatchdogLock 389 #define fBlockedArray pwrMgt->BlockedArray 390 #define fPendingResponseDeadline pwrMgt->PendingResponseDeadline 391 #define fSettleTimeUS pwrMgt->SettleTimeUS 392 #define fIdleTimerGeneration pwrMgt->IdleTimerGeneration 393 #define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags 394 #define fHeadNotePowerState pwrMgt->HeadNotePowerState 395 #define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry 396 #define fHeadNoteDomainFlags pwrMgt->HeadNoteDomainFlags 397 #define fHeadNoteDomainTargetFlags pwrMgt->HeadNoteDomainTargetFlags 398 #define fHeadNoteParentConnection pwrMgt->HeadNoteParentConnection 399 #define fHeadNoteParentFlags pwrMgt->HeadNoteParentFlags 400 #define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks 401 #define fPMLock pwrMgt->PMLock 402 #define fInitialPowerChange pwrMgt->InitialPowerChange 403 #define fInitialSetPowerState pwrMgt->InitialSetPowerState 404 #define fDeviceOverrideEnabled pwrMgt->DeviceOverrideEnabled 405 #define fDoNotPowerDown pwrMgt->DoNotPowerDown 406 #define fParentsKnowState pwrMgt->ParentsKnowState 407 #define fStrictTreeOrder pwrMgt->StrictTreeOrder 408 #define fIdleTimerStopped pwrMgt->IdleTimerStopped 409 #define fAdjustPowerScheduled pwrMgt->AdjustPowerScheduled 410 #define fIsPreChange pwrMgt->IsPreChange 411 #define fDriverCallBusy pwrMgt->DriverCallBusy 412 #define fPCDFunctionOverride pwrMgt->PCDFunctionOverride 413 #define fIdleTimerIgnored pwrMgt->IdleTimerIgnored 414 #define fHasAdvisoryDesire pwrMgt->HasAdvisoryDesire 415 #define fAdvisoryTickleUsed pwrMgt->AdvisoryTickleUsed 416 #define fResetPowerStateOnWake pwrMgt->ResetPowerStateOnWake 417 #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp 418 #define fMaxPowerStateEntryTime pwrMgt->MaxPowerStateEntryTime 419 #define fMaxPowerStateExitTime pwrMgt->MaxPowerStateExitTime 420 #define fActivityLock pwrMgt->ActivityLock 421 #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod 422 #define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState 423 #define fNextIdleTimerPeriod pwrMgt->NextIdleTimerPeriod 424 #define fIdleTimerStartTime pwrMgt->IdleTimerStartTime 425 #define fDeviceDesire pwrMgt->DeviceDesire 426 #define fDesiredPowerState pwrMgt->DesiredPowerState 427 #define fPreviousRequestPowerFlags pwrMgt->PreviousRequestPowerFlags 428 #define fName pwrMgt->Name 429 #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates 430 #define fHighestPowerState pwrMgt->HighestPowerState 431 #define fPowerStates pwrMgt->PowerStates 432 #define fControllingDriver pwrMgt->ControllingDriver 433 #define fCurrentPowerState pwrMgt->CurrentPowerState 434 #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags 435 #define fMaxPowerState pwrMgt->MaxPowerState 436 #define fMergedOutputPowerFlags pwrMgt->MergedOutputPowerFlags 437 #define fResponseArray pwrMgt->ResponseArray 438 #define fNotifyClientArray pwrMgt->NotifyClientArray 439 #define fSerialNumber pwrMgt->SerialNumber 440 #define fOutOfBandParameter pwrMgt->OutOfBandParameter 441 #define fDriverCallStartTime pwrMgt->DriverCallStartTime 442 #define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags 443 #define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption 444 #define fTempClampPowerState pwrMgt->TempClampPowerState 445 #define fNotifyChildArray pwrMgt->NotifyChildArray 446 #define fPowerClients pwrMgt->PowerClients 447 #define fDriverCallEntry pwrMgt->DriverCallEntry 448 #define fDriverCallParamPtr pwrMgt->DriverCallParamPtr 449 #define fDriverCallParamCount pwrMgt->DriverCallParamCount 450 #define fDriverCallParamSlots pwrMgt->DriverCallParamSlots 451 #define fDriverCallReason pwrMgt->DriverCallReason 452 #define fOutOfBandMessage pwrMgt->OutOfBandMessage 453 #define fTempClampCount pwrMgt->TempClampCount 454 #define fOverrideMaxPowerState pwrMgt->OverrideMaxPowerState 455 #define fDeviceUsablePowerState pwrMgt->DeviceUsablePowerState 456 #define fDriverCallTimer pwrMgt->DriverCallTimer 457 #define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState 458 #define fAdvisoryTicklePowerState pwrMgt->AdvisoryTicklePowerState 459 #define fActivityTickleCount pwrMgt->ActivityTickleCount 460 #define fDeviceWasActive pwrMgt->DeviceWasActive 461 #define fAdvisoryTickled pwrMgt->AdvisoryTickled 462 #define fWaitReason pwrMgt->WaitReason 463 #define fSavedMachineState pwrMgt->SavedMachineState 464 #define fLockedFlags pwrMgt->LockedFlags 465 #define fPMDriverCallQueue pwrMgt->PMDriverCallQueue 466 #define fInsertInterestSet pwrMgt->InsertInterestSet 467 #define fRemoveInterestSet pwrMgt->RemoveInterestSet 468 #define fReportClientCnt pwrMgt->ReportClientCnt 469 #define fReportBuf pwrMgt->ReportBuf 470 #define fPMVars pwrMgt->PMVars 471 #define fPMActions pwrMgt->PMActions 472 473 #define StateOrder(state) (((state) < fNumberOfPowerStates) \ 474 ? pwrMgt->PowerStates[(state)].stateOrder \ 475 : (state)) 476 #define StateMax(a, b) (StateOrder((a)) < StateOrder((b)) ? (b) : (a)) 477 #define StateMin(a, b) (StateOrder((a)) < StateOrder((b)) ? (a) : (b)) 478 479 #define kPowerStateZero (0) 480 481 /* 482 * When an IOService is waiting for acknowledgement to a power change 483 * notification from an interested driver or the controlling driver, 484 * the ack timer is ticking every tenth of a second. 485 * (100000000 nanoseconds are one tenth of a second). 486 */ 487 #define ACK_TIMER_PERIOD 100000000 488 489 #if defined(__i386__) || defined(__x86_64__) 490 #define WATCHDOG_SLEEP_TIMEOUT (180) // 180 secs 491 #define WATCHDOG_WAKE_TIMEOUT (180) // 180 secs 492 #else 493 #define WATCHDOG_SLEEP_TIMEOUT (35) // 35 secs (kMaxTimeRequested + 5s) 494 #define WATCHDOG_WAKE_TIMEOUT (35) // 35 secs (kMaxTimeRequested + 5s) 495 #endif 496 // Slightly larger than the internal VM flush timeout 497 #define WATCHDOG_HIBERNATION_TIMEOUT (HIBERNATE_FLUSHING_SECS_TO_COMPLETE + 1) 498 499 // Max wait time in microseconds for kernel priority and capability clients 500 // with async message handlers to acknowledge. 501 // 502 #define kPriorityClientMaxWait (90 * 1000 * 1000) 503 #define kCapabilityClientMaxWait (240 * 1000 * 1000) 504 505 // Attributes describing a power state change. 506 // See IOPMPowerChangeFlags data type. 507 // 508 #define kIOPMParentInitiated 0x0001 // power change initiated by our parent 509 #define kIOPMSelfInitiated 0x0002 // power change initiated by this device 510 #define kIOPMNotDone 0x0004 // we couldn't make this change 511 #define kIOPMDomainWillChange 0x0008 // change started by PowerDomainWillChangeTo 512 #define kIOPMDomainDidChange 0x0010 // change started by PowerDomainDidChangeTo 513 #define kIOPMDomainPowerDrop 0x0020 // Domain is lowering power 514 #define kIOPMIgnoreChildren 0x0040 // Ignore children and driver power desires 515 #define kIOPMSkipAskPowerDown 0x0080 // skip the ask app phase 516 #define kIOPMSynchronize 0x0100 // change triggered by power tree re-sync 517 #define kIOPMSyncNoChildNotify 0x0200 // sync root domain only, not entire tree 518 #define kIOPMSyncTellPowerDown 0x0400 // send the ask/will power off messages 519 #define kIOPMSyncCancelPowerDown 0x0800 // sleep cancel for maintenance wake 520 #define kIOPMInitialPowerChange 0x1000 // set for initial power change 521 #define kIOPMRootChangeUp 0x2000 // Root power domain change up 522 #define kIOPMRootChangeDown 0x4000 // Root power domain change down 523 #define kIOPMExpireIdleTimer 0x8000 // Accelerate idle timer expiration 524 525 #define kIOPMRootBroadcastFlags (kIOPMSynchronize | \ 526 kIOPMRootChangeUp | kIOPMRootChangeDown) 527 528 // Activity tickle request flags 529 #define kTickleTypePowerDrop 0x01 530 #define kTickleTypePowerRise 0x02 531 #define kTickleTypeActivity 0x04 532 #define kTickleTypeAdvisory 0x08 533 534 enum { 535 kDriverCallInformPreChange, 536 kDriverCallInformPostChange, 537 kDriverCallSetPowerState, 538 kRootDomainInformPreChange 539 }; 540 541 struct DriverCallParam { 542 OSObject * Target; 543 IOReturn Result; 544 }; 545 546 // values of OutOfBandParameter 547 enum { 548 kNotifyApps, 549 kNotifyPriority, 550 kNotifyCapabilityChangeApps, 551 kNotifyCapabilityChangePriority 552 }; 553 554 typedef bool (*IOPMMessageFilter)( 555 void * target, void * object, void * arg1, void * arg2, void * arg3 ); 556 557 // used for applyToInterested 558 struct IOPMInterestContext { 559 OSArray * responseArray; 560 OSArray * notifyClients; 561 uint16_t serialNumber; 562 uint8_t isPreChange; 563 uint8_t enableTracing; 564 uint32_t maxTimeRequested; 565 uint32_t messageType; 566 uint32_t notifyType; 567 uint32_t skippedInDark; 568 uint32_t notSkippedInDark; 569 IOService * us; 570 IOPMPowerStateIndex stateNumber; 571 IOPMPowerFlags stateFlags; 572 IOPMPowerChangeFlags changeFlags; 573 IOPMMessageFilter messageFilter; 574 }; 575 576 // track client ack requirements 577 class IOPMClientAck : public OSObject { 578 OSDeclareDefaultStructors( IOPMClientAck ); 579 public: 580 uint64_t completionTimestamp; // absolute time 581 uint32_t maxTimeRequested; // microseconds 582 }; 583 584 // assertPMDriverCall() options 585 enum { 586 kIOPMDriverCallNoInactiveCheck = 1 587 }; 588 589 // assertPMDriverCall() method 590 enum { 591 kIOPMDriverCallMethodUnknown = 0, 592 kIOPMDriverCallMethodSetPowerState = 1, 593 kIOPMDriverCallMethodWillChange = 2, 594 kIOPMDriverCallMethodDidChange = 3, 595 kIOPMDriverCallMethodChangeDone = 4, 596 kIOPMDriverCallMethodSetAggressive = 5, 597 kIOPMDriverCallMethodMaxCapabilityForDomainState = 6, 598 kIOPMDriverCallMethodInitialPowerStateForDomainState = 7 599 }; 600 601 //****************************************************************************** 602 // PM Statistics & Diagnostics 603 //****************************************************************************** 604 605 extern OSPtr<const OSSymbol> gIOPMStatsResponseTimedOut; 606 extern OSPtr<const OSSymbol> gIOPMStatsResponseCancel; 607 extern OSPtr<const OSSymbol> gIOPMStatsResponseSlow; 608 extern OSPtr<const OSSymbol> gIOPMStatsResponsePrompt; 609 extern OSPtr<const OSSymbol> gIOPMStatsDriverPSChangeSlow; 610 611 //****************************************************************************** 612 // IOPMRequest 613 //****************************************************************************** 614 615 class IOPMRequest : public IOCommand 616 { 617 OSDeclareDefaultStructors( IOPMRequest ); 618 619 protected: 620 IOService * fTarget; // request target 621 IOPMRequest * fRequestNext; // the next request in the chain 622 IOPMRequest * fRequestRoot; // the root request in the call tree 623 uint32_t fWorkWaitCount; // execution blocked if non-zero 624 uint32_t fFreeWaitCount; // completion blocked if non-zero 625 uint64_t fTimestamp; // MCTU 626 uint32_t fRequestType; // request type 627 bool fIsQuiesceBlocker; 628 629 IOPMCompletionAction fCompletionAction; 630 void * fCompletionTarget; 631 void * fCompletionParam; 632 633 public: 634 uint32_t fTag; 635 void * fArg0; 636 void * fArg1; 637 void * fArg2; 638 639 inline bool isWorkBlocked(void)640 isWorkBlocked( void ) const 641 { 642 return fWorkWaitCount != 0; 643 } 644 645 inline bool isFreeBlocked(void)646 isFreeBlocked( void ) const 647 { 648 return fFreeWaitCount != 0; 649 } 650 651 inline IOPMRequest * getNextRequest(void)652 getNextRequest( void ) const 653 { 654 return fRequestNext; 655 } 656 657 inline IOPMRequest * getRootRequest(void)658 getRootRequest( void ) const 659 { 660 if (fRequestRoot) { 661 return fRequestRoot; 662 } 663 #if NOT_READY 664 if (fCompletionAction) { 665 return (IOPMRequest *) this; 666 } 667 #endif 668 return NULL; 669 } 670 671 inline uint32_t getType(void)672 getType( void ) const 673 { 674 return fRequestType; 675 } 676 677 inline uint32_t getTag(void)678 getTag( void ) const 679 { 680 return fTag; 681 } 682 683 inline bool isReplyType(void)684 isReplyType( void ) const 685 { 686 return fRequestType > kIOPMRequestTypeReplyStart; 687 } 688 689 inline IOService * getTarget(void)690 getTarget( void ) const 691 { 692 return fTarget; 693 } 694 695 inline bool isQuiesceBlocker(void)696 isQuiesceBlocker( void ) const 697 { 698 return fIsQuiesceBlocker; 699 } 700 701 inline bool isQuiesceType(void)702 isQuiesceType( void ) const 703 { 704 return (kIOPMRequestTypeQuiescePowerTree == fRequestType) && 705 (fCompletionAction != NULL) && (fCompletionTarget != NULL); 706 } 707 708 inline void installCompletionAction(void * target,IOPMCompletionAction action,void * param)709 installCompletionAction( 710 void * target, 711 IOPMCompletionAction action, 712 void * param ) 713 { 714 fCompletionTarget = target; 715 fCompletionAction = action; 716 fCompletionParam = param; 717 } 718 719 inline void setTimestamp(uint64_t time)720 setTimestamp( uint64_t time ) 721 { 722 fTimestamp = time; 723 } 724 725 inline uint64_t getTimestamp(void)726 getTimestamp( void ) const 727 { 728 return fTimestamp; 729 } 730 731 static IOPMRequest * create( void ); 732 bool init( IOService * owner, IOOptionBits type ); 733 void reset( void ); 734 bool attachNextRequest( IOPMRequest * next ); 735 bool detachNextRequest( void ); 736 bool attachRootRequest( IOPMRequest * root ); 737 bool detachRootRequest( void ); 738 }; 739 740 //****************************************************************************** 741 // IOPMRequestQueue 742 //****************************************************************************** 743 744 class IOPMRequestQueue : public IOEventSource 745 { 746 OSDeclareDefaultStructors( IOPMRequestQueue ); 747 748 public: 749 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * ); 750 751 protected: 752 queue_head_t fQueue; 753 IOLock * fLock; 754 755 enum { kMaxDequeueCount = 256 }; 756 757 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 758 virtual void free( void ) APPLE_KEXT_OVERRIDE; 759 virtual bool init( IOService * inOwner, Action inAction ); 760 761 public: 762 static IOPMRequestQueue * create( IOService * inOwner, Action inAction ); 763 void queuePMRequest( LIBKERN_CONSUMED IOPMRequest * request ); 764 void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count ); 765 }; 766 767 //****************************************************************************** 768 // IOPMWorkQueue 769 //****************************************************************************** 770 771 #define WORK_QUEUE_STATS 1 772 773 class IOPMWorkQueue : public IOEventSource 774 { 775 OSDeclareDefaultStructors( IOPMWorkQueue ); 776 777 public: 778 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * ); 779 780 #if WORK_QUEUE_STATS 781 uint64_t fStatCheckForWork; 782 uint64_t fStatScanEntries; 783 uint64_t fStatQueueEmpty; 784 uint64_t fStatNoWorkDone; 785 #endif 786 787 protected: 788 queue_head_t fWorkQueue; 789 Action fInvokeAction; 790 Action fRetireAction; 791 uint32_t fQueueLength; 792 uint32_t fConsumerCount; 793 volatile uint32_t fProducerCount; 794 IOPMRequest * fQuiesceRequest; 795 AbsoluteTime fQuiesceStartTime; 796 AbsoluteTime fQuiesceFinishTime; 797 798 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 799 virtual bool init( IOService * inOwner, Action invoke, Action retire ); 800 bool checkRequestQueue( queue_head_t * queue, bool * empty ); 801 802 public: 803 static IOPMWorkQueue * create( IOService * inOwner, Action invoke, Action retire ); 804 bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt ); 805 void signalWorkAvailable( void ); 806 void incrementProducerCount( void ); 807 void attachQuiesceRequest( IOPMRequest * quiesceRequest ); 808 void finishQuiesceRequest( IOPMRequest * quiesceRequest ); 809 }; 810 811 //****************************************************************************** 812 // IOPMCompletionQueue 813 //****************************************************************************** 814 815 class IOPMCompletionQueue : public IOEventSource 816 { 817 OSDeclareDefaultStructors( IOPMCompletionQueue ); 818 819 public: 820 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * ); 821 822 protected: 823 queue_head_t fQueue; 824 825 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 826 virtual bool init( IOService * inOwner, Action inAction ); 827 828 public: 829 static IOPMCompletionQueue * create( IOService * inOwner, Action inAction ); 830 bool queuePMRequest( IOPMRequest * request ); 831 }; 832 833 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */ 834