1 // 2 // Copyright (C) Microsoft. All rights reserved. 3 // 4 #ifndef _FXWAKEINTERRUPTSTATEMACHINE_H_ 5 #define _FXWAKEINTERRUPTSTATEMACHINE_H_ 6 7 // 8 // This is a magical number based on inspection. If the queue overflows, 9 // it is OK to increase these numbers without fear of either dependencies or 10 // weird side affects. 11 // 12 const UCHAR FxWakeInterruptEventQueueDepth = 8; 13 14 enum FxWakeInterruptEvents : UINT32 { 15 WakeInterruptEventInvalid = 0x00, 16 WakeInterruptEventIsr = 0x01, 17 WakeInterruptEventEnteringD0 = 0x02, 18 WakeInterruptEventLeavingD0 = 0x04, 19 WakeInterruptEventD0EntryFailed = 0x08, 20 WakeInterruptEventLeavingD0NotArmedForWake = 0x10, 21 WakeInterruptEventNull = 0xFF, 22 }; 23 24 enum FxWakeInterruptStates { 25 WakeInterruptInvalid = 0, 26 WakeInterruptFailed, 27 WakeInterruptD0, 28 WakeInterruptDx, 29 WakeInterruptWaking, 30 WakeInterruptInvokingEvtIsrPostWake, 31 WakeInterruptCompletingD0, 32 WakeInterruptInvokingEvtIsrInD0, 33 WakeInterruptDxNotArmedForWake, 34 WakeInterruptInvokingEvtIsrInDxNotArmedForWake, 35 WakeInterruptMax 36 }; 37 38 // 39 // Forward declaration 40 // 41 class FxWakeInterruptMachine; 42 class FxInterrupt; 43 44 typedef 45 _Must_inspect_result_ 46 FxWakeInterruptStates 47 (*PFN_WAKE_INTERRUPT_STATE_ENTRY_FUNCTION)( 48 __in FxWakeInterruptMachine* This 49 ); 50 51 struct FxWakeInterruptTargetState { 52 FxWakeInterruptEvents WakeInterruptEvent; 53 54 FxWakeInterruptStates WakeInterruptState; 55 56 #if FX_SUPER_DBG 57 BOOLEAN EventDebugged; 58 #endif 59 }; 60 61 // 62 // This type of union is done so that we can 63 // 1) shrink the array element to the smallest size possible 64 // 2) keep types within the structure so we can dump it in the debugger 65 // 66 union FxWakeInterruptMachineStateHistory { 67 struct { 68 FxWakeInterruptStates State1 : 8; 69 FxWakeInterruptStates State2 : 8; 70 FxWakeInterruptStates State3 : 8; 71 FxWakeInterruptStates State4 : 8; 72 FxWakeInterruptStates State5 : 8; 73 FxWakeInterruptStates State6 : 8; 74 FxWakeInterruptStates State7 : 8; 75 FxWakeInterruptStates State8 : 8; 76 } S; 77 78 UCHAR History[FxWakeInterruptEventQueueDepth]; 79 }; 80 81 struct FxWakeInterruptStateTable { 82 PFN_WAKE_INTERRUPT_STATE_ENTRY_FUNCTION StateFunc; 83 84 const FxWakeInterruptTargetState* TargetStates; 85 86 ULONG TargetStatesCount; 87 }; 88 89 class FxWakeInterruptMachine : public FxThreadedEventQueue { 90 91 friend FxInterrupt; 92 93 public: 94 FxWakeInterruptMachine( 95 __in FxInterrupt * Interrupt 96 ); 97 98 VOID 99 ProcessEvent( 100 __in FxWakeInterruptEvents Event 101 ); 102 103 static 104 VOID 105 _ProcessEventInner( 106 __inout FxPkgPnp* PkgPnp, 107 __inout FxPostProcessInfo* Info, 108 __in PVOID WorkerContext 109 ); 110 111 private: 112 VOID 113 ProcessEventInner( 114 __inout FxPostProcessInfo* Info 115 ); 116 117 static 118 FxWakeInterruptStates 119 Waking( 120 __in FxWakeInterruptMachine* This 121 ); 122 123 static 124 FxWakeInterruptStates 125 Dx( 126 __in FxWakeInterruptMachine* This 127 ); 128 129 static 130 FxWakeInterruptStates 131 DxNotArmedForWake( 132 __in FxWakeInterruptMachine* This 133 ); 134 135 static 136 FxWakeInterruptStates 137 Failed( 138 __in FxWakeInterruptMachine* This 139 ); 140 141 static 142 FxWakeInterruptStates 143 InvokingEvtIsrPostWake( 144 __in FxWakeInterruptMachine* This 145 ); 146 147 static 148 FxWakeInterruptStates 149 InvokingEvtIsrInDxNotArmedForWake( 150 __in FxWakeInterruptMachine* This 151 ); 152 153 static 154 FxWakeInterruptStates 155 InvokingEvtIsrInD0( 156 __in FxWakeInterruptMachine* This 157 ); 158 159 static 160 FxWakeInterruptStates 161 CompletingD0( 162 __in FxWakeInterruptMachine* This 163 ); 164 165 protected: 166 //FxPkgPnp* m_PkgPnp; 167 FxInterrupt* m_Interrupt; 168 // 169 // Set if the interrupt was left active during Dx transition to handle wake 170 // events. 171 // 172 BOOLEAN m_ActiveForWake; 173 BOOLEAN m_Claimed; 174 MxEvent m_IsrEvent; 175 176 // uses FxWakeInterruptStates values 177 BYTE m_CurrentState; 178 179 // three extra padded bytes are put in here by the compiler 180 181 FxWakeInterruptEvents m_Queue[FxWakeInterruptEventQueueDepth]; 182 FxWakeInterruptMachineStateHistory m_States; 183 184 static const FxWakeInterruptStateTable m_StateTable[]; 185 186 static const FxWakeInterruptTargetState m_FailedStates[]; 187 static const FxWakeInterruptTargetState m_D0States[]; 188 static const FxWakeInterruptTargetState m_DxStates[]; 189 static const FxWakeInterruptTargetState m_DxNotArmedForWakeStates[]; 190 static const FxWakeInterruptTargetState m_WakingStates[]; 191 static const FxWakeInterruptTargetState m_InvokingEvtIsrPostWakeStates[]; 192 static const FxWakeInterruptTargetState m_CompletingD0States[]; 193 static const FxWakeInterruptTargetState m_InvokingIsrInD0[]; 194 }; 195 196 #endif // _FXWAKEINTERRUPTSTATEMACHINE_H_ 197