TianoCore EDK2 master
Loading...
Searching...
No Matches
Dependency.c
Go to the documentation of this file.
1
13#include "PeiMain.h"
14#include "Dependency.h"
15
30BOOLEAN
32 IN EFI_PEI_SERVICES **PeiServices,
33 IN EVAL_STACK_ENTRY *Stack
34 )
35{
36 VOID *PeiInstance;
37 EFI_STATUS Status;
38 EFI_GUID PpiGuid;
39
40 //
41 // If there is no GUID to evaluate, just return current result on stack.
42 //
43 if (Stack->Operator == NULL) {
44 return Stack->Result;
45 }
46
47 //
48 // Copy the GUID into a local variable so that there are no
49 // possibilities of alignment faults for cross-compilation
50 // environments such as Intel?Itanium(TM).
51 //
52 CopyMem (&PpiGuid, Stack->Operator, sizeof (EFI_GUID));
53
54 //
55 // Check if the PPI is installed.
56 //
57 Status = PeiServicesLocatePpi (
58 &PpiGuid, // GUID
59 0, // INSTANCE
60 NULL, // EFI_PEI_PPI_DESCRIPTOR
61 &PeiInstance // PPI
62 );
63
64 if (EFI_ERROR (Status)) {
65 return FALSE;
66 }
67
68 return TRUE;
69}
70
91BOOLEAN
93 IN EFI_PEI_SERVICES **PeiServices,
94 IN VOID *DependencyExpression
95 )
96{
97 DEPENDENCY_EXPRESSION_OPERAND *Iterator;
98 EVAL_STACK_ENTRY *StackPtr;
99 EVAL_STACK_ENTRY EvalStack[MAX_GRAMMAR_SIZE];
100
101 Iterator = DependencyExpression;
102
103 StackPtr = EvalStack;
104
105 while (TRUE) {
106 switch (*(Iterator++)) {
107 //
108 // For performance reason we put the frequently used items in front of
109 // the rarely used items
110 //
111
112 case (EFI_DEP_PUSH):
113 //
114 // Check to make sure the dependency grammar doesn't overflow the
115 // EvalStack on the push
116 //
117 if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
118 DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Underflow Error)\n"));
119 return FALSE;
120 }
121
122 //
123 // Push the pointer to the PUSH opcode operator (pointer to PPI GUID)
124 // We will evaluate if the PPI is installed on the POP operation.
125 //
126 StackPtr->Operator = (VOID *)Iterator;
127 Iterator = Iterator + sizeof (EFI_GUID);
128 DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = %a\n", StackPtr->Operator, IsPpiInstalled (PeiServices, StackPtr) ? "TRUE" : "FALSE"));
129 StackPtr++;
130 break;
131
132 case (EFI_DEP_AND):
133 case (EFI_DEP_OR):
134 if (*(Iterator - 1) == EFI_DEP_AND) {
135 DEBUG ((DEBUG_DISPATCH, " AND\n"));
136 } else {
137 DEBUG ((DEBUG_DISPATCH, " OR\n"));
138 }
139
140 //
141 // Check to make sure the dependency grammar doesn't underflow the
142 // EvalStack on the two POPs for the AND operation. Don't need to
143 // check for the overflow on PUSHing the result since we already
144 // did two POPs.
145 //
146 if (StackPtr < &EvalStack[2]) {
147 DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Underflow Error)\n"));
148 return FALSE;
149 }
150
151 //
152 // Evaluate the first POPed operator only. If the operand is
153 // EFI_DEP_AND and the POPed operator evaluates to FALSE, or the
154 // operand is EFI_DEP_OR and the POPed operator evaluates to TRUE,
155 // we don't need to check the second operator, and the result will be
156 // evaluation of the POPed operator. Otherwise, don't POP the second
157 // operator since it will now evaluate to the final result on the
158 // next operand that causes a POP.
159 //
160 StackPtr--;
161 //
162 // Iterator has increased by 1 after we retrieve the operand, so here we
163 // should get the value pointed by (Iterator - 1), in order to obtain the
164 // same operand.
165 //
166 if (*(Iterator - 1) == EFI_DEP_AND) {
167 if (!(IsPpiInstalled (PeiServices, StackPtr))) {
168 (StackPtr-1)->Result = FALSE;
169 (StackPtr-1)->Operator = NULL;
170 }
171 } else {
172 if (IsPpiInstalled (PeiServices, StackPtr)) {
173 (StackPtr-1)->Result = TRUE;
174 (StackPtr-1)->Operator = NULL;
175 }
176 }
177
178 break;
179
180 case (EFI_DEP_END):
181 DEBUG ((DEBUG_DISPATCH, " END\n"));
182 StackPtr--;
183 //
184 // Check to make sure EvalStack is balanced. If not, then there is
185 // an error in the dependency grammar, so return EFI_INVALID_PARAMETER.
186 //
187 if (StackPtr != &EvalStack[0]) {
188 DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Underflow Error)\n"));
189 return FALSE;
190 }
191
192 DEBUG ((DEBUG_DISPATCH, " RESULT = %a\n", IsPpiInstalled (PeiServices, StackPtr) ? "TRUE" : "FALSE"));
193 return IsPpiInstalled (PeiServices, StackPtr);
194
195 case (EFI_DEP_NOT):
196 DEBUG ((DEBUG_DISPATCH, " NOT\n"));
197 //
198 // Check to make sure the dependency grammar doesn't underflow the
199 // EvalStack on the POP for the NOT operation. Don't need to
200 // check for the overflow on PUSHing the result since we already
201 // did a POP.
202 //
203 if (StackPtr < &EvalStack[1]) {
204 DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Underflow Error)\n"));
205 return FALSE;
206 }
207
208 (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));
209 (StackPtr-1)->Operator = NULL;
210 break;
211
212 case (EFI_DEP_TRUE):
213 case (EFI_DEP_FALSE):
214 if (*(Iterator - 1) == EFI_DEP_TRUE) {
215 DEBUG ((DEBUG_DISPATCH, " TRUE\n"));
216 } else {
217 DEBUG ((DEBUG_DISPATCH, " FALSE\n"));
218 }
219
220 //
221 // Check to make sure the dependency grammar doesn't overflow the
222 // EvalStack on the push
223 //
224 if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
225 DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Underflow Error)\n"));
226 return FALSE;
227 }
228
229 //
230 // Iterator has increased by 1 after we retrieve the operand, so here we
231 // should get the value pointed by (Iterator - 1), in order to obtain the
232 // same operand.
233 //
234 if (*(Iterator - 1) == EFI_DEP_TRUE) {
235 StackPtr->Result = TRUE;
236 } else {
237 StackPtr->Result = FALSE;
238 }
239
240 StackPtr->Operator = NULL;
241 StackPtr++;
242 break;
243
244 default:
245 DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Invalid opcode)\n"));
246 //
247 // The grammar should never arrive here
248 //
249 return FALSE;
250 }
251 }
252}
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
BOOLEAN PeimDispatchReadiness(IN EFI_PEI_SERVICES **PeiServices, IN VOID *DependencyExpression)
Definition: Dependency.c:92
BOOLEAN IsPpiInstalled(IN EFI_PEI_SERVICES **PeiServices, IN EVAL_STACK_ENTRY *Stack)
Definition: Dependency.c:31
#define NULL
Definition: Base.h:319
#define VOID
Definition: Base.h:269
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:435
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
GUID EFI_GUID
Definition: UefiBaseType.h:25
Definition: Base.h:213