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