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 uint64_t PMDriverClass; 372 #define fPMDriverClass pwrMgt->PMDriverClass 373 374 // Serialize IOServicePM state for debug output. 375 IOReturn gatedSerialize( OSSerialize * s ) const; 376 virtual bool serialize( OSSerialize * s ) const APPLE_KEXT_OVERRIDE; 377 378 // PM log and trace 379 void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; 380 void pmTrace( uint32_t event, uint32_t eventFunc, uintptr_t param1, uintptr_t param2 ) const; 381 }; 382 383 #define fOwner pwrMgt->Owner 384 #define fInterestedDrivers pwrMgt->InterestedDrivers 385 #define fDriverTimer pwrMgt->DriverTimer 386 #define fMachineState pwrMgt->MachineState 387 #define fAckTimer pwrMgt->AckTimer 388 #define fSettleTimer pwrMgt->SettleTimer 389 #define fIdleTimer pwrMgt->IdleTimer 390 #define fWatchdogTimer pwrMgt->WatchdogTimer 391 #define fWatchdogDeadline pwrMgt->WatchdogDeadline 392 #define fWatchdogStart pwrMgt->WatchdogStart 393 #define fWatchdogLock pwrMgt->WatchdogLock 394 #define fBlockedArray pwrMgt->BlockedArray 395 #define fPendingResponseDeadline pwrMgt->PendingResponseDeadline 396 #define fSettleTimeUS pwrMgt->SettleTimeUS 397 #define fIdleTimerGeneration pwrMgt->IdleTimerGeneration 398 #define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags 399 #define fHeadNotePowerState pwrMgt->HeadNotePowerState 400 #define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry 401 #define fHeadNoteDomainFlags pwrMgt->HeadNoteDomainFlags 402 #define fHeadNoteDomainTargetFlags pwrMgt->HeadNoteDomainTargetFlags 403 #define fHeadNoteParentConnection pwrMgt->HeadNoteParentConnection 404 #define fHeadNoteParentFlags pwrMgt->HeadNoteParentFlags 405 #define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks 406 #define fPMLock pwrMgt->PMLock 407 #define fInitialPowerChange pwrMgt->InitialPowerChange 408 #define fInitialSetPowerState pwrMgt->InitialSetPowerState 409 #define fDeviceOverrideEnabled pwrMgt->DeviceOverrideEnabled 410 #define fDoNotPowerDown pwrMgt->DoNotPowerDown 411 #define fParentsKnowState pwrMgt->ParentsKnowState 412 #define fStrictTreeOrder pwrMgt->StrictTreeOrder 413 #define fIdleTimerStopped pwrMgt->IdleTimerStopped 414 #define fAdjustPowerScheduled pwrMgt->AdjustPowerScheduled 415 #define fIsPreChange pwrMgt->IsPreChange 416 #define fDriverCallBusy pwrMgt->DriverCallBusy 417 #define fPCDFunctionOverride pwrMgt->PCDFunctionOverride 418 #define fIdleTimerIgnored pwrMgt->IdleTimerIgnored 419 #define fHasAdvisoryDesire pwrMgt->HasAdvisoryDesire 420 #define fAdvisoryTickleUsed pwrMgt->AdvisoryTickleUsed 421 #define fResetPowerStateOnWake pwrMgt->ResetPowerStateOnWake 422 #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp 423 #define fMaxPowerStateEntryTime pwrMgt->MaxPowerStateEntryTime 424 #define fMaxPowerStateExitTime pwrMgt->MaxPowerStateExitTime 425 #define fActivityLock pwrMgt->ActivityLock 426 #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod 427 #define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState 428 #define fNextIdleTimerPeriod pwrMgt->NextIdleTimerPeriod 429 #define fIdleTimerStartTime pwrMgt->IdleTimerStartTime 430 #define fDeviceDesire pwrMgt->DeviceDesire 431 #define fDesiredPowerState pwrMgt->DesiredPowerState 432 #define fPreviousRequestPowerFlags pwrMgt->PreviousRequestPowerFlags 433 #define fName pwrMgt->Name 434 #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates 435 #define fHighestPowerState pwrMgt->HighestPowerState 436 #define fPowerStates pwrMgt->PowerStates 437 #define fControllingDriver pwrMgt->ControllingDriver 438 #define fCurrentPowerState pwrMgt->CurrentPowerState 439 #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags 440 #define fMaxPowerState pwrMgt->MaxPowerState 441 #define fMergedOutputPowerFlags pwrMgt->MergedOutputPowerFlags 442 #define fResponseArray pwrMgt->ResponseArray 443 #define fNotifyClientArray pwrMgt->NotifyClientArray 444 #define fSerialNumber pwrMgt->SerialNumber 445 #define fOutOfBandParameter pwrMgt->OutOfBandParameter 446 #define fDriverCallStartTime pwrMgt->DriverCallStartTime 447 #define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags 448 #define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption 449 #define fTempClampPowerState pwrMgt->TempClampPowerState 450 #define fNotifyChildArray pwrMgt->NotifyChildArray 451 #define fPowerClients pwrMgt->PowerClients 452 #define fDriverCallEntry pwrMgt->DriverCallEntry 453 #define fDriverCallParamPtr pwrMgt->DriverCallParamPtr 454 #define fDriverCallParamCount pwrMgt->DriverCallParamCount 455 #define fDriverCallParamSlots pwrMgt->DriverCallParamSlots 456 #define fDriverCallReason pwrMgt->DriverCallReason 457 #define fOutOfBandMessage pwrMgt->OutOfBandMessage 458 #define fTempClampCount pwrMgt->TempClampCount 459 #define fOverrideMaxPowerState pwrMgt->OverrideMaxPowerState 460 #define fDeviceUsablePowerState pwrMgt->DeviceUsablePowerState 461 #define fDriverCallTimer pwrMgt->DriverCallTimer 462 #define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState 463 #define fAdvisoryTicklePowerState pwrMgt->AdvisoryTicklePowerState 464 #define fActivityTickleCount pwrMgt->ActivityTickleCount 465 #define fDeviceWasActive pwrMgt->DeviceWasActive 466 #define fAdvisoryTickled pwrMgt->AdvisoryTickled 467 #define fWaitReason pwrMgt->WaitReason 468 #define fSavedMachineState pwrMgt->SavedMachineState 469 #define fLockedFlags pwrMgt->LockedFlags 470 #define fPMDriverCallQueue pwrMgt->PMDriverCallQueue 471 #define fInsertInterestSet pwrMgt->InsertInterestSet 472 #define fRemoveInterestSet pwrMgt->RemoveInterestSet 473 #define fReportClientCnt pwrMgt->ReportClientCnt 474 #define fReportBuf pwrMgt->ReportBuf 475 #define fPMVars pwrMgt->PMVars 476 #define fPMActions pwrMgt->PMActions 477 478 #define StateOrder(state) (((state) < fNumberOfPowerStates) \ 479 ? pwrMgt->PowerStates[(state)].stateOrder \ 480 : (state)) 481 #define StateMax(a, b) (StateOrder((a)) < StateOrder((b)) ? (b) : (a)) 482 #define StateMin(a, b) (StateOrder((a)) < StateOrder((b)) ? (a) : (b)) 483 484 #define kPowerStateZero (0) 485 486 /* 487 * When an IOService is waiting for acknowledgement to a power change 488 * notification from an interested driver or the controlling driver, 489 * the ack timer is ticking every tenth of a second. 490 * (100000000 nanoseconds are one tenth of a second). 491 */ 492 #define ACK_TIMER_PERIOD 100000000 493 494 #if defined(__i386__) || defined(__x86_64__) 495 #define WATCHDOG_SLEEP_TIMEOUT (180) // 180 secs 496 #define WATCHDOG_WAKE_TIMEOUT (180) // 180 secs 497 #else 498 #define WATCHDOG_SLEEP_TIMEOUT (35) // 35 secs (kMaxTimeRequested + 5s) 499 #define WATCHDOG_WAKE_TIMEOUT (35) // 35 secs (kMaxTimeRequested + 5s) 500 #endif 501 #define WATCHDOG_HIBERNATION_TIMEOUT (180) 502 503 // Max wait time in microseconds for kernel priority and capability clients 504 // with async message handlers to acknowledge. 505 // 506 #define kPriorityClientMaxWait (90 * 1000 * 1000) 507 #define kCapabilityClientMaxWait (240 * 1000 * 1000) 508 509 // Attributes describing a power state change. 510 // See IOPMPowerChangeFlags data type. 511 // 512 #define kIOPMParentInitiated 0x0001 // power change initiated by our parent 513 #define kIOPMSelfInitiated 0x0002 // power change initiated by this device 514 #define kIOPMNotDone 0x0004 // we couldn't make this change 515 #define kIOPMDomainWillChange 0x0008 // change started by PowerDomainWillChangeTo 516 #define kIOPMDomainDidChange 0x0010 // change started by PowerDomainDidChangeTo 517 #define kIOPMDomainPowerDrop 0x0020 // Domain is lowering power 518 #define kIOPMIgnoreChildren 0x0040 // Ignore children and driver power desires 519 #define kIOPMSkipAskPowerDown 0x0080 // skip the ask app phase 520 #define kIOPMSynchronize 0x0100 // change triggered by power tree re-sync 521 #define kIOPMSyncNoChildNotify 0x0200 // sync root domain only, not entire tree 522 #define kIOPMSyncTellPowerDown 0x0400 // send the ask/will power off messages 523 #define kIOPMSyncCancelPowerDown 0x0800 // sleep cancel for maintenance wake 524 #define kIOPMInitialPowerChange 0x1000 // set for initial power change 525 #define kIOPMRootChangeUp 0x2000 // Root power domain change up 526 #define kIOPMRootChangeDown 0x4000 // Root power domain change down 527 #define kIOPMExpireIdleTimer 0x8000 // Accelerate idle timer expiration 528 529 #define kIOPMRootBroadcastFlags (kIOPMSynchronize | \ 530 kIOPMRootChangeUp | kIOPMRootChangeDown) 531 532 // Activity tickle request flags 533 #define kTickleTypePowerDrop 0x01 534 #define kTickleTypePowerRise 0x02 535 #define kTickleTypeActivity 0x04 536 #define kTickleTypeAdvisory 0x08 537 538 enum { 539 kDriverCallInformPreChange, 540 kDriverCallInformPostChange, 541 kDriverCallSetPowerState, 542 kRootDomainInformPreChange 543 }; 544 545 struct DriverCallParam { 546 OSObject * Target; 547 IOReturn Result; 548 }; 549 550 // values of OutOfBandParameter 551 enum { 552 kNotifyApps, 553 kNotifyPriority, 554 kNotifyCapabilityChangeApps, 555 kNotifyCapabilityChangePriority 556 }; 557 558 typedef bool (*IOPMMessageFilter)( 559 void * target, void * object, void * arg1, void * arg2, void * arg3 ); 560 561 // used for applyToInterested 562 struct IOPMInterestContext { 563 OSArray * responseArray; 564 OSArray * notifyClients; 565 uint16_t serialNumber; 566 uint8_t isPreChange; 567 uint8_t enableTracing; 568 uint32_t maxTimeRequested; 569 uint32_t messageType; 570 uint32_t notifyType; 571 uint32_t skippedInDark; 572 uint32_t notSkippedInDark; 573 IOService * us; 574 IOPMPowerStateIndex stateNumber; 575 IOPMPowerFlags stateFlags; 576 IOPMPowerChangeFlags changeFlags; 577 IOPMMessageFilter messageFilter; 578 }; 579 580 // track client ack requirements 581 class IOPMClientAck : public OSObject { 582 OSDeclareDefaultStructors( IOPMClientAck ); 583 public: 584 uint64_t completionTimestamp; // absolute time 585 uint32_t maxTimeRequested; // microseconds 586 }; 587 588 // assertPMDriverCall() options 589 enum { 590 kIOPMDriverCallNoInactiveCheck = 1 591 }; 592 593 // assertPMDriverCall() method 594 enum { 595 kIOPMDriverCallMethodUnknown = 0, 596 kIOPMDriverCallMethodSetPowerState = 1, 597 kIOPMDriverCallMethodWillChange = 2, 598 kIOPMDriverCallMethodDidChange = 3, 599 kIOPMDriverCallMethodChangeDone = 4, 600 kIOPMDriverCallMethodSetAggressive = 5, 601 kIOPMDriverCallMethodMaxCapabilityForDomainState = 6, 602 kIOPMDriverCallMethodInitialPowerStateForDomainState = 7 603 }; 604 605 606 enum { 607 kIOPMDriverClassStorage = 0x00000010, 608 kIOPMDriverClassNetwork = 0x00000020, 609 kIOPMDriverClassDriverKit = 0x00000040, 610 kIOPMDriverClassDone = (1ULL << 63), 611 }; 612 613 extern uint64_t gLPWFlags; 614 615 //****************************************************************************** 616 // PM Statistics & Diagnostics 617 //****************************************************************************** 618 619 extern OSPtr<const OSSymbol> gIOPMStatsResponseTimedOut; 620 extern OSPtr<const OSSymbol> gIOPMStatsResponseCancel; 621 extern OSPtr<const OSSymbol> gIOPMStatsResponseSlow; 622 extern OSPtr<const OSSymbol> gIOPMStatsResponsePrompt; 623 extern OSPtr<const OSSymbol> gIOPMStatsDriverPSChangeSlow; 624 625 //****************************************************************************** 626 // IOPMRequest 627 //****************************************************************************** 628 629 class IOPMRequest : public IOCommand 630 { 631 OSDeclareDefaultStructors( IOPMRequest ); 632 633 protected: 634 IOService * fTarget; // request target 635 IOPMRequest * fRequestNext; // the next request in the chain 636 IOPMRequest * fRequestRoot; // the root request in the call tree 637 uint32_t fWorkWaitCount; // execution blocked if non-zero 638 uint32_t fFreeWaitCount; // completion blocked if non-zero 639 uint64_t fTimestamp; // MCTU 640 uint32_t fRequestType; // request type 641 bool fIsQuiesceBlocker; 642 643 IOPMCompletionAction fCompletionAction; 644 void * fCompletionTarget; 645 void * fCompletionParam; 646 647 public: 648 uint32_t fTag; 649 void * fArg0; 650 void * fArg1; 651 void * fArg2; 652 653 inline bool isWorkBlocked(void)654 isWorkBlocked( void ) const 655 { 656 return fWorkWaitCount != 0; 657 } 658 659 inline bool isFreeBlocked(void)660 isFreeBlocked( void ) const 661 { 662 return fFreeWaitCount != 0; 663 } 664 665 inline IOPMRequest * getNextRequest(void)666 getNextRequest( void ) const 667 { 668 return fRequestNext; 669 } 670 671 inline IOPMRequest * getRootRequest(void)672 getRootRequest( void ) const 673 { 674 if (fRequestRoot) { 675 return fRequestRoot; 676 } 677 #if NOT_READY 678 if (fCompletionAction) { 679 return (IOPMRequest *) this; 680 } 681 #endif 682 return NULL; 683 } 684 685 inline uint32_t getType(void)686 getType( void ) const 687 { 688 return fRequestType; 689 } 690 691 inline uint32_t getTag(void)692 getTag( void ) const 693 { 694 return fTag; 695 } 696 697 inline bool isReplyType(void)698 isReplyType( void ) const 699 { 700 return fRequestType > kIOPMRequestTypeReplyStart; 701 } 702 703 inline IOService * getTarget(void)704 getTarget( void ) const 705 { 706 return fTarget; 707 } 708 709 inline bool isQuiesceBlocker(void)710 isQuiesceBlocker( void ) const 711 { 712 return fIsQuiesceBlocker; 713 } 714 715 inline bool isQuiesceType(void)716 isQuiesceType( void ) const 717 { 718 return (kIOPMRequestTypeQuiescePowerTree == fRequestType) && 719 (fCompletionAction != NULL) && (fCompletionTarget != NULL); 720 } 721 722 inline void installCompletionAction(void * target,IOPMCompletionAction action,void * param)723 installCompletionAction( 724 void * target, 725 IOPMCompletionAction action, 726 void * param ) 727 { 728 fCompletionTarget = target; 729 fCompletionAction = action; 730 fCompletionParam = param; 731 } 732 733 inline void setTimestamp(uint64_t time)734 setTimestamp( uint64_t time ) 735 { 736 fTimestamp = time; 737 } 738 739 inline uint64_t getTimestamp(void)740 getTimestamp( void ) const 741 { 742 return fTimestamp; 743 } 744 745 static IOPMRequest * create( void ); 746 bool init( IOService * owner, IOOptionBits type ); 747 void reset( void ); 748 bool attachNextRequest( IOPMRequest * next ); 749 bool detachNextRequest( void ); 750 bool attachRootRequest( IOPMRequest * root ); 751 bool detachRootRequest( void ); 752 }; 753 754 //****************************************************************************** 755 // IOPMRequestQueue 756 //****************************************************************************** 757 758 class IOPMRequestQueue : public IOEventSource 759 { 760 OSDeclareDefaultStructors( IOPMRequestQueue ); 761 762 public: 763 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * ); 764 765 protected: 766 queue_head_t fQueue; 767 IOLock * fLock; 768 769 enum { kMaxDequeueCount = 256 }; 770 771 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 772 virtual void free( void ) APPLE_KEXT_OVERRIDE; 773 virtual bool init( IOService * inOwner, Action inAction ); 774 775 public: 776 static IOPMRequestQueue * create( IOService * inOwner, Action inAction ); 777 void queuePMRequest( LIBKERN_CONSUMED IOPMRequest * request ); 778 void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count ); 779 }; 780 781 //****************************************************************************** 782 // IOPMWorkQueue 783 //****************************************************************************** 784 785 #define WORK_QUEUE_STATS 1 786 787 class IOPMWorkQueue : public IOEventSource 788 { 789 OSDeclareDefaultStructors( IOPMWorkQueue ); 790 791 public: 792 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * ); 793 794 #if WORK_QUEUE_STATS 795 uint64_t fStatCheckForWork; 796 uint64_t fStatScanEntries; 797 uint64_t fStatQueueEmpty; 798 uint64_t fStatNoWorkDone; 799 #endif 800 801 protected: 802 queue_head_t fWorkQueue; 803 Action fInvokeAction; 804 Action fRetireAction; 805 uint32_t fQueueLength; 806 uint32_t fConsumerCount; 807 volatile uint32_t fProducerCount; 808 IOPMRequest * fQuiesceRequest; 809 AbsoluteTime fQuiesceStartTime; 810 AbsoluteTime fQuiesceFinishTime; 811 812 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 813 virtual bool init( IOService * inOwner, Action invoke, Action retire ); 814 bool checkRequestQueue( queue_head_t * queue, bool * empty ); 815 816 public: 817 static IOPMWorkQueue * create( IOService * inOwner, Action invoke, Action retire ); 818 bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt ); 819 void signalWorkAvailable( void ); 820 void incrementProducerCount( void ); 821 void attachQuiesceRequest( IOPMRequest * quiesceRequest ); 822 void finishQuiesceRequest( IOPMRequest * quiesceRequest ); 823 }; 824 825 //****************************************************************************** 826 // IOPMCompletionQueue 827 //****************************************************************************** 828 829 class IOPMCompletionQueue : public IOEventSource 830 { 831 OSDeclareDefaultStructors( IOPMCompletionQueue ); 832 833 public: 834 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * ); 835 836 protected: 837 queue_head_t fQueue; 838 839 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 840 virtual bool init( IOService * inOwner, Action inAction ); 841 842 public: 843 static IOPMCompletionQueue * create( IOService * inOwner, Action inAction ); 844 bool queuePMRequest( IOPMRequest * request ); 845 }; 846 847 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */ 848