]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Universal/PCD/Pei/Service.c
521c88b7fc1e1979b405da12c241d5ab98c60e95
[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 if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {
341 return EFI_UNSUPPORTED;
342 }
343
344 //
345 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
346 // We have to decrement TokenNumber by 1 to make it usable
347 // as the array index.
348 //
349 TokenNumber--;
350
351 // EBC compiler is very choosy. It may report warning about comparison
352 // between UINTN and 0 . So we add 1 in each size of the
353 // comparison.
354 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
355
356 PeiPcdDb = GetPcdDatabase ();
357
358 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];
359
360 if (!PtrType) {
361 ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size);
362 }
363
364 //
365 // We only invoke the callback function for Dynamic Type PCD Entry.
366 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
367 // type PCD entry in ExSetWorker.
368 //
369 if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {
370 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);
371 }
372
373 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
374 if (PtrType) {
375 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);
376 } else {
377 MaxSize = *Size;
378 }
379 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
380 }
381
382 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
383 InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);
384
385 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
386 case PCD_TYPE_VPD:
387 case PCD_TYPE_HII:
388 {
389 ASSERT (FALSE);
390 return EFI_INVALID_PARAMETER;
391 }
392
393 case PCD_TYPE_STRING:
394 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {
395 StringTableIdx = *((UINT16 *)InternalData);
396 CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);
397 return EFI_SUCCESS;
398 } else {
399 return EFI_INVALID_PARAMETER;
400 }
401
402 case PCD_TYPE_DATA:
403 {
404 if (PtrType) {
405 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {
406 CopyMem (InternalData, Data, *Size);
407 return EFI_SUCCESS;
408 } else {
409 return EFI_INVALID_PARAMETER;
410 }
411 }
412
413 switch (*Size) {
414 case sizeof(UINT8):
415 *((UINT8 *) InternalData) = *((UINT8 *) Data);
416 return EFI_SUCCESS;
417
418 case sizeof(UINT16):
419 *((UINT16 *) InternalData) = *((UINT16 *) Data);
420 return EFI_SUCCESS;
421
422 case sizeof(UINT32):
423 *((UINT32 *) InternalData) = *((UINT32 *) Data);
424 return EFI_SUCCESS;
425
426 case sizeof(UINT64):
427 *((UINT64 *) InternalData) = *((UINT64 *) Data);
428 return EFI_SUCCESS;
429
430 default:
431 ASSERT (FALSE);
432 return EFI_NOT_FOUND;
433 }
434 }
435
436 }
437
438 ASSERT (FALSE);
439 return EFI_NOT_FOUND;
440
441 }
442
443
444
445 EFI_STATUS
446 ExSetValueWorker (
447 IN UINTN ExTokenNumber,
448 IN CONST EFI_GUID *Guid,
449 IN VOID *Data,
450 IN UINTN Size
451 )
452 {
453 return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);
454 }
455
456
457
458 EFI_STATUS
459 ExSetWorker (
460 IN UINTN ExTokenNumber,
461 IN CONST EFI_GUID *Guid,
462 IN VOID *Data,
463 IN OUT UINTN *Size,
464 IN BOOLEAN PtrType
465 )
466 {
467 UINTN TokenNumber;
468
469 if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {
470 return EFI_UNSUPPORTED;
471 }
472
473 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);
474
475 InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);
476
477 return SetWorker (TokenNumber, Data, Size, PtrType);
478
479 }
480
481
482
483
484 VOID *
485 ExGetWorker (
486 IN CONST EFI_GUID *Guid,
487 IN UINTN ExTokenNumber,
488 IN UINTN GetSize
489 )
490 {
491 if (!FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) {
492 ASSERT (FALSE);
493 return 0;
494 }
495
496 return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);
497 }
498
499
500
501
502 VOID *
503 GetWorker (
504 UINTN TokenNumber,
505 UINTN GetSize
506 )
507 {
508 UINT32 Offset;
509 EFI_GUID *Guid;
510 UINT16 *Name;
511 VARIABLE_HEAD *VariableHead;
512 EFI_STATUS Status;
513 UINTN DataSize;
514 VOID *Data;
515 UINT16 *StringTable;
516 UINT16 StringTableIdx;
517 PEI_PCD_DATABASE *PeiPcdDb;
518 UINT32 LocalTokenNumber;
519 UINTN MaxSize;
520
521 //
522 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
523 // We have to decrement TokenNumber by 1 to make it usable
524 // as the array index.
525 //
526 TokenNumber--;
527
528 // EBC compiler is very choosy. It may report warning about comparison
529 // between UINTN and 0 . So we add 1 in each size of the
530 // comparison.
531 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
532
533 ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));
534
535 PeiPcdDb = GetPcdDatabase ();
536
537 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];
538
539 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
540 if (GetSize == 0) {
541 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);
542 } else {
543 MaxSize = GetSize;
544 }
545 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
546 }
547
548 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
549 StringTable = PeiPcdDb->Init.StringTable;
550
551 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
552 case PCD_TYPE_VPD:
553 {
554 VPD_HEAD *VpdHead;
555 VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);
556 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);
557 }
558
559 case PCD_TYPE_HII:
560 {
561 VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);
562
563 Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);
564 Name = &StringTable[VariableHead->StringIndex];
565
566 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
567
568 if (Status == EFI_SUCCESS) {
569 return (VOID *) ((UINT8 *) Data + VariableHead->Offset);
570 } else {
571 //
572 // Return the default value specified by Platform Integrator
573 //
574 return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset);
575 }
576 }
577
578 case PCD_TYPE_DATA:
579 return (VOID *) ((UINT8 *)PeiPcdDb + Offset);
580
581 case PCD_TYPE_STRING:
582 StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);
583 return (VOID *) (&StringTable[StringTableIdx]);
584
585 default:
586 ASSERT (FALSE);
587 break;
588
589 }
590
591 ASSERT (FALSE);
592
593 return NULL;
594
595 }
596
597
598
599 UINTN
600 GetExPcdTokenNumber (
601 IN CONST EFI_GUID *Guid,
602 IN UINTN ExTokenNumber
603 )
604 {
605 UINT32 i;
606 DYNAMICEX_MAPPING *ExMap;
607 EFI_GUID *GuidTable;
608 EFI_GUID *MatchGuid;
609 UINTN MatchGuidIdx;
610 PEI_PCD_DATABASE *PeiPcdDb;
611
612 PeiPcdDb = GetPcdDatabase();
613
614 ExMap = PeiPcdDb->Init.ExMapTable;
615 GuidTable = PeiPcdDb->Init.GuidTable;
616
617 MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);
618 //
619 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
620 // error in the BUILD system.
621 //
622 ASSERT (MatchGuid != NULL);
623
624 MatchGuidIdx = MatchGuid - GuidTable;
625
626 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {
627 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&
628 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {
629 return ExMap[i].LocalTokenNumber;
630 }
631 }
632
633 ASSERT (FALSE);
634
635 return 0;
636 }
637
638
639
640 PEI_PCD_DATABASE *
641 GetPcdDatabase (
642 VOID
643 )
644 {
645 EFI_HOB_GUID_TYPE *GuidHob;
646
647 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
648 ASSERT (GuidHob != NULL);
649
650 return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
651 }
652
653
654
655 SKU_ID *
656 GetSkuIdArray (
657 IN UINTN LocalTokenNumberTableIdx,
658 IN PEI_PCD_DATABASE *Database
659 )
660 {
661 SKU_HEAD *SkuHead;
662 UINTN LocalTokenNumber;
663
664 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
665
666 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);
667
668 SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
669
670 return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);
671
672 }
673
674
675
676 UINTN
677 GetSizeTableIndex (
678 IN UINTN LocalTokenNumberTableIdx,
679 IN PEI_PCD_DATABASE *Database
680 )
681 {
682 UINTN i;
683 UINTN SizeTableIdx;
684 UINTN LocalTokenNumber;
685 SKU_ID *SkuIdTable;
686
687 SizeTableIdx = 0;
688
689 for (i=0; i<LocalTokenNumberTableIdx; i++) {
690 LocalTokenNumber = Database->Init.LocalTokenNumberTable[i];
691
692 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {
693 //
694 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
695 // PCD entry.
696 //
697 if (LocalTokenNumber & PCD_TYPE_VPD) {
698 //
699 // We have only one entry for VPD enabled PCD entry:
700 // 1) MAX Size.
701 // We consider current size is equal to MAX size.
702 //
703 SizeTableIdx++;
704 } else {
705 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
706 //
707 // We have only two entry for Non-Sku enabled PCD entry:
708 // 1) MAX SIZE
709 // 2) Current Size
710 //
711 SizeTableIdx += 2;
712 } else {
713 //
714 // We have these entry for SKU enabled PCD entry
715 // 1) MAX SIZE
716 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
717 //
718 SkuIdTable = GetSkuIdArray (i, Database);
719 SizeTableIdx += (UINTN)*SkuIdTable + 1;
720 }
721 }
722 }
723
724 }
725
726 return SizeTableIdx;
727 }
728
729
730
731
732 UINTN
733 GetPtrTypeSize (
734 IN UINTN LocalTokenNumberTableIdx,
735 OUT UINTN *MaxSize,
736 IN PEI_PCD_DATABASE *Database
737 )
738 {
739 INTN SizeTableIdx;
740 UINTN LocalTokenNumber;
741 SKU_ID *SkuIdTable;
742 SIZE_INFO *SizeTable;
743 UINTN i;
744
745 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);
746
747 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
748
749 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
750
751 SizeTable = Database->Init.SizeTable;
752
753 *MaxSize = SizeTable[SizeTableIdx];
754 //
755 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
756 // PCD entry.
757 //
758 if (LocalTokenNumber & PCD_TYPE_VPD) {
759 //
760 // We have only one entry for VPD enabled PCD entry:
761 // 1) MAX Size.
762 // We consider current size is equal to MAX size.
763 //
764 return *MaxSize;
765 } else {
766 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
767 //
768 // We have only two entry for Non-Sku enabled PCD entry:
769 // 1) MAX SIZE
770 // 2) Current Size
771 //
772 return SizeTable[SizeTableIdx + 1];
773 } else {
774 //
775 // We have these entry for SKU enabled PCD entry
776 // 1) MAX SIZE
777 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
778 //
779 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);
780 for (i = 0; i < SkuIdTable[0]; i++) {
781 if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) {
782 return SizeTable[SizeTableIdx + 1 + i];
783 }
784 }
785 return SizeTable[SizeTableIdx + 1];
786 }
787 }
788 }
789
790
791
792 BOOLEAN
793 SetPtrTypeSize (
794 IN UINTN LocalTokenNumberTableIdx,
795 IN OUT UINTN *CurrentSize,
796 IN PEI_PCD_DATABASE *Database
797 )
798 {
799 INTN SizeTableIdx;
800 UINTN LocalTokenNumber;
801 SKU_ID *SkuIdTable;
802 SIZE_INFO *SizeTable;
803 UINTN i;
804 UINTN MaxSize;
805
806 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);
807
808 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
809
810 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
811
812 SizeTable = Database->Init.SizeTable;
813
814 MaxSize = SizeTable[SizeTableIdx];
815 //
816 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
817 // PCD entry.
818 //
819 if (LocalTokenNumber & PCD_TYPE_VPD) {
820 //
821 // We shouldn't come here as we don't support SET for VPD
822 //
823 ASSERT (FALSE);
824 return FALSE;
825 } else {
826 if ((*CurrentSize > MaxSize) ||
827 (*CurrentSize == MAX_ADDRESS)) {
828 *CurrentSize = MaxSize;
829 return FALSE;
830 }
831
832 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
833 //
834 // We have only two entry for Non-Sku enabled PCD entry:
835 // 1) MAX SIZE
836 // 2) Current Size
837 //
838 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;
839 return TRUE;
840 } else {
841 //
842 // We have these entry for SKU enabled PCD entry
843 // 1) MAX SIZE
844 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
845 //
846 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);
847 for (i = 0; i < SkuIdTable[0]; i++) {
848 if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) {
849 SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize;
850 return TRUE;
851 }
852 }
853 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;
854 return TRUE;
855 }
856 }
857
858 }