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