]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Universal/PCD/Pei/Service.c
Partially make EdkModulePkg pass intel IPF compiler with /W4 /WX switched on.
[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 STATIC
158 EFI_STATUS
159 GetHiiVariable (
160 IN CONST EFI_GUID *VariableGuid,
161 IN UINT16 *VariableName,
162 OUT VOID **VariableData,
163 OUT UINTN *VariableSize
164 )
165 {
166 UINTN Size;
167 EFI_STATUS Status;
168 VOID *Buffer;
169 EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;
170
171 Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, (VOID **) &VariablePpi);
172 ASSERT_EFI_ERROR (Status);
173
174 Size = 0;
175 Status = VariablePpi->PeiGetVariable (
176 GetPeiServicesTablePointer (),
177 VariableName,
178 (EFI_GUID *) VariableGuid,
179 NULL,
180 &Size,
181 NULL
182 );
183 if (Status == EFI_BUFFER_TOO_SMALL) {
184
185
186 Status = PeiServicesAllocatePool (Size, &Buffer);
187 ASSERT_EFI_ERROR (Status);
188
189 Status = VariablePpi->PeiGetVariable (
190 GetPeiServicesTablePointer (),
191 (UINT16 *) VariableName,
192 (EFI_GUID *) VariableGuid,
193 NULL,
194 &Size,
195 Buffer
196 );
197 ASSERT_EFI_ERROR (Status);
198
199 *VariableSize = Size;
200 *VariableData = Buffer;
201
202 return EFI_SUCCESS;
203 } else {
204 return EFI_NOT_FOUND;
205 }
206
207 }
208
209 STATIC
210 UINT32
211 GetSkuEnabledTokenNumber (
212 UINT32 LocalTokenNumber,
213 UINTN Size
214 )
215 {
216 PEI_PCD_DATABASE *PeiPcdDb;
217 SKU_HEAD *SkuHead;
218 SKU_ID *SkuIdTable;
219 INTN i;
220 UINT8 *Value;
221
222 PeiPcdDb = GetPcdDatabase ();
223
224 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);
225
226 SkuHead = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
227 Value = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));
228 SkuIdTable = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));
229
230 for (i = 0; i < SkuIdTable[0]; i++) {
231 if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[i + 1]) {
232 break;
233 }
234 }
235
236 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
237 case PCD_TYPE_VPD:
238 Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);
239 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);
240
241 case PCD_TYPE_HII:
242 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);
243 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);
244
245 case PCD_TYPE_STRING:
246 Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]);
247 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);
248
249 case PCD_TYPE_DATA:
250 Value += Size * i;
251 return (UINT32) (Value - (UINT8 *) PeiPcdDb);
252
253 default:
254 ASSERT (FALSE);
255 }
256
257 ASSERT (FALSE);
258
259 return 0;
260
261 }
262
263
264
265 STATIC
266 VOID
267 InvokeCallbackOnSet (
268 UINTN ExTokenNumber,
269 CONST EFI_GUID *Guid, OPTIONAL
270 UINTN TokenNumber,
271 VOID *Data,
272 UINTN Size
273 )
274 {
275 EFI_HOB_GUID_TYPE *GuidHob;
276 PCD_PPI_CALLBACK *CallbackTable;
277 UINTN Idx;
278
279 //
280 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
281 // We have to decrement TokenNumber by 1 to make it usable
282 // as the array index.
283 //
284 TokenNumber--;
285
286 if (Guid == NULL) {
287 // EBC compiler is very choosy. It may report warning about comparison
288 // between UINTN and 0 . So we add 1 in each size of the
289 // comparison.
290 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
291 }
292
293 GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);
294 ASSERT (GuidHob != NULL);
295
296 CallbackTable = GET_GUID_HOB_DATA (GuidHob);
297
298 CallbackTable += (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));
299
300 for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {
301 if (CallbackTable[Idx] != NULL) {
302 CallbackTable[Idx] (Guid,
303 (Guid == NULL)? TokenNumber: ExTokenNumber,
304 Data,
305 Size
306 );
307 }
308 }
309
310 }
311
312
313
314 EFI_STATUS
315 SetValueWorker (
316 IN UINTN TokenNumber,
317 IN VOID *Data,
318 IN UINTN Size
319 )
320 {
321 return SetWorker (TokenNumber, Data, &Size, FALSE);
322 }
323
324
325
326 EFI_STATUS
327 SetWorker (
328 IN UINTN TokenNumber,
329 IN OUT VOID *Data,
330 IN OUT UINTN *Size,
331 IN BOOLEAN PtrType
332 )
333 {
334 UINT32 LocalTokenNumber;
335 PEI_PCD_DATABASE *PeiPcdDb;
336 UINT16 StringTableIdx;
337 UINTN Offset;
338 VOID *InternalData;
339 UINTN MaxSize;
340
341 if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {
342 return EFI_UNSUPPORTED;
343 }
344
345 //
346 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
347 // We have to decrement TokenNumber by 1 to make it usable
348 // as the array index.
349 //
350 TokenNumber--;
351
352 // EBC compiler is very choosy. It may report warning about comparison
353 // between UINTN and 0 . So we add 1 in each size of the
354 // comparison.
355 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
356
357 PeiPcdDb = GetPcdDatabase ();
358
359 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];
360
361 if (!PtrType) {
362 ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size);
363 }
364
365 //
366 // We only invoke the callback function for Dynamic Type PCD Entry.
367 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
368 // type PCD entry in ExSetWorker.
369 //
370 if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {
371 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);
372 }
373
374 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
375 if (PtrType) {
376 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);
377 } else {
378 MaxSize = *Size;
379 }
380 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
381 }
382
383 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
384 InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);
385
386 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
387 case PCD_TYPE_VPD:
388 case PCD_TYPE_HII:
389 {
390 ASSERT (FALSE);
391 return EFI_INVALID_PARAMETER;
392 }
393
394 case PCD_TYPE_STRING:
395 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {
396 StringTableIdx = *((UINT16 *)InternalData);
397 CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);
398 return EFI_SUCCESS;
399 } else {
400 return EFI_INVALID_PARAMETER;
401 }
402
403 case PCD_TYPE_DATA:
404 {
405 if (PtrType) {
406 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {
407 CopyMem (InternalData, Data, *Size);
408 return EFI_SUCCESS;
409 } else {
410 return EFI_INVALID_PARAMETER;
411 }
412 }
413
414 switch (*Size) {
415 case sizeof(UINT8):
416 *((UINT8 *) InternalData) = *((UINT8 *) Data);
417 return EFI_SUCCESS;
418
419 case sizeof(UINT16):
420 *((UINT16 *) InternalData) = *((UINT16 *) Data);
421 return EFI_SUCCESS;
422
423 case sizeof(UINT32):
424 *((UINT32 *) InternalData) = *((UINT32 *) Data);
425 return EFI_SUCCESS;
426
427 case sizeof(UINT64):
428 *((UINT64 *) InternalData) = *((UINT64 *) Data);
429 return EFI_SUCCESS;
430
431 default:
432 ASSERT (FALSE);
433 return EFI_NOT_FOUND;
434 }
435 }
436
437 }
438
439 ASSERT (FALSE);
440 return EFI_NOT_FOUND;
441
442 }
443
444
445
446 EFI_STATUS
447 ExSetValueWorker (
448 IN UINTN ExTokenNumber,
449 IN CONST EFI_GUID *Guid,
450 IN VOID *Data,
451 IN UINTN Size
452 )
453 {
454 return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);
455 }
456
457
458
459 EFI_STATUS
460 ExSetWorker (
461 IN UINTN ExTokenNumber,
462 IN CONST EFI_GUID *Guid,
463 IN VOID *Data,
464 IN OUT UINTN *Size,
465 IN BOOLEAN PtrType
466 )
467 {
468 UINTN TokenNumber;
469
470 if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {
471 return EFI_UNSUPPORTED;
472 }
473
474 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);
475
476 InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);
477
478 return SetWorker (TokenNumber, Data, Size, PtrType);
479
480 }
481
482
483
484
485 VOID *
486 ExGetWorker (
487 IN CONST EFI_GUID *Guid,
488 IN UINTN ExTokenNumber,
489 IN UINTN GetSize
490 )
491 {
492 if (!FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) {
493 ASSERT (FALSE);
494 return 0;
495 }
496
497 return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);
498 }
499
500
501
502
503 VOID *
504 GetWorker (
505 UINTN TokenNumber,
506 UINTN GetSize
507 )
508 {
509 UINT32 Offset;
510 EFI_GUID *Guid;
511 UINT16 *Name;
512 VARIABLE_HEAD *VariableHead;
513 EFI_STATUS Status;
514 UINTN DataSize;
515 VOID *Data;
516 UINT16 *StringTable;
517 UINT16 StringTableIdx;
518 PEI_PCD_DATABASE *PeiPcdDb;
519 UINT32 LocalTokenNumber;
520 UINTN MaxSize;
521
522 //
523 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
524 // We have to decrement TokenNumber by 1 to make it usable
525 // as the array index.
526 //
527 TokenNumber--;
528
529 // EBC compiler is very choosy. It may report warning about comparison
530 // between UINTN and 0 . So we add 1 in each size of the
531 // comparison.
532 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
533
534 ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));
535
536 PeiPcdDb = GetPcdDatabase ();
537
538 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];
539
540 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
541 if (GetSize == 0) {
542 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);
543 } else {
544 MaxSize = GetSize;
545 }
546 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
547 }
548
549 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
550 StringTable = PeiPcdDb->Init.StringTable;
551
552 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
553 case PCD_TYPE_VPD:
554 {
555 VPD_HEAD *VpdHead;
556 VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);
557 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);
558 }
559
560 case PCD_TYPE_HII:
561 {
562 VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);
563
564 Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);
565 Name = &StringTable[VariableHead->StringIndex];
566
567 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
568
569 if (Status == EFI_SUCCESS) {
570 return (VOID *) ((UINT8 *) Data + VariableHead->Offset);
571 } else {
572 //
573 // Return the default value specified by Platform Integrator
574 //
575 return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset);
576 }
577 }
578
579 case PCD_TYPE_DATA:
580 return (VOID *) ((UINT8 *)PeiPcdDb + Offset);
581
582 case PCD_TYPE_STRING:
583 StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);
584 return (VOID *) (&StringTable[StringTableIdx]);
585
586 default:
587 ASSERT (FALSE);
588 break;
589
590 }
591
592 ASSERT (FALSE);
593
594 return NULL;
595
596 }
597
598
599
600 UINTN
601 GetExPcdTokenNumber (
602 IN CONST EFI_GUID *Guid,
603 IN UINTN ExTokenNumber
604 )
605 {
606 UINT32 i;
607 DYNAMICEX_MAPPING *ExMap;
608 EFI_GUID *GuidTable;
609 EFI_GUID *MatchGuid;
610 UINTN MatchGuidIdx;
611 PEI_PCD_DATABASE *PeiPcdDb;
612
613 PeiPcdDb = GetPcdDatabase();
614
615 ExMap = PeiPcdDb->Init.ExMapTable;
616 GuidTable = PeiPcdDb->Init.GuidTable;
617
618 MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);
619 //
620 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
621 // error in the BUILD system.
622 //
623 ASSERT (MatchGuid != NULL);
624
625 MatchGuidIdx = MatchGuid - GuidTable;
626
627 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {
628 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&
629 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {
630 return ExMap[i].LocalTokenNumber;
631 }
632 }
633
634 ASSERT (FALSE);
635
636 return 0;
637 }
638
639
640
641 PEI_PCD_DATABASE *
642 GetPcdDatabase (
643 VOID
644 )
645 {
646 EFI_HOB_GUID_TYPE *GuidHob;
647
648 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
649 ASSERT (GuidHob != NULL);
650
651 return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
652 }
653
654
655 STATIC
656 SKU_ID *
657 GetSkuIdArray (
658 IN UINTN LocalTokenNumberTableIdx,
659 IN PEI_PCD_DATABASE *Database
660 )
661 {
662 SKU_HEAD *SkuHead;
663 UINTN LocalTokenNumber;
664
665 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
666
667 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);
668
669 SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
670
671 return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);
672
673 }
674
675
676 STATIC
677 UINTN
678 GetSizeTableIndex (
679 IN UINTN LocalTokenNumberTableIdx,
680 IN PEI_PCD_DATABASE *Database
681 )
682 {
683 UINTN i;
684 UINTN SizeTableIdx;
685 UINTN LocalTokenNumber;
686 SKU_ID *SkuIdTable;
687
688 SizeTableIdx = 0;
689
690 for (i=0; i<LocalTokenNumberTableIdx; i++) {
691 LocalTokenNumber = Database->Init.LocalTokenNumberTable[i];
692
693 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {
694 //
695 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
696 // PCD entry.
697 //
698 if (LocalTokenNumber & PCD_TYPE_VPD) {
699 //
700 // We have only one entry for VPD enabled PCD entry:
701 // 1) MAX Size.
702 // We consider current size is equal to MAX size.
703 //
704 SizeTableIdx++;
705 } else {
706 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
707 //
708 // We have only two entry for Non-Sku enabled PCD entry:
709 // 1) MAX SIZE
710 // 2) Current Size
711 //
712 SizeTableIdx += 2;
713 } else {
714 //
715 // We have these entry for SKU enabled PCD entry
716 // 1) MAX SIZE
717 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
718 //
719 SkuIdTable = GetSkuIdArray (i, Database);
720 SizeTableIdx += (UINTN)*SkuIdTable + 1;
721 }
722 }
723 }
724
725 }
726
727 return SizeTableIdx;
728 }
729
730
731
732
733 UINTN
734 GetPtrTypeSize (
735 IN UINTN LocalTokenNumberTableIdx,
736 OUT UINTN *MaxSize,
737 IN PEI_PCD_DATABASE *Database
738 )
739 {
740 INTN SizeTableIdx;
741 UINTN LocalTokenNumber;
742 SKU_ID *SkuIdTable;
743 SIZE_INFO *SizeTable;
744 UINTN i;
745
746 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);
747
748 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
749
750 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
751
752 SizeTable = Database->Init.SizeTable;
753
754 *MaxSize = SizeTable[SizeTableIdx];
755 //
756 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
757 // PCD entry.
758 //
759 if (LocalTokenNumber & PCD_TYPE_VPD) {
760 //
761 // We have only one entry for VPD enabled PCD entry:
762 // 1) MAX Size.
763 // We consider current size is equal to MAX size.
764 //
765 return *MaxSize;
766 } else {
767 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
768 //
769 // We have only two entry for Non-Sku enabled PCD entry:
770 // 1) MAX SIZE
771 // 2) Current Size
772 //
773 return SizeTable[SizeTableIdx + 1];
774 } else {
775 //
776 // We have these entry for SKU enabled PCD entry
777 // 1) MAX SIZE
778 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
779 //
780 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);
781 for (i = 0; i < SkuIdTable[0]; i++) {
782 if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) {
783 return SizeTable[SizeTableIdx + 1 + i];
784 }
785 }
786 return SizeTable[SizeTableIdx + 1];
787 }
788 }
789 }
790
791
792
793 BOOLEAN
794 SetPtrTypeSize (
795 IN UINTN LocalTokenNumberTableIdx,
796 IN OUT UINTN *CurrentSize,
797 IN PEI_PCD_DATABASE *Database
798 )
799 {
800 INTN SizeTableIdx;
801 UINTN LocalTokenNumber;
802 SKU_ID *SkuIdTable;
803 SIZE_INFO *SizeTable;
804 UINTN i;
805 UINTN MaxSize;
806
807 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);
808
809 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
810
811 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
812
813 SizeTable = Database->Init.SizeTable;
814
815 MaxSize = SizeTable[SizeTableIdx];
816 //
817 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
818 // PCD entry.
819 //
820 if (LocalTokenNumber & PCD_TYPE_VPD) {
821 //
822 // We shouldn't come here as we don't support SET for VPD
823 //
824 ASSERT (FALSE);
825 return FALSE;
826 } else {
827 if ((*CurrentSize > MaxSize) ||
828 (*CurrentSize == MAX_ADDRESS)) {
829 *CurrentSize = MaxSize;
830 return FALSE;
831 }
832
833 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
834 //
835 // We have only two entry for Non-Sku enabled PCD entry:
836 // 1) MAX SIZE
837 // 2) Current Size
838 //
839 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;
840 return TRUE;
841 } else {
842 //
843 // We have these entry for SKU enabled PCD entry
844 // 1) MAX SIZE
845 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
846 //
847 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);
848 for (i = 0; i < SkuIdTable[0]; i++) {
849 if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) {
850 SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize;
851 return TRUE;
852 }
853 }
854 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;
855 return TRUE;
856 }
857 }
858
859 }