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