]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkModulePkg/Universal/PCD/Pei/Service.c
Make EDK Module Package pass Intel IPF compiler with /Ox switch.
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Pei / Service.c
... / ...
CommitLineData
1/** @file\r
2Private functions used by PCD PEIM.\r
3\r
4Copyright (c) 2006, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13\r
14Module Name: Service.c\r
15\r
16**/\r
17#include "Service.h"\r
18\r
19/**\r
20 The function registers the CallBackOnSet fucntion\r
21 according to TokenNumber and EFI_GUID space.\r
22\r
23 @param TokenNumber The token number.\r
24 @param Guid The GUID space.\r
25 @param CallBackFunction The Callback function to be registered.\r
26 @param Register To register or unregister the callback function.\r
27\r
28 @retval EFI_SUCCESS If the Callback function is registered.\r
29 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.\r
30 @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free\r
31 slot left in the CallbackFnTable.\r
32--*/\r
33EFI_STATUS\r
34PeiRegisterCallBackWorker (\r
35 IN UINTN ExTokenNumber,\r
36 IN CONST EFI_GUID *Guid, OPTIONAL\r
37 IN PCD_PPI_CALLBACK CallBackFunction,\r
38 IN BOOLEAN Register\r
39)\r
40{\r
41 EFI_HOB_GUID_TYPE *GuidHob;\r
42 PCD_PPI_CALLBACK *CallbackTable;\r
43 PCD_PPI_CALLBACK Compare;\r
44 PCD_PPI_CALLBACK Assign;\r
45 UINT32 LocalTokenNumber;\r
46 UINTN TokenNumber;\r
47 UINTN Idx;\r
48\r
49 if (Guid == NULL) {\r
50 TokenNumber = ExTokenNumber;\r
51\r
52 //\r
53 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
54 // We have to decrement TokenNumber by 1 to make it usable\r
55 // as the array index.\r
56 //\r
57 TokenNumber--;\r
58 ASSERT (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1);\r
59 } else {\r
60 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
61\r
62 //\r
63 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
64 // We have to decrement TokenNumber by 1 to make it usable\r
65 // as the array index.\r
66 //\r
67 TokenNumber--;\r
68 // EBC compiler is very choosy. It may report warning about comparison\r
69 // between UINTN and 0 . So we add 1 in each size of the \r
70 // comparison.\r
71 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
72 }\r
73\r
74\r
75 LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber];\r
76\r
77 //\r
78 // We don't support SET for HII and VPD type PCD entry in PEI phase.\r
79 // So we will assert if any register callback for such PCD entry.\r
80 //\r
81 ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0);\r
82 ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0);\r
83\r
84 GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
85 ASSERT (GuidHob != NULL);\r
86 \r
87 CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
88 CallbackTable = CallbackTable + (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
89\r
90 Compare = Register? NULL: CallBackFunction;\r
91 Assign = Register? CallBackFunction: NULL;\r
92\r
93\r
94 for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
95 if (CallbackTable[Idx] == Compare) {\r
96 CallbackTable[Idx] = Assign;\r
97 return EFI_SUCCESS;\r
98 }\r
99 }\r
100\r
101 return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND;\r
102\r
103}\r
104\r
105\r
106\r
107\r
108/**\r
109 The function builds the PCD database.\r
110\r
111 @param VOID\r
112\r
113 @retval VOID\r
114--*/\r
115VOID\r
116BuildPcdDatabase (\r
117 VOID\r
118 )\r
119{\r
120 PEI_PCD_DATABASE *Database;\r
121 VOID *CallbackFnTable;\r
122 UINTN SizeOfCallbackFnTable;\r
123 \r
124 Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE));\r
125\r
126 ZeroMem (Database, sizeof (PEI_PCD_DATABASE));\r
127\r
128 //\r
129 // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE\r
130 //\r
131 \r
132 CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit));\r
133\r
134 SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry);\r
135\r
136 CallbackFnTable = BuildGuidHob (&gPcdPeiCallbackFnTableHobGuid, SizeOfCallbackFnTable);\r
137 \r
138 ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);\r
139 \r
140 return;\r
141}\r
142\r
143\r
144\r
145/**\r
146 The function is provided by PCD PEIM and PCD DXE driver to\r
147 do the work of reading a HII variable from variable service.\r
148\r
149 @param VariableGuid The Variable GUID.\r
150 @param VariableName The Variable Name.\r
151 @param VariableData The output data.\r
152 @param VariableSize The size of the variable.\r
153\r
154 @retval EFI_SUCCESS Operation successful.\r
155 @retval EFI_NOT_FOUND Variablel not found.\r
156--*/\r
157STATIC\r
158EFI_STATUS\r
159GetHiiVariable (\r
160 IN CONST EFI_GUID *VariableGuid,\r
161 IN UINT16 *VariableName,\r
162 OUT VOID **VariableData,\r
163 OUT UINTN *VariableSize\r
164 )\r
165{\r
166 UINTN Size;\r
167 EFI_STATUS Status;\r
168 VOID *Buffer;\r
169 EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;\r
170\r
171 Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, (VOID **) &VariablePpi);\r
172 ASSERT_EFI_ERROR (Status);\r
173\r
174 Size = 0;\r
175 Status = VariablePpi->PeiGetVariable (\r
176 GetPeiServicesTablePointer (),\r
177 VariableName,\r
178 (EFI_GUID *) VariableGuid,\r
179 NULL,\r
180 &Size,\r
181 NULL\r
182 );\r
183 if (Status == EFI_BUFFER_TOO_SMALL) {\r
184\r
185\r
186 Status = PeiServicesAllocatePool (Size, &Buffer);\r
187 ASSERT_EFI_ERROR (Status);\r
188\r
189 Status = VariablePpi->PeiGetVariable (\r
190 GetPeiServicesTablePointer (),\r
191 (UINT16 *) VariableName,\r
192 (EFI_GUID *) VariableGuid,\r
193 NULL,\r
194 &Size,\r
195 Buffer\r
196 );\r
197 ASSERT_EFI_ERROR (Status);\r
198\r
199 *VariableSize = Size;\r
200 *VariableData = Buffer;\r
201\r
202 return EFI_SUCCESS;\r
203 } else {\r
204 return EFI_NOT_FOUND;\r
205 }\r
206\r
207}\r
208\r
209STATIC\r
210UINT32\r
211GetSkuEnabledTokenNumber (\r
212 UINT32 LocalTokenNumber,\r
213 UINTN Size\r
214 ) \r
215{\r
216 PEI_PCD_DATABASE *PeiPcdDb;\r
217 SKU_HEAD *SkuHead;\r
218 SKU_ID *SkuIdTable;\r
219 INTN i;\r
220 UINT8 *Value;\r
221\r
222 PeiPcdDb = GetPcdDatabase ();\r
223\r
224 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
225\r
226 SkuHead = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
227 Value = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));\r
228 SkuIdTable = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));\r
229 \r
230 for (i = 0; i < SkuIdTable[0]; i++) {\r
231 if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[i + 1]) {\r
232 break;\r
233 }\r
234 }\r
235\r
236 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
237 case PCD_TYPE_VPD:\r
238 Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);\r
239 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);\r
240\r
241 case PCD_TYPE_HII:\r
242 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);\r
243 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);\r
244 \r
245 case PCD_TYPE_STRING:\r
246 Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]);\r
247 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);\r
248\r
249 case PCD_TYPE_DATA:\r
250 Value += Size * i;\r
251 return (UINT32) (Value - (UINT8 *) PeiPcdDb);\r
252\r
253 default:\r
254 ASSERT (FALSE);\r
255 }\r
256\r
257 ASSERT (FALSE);\r
258\r
259 return 0;\r
260 \r
261}\r
262\r
263\r
264\r
265STATIC\r
266VOID\r
267InvokeCallbackOnSet (\r
268 UINTN ExTokenNumber,\r
269 CONST EFI_GUID *Guid, OPTIONAL\r
270 UINTN TokenNumber,\r
271 VOID *Data,\r
272 UINTN Size\r
273 )\r
274{\r
275 EFI_HOB_GUID_TYPE *GuidHob;\r
276 PCD_PPI_CALLBACK *CallbackTable;\r
277 UINTN Idx;\r
278\r
279 //\r
280 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
281 // We have to decrement TokenNumber by 1 to make it usable\r
282 // as the array index.\r
283 //\r
284 TokenNumber--;\r
285 \r
286 if (Guid == NULL) {\r
287 // EBC compiler is very choosy. It may report warning about comparison\r
288 // between UINTN and 0 . So we add 1 in each size of the \r
289 // comparison.\r
290 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
291 }\r
292\r
293 GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
294 ASSERT (GuidHob != NULL);\r
295 \r
296 CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
297\r
298 CallbackTable += (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
299\r
300 for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
301 if (CallbackTable[Idx] != NULL) {\r
302 CallbackTable[Idx] (Guid,\r
303 (Guid == NULL)? TokenNumber: ExTokenNumber,\r
304 Data,\r
305 Size\r
306 );\r
307 }\r
308 }\r
309 \r
310}\r
311\r
312\r
313\r
314EFI_STATUS\r
315SetValueWorker (\r
316 IN UINTN TokenNumber,\r
317 IN VOID *Data,\r
318 IN UINTN Size\r
319 )\r
320{\r
321 return SetWorker (TokenNumber, Data, &Size, FALSE);\r
322}\r
323\r
324\r
325\r
326EFI_STATUS\r
327SetWorker (\r
328 IN UINTN TokenNumber,\r
329 IN OUT VOID *Data,\r
330 IN OUT UINTN *Size,\r
331 IN BOOLEAN PtrType\r
332 )\r
333{\r
334 UINT32 LocalTokenNumber;\r
335 PEI_PCD_DATABASE *PeiPcdDb;\r
336 UINT16 StringTableIdx;\r
337 UINTN Offset;\r
338 VOID *InternalData;\r
339 UINTN MaxSize;\r
340\r
341 if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {\r
342 return EFI_UNSUPPORTED;\r
343 }\r
344 \r
345 //\r
346 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
347 // We have to decrement TokenNumber by 1 to make it usable\r
348 // as the array index.\r
349 //\r
350 TokenNumber--;\r
351\r
352 // EBC compiler is very choosy. It may report warning about comparison\r
353 // between UINTN and 0 . So we add 1 in each size of the \r
354 // comparison.\r
355 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
356 \r
357 PeiPcdDb = GetPcdDatabase ();\r
358\r
359 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
360\r
361 if (!PtrType) {\r
362 ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size);\r
363 }\r
364\r
365 //\r
366 // We only invoke the callback function for Dynamic Type PCD Entry.\r
367 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX\r
368 // type PCD entry in ExSetWorker.\r
369 //\r
370 if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {\r
371 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
372 }\r
373\r
374 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
375 if (PtrType) {\r
376 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
377 } else {\r
378 MaxSize = *Size;\r
379 }\r
380 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
381 }\r
382\r
383 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
384 InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);\r
385 \r
386 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
387 case PCD_TYPE_VPD:\r
388 case PCD_TYPE_HII:\r
389 {\r
390 ASSERT (FALSE);\r
391 return EFI_INVALID_PARAMETER;\r
392 }\r
393\r
394 case PCD_TYPE_STRING:\r
395 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
396 StringTableIdx = *((UINT16 *)InternalData);\r
397 CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);\r
398 return EFI_SUCCESS;\r
399 } else {\r
400 return EFI_INVALID_PARAMETER;\r
401 }\r
402\r
403 case PCD_TYPE_DATA:\r
404 {\r
405 if (PtrType) {\r
406 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
407 CopyMem (InternalData, Data, *Size);\r
408 return EFI_SUCCESS;\r
409 } else {\r
410 return EFI_INVALID_PARAMETER;\r
411 }\r
412 }\r
413\r
414 switch (*Size) {\r
415 case sizeof(UINT8):\r
416 *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
417 return EFI_SUCCESS;\r
418\r
419 case sizeof(UINT16):\r
420 *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
421 return EFI_SUCCESS;\r
422\r
423 case sizeof(UINT32):\r
424 *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
425 return EFI_SUCCESS;\r
426\r
427 case sizeof(UINT64):\r
428 *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
429 return EFI_SUCCESS;\r
430\r
431 default:\r
432 ASSERT (FALSE);\r
433 return EFI_NOT_FOUND;\r
434 }\r
435 }\r
436 \r
437 }\r
438\r
439 ASSERT (FALSE);\r
440 return EFI_NOT_FOUND;\r
441\r
442}\r
443\r
444\r
445\r
446EFI_STATUS\r
447ExSetValueWorker (\r
448 IN UINTN ExTokenNumber,\r
449 IN CONST EFI_GUID *Guid,\r
450 IN VOID *Data,\r
451 IN UINTN Size\r
452 )\r
453{\r
454 return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);\r
455}\r
456\r
457\r
458\r
459EFI_STATUS\r
460ExSetWorker (\r
461 IN UINTN ExTokenNumber,\r
462 IN CONST EFI_GUID *Guid,\r
463 IN VOID *Data,\r
464 IN OUT UINTN *Size,\r
465 IN BOOLEAN PtrType\r
466 )\r
467{\r
468 UINTN TokenNumber;\r
469\r
470 if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {\r
471 return EFI_UNSUPPORTED;\r
472 }\r
473\r
474 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
475\r
476 InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);\r
477\r
478 return SetWorker (TokenNumber, Data, Size, PtrType);\r
479\r
480}\r
481\r
482\r
483\r
484\r
485VOID *\r
486ExGetWorker (\r
487 IN CONST EFI_GUID *Guid,\r
488 IN UINTN ExTokenNumber,\r
489 IN UINTN GetSize\r
490 )\r
491{\r
492 if (!FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) {\r
493 ASSERT (FALSE);\r
494 return 0;\r
495 }\r
496 \r
497 return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);\r
498}\r
499\r
500\r
501\r
502\r
503VOID *\r
504GetWorker (\r
505 UINTN TokenNumber,\r
506 UINTN GetSize\r
507 )\r
508{\r
509 UINT32 Offset;\r
510 EFI_GUID *Guid;\r
511 UINT16 *Name;\r
512 VARIABLE_HEAD *VariableHead;\r
513 EFI_STATUS Status;\r
514 UINTN DataSize;\r
515 VOID *Data;\r
516 UINT16 *StringTable;\r
517 UINT16 StringTableIdx;\r
518 PEI_PCD_DATABASE *PeiPcdDb;\r
519 UINT32 LocalTokenNumber;\r
520 UINTN MaxSize;\r
521\r
522 //\r
523 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
524 // We have to decrement TokenNumber by 1 to make it usable\r
525 // as the array index.\r
526 //\r
527 TokenNumber--;\r
528\r
529 // EBC compiler is very choosy. It may report warning about comparison\r
530 // between UINTN and 0 . So we add 1 in each size of the \r
531 // comparison.\r
532 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
533\r
534 ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));\r
535\r
536 PeiPcdDb = GetPcdDatabase ();\r
537\r
538 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
539\r
540 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
541 if (GetSize == 0) {\r
542 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
543 } else {\r
544 MaxSize = GetSize;\r
545 }\r
546 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
547 }\r
548\r
549 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
550 StringTable = PeiPcdDb->Init.StringTable;\r
551 \r
552 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
553 case PCD_TYPE_VPD:\r
554 {\r
555 VPD_HEAD *VpdHead;\r
556 VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
557 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
558 }\r
559 \r
560 case PCD_TYPE_HII:\r
561 {\r
562 VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
563 \r
564 Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);\r
565 Name = &StringTable[VariableHead->StringIndex];\r
566\r
567 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
568\r
569 if (Status == EFI_SUCCESS) {\r
570 return (VOID *) ((UINT8 *) Data + VariableHead->Offset);\r
571 } else {\r
572 //\r
573 // Return the default value specified by Platform Integrator \r
574 //\r
575 return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset);\r
576 }\r
577 }\r
578\r
579 case PCD_TYPE_DATA:\r
580 return (VOID *) ((UINT8 *)PeiPcdDb + Offset);\r
581\r
582 case PCD_TYPE_STRING:\r
583 StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);\r
584 return (VOID *) (&StringTable[StringTableIdx]);\r
585\r
586 default:\r
587 ASSERT (FALSE);\r
588 break;\r
589 \r
590 }\r
591\r
592 ASSERT (FALSE);\r
593 \r
594 return NULL;\r
595 \r
596}\r
597\r
598\r
599\r
600UINTN \r
601GetExPcdTokenNumber (\r
602 IN CONST EFI_GUID *Guid,\r
603 IN UINTN ExTokenNumber\r
604 )\r
605{\r
606 UINT32 i;\r
607 DYNAMICEX_MAPPING *ExMap;\r
608 EFI_GUID *GuidTable;\r
609 EFI_GUID *MatchGuid;\r
610 UINTN MatchGuidIdx;\r
611 PEI_PCD_DATABASE *PeiPcdDb;\r
612\r
613 PeiPcdDb = GetPcdDatabase();\r
614 \r
615 ExMap = PeiPcdDb->Init.ExMapTable;\r
616 GuidTable = PeiPcdDb->Init.GuidTable;\r
617\r
618 MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);\r
619 //\r
620 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
621 // error in the BUILD system.\r
622 //\r
623 ASSERT (MatchGuid != NULL);\r
624 \r
625 MatchGuidIdx = MatchGuid - GuidTable;\r
626 \r
627 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
628 if ((ExTokenNumber == ExMap[i].ExTokenNumber) && \r
629 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
630 return ExMap[i].LocalTokenNumber;\r
631 }\r
632 }\r
633 \r
634 ASSERT (FALSE);\r
635 \r
636 return 0;\r
637}\r
638\r
639\r
640\r
641PEI_PCD_DATABASE *\r
642GetPcdDatabase (\r
643 VOID\r
644 )\r
645{\r
646 EFI_HOB_GUID_TYPE *GuidHob;\r
647\r
648 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
649 ASSERT (GuidHob != NULL);\r
650 \r
651 return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
652}\r
653\r
654\r
655\r
656SKU_ID *\r
657GetSkuIdArray (\r
658 IN UINTN LocalTokenNumberTableIdx,\r
659 IN PEI_PCD_DATABASE *Database\r
660 )\r
661{\r
662 SKU_HEAD *SkuHead;\r
663 UINTN LocalTokenNumber;\r
664\r
665 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
666\r
667 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
668\r
669 SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
670\r
671 return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);\r
672 \r
673}\r
674\r
675\r
676\r
677UINTN\r
678GetSizeTableIndex (\r
679 IN UINTN LocalTokenNumberTableIdx,\r
680 IN PEI_PCD_DATABASE *Database\r
681 )\r
682{\r
683 UINTN i;\r
684 UINTN SizeTableIdx;\r
685 UINTN LocalTokenNumber;\r
686 SKU_ID *SkuIdTable;\r
687 \r
688 SizeTableIdx = 0;\r
689\r
690 for (i=0; i<LocalTokenNumberTableIdx; i++) {\r
691 LocalTokenNumber = Database->Init.LocalTokenNumberTable[i];\r
692\r
693 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {\r
694 //\r
695 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
696 // PCD entry.\r
697 //\r
698 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
699 //\r
700 // We have only one entry for VPD enabled PCD entry:\r
701 // 1) MAX Size.\r
702 // We consider current size is equal to MAX size.\r
703 //\r
704 SizeTableIdx++;\r
705 } else {\r
706 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
707 //\r
708 // We have only two entry for Non-Sku enabled PCD entry:\r
709 // 1) MAX SIZE\r
710 // 2) Current Size\r
711 //\r
712 SizeTableIdx += 2;\r
713 } else {\r
714 //\r
715 // We have these entry for SKU enabled PCD entry\r
716 // 1) MAX SIZE\r
717 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
718 //\r
719 SkuIdTable = GetSkuIdArray (i, Database);\r
720 SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
721 }\r
722 }\r
723 }\r
724\r
725 }\r
726\r
727 return SizeTableIdx;\r
728}\r