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