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