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