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