]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParserExpression.c
1) Add in support for Framework VFR file which specify all VAR Store correctly. This...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / UefiIfrParserExpression.c
CommitLineData
59336178 1/** @file\r
2\r
3Copyright (c) 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 Expression.c\r
15\r
16Abstract:\r
17\r
18 Expression evaluation.\r
19\r
20\r
21**/\r
22#include <PiDxe.h>\r
23#include <Library/BaseLib.h>\r
24#include <Library/BaseMemoryLib.h>\r
25#include <Library/DebugLib.h>\r
26#include <Library/MemoryAllocationLib.h>\r
27#include <Library/PrintLib.h>\r
28#include <Library/UefiBootServicesTableLib.h>\r
29#include <Protocol/UnicodeCollation.h>\r
30 \r
31#include "UefiIfrParser.h"\r
32#include "UefiIfrParserExpressionInternal.h"\r
59336178 33\r
34//\r
35// Global stack used to evaluate boolean expresions\r
36//\r
37EFI_HII_VALUE *mOpCodeScopeStack = NULL;\r
38EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;\r
39EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;\r
40\r
41EFI_HII_VALUE *mExpressionEvaluationStack = NULL;\r
42EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;\r
43EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;\r
44\r
a9d85320 45#define EXPRESSION_STACK_SIZE_INCREMENT 0x100\r
59336178 46\r
47\r
48/**\r
49 Grow size of the stack\r
50\r
51 @param Stack On input: old stack; On output: new stack\r
52 @param StackPtr On input: old stack pointer; On output: new stack\r
53 pointer\r
54 @param StackPtr On input: old stack end; On output: new stack end\r
55\r
56 @retval EFI_SUCCESS Grow stack success.\r
57 @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.\r
58\r
59**/\r
60STATIC\r
61EFI_STATUS\r
62GrowStack (\r
63 IN OUT EFI_HII_VALUE **Stack,\r
64 IN OUT EFI_HII_VALUE **StackPtr,\r
65 IN OUT EFI_HII_VALUE **StackEnd\r
66 )\r
67{\r
68 UINTN Size;\r
69 EFI_HII_VALUE *NewStack;\r
70\r
71 Size = EXPRESSION_STACK_SIZE_INCREMENT;\r
72 if (*StackPtr != NULL) {\r
73 Size = Size + (*StackEnd - *Stack);\r
74 }\r
75\r
76 NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));\r
77 if (NewStack == NULL) {\r
78 return EFI_OUT_OF_RESOURCES;\r
79 }\r
80\r
81 if (*StackPtr != NULL) {\r
82 //\r
83 // Copy from Old Stack to the New Stack\r
84 //\r
85 CopyMem (\r
86 NewStack,\r
87 *Stack,\r
88 (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)\r
89 );\r
90\r
91 //\r
92 // Free The Old Stack\r
93 //\r
94 gBS->FreePool (*Stack);\r
95 }\r
96\r
97 //\r
98 // Make the Stack pointer point to the old data in the new stack\r
99 //\r
100 *StackPtr = NewStack + (*StackPtr - *Stack);\r
101 *Stack = NewStack;\r
102 *StackEnd = NewStack + Size;\r
103\r
104 return EFI_SUCCESS;\r
105}\r
106\r
107\r
108/**\r
109 Push an element onto the Boolean Stack\r
110\r
111 @param Stack On input: old stack; On output: new stack\r
112 @param StackPtr On input: old stack pointer; On output: new stack\r
113 pointer\r
114 @param StackPtr On input: old stack end; On output: new stack end\r
115 @param Data Data to push.\r
116\r
117 @retval EFI_SUCCESS Push stack success.\r
118\r
119**/\r
120EFI_STATUS\r
121PushStack (\r
122 IN OUT EFI_HII_VALUE **Stack,\r
123 IN OUT EFI_HII_VALUE **StackPtr,\r
124 IN OUT EFI_HII_VALUE **StackEnd,\r
125 IN EFI_HII_VALUE *Data\r
126 )\r
127{\r
128 EFI_STATUS Status;\r
129\r
130 //\r
131 // Check for a stack overflow condition\r
132 //\r
133 if (*StackPtr >= *StackEnd) {\r
134 //\r
135 // Grow the stack\r
136 //\r
137 Status = GrowStack (Stack, StackPtr, StackEnd);\r
138 if (EFI_ERROR (Status)) {\r
139 return Status;\r
140 }\r
141 }\r
142\r
143 //\r
144 // Push the item onto the stack\r
145 //\r
146 CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));\r
147 *StackPtr = *StackPtr + 1;\r
148\r
149 return EFI_SUCCESS;\r
150}\r
151\r
152\r
153/**\r
154 Pop an element from the stack.\r
155\r
156 @param Stack On input: old stack; On output: new stack\r
157 @param StackPtr On input: old stack pointer; On output: new stack\r
158 pointer\r
159 @param StackPtr On input: old stack end; On output: new stack end\r
160 @param Data Data to pop.\r
161\r
162 @retval EFI_SUCCESS The value was popped onto the stack.\r
163 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
164\r
165**/\r
166EFI_STATUS\r
167PopStack (\r
168 IN OUT EFI_HII_VALUE **Stack,\r
169 IN OUT EFI_HII_VALUE **StackPtr,\r
170 IN OUT EFI_HII_VALUE **StackEnd,\r
171 OUT EFI_HII_VALUE *Data\r
172 )\r
173{\r
174 //\r
175 // Check for a stack underflow condition\r
176 //\r
177 if (*StackPtr == *Stack) {\r
178 return EFI_ACCESS_DENIED;\r
179 }\r
180\r
181 //\r
182 // Pop the item off the stack\r
183 //\r
184 *StackPtr = *StackPtr - 1;\r
185 CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE));\r
186 return EFI_SUCCESS;\r
187}\r
188\r
59336178 189/**\r
190 Reset stack pointer to begin of the stack.\r
191\r
192 None.\r
193\r
194 @return None.\r
195\r
196**/\r
197VOID\r
198ResetScopeStack (\r
199 VOID\r
200 )\r
201{\r
202 mOpCodeScopeStackPointer = mOpCodeScopeStack;\r
203}\r
204\r
205\r
206/**\r
207 Push an Operand onto the Stack\r
208\r
209 @param Operand Operand to push.\r
210\r
211 @retval EFI_SUCCESS The value was pushed onto the stack.\r
212 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
213 stack.\r
214\r
215**/\r
216EFI_STATUS\r
217PushScope (\r
218 IN UINT8 Operand\r
219 )\r
220{\r
221 EFI_HII_VALUE Data;\r
222\r
223 Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
224 Data.Value.u8 = Operand;\r
225\r
226 return PushStack (\r
227 &mOpCodeScopeStack,\r
228 &mOpCodeScopeStackPointer,\r
229 &mOpCodeScopeStackEnd,\r
230 &Data\r
231 );\r
232}\r
233\r
234\r
235/**\r
236 Pop an Operand from the Stack\r
237\r
238 @param Operand Operand to pop.\r
239\r
240 @retval EFI_SUCCESS The value was pushed onto the stack.\r
241 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
242 stack.\r
243\r
244**/\r
245EFI_STATUS\r
246PopScope (\r
247 OUT UINT8 *Operand\r
248 )\r
249{\r
250 EFI_STATUS Status;\r
251 EFI_HII_VALUE Data;\r
252\r
253 Status = PopStack (\r
254 &mOpCodeScopeStack,\r
255 &mOpCodeScopeStackPointer,\r
256 &mOpCodeScopeStackEnd,\r
257 &Data\r
258 );\r
259\r
260 *Operand = Data.Value.u8;\r
261\r
262 return Status;\r
263}\r
264\r
265\r
266/**\r
267 Reset stack pointer to begin of the stack.\r
268\r
269 None.\r
270\r
271 @return None.\r
272\r
273**/\r
274VOID\r
275ResetExpressionStack (\r
276 VOID\r
277 )\r
278{\r
279 mExpressionEvaluationStackPointer = mExpressionEvaluationStack;\r
280}\r
281\r
282\r
283/**\r
284 Push an Expression value onto the Stack\r
285\r
286 @param Value Expression value to push.\r
287\r
288 @retval EFI_SUCCESS The value was pushed onto the stack.\r
289 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
290 stack.\r
291\r
292**/\r
293EFI_STATUS\r
294PushExpression (\r
295 IN EFI_HII_VALUE *Value\r
296 )\r
297{\r
298 return PushStack (\r
299 &mExpressionEvaluationStack,\r
300 &mExpressionEvaluationStackPointer,\r
301 &mExpressionEvaluationStackEnd,\r
302 Value\r
303 );\r
304}\r
305\r
306\r
307/**\r
308 Pop an Expression value from the stack.\r
309\r
310 @param Value Expression value to pop.\r
311\r
312 @retval EFI_SUCCESS The value was popped onto the stack.\r
313 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
314\r
315**/\r
316EFI_STATUS\r
317PopExpression (\r
318 OUT EFI_HII_VALUE *Value\r
319 )\r
320{\r
321 return PopStack (\r
322 &mExpressionEvaluationStack,\r
323 &mExpressionEvaluationStackPointer,\r
324 &mExpressionEvaluationStackEnd,\r
325 Value\r
326 );\r
327}\r
328\r
59336178 329/**\r
330 Zero extend integer/boolean/date/time to UINT64 for comparing.\r
331\r
332 @param Value HII Value to be converted.\r
333\r
334 @return None.\r
335\r
336**/\r
337VOID\r
338ExtendValueToU64 (\r
339 IN EFI_HII_VALUE *Value\r
340 )\r
341{\r
342 UINT64 Temp;\r
343\r
344 Temp = 0;\r
345 switch (Value->Type) {\r
346 case EFI_IFR_TYPE_NUM_SIZE_8:\r
347 Temp = Value->Value.u8;\r
348 break;\r
349\r
350 case EFI_IFR_TYPE_NUM_SIZE_16:\r
351 Temp = Value->Value.u16;\r
352 break;\r
353\r
354 case EFI_IFR_TYPE_NUM_SIZE_32:\r
355 Temp = Value->Value.u32;\r
356 break;\r
357\r
358 case EFI_IFR_TYPE_BOOLEAN:\r
359 Temp = Value->Value.b;\r
360 break;\r
361\r
362 case EFI_IFR_TYPE_TIME:\r
363 Temp = Value->Value.u32 & 0xffffff;\r
364 break;\r
365\r
366 case EFI_IFR_TYPE_DATE:\r
367 Temp = Value->Value.u32;\r
368 break;\r
369\r
370 default:\r
371 return;\r
372 }\r
373\r
374 Value->Value.u64 = Temp;\r
375}\r