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