// // Copyright (C) Microsoft. All rights reserved. // #ifndef _FXWAKEINTERRUPTSTATEMACHINE_H_ #define _FXWAKEINTERRUPTSTATEMACHINE_H_ // // This is a magical number based on inspection. If the queue overflows, // it is OK to increase these numbers without fear of either dependencies or // weird side affects. // const UCHAR FxWakeInterruptEventQueueDepth = 8; enum FxWakeInterruptEvents : UINT32 { WakeInterruptEventInvalid = 0x00, WakeInterruptEventIsr = 0x01, WakeInterruptEventEnteringD0 = 0x02, WakeInterruptEventLeavingD0 = 0x04, WakeInterruptEventD0EntryFailed = 0x08, WakeInterruptEventLeavingD0NotArmedForWake = 0x10, WakeInterruptEventNull = 0xFF, }; enum FxWakeInterruptStates { WakeInterruptInvalid = 0, WakeInterruptFailed, WakeInterruptD0, WakeInterruptDx, WakeInterruptWaking, WakeInterruptInvokingEvtIsrPostWake, WakeInterruptCompletingD0, WakeInterruptInvokingEvtIsrInD0, WakeInterruptDxNotArmedForWake, WakeInterruptInvokingEvtIsrInDxNotArmedForWake, WakeInterruptMax }; // // Forward declaration // class FxWakeInterruptMachine; class FxInterrupt; typedef _Must_inspect_result_ FxWakeInterruptStates (*PFN_WAKE_INTERRUPT_STATE_ENTRY_FUNCTION)( __in FxWakeInterruptMachine* This ); struct FxWakeInterruptTargetState { FxWakeInterruptEvents WakeInterruptEvent; FxWakeInterruptStates WakeInterruptState; #if FX_SUPER_DBG BOOLEAN EventDebugged; #endif }; // // This type of union is done so that we can // 1) shrink the array element to the smallest size possible // 2) keep types within the structure so we can dump it in the debugger // union FxWakeInterruptMachineStateHistory { struct { FxWakeInterruptStates State1 : 8; FxWakeInterruptStates State2 : 8; FxWakeInterruptStates State3 : 8; FxWakeInterruptStates State4 : 8; FxWakeInterruptStates State5 : 8; FxWakeInterruptStates State6 : 8; FxWakeInterruptStates State7 : 8; FxWakeInterruptStates State8 : 8; } S; UCHAR History[FxWakeInterruptEventQueueDepth]; }; struct FxWakeInterruptStateTable { PFN_WAKE_INTERRUPT_STATE_ENTRY_FUNCTION StateFunc; const FxWakeInterruptTargetState* TargetStates; ULONG TargetStatesCount; }; class FxWakeInterruptMachine : public FxThreadedEventQueue { friend FxInterrupt; public: FxWakeInterruptMachine( __in FxInterrupt * Interrupt ); VOID ProcessEvent( __in FxWakeInterruptEvents Event ); static VOID _ProcessEventInner( __inout FxPkgPnp* PkgPnp, __inout FxPostProcessInfo* Info, __in PVOID WorkerContext ); private: VOID ProcessEventInner( __inout FxPostProcessInfo* Info ); static FxWakeInterruptStates Waking( __in FxWakeInterruptMachine* This ); static FxWakeInterruptStates Dx( __in FxWakeInterruptMachine* This ); static FxWakeInterruptStates DxNotArmedForWake( __in FxWakeInterruptMachine* This ); static FxWakeInterruptStates Failed( __in FxWakeInterruptMachine* This ); static FxWakeInterruptStates InvokingEvtIsrPostWake( __in FxWakeInterruptMachine* This ); static FxWakeInterruptStates InvokingEvtIsrInDxNotArmedForWake( __in FxWakeInterruptMachine* This ); static FxWakeInterruptStates InvokingEvtIsrInD0( __in FxWakeInterruptMachine* This ); static FxWakeInterruptStates CompletingD0( __in FxWakeInterruptMachine* This ); protected: //FxPkgPnp* m_PkgPnp; FxInterrupt* m_Interrupt; // // Set if the interrupt was left active during Dx transition to handle wake // events. // BOOLEAN m_ActiveForWake; BOOLEAN m_Claimed; MxEvent m_IsrEvent; // uses FxWakeInterruptStates values BYTE m_CurrentState; // three extra padded bytes are put in here by the compiler FxWakeInterruptEvents m_Queue[FxWakeInterruptEventQueueDepth]; FxWakeInterruptMachineStateHistory m_States; static const FxWakeInterruptStateTable m_StateTable[]; static const FxWakeInterruptTargetState m_FailedStates[]; static const FxWakeInterruptTargetState m_D0States[]; static const FxWakeInterruptTargetState m_DxStates[]; static const FxWakeInterruptTargetState m_DxNotArmedForWakeStates[]; static const FxWakeInterruptTargetState m_WakingStates[]; static const FxWakeInterruptTargetState m_InvokingEvtIsrPostWakeStates[]; static const FxWakeInterruptTargetState m_CompletingD0States[]; static const FxWakeInterruptTargetState m_InvokingIsrInD0[]; }; #endif // _FXWAKEINTERRUPTSTATEMACHINE_H_