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