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