X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/db6096698656d32db7df630594bd9617ee54f828..bb59bff194111743b33cc36712410b5656329d3c:/iokit/Kernel/IOServicePMPrivate.h diff --git a/iokit/Kernel/IOServicePMPrivate.h b/iokit/Kernel/IOServicePMPrivate.h index bdb74358b..313d8e3c5 100644 --- a/iokit/Kernel/IOServicePMPrivate.h +++ b/iokit/Kernel/IOServicePMPrivate.h @@ -55,7 +55,7 @@ enum { kIOPMRequestTypeRequestPowerStateOverride = 0x0E, kIOPMRequestTypeSetIdleTimerPeriod = 0x0F, kIOPMRequestTypeIgnoreIdleTimer = 0x10, - + /* Reply Types */ kIOPMRequestTypeReplyStart = 0x80, kIOPMRequestTypeAckPowerChange = 0x81, @@ -75,33 +75,46 @@ struct IOPMActions; typedef void (*IOPMActionPowerChangeStart)( - void * target, - IOService * service, - IOPMActions * actions, - uint32_t powerState, - uint32_t * changeFlags ); + void * target, + IOService * service, + IOPMActions * actions, + IOPMPowerStateIndex powerState, + IOPMPowerChangeFlags * changeFlags, + IOPMRequestTag requestTag ); typedef void (*IOPMActionPowerChangeDone)( - void * target, - IOService * service, - IOPMActions * actions, - uint32_t powerState, - uint32_t changeFlags ); + void * target, + IOService * service, + IOPMActions * actions, + IOPMPowerStateIndex powerState, + IOPMPowerChangeFlags changeFlags, + IOPMRequestTag requestTag ); typedef void (*IOPMActionPowerChangeOverride)( - void * target, - IOService * service, - IOPMActions * actions, - unsigned long * powerState, - uint32_t * changeFlags ); + void * target, + IOService * service, + IOPMActions * actions, + IOPMPowerStateIndex * powerState, + IOPMPowerChangeFlags * changeFlags, + IOPMRequestTag requestTag ); typedef void (*IOPMActionActivityTickle)( - void * target, - IOService * service, - IOPMActions * actions ); + void * target, + IOService * service, + IOPMActions * actions ); + +typedef void +(*IOPMActionUpdatePowerClient)( + void * target, + IOService * service, + IOPMActions * actions, + const OSSymbol * powerClient, + IOPMPowerStateIndex oldPowerState, + IOPMPowerStateIndex newPowerState +); struct IOPMActions { void * target; @@ -110,59 +123,30 @@ struct IOPMActions { IOPMActionPowerChangeDone actionPowerChangeDone; IOPMActionPowerChangeOverride actionPowerChangeOverride; IOPMActionActivityTickle actionActivityTickle; + IOPMActionUpdatePowerClient actionUpdatePowerClient; }; -//****************************************************************************** - +// IOPMActions parameter flags enum { - kIOPMEventClassSystemEvent = 0x00, - kIOPMEventClassDriverEvent = 0x1 -}; - -class PMEventDetails : public OSObject -{ - OSDeclareDefaultStructors( PMEventDetails ); - friend class IOServicePM; - friend class IOPMrootDomain; - friend class IOPMTimeline; -public: - static PMEventDetails *eventDetails(uint32_t type, - const char *ownerName, - uintptr_t ownerUnique, - const char *interestName, - uint8_t oldState, - uint8_t newState, - uint32_t result, - uint32_t elapsedTimeUS); - - static PMEventDetails *eventDetails(uint32_t type, - const char *uuid, - uint32_t reason, - uint32_t result); -private: - uint8_t eventClassifier; - uint32_t eventType; - const char *ownerName; - uintptr_t ownerUnique; - const char *interestName; - uint8_t oldState; - uint8_t newState; - uint32_t result; - uint32_t elapsedTimeUS; - - const char *uuid; - uint32_t reason; + kPMActionsFlagIsDisplayWrangler = 0x00000100, + kPMActionsFlagIsGraphicsDevice = 0x00000200, + kPMActionsFlagIsAudioDevice = 0x00000400, + kPMActionsFlagLimitPower = 0x00000800, + kPMActionsPCIBitNumberMask = 0x000000ff }; +//****************************************************************************** // Internal concise representation of IOPMPowerState struct IOPMPSEntry { - IOPMPowerFlags capabilityFlags; - IOPMPowerFlags outputPowerFlags; - IOPMPowerFlags inputPowerFlags; - uint32_t staticPower; - uint32_t settleUpTime; - uint32_t settleDownTime; + IOPMPowerFlags capabilityFlags; + IOPMPowerFlags outputPowerFlags; + IOPMPowerFlags inputPowerFlags; + uint32_t staticPower; + uint32_t settleUpTime; + uint32_t settleDownTime; + IOPMPowerStateIndex stateOrder; + IOPMPowerStateIndex stateOrderToIndex; }; //****************************************************************************** @@ -179,7 +163,7 @@ class IOServicePM : public OSObject private: // Link IOServicePM objects on IOPMWorkQueue. queue_chain_t WorkChain; - + // Queue of IOPMRequest objects. queue_head_t RequestHead; @@ -198,9 +182,11 @@ private: thread_call_t AckTimer; thread_call_t SettleTimer; thread_call_t IdleTimer; + thread_call_t WatchdogTimer; // Settle time after changing power state. uint32_t SettleTimeUS; + uint32_t IdleTimerGeneration; // The flags describing current change note. IOPMPowerChangeFlags HeadNoteChangeFlags; @@ -219,7 +205,7 @@ private: // Connection attached to the changing parent. IOPowerConnection * HeadNoteParentConnection; - + // Power flags supplied by the changing parent. IOPMPowerFlags HeadNoteParentFlags; @@ -229,23 +215,27 @@ private: // PM state lock. IOLock * PMLock; - unsigned int InitialPowerChange:1; - unsigned int InitialSetPowerState:1; - unsigned int DeviceOverrideEnabled:1; - unsigned int DoNotPowerDown:1; - unsigned int ParentsKnowState:1; - unsigned int StrictTreeOrder:1; - unsigned int IdleTimerStopped:1; - unsigned int AdjustPowerScheduled:1; - unsigned int IsPreChange:1; - unsigned int DriverCallBusy:1; - unsigned int PCDFunctionOverride:1; - unsigned int IdleTimerIgnored:1; - unsigned int HasAdvisoryDesire:1; - unsigned int AdvisoryTickleUsed:1; + unsigned int InitialPowerChange :1; + unsigned int InitialSetPowerState :1; + unsigned int DeviceOverrideEnabled :1; + unsigned int DoNotPowerDown :1; + unsigned int ParentsKnowState :1; + unsigned int StrictTreeOrder :1; + unsigned int IdleTimerStopped :1; + unsigned int AdjustPowerScheduled :1; + + unsigned int IsPreChange :1; + unsigned int DriverCallBusy :1; + unsigned int PCDFunctionOverride :1; + unsigned int IdleTimerIgnored :1; + unsigned int HasAdvisoryDesire :1; + unsigned int AdvisoryTickleUsed :1; + unsigned int ResetPowerStateOnWake :1; // Time of last device activity. AbsoluteTime DeviceActiveTimestamp; + AbsoluteTime MaxPowerStateEntryTime; + AbsoluteTime MaxPowerStateExitTime; // Used to protect activity flag. IOLock * ActivityLock; @@ -253,6 +243,7 @@ private: // Idle timer's period in seconds. unsigned long IdleTimerPeriod; unsigned long IdleTimerMinPowerState; + unsigned long NextIdleTimerPeriod; AbsoluteTime IdleTimerStartTime; // Power state desired by a subclassed device object. @@ -270,6 +261,9 @@ private: // Number of power states in the power array. IOPMPowerStateIndex NumberOfPowerStates; + // Ordered highest power state in the power array. + IOPMPowerStateIndex HighestPowerState; + // Power state array. IOPMPSEntry * PowerStates; @@ -285,8 +279,8 @@ private: // The highest power state we can achieve in current power domain. IOPMPowerStateIndex MaxPowerState; - // Logical OR of all output power character flags in the array. - IOPMPowerFlags OutputPowerCharacterFlags; + // Logical OR of all output power flags in the power state array. + IOPMPowerFlags MergedOutputPowerFlags; // OSArray which manages responses from notified apps and clients. OSArray * ResponseArray; @@ -316,8 +310,8 @@ private: uint32_t DeviceUsablePowerState; // Protected by ActivityLock - BEGIN - int ActivityTicklePowerState; - int AdvisoryTicklePowerState; + IOPMPowerStateIndex ActivityTicklePowerState; + IOPMPowerStateIndex AdvisoryTicklePowerState; uint32_t ActivityTickleCount; uint32_t DeviceWasActive : 1; uint32_t AdvisoryTickled : 1; @@ -325,7 +319,6 @@ private: uint32_t WaitReason; uint32_t SavedMachineState; - uint32_t RootDomainState; // Protected by PMLock - BEGIN struct { @@ -336,6 +329,10 @@ private: queue_head_t PMDriverCallQueue; OSSet * InsertInterestSet; OSSet * RemoveInterestSet; + + // IOReporter Data + uint32_t ReportClientCnt; + void * ReportBuf; // Protected by PMLock - END #if PM_VARS_SUPPORT @@ -345,8 +342,12 @@ private: IOPMActions PMActions; // Serialize IOServicePM state for debug output. - IOReturn gatedSerialize( OSSerialize * s ); + IOReturn gatedSerialize( OSSerialize * s ) const; virtual bool serialize( OSSerialize * s ) const; + + // PM log and trace + void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; + void pmTrace( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; }; #define fOwner pwrMgt->Owner @@ -356,7 +357,9 @@ private: #define fAckTimer pwrMgt->AckTimer #define fSettleTimer pwrMgt->SettleTimer #define fIdleTimer pwrMgt->IdleTimer +#define fWatchdogTimer pwrMgt->WatchdogTimer #define fSettleTimeUS pwrMgt->SettleTimeUS +#define fIdleTimerGeneration pwrMgt->IdleTimerGeneration #define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags #define fHeadNotePowerState pwrMgt->HeadNotePowerState #define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry @@ -380,22 +383,27 @@ private: #define fIdleTimerIgnored pwrMgt->IdleTimerIgnored #define fHasAdvisoryDesire pwrMgt->HasAdvisoryDesire #define fAdvisoryTickleUsed pwrMgt->AdvisoryTickleUsed +#define fResetPowerStateOnWake pwrMgt->ResetPowerStateOnWake #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp +#define fMaxPowerStateEntryTime pwrMgt->MaxPowerStateEntryTime +#define fMaxPowerStateExitTime pwrMgt->MaxPowerStateExitTime #define fActivityLock pwrMgt->ActivityLock #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod #define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState +#define fNextIdleTimerPeriod pwrMgt->NextIdleTimerPeriod #define fIdleTimerStartTime pwrMgt->IdleTimerStartTime #define fDeviceDesire pwrMgt->DeviceDesire #define fDesiredPowerState pwrMgt->DesiredPowerState #define fPreviousRequestPowerFlags pwrMgt->PreviousRequestPowerFlags #define fName pwrMgt->Name #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates +#define fHighestPowerState pwrMgt->HighestPowerState #define fPowerStates pwrMgt->PowerStates #define fControllingDriver pwrMgt->ControllingDriver #define fCurrentPowerState pwrMgt->CurrentPowerState #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags #define fMaxPowerState pwrMgt->MaxPowerState -#define fOutputPowerCharacterFlags pwrMgt->OutputPowerCharacterFlags +#define fMergedOutputPowerFlags pwrMgt->MergedOutputPowerFlags #define fResponseArray pwrMgt->ResponseArray #define fNotifyClientArray pwrMgt->NotifyClientArray #define fSerialNumber pwrMgt->SerialNumber @@ -422,14 +430,23 @@ private: #define fAdvisoryTickled pwrMgt->AdvisoryTickled #define fWaitReason pwrMgt->WaitReason #define fSavedMachineState pwrMgt->SavedMachineState -#define fRootDomainState pwrMgt->RootDomainState #define fLockedFlags pwrMgt->LockedFlags #define fPMDriverCallQueue pwrMgt->PMDriverCallQueue #define fInsertInterestSet pwrMgt->InsertInterestSet #define fRemoveInterestSet pwrMgt->RemoveInterestSet +#define fReportClientCnt pwrMgt->ReportClientCnt +#define fReportBuf pwrMgt->ReportBuf #define fPMVars pwrMgt->PMVars #define fPMActions pwrMgt->PMActions +#define StateOrder(state) (((state) < fNumberOfPowerStates) \ + ? pwrMgt->PowerStates[(state)].stateOrder \ + : (state)) +#define StateMax(a,b) (StateOrder((a)) < StateOrder((b)) ? (b) : (a)) +#define StateMin(a,b) (StateOrder((a)) < StateOrder((b)) ? (a) : (b)) + +#define kPowerStateZero (0) + /* When an IOService is waiting for acknowledgement to a power change notification from an interested driver or the controlling driver, @@ -438,17 +455,19 @@ the ack timer is ticking every tenth of a second. */ #define ACK_TIMER_PERIOD 100000000 +#define WATCHDOG_TIMER_PERIOD (300) // 300 secs + // Max wait time in microseconds for kernel priority and capability clients // with async message handlers to acknowledge. -// +// #define kPriorityClientMaxWait (90 * 1000 * 1000) #define kCapabilityClientMaxWait (240 * 1000 * 1000) // Attributes describing a power state change. // See IOPMPowerChangeFlags data type. // -#define kIOPMParentInitiated 0x0001 // this power change initiated by our parent -#define kIOPMSelfInitiated 0x0002 // this power change initiated by this device +#define kIOPMParentInitiated 0x0001 // power change initiated by our parent +#define kIOPMSelfInitiated 0x0002 // power change initiated by this device #define kIOPMNotDone 0x0004 // we couldn't make this change #define kIOPMDomainWillChange 0x0008 // change started by PowerDomainWillChangeTo #define kIOPMDomainDidChange 0x0010 // change started by PowerDomainDidChangeTo @@ -460,11 +479,24 @@ the ack timer is ticking every tenth of a second. #define kIOPMSyncTellPowerDown 0x0400 // send the ask/will power off messages #define kIOPMSyncCancelPowerDown 0x0800 // sleep cancel for maintenance wake #define kIOPMInitialPowerChange 0x1000 // set for initial power change +#define kIOPMRootChangeUp 0x2000 // Root power domain change up +#define kIOPMRootChangeDown 0x4000 // Root power domain change down +#define kIOPMExpireIdleTimer 0x8000 // Accelerate idle timer expiration + +#define kIOPMRootBroadcastFlags (kIOPMSynchronize | \ + kIOPMRootChangeUp | kIOPMRootChangeDown) + +// Activity tickle request flags +#define kTickleTypePowerDrop 0x01 +#define kTickleTypePowerRise 0x02 +#define kTickleTypeActivity 0x04 +#define kTickleTypeAdvisory 0x08 enum { kDriverCallInformPreChange, kDriverCallInformPostChange, - kDriverCallSetPowerState + kDriverCallSetPowerState, + kRootDomainInformPreChange }; struct DriverCallParam { @@ -513,6 +545,8 @@ enum { extern const OSSymbol *gIOPMStatsApplicationResponseTimedOut; extern const OSSymbol *gIOPMStatsApplicationResponseCancel; extern const OSSymbol *gIOPMStatsApplicationResponseSlow; +extern const OSSymbol *gIOPMStatsApplicationResponsePrompt; +extern const OSSymbol *gIOPMStatsDriverPSChangeSlow; //****************************************************************************** // IOPMRequest @@ -532,12 +566,15 @@ protected: IOItemCount fFreeWaitCount; // completion blocked if non-zero uint32_t fType; // request type +#if NOT_READY IOPMCompletionAction fCompletionAction; void * fCompletionTarget; void * fCompletionParam; IOReturn fCompletionStatus; +#endif public: + uint32_t fRequestTag; void * fArg0; void * fArg1; void * fArg2; @@ -560,7 +597,9 @@ public: inline IOPMRequest * getRootRequest( void ) const { if (fRequestRoot) return fRequestRoot; +#if NOT_READY if (fCompletionAction) return (IOPMRequest *) this; +#endif return 0; } @@ -579,6 +618,7 @@ public: return fTarget; } +#if NOT_READY inline bool isCompletionInstalled( void ) { return (fCompletionAction != 0); @@ -593,6 +633,7 @@ public: fCompletionTarget = target; fCompletionParam = param; } +#endif /* NOT_READY */ static IOPMRequest * create( void ); bool init( IOService * owner, IOOptionBits type );