1 //
2 //    Copyright (C) Microsoft.  All rights reserved.
3 //
4 #ifndef _FXDEVICEPWRREQUIRESTATEMACHINE_H_
5 #define _FXDEVICEPWRREQUIRESTATEMACHINE_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 FxDevicePwrRequirementEventQueueDepth = 8;
13 
14 enum FxDevicePwrRequirementEvents {
15     DprEventInvalid                 = 0x00,
16     DprEventRegisteredWithPox       = 0x01,
17     DprEventUnregisteredWithPox     = 0x02,
18     DprEventPoxRequiresPower        = 0x04,
19     DprEventPoxDoesNotRequirePower  = 0x08,
20     DprEventDeviceGoingToDx         = 0x10,
21     DprEventDeviceReturnedToD0      = 0x20,
22     DprEventNull                    = 0xFF,
23 };
24 
25 enum FxDevicePwrRequirementStates {
26     DprInvalid = 0,
27     DprUnregistered,
28     DprDevicePowerRequiredD0,
29     DprDevicePowerNotRequiredD0,
30     DprDevicePowerNotRequiredDx,
31     DprDevicePowerRequiredDx,
32     DprReportingDevicePowerAvailable,
33     DprWaitingForDevicePowerRequiredD0,
34     DprMax
35 };
36 
37 //
38 // Forward declaration
39 //
40 class FxDevicePwrRequirementMachine;
41 class FxPoxInterface;
42 
43 typedef
44 _Must_inspect_result_
45 FxDevicePwrRequirementStates
46 (*PFN_DEVICE_POWER_REQUIREMENT_STATE_ENTRY_FUNCTION)(
47     __in FxDevicePwrRequirementMachine* This
48     );
49 
50 struct FxDevicePwrRequirementTargetState {
51     FxDevicePwrRequirementEvents DprEvent;
52 
53     FxDevicePwrRequirementStates DprState;
54 
55 #if FX_SUPER_DBG
56     BOOLEAN EventDebugged;
57 #endif
58 };
59 
60 //
61 // This type of union is done so that we can
62 // 1) shrink the array element to the smallest size possible
63 // 2) keep types within the structure so we can dump it in the debugger
64 //
65 union FxDevicePwrRequirementMachineStateHistory {
66     struct {
67         FxDevicePwrRequirementStates State1 : 8;
68         FxDevicePwrRequirementStates State2 : 8;
69         FxDevicePwrRequirementStates State3 : 8;
70         FxDevicePwrRequirementStates State4 : 8;
71         FxDevicePwrRequirementStates State5 : 8;
72         FxDevicePwrRequirementStates State6 : 8;
73         FxDevicePwrRequirementStates State7 : 8;
74         FxDevicePwrRequirementStates State8 : 8;
75     } S;
76 
77     UCHAR History[FxDevicePwrRequirementEventQueueDepth];
78 };
79 
80 struct FxDevicePwrRequirementStateTable {
81     PFN_DEVICE_POWER_REQUIREMENT_STATE_ENTRY_FUNCTION StateFunc;
82 
83     const FxDevicePwrRequirementTargetState* TargetStates;
84 
85     ULONG TargetStatesCount;
86 };
87 
88 class FxDevicePwrRequirementMachine : public FxThreadedEventQueue {
89 
90 public:
91     FxDevicePwrRequirementMachine(
92         __in FxPoxInterface * PoxInterface
93         );
94 
95     VOID
96     ProcessEvent(
97         __in FxDevicePwrRequirementEvents Event
98         );
99 
100     static
101     VOID
102     _ProcessEventInner(
103         __inout FxPkgPnp* PkgPnp,
104         __inout FxPostProcessInfo* Info,
105         __in PVOID WorkerContext
106         );
107 
108 private:
109     VOID
110     ProcessEventInner(
111         __inout FxPostProcessInfo* Info
112         );
113 
114     static
115     FxDevicePwrRequirementStates
116     PowerNotRequiredD0(
117         __in FxDevicePwrRequirementMachine* This
118         );
119 
120     static
121     FxDevicePwrRequirementStates
122     PowerRequiredDx(
123         __in FxDevicePwrRequirementMachine* This
124         );
125 
126     static
127     FxDevicePwrRequirementStates
128     ReportingDevicePowerAvailable(
129         __in FxDevicePwrRequirementMachine* This
130         );
131 
132 protected:
133     FxPoxInterface* m_PoxInterface;
134 
135     // uses FxDevicePwrRequirementStates values
136     BYTE m_CurrentState;
137 
138     // three extra padded bytes are put in here by the compiler
139 
140     FxDevicePwrRequirementEvents m_Queue[FxDevicePwrRequirementEventQueueDepth];
141     FxDevicePwrRequirementMachineStateHistory m_States;
142 
143     static const FxDevicePwrRequirementStateTable m_StateTable[];
144 
145     static const FxDevicePwrRequirementTargetState m_UnregisteredStates[];
146     static const FxDevicePwrRequirementTargetState m_DevicePowerRequiredD0States[];
147     static const FxDevicePwrRequirementTargetState m_DevicePowerNotRequiredD0States[];
148     static const FxDevicePwrRequirementTargetState m_DevicePowerNotRequiredDxStates[];
149     static const FxDevicePwrRequirementTargetState m_DevicePowerRequiredDxStates[];
150     static const FxDevicePwrRequirementTargetState m_WaitingForDevicePowerRequiredD0States[];
151 };
152 
153 #endif // _FXDEVICEPWRREQUIRESTATEMACHINE_H_
154