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