]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/PCD/Dxe/Service.c
Fix some typo.
[mirror_edk2.git] / MdeModulePkg / Universal / PCD / Dxe / Service.c
1 /** @file
2 Help functions used by PCD DXE driver.
3
4 Copyright (c) 2006 - 2007, 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
15 #include "Service.h"
16
17 PCD_DATABASE * mPcdDatabase;
18
19 LIST_ENTRY *mCallbackFnTable;
20
21 /**
22 Get the PCD entry pointer in PCD database.
23
24 This routine will visit PCD database to find the PCD entry according to given
25 token number. The given token number is autogened by build tools and it will be
26 translated to local token number. Local token number contains PCD's type and
27 offset of PCD entry in PCD database.
28
29 @param TokenNumber Token's number, it is autogened by build tools
30 @param GetSize The size of token's value
31
32 @return PCD entry pointer in PCD database
33
34 **/
35 VOID *
36 GetWorker (
37 IN UINTN TokenNumber,
38 IN UINTN GetSize
39 )
40 {
41 UINT32 *LocalTokenNumberTable;
42 EFI_GUID *GuidTable;
43 UINT16 *StringTable;
44 EFI_GUID *Guid;
45 UINT16 *Name;
46 VARIABLE_HEAD *VariableHead;
47 UINT8 *VaraiableDefaultBuffer;
48 UINT8 *Data;
49 VPD_HEAD *VpdHead;
50 UINT8 *PcdDb;
51 VOID *RetPtr;
52 UINTN MaxSize;
53 UINTN TmpTokenNumber;
54 UINTN DataSize;
55 EFI_STATUS Status;
56 UINT32 LocalTokenNumber;
57 UINT32 Offset;
58 UINT16 StringTableIdx;
59 BOOLEAN IsPeiDb;
60
61 //
62 // Aquire lock to prevent reentrance from TPL_CALLBACK level
63 //
64 EfiAcquireLock (&mPcdDatabaseLock);
65
66 RetPtr = NULL;
67 //
68 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
69 // We have to decrement TokenNumber by 1 to make it usable
70 // as the array index.
71 //
72 TokenNumber--;
73
74 TmpTokenNumber = TokenNumber;
75
76 //
77 // PCD_TOTAL_TOKEN_NUMBER is a auto-generated constant.
78 // It could be zero. EBC compiler is very choosy. It may
79 // report warning. So we add 1 in each size of the
80 // comparison.
81 //
82 ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);
83
84 ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0));
85
86 // EBC compiler is very choosy. It may report warning about comparison
87 // between UINTN and 0 . So we add 1 in each size of the
88 // comparison.
89 IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);
90
91 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
92 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
93
94 TokenNumber = IsPeiDb ? TokenNumber :
95 TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
96
97 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
98
99 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
100 if (GetSize == 0) {
101 GetPtrTypeSize (TmpTokenNumber, &MaxSize);
102 } else {
103 MaxSize = GetSize;
104 }
105 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);
106 }
107
108 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);
109 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :
110 mPcdDatabase->DxeDb.Init.StringTable;
111
112 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
113
114 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
115 case PCD_TYPE_VPD:
116 VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset);
117 RetPtr = (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);
118 break;
119
120 case PCD_TYPE_HII:
121 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :
122 mPcdDatabase->DxeDb.Init.GuidTable;
123
124 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
125
126 Guid = &(GuidTable[VariableHead->GuidTableIndex]);
127 Name = &(StringTable[VariableHead->StringIndex]);
128 VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset;
129
130 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
131 if (Status == EFI_SUCCESS) {
132 if (GetSize == 0) {
133 //
134 // It is a pointer type. So get the MaxSize reserved for
135 // this PCD entry.
136 //
137 GetPtrTypeSize (TmpTokenNumber, &GetSize);
138 }
139 CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
140 FreePool (Data);
141 }
142 //
143 // If the operation is successful, we copy the data
144 // to the default value buffer in the PCD Database.
145 // So that we can free the Data allocated in GetHiiVariable.
146 //
147 //
148 // If the operation is not successful,
149 // Return 1) either the default value specified by Platform Integrator
150 // 2) Or the value Set by a PCD set operation.
151 //
152 RetPtr = (VOID *) VaraiableDefaultBuffer;
153 break;
154
155 case PCD_TYPE_STRING:
156 StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset);
157 RetPtr = (VOID *) &StringTable[StringTableIdx];
158 break;
159
160 case PCD_TYPE_DATA:
161 RetPtr = (VOID *) ((UINT8 *) PcdDb + Offset);
162 break;
163
164 default:
165 ASSERT (FALSE);
166 break;
167
168 }
169
170 EfiReleaseLock (&mPcdDatabaseLock);
171
172 return RetPtr;
173
174 }
175
176 /**
177 Register the callback function for a PCD entry.
178
179 This routine will register a callback function to a PCD entry by given token number
180 and token space guid.
181
182 @param TokenNumber PCD token's number, it is autogened by build tools.
183 @param Guid PCD token space's guid,
184 if not NULL, this PCD is dynamicEx type PCD.
185 @param CallBackFunction Callback function pointer
186
187 @return EFI_SUCCESS Always success for registering callback function.
188
189 **/
190 EFI_STATUS
191 DxeRegisterCallBackWorker (
192 IN UINTN TokenNumber,
193 IN CONST EFI_GUID *Guid, OPTIONAL
194 IN PCD_PROTOCOL_CALLBACK CallBackFunction
195 )
196 {
197 CALLBACK_FN_ENTRY *FnTableEntry;
198 LIST_ENTRY *ListHead;
199 LIST_ENTRY *ListNode;
200
201 if (Guid != NULL) {
202 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);
203 }
204
205 //
206 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
207 // We have to decrement TokenNumber by 1 to make it usable
208 // as the array index.
209 //
210 TokenNumber--;
211
212 ListHead = &mCallbackFnTable[TokenNumber];
213 ListNode = GetFirstNode (ListHead);
214
215 while (ListNode != ListHead) {
216 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);
217
218 if (FnTableEntry->CallbackFn == CallBackFunction) {
219 //
220 // We only allow a Callback function to be register once
221 // for a TokenNumber. So just return EFI_SUCCESS
222 //
223 return EFI_SUCCESS;
224 }
225 ListNode = GetNextNode (ListHead, ListNode);
226 }
227
228 FnTableEntry = AllocatePool (sizeof(CALLBACK_FN_ENTRY));
229 ASSERT (FnTableEntry != NULL);
230
231 FnTableEntry->CallbackFn = CallBackFunction;
232 InsertTailList (ListHead, &FnTableEntry->Node);
233
234 return EFI_SUCCESS;
235 }
236
237 /**
238 UnRegister the callback function for a PCD entry.
239
240 This routine will unregister a callback function to a PCD entry by given token number
241 and token space guid.
242
243 @param TokenNumber PCD token's number, it is autogened by build tools.
244 @param Guid PCD token space's guid.
245 if not NULL, this PCD is dynamicEx type PCD.
246 @param CallBackFunction Callback function pointer
247
248 @retval EFI_SUCCESS Callback function is success to be unregister.
249 @retval EFI_INVALID_PARAMETER Can not find the PCD entry by given token number.
250 **/
251 EFI_STATUS
252 DxeUnRegisterCallBackWorker (
253 IN UINTN TokenNumber,
254 IN CONST EFI_GUID *Guid, OPTIONAL
255 IN PCD_PROTOCOL_CALLBACK CallBackFunction
256 )
257 {
258 CALLBACK_FN_ENTRY *FnTableEntry;
259 LIST_ENTRY *ListHead;
260 LIST_ENTRY *ListNode;
261
262 if (Guid != NULL) {
263 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);
264 }
265
266 //
267 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
268 // We have to decrement TokenNumber by 1 to make it usable
269 // as the array index.
270 //
271 TokenNumber--;
272
273 ListHead = &mCallbackFnTable[TokenNumber];
274 ListNode = GetFirstNode (ListHead);
275
276 while (ListNode != ListHead) {
277 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);
278
279 if (FnTableEntry->CallbackFn == CallBackFunction) {
280 //
281 // We only allow a Callback function to be register once
282 // for a TokenNumber. So we can safely remove the Node from
283 // the Link List and return EFI_SUCCESS.
284 //
285 RemoveEntryList (ListNode);
286 FreePool (FnTableEntry);
287
288 return EFI_SUCCESS;
289 }
290 ListNode = GetNextNode (ListHead, ListNode);
291 }
292
293 return EFI_INVALID_PARAMETER;
294 }
295
296 /**
297 Get next token number in given token space.
298
299 This routine is used for dynamicEx type PCD. It will firstly scan token space
300 table to get token space according to given token space guid. Then scan given
301 token number in found token space, if found, then return next token number in
302 this token space.
303
304 @param Guid Token space guid. Next token number will be scaned in
305 this token space.
306 @param TokenNumber Token number.
307 If PCD_INVALID_TOKEN_NUMBER, return first token number in
308 token space table.
309 If not PCD_INVALID_TOKEN_NUMBER, return next token number
310 in token space table.
311 @param GuidTable Token space guid table. It will be used for scan token space
312 by given token space guid.
313 @param SizeOfGuidTable The size of guid table.
314 @param ExMapTable DynamicEx token number mapping table.
315 @param SizeOfExMapTable The size of dynamicEx token number mapping table.
316
317 @retval EFI_NOT_FOUND Can not given token space or token number.
318 @retval EFI_SUCCESS Success to get next token number.
319
320 **/
321 EFI_STATUS
322 ExGetNextTokeNumber (
323 IN CONST EFI_GUID *Guid,
324 IN OUT UINTN *TokenNumber,
325 IN EFI_GUID *GuidTable,
326 IN UINTN SizeOfGuidTable,
327 IN DYNAMICEX_MAPPING *ExMapTable,
328 IN UINTN SizeOfExMapTable
329 )
330 {
331 EFI_GUID *MatchGuid;
332 UINTN Index;
333 UINTN GuidTableIdx;
334 BOOLEAN Found;
335
336 //
337 // Scan token space guid
338 //
339 MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid);
340 if (MatchGuid == NULL) {
341 return EFI_NOT_FOUND;
342 }
343
344 //
345 // Find the token space table in dynamicEx mapping table.
346 //
347 Found = FALSE;
348 GuidTableIdx = MatchGuid - GuidTable;
349 for (Index = 0; Index < SizeOfExMapTable; Index++) {
350 if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
351 Found = TRUE;
352 break;
353 }
354 }
355
356 if (Found) {
357 //
358 // If given token number is PCD_INVALID_TOKEN_NUMBER, then return the first
359 // token number in found token space.
360 //
361 if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
362 *TokenNumber = ExMapTable[Index].ExTokenNumber;
363 return EFI_SUCCESS;
364 }
365
366 for ( ; Index < SizeOfExMapTable; Index++) {
367 if (ExMapTable[Index].ExTokenNumber == *TokenNumber) {
368 Index ++;
369 if (Index == SizeOfExMapTable) {
370 //
371 // Exceed the length of ExMap Table
372 //
373 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
374 return EFI_SUCCESS;
375 } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
376 //
377 // Found the next match
378 //
379 *TokenNumber = ExMapTable[Index].ExTokenNumber;
380 return EFI_SUCCESS;
381 } else {
382 //
383 // Guid has been changed. It is the next Token Space Guid.
384 // We should flag no more TokenNumber.
385 //
386 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
387 return EFI_SUCCESS;
388 }
389 }
390 }
391 }
392
393 return EFI_NOT_FOUND;
394 }
395
396
397 /**
398 Initialize the PCD database in DXE phase.
399
400 PCD database in DXE phase also contains PCD database in PEI phase which is copied
401 from GUID Hob.
402
403 **/
404 VOID
405 BuildPcdDxeDataBase (
406 VOID
407 )
408 {
409 PEI_PCD_DATABASE *PeiDatabase;
410 EFI_HOB_GUID_TYPE *GuidHob;
411 UINTN Index;
412
413 mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));
414 ASSERT (mPcdDatabase != NULL);
415
416 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
417 if (GuidHob != NULL) {
418
419 //
420 // We will copy over the PEI phase's PCD Database.
421 //
422 // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM
423 // should not be included at all. So the GuidHob could
424 // be NULL. If it is NULL, we just copy over the DXE Default
425 // Value to PCD Database.
426 //
427
428 PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
429 //
430 // Copy PCD Entries refereneced in PEI phase to PCD DATABASE
431 //
432 CopyMem (&mPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE));
433 }
434
435 //
436 // Copy PCD Entries with default value to PCD DATABASE
437 //
438 CopyMem (&mPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT));
439
440
441 //
442 // Initialized the Callback Function Table
443 //
444
445 mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY));
446 ASSERT(mCallbackFnTable != NULL);
447
448 // EBC compiler is very choosy. It may report warning about comparison
449 // between UINTN and 0 . So we add 1 in each size of the
450 // comparison.
451 for (Index = 0; Index + 1 < PCD_TOTAL_TOKEN_NUMBER + 1; Index++) {
452 InitializeListHead (&mCallbackFnTable[Index]);
453 }
454 }
455
456 /**
457 Get Variable which contains HII type PCD entry.
458
459 @param VariableGuid Variable's guid
460 @param VariableName Variable's unicode name string
461 @param VariableData Variable's data pointer,
462 @param VariableSize Variable's size.
463
464 @return the status of gRT->GetVariable
465 **/
466 EFI_STATUS
467 GetHiiVariable (
468 IN EFI_GUID *VariableGuid,
469 IN UINT16 *VariableName,
470 OUT UINT8 **VariableData,
471 OUT UINTN *VariableSize
472 )
473 {
474 UINTN Size;
475 EFI_STATUS Status;
476 UINT8 *Buffer;
477
478 Size = 0;
479 Buffer = NULL;
480
481 //
482 // Firstly get the real size of HII variable
483 //
484 Status = gRT->GetVariable (
485 (UINT16 *)VariableName,
486 VariableGuid,
487 NULL,
488 &Size,
489 Buffer
490 );
491
492 //
493 // Allocate buffer to hold whole variable data according to variable size.
494 //
495 if (Status == EFI_BUFFER_TOO_SMALL) {
496 Buffer = (UINT8 *) AllocatePool (Size);
497
498 ASSERT (Buffer != NULL);
499
500 Status = gRT->GetVariable (
501 VariableName,
502 VariableGuid,
503 NULL,
504 &Size,
505 Buffer
506 );
507
508 ASSERT (Status == EFI_SUCCESS);
509 *VariableData = Buffer;
510 *VariableSize = Size;
511 }
512
513 return Status;
514 }
515
516 /**
517 Find the local token number according to system SKU ID.
518
519 @param LocalTokenNumber PCD token number
520 @param Size The size of PCD entry.
521 @param IsPeiDb If TRUE, the PCD entry is initialized in PEI phase.
522 If False, the PCD entry is initialized in DXE phase.
523
524 @return Token number according to system SKU ID.
525
526 **/
527 UINT32
528 GetSkuEnabledTokenNumber (
529 UINT32 LocalTokenNumber,
530 UINTN Size,
531 BOOLEAN IsPeiDb
532 )
533 {
534 SKU_HEAD *SkuHead;
535 SKU_ID *SkuIdTable;
536 INTN Index;
537 UINT8 *Value;
538 SKU_ID *PhaseSkuIdTable;
539 UINT8 *PcdDb;
540
541 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);
542
543 PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb;
544
545 SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
546 Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset);
547
548 PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :
549 mPcdDatabase->DxeDb.Init.SkuIdTable;
550
551 SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];
552
553 //
554 // Find the current system's SKU ID entry in SKU ID table.
555 //
556 for (Index = 0; Index < SkuIdTable[0]; Index++) {
557 if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[Index + 1]) {
558 break;
559 }
560 }
561 ASSERT (Index < SkuIdTable[0]);
562
563 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
564 case PCD_TYPE_VPD:
565 Value = (UINT8 *) &(((VPD_HEAD *) Value)[Index]);
566 return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD);
567
568 case PCD_TYPE_HII:
569 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
570 return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);
571
572 case PCD_TYPE_STRING:
573 Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);
574 return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING);
575
576 case PCD_TYPE_DATA:
577 Value += Size * Index;
578 return (UINT32) (Value - PcdDb);
579
580 default:
581 ASSERT (FALSE);
582 }
583
584 ASSERT (FALSE);
585
586 return 0;
587
588 }
589
590 /**
591 Invoke the callback function when dynamic PCD entry was set, if this PCD entry
592 has registered callback function.
593
594 @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx
595 type PCD.
596 @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type
597 PCD.
598 @param TokenNumber PCD token number generated by build tools.
599 @param Data Value want to be set for this PCD entry
600 @param Size The size of value
601
602 **/
603 VOID
604 InvokeCallbackOnSet (
605 UINT32 ExTokenNumber,
606 CONST EFI_GUID *Guid, OPTIONAL
607 UINTN TokenNumber,
608 VOID *Data,
609 UINTN Size
610 )
611 {
612 CALLBACK_FN_ENTRY *FnTableEntry;
613 LIST_ENTRY *ListHead;
614 LIST_ENTRY *ListNode;
615
616 //
617 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
618 // We have to decrement TokenNumber by 1 to make it usable
619 // as the array index.
620 //
621 TokenNumber--;
622
623 ListHead = &mCallbackFnTable[TokenNumber];
624 ListNode = GetFirstNode (ListHead);
625
626 while (ListNode != ListHead) {
627 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);
628
629 FnTableEntry->CallbackFn(Guid,
630 (Guid == NULL) ? TokenNumber : ExTokenNumber,
631 Data,
632 Size);
633
634 ListNode = GetNextNode (ListHead, ListNode);
635 }
636
637 return;
638 }
639
640
641 /**
642 Wrapper function for setting non-pointer type value for a PCD entry.
643
644 @param TokenNumber Pcd token number autogenerated by build tools.
645 @param Data Value want to be set for PCD entry
646 @param Size Size of value.
647
648 @return status of SetWorker.
649
650 **/
651 EFI_STATUS
652 SetValueWorker (
653 IN UINTN TokenNumber,
654 IN VOID *Data,
655 IN UINTN Size
656 )
657 {
658 return SetWorker (TokenNumber, Data, &Size, FALSE);
659 }
660
661
662 /**
663 Set value for an PCD entry
664
665 @param TokenNumber Pcd token number autogenerated by build tools.
666 @param Data Value want to be set for PCD entry
667 @param Size Size of value.
668 @param PtrType If TRUE, the type of PCD entry's value is Pointer.
669 If False, the type of PCD entry's value is not Pointer.
670
671 @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.
672 @retval EFI_INVALID_PARAMETER If Size can not be set to size table.
673 @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in
674 range of UINT8, UINT16, UINT32, UINT64
675 @retval EFI_NOT_FOUND Can not find the PCD type according to token number.
676 **/
677 EFI_STATUS
678 SetWorker (
679 IN UINTN TokenNumber,
680 IN VOID *Data,
681 IN OUT UINTN *Size,
682 IN BOOLEAN PtrType
683 )
684 {
685 UINT32 *LocalTokenNumberTable;
686 BOOLEAN IsPeiDb;
687 UINT32 LocalTokenNumber;
688 EFI_GUID *GuidTable;
689 UINT16 *StringTable;
690 EFI_GUID *Guid;
691 UINT16 *Name;
692 UINTN VariableOffset;
693 VOID *InternalData;
694 VARIABLE_HEAD *VariableHead;
695 UINTN Offset;
696 UINT8 *PcdDb;
697 EFI_STATUS Status;
698 UINTN MaxSize;
699 UINTN TmpTokenNumber;
700
701 //
702 // Aquire lock to prevent reentrance from TPL_CALLBACK level
703 //
704 EfiAcquireLock (&mPcdDatabaseLock);
705
706 //
707 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
708 // We have to decrement TokenNumber by 1 to make it usable
709 // as the array index.
710 //
711 TokenNumber--;
712
713 TmpTokenNumber = TokenNumber;
714
715 //
716 // EBC compiler is very choosy. It may report warning about comparison
717 // between UINTN and 0 . So we add 1 in each size of the
718 // comparison.
719 //
720 ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);
721
722 if (!PtrType) {
723 ASSERT (*Size == DxePcdGetSize (TokenNumber + 1));
724 }
725
726 //
727 // EBC compiler is very choosy. It may report warning about comparison
728 // between UINTN and 0 . So we add 1 in each size of the
729 // comparison.
730 //
731 IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);
732
733 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
734 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
735
736 //
737 // EBC compiler is very choosy. It may report warning about comparison
738 // between UINTN and 0 . So we add 1 in each size of the
739 // comparison.
740 //
741 if ((TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) ||
742 (TokenNumber + 1 >= PEI_LOCAL_TOKEN_NUMBER + 1 || TokenNumber + 1 < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1))) {
743 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);
744 }
745
746 TokenNumber = IsPeiDb ? TokenNumber
747 : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
748
749 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
750
751 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
752 if (PtrType) {
753 GetPtrTypeSize (TmpTokenNumber, &MaxSize);
754 } else {
755 MaxSize = *Size;
756 }
757 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);
758 }
759
760 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
761
762 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);
763
764 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :
765 mPcdDatabase->DxeDb.Init.StringTable;
766
767 InternalData = PcdDb + Offset;
768
769 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
770 case PCD_TYPE_VPD:
771 ASSERT (FALSE);
772 Status = EFI_INVALID_PARAMETER;
773 break;
774
775 case PCD_TYPE_STRING:
776 if (SetPtrTypeSize (TmpTokenNumber, Size)) {
777 CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, *Size);
778 Status = EFI_SUCCESS;
779 } else {
780 Status = EFI_INVALID_PARAMETER;
781 }
782 break;
783
784 case PCD_TYPE_HII:
785 if (PtrType) {
786 if (!SetPtrTypeSize (TmpTokenNumber, Size)) {
787 Status = EFI_INVALID_PARAMETER;
788 break;
789 }
790 }
791
792 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :
793 mPcdDatabase->DxeDb.Init.GuidTable;
794
795 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
796
797 Guid = &(GuidTable[VariableHead->GuidTableIndex]);
798 Name = &(StringTable[VariableHead->StringIndex]);
799 VariableOffset = VariableHead->Offset;
800
801 Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset);
802
803 if (EFI_NOT_FOUND == Status) {
804 CopyMem (PcdDb + VariableHead->DefaultValueOffset, Data, *Size);
805 Status = EFI_SUCCESS;
806 }
807 break;
808
809 case PCD_TYPE_DATA:
810 if (PtrType) {
811 if (SetPtrTypeSize (TmpTokenNumber, Size)) {
812 CopyMem (InternalData, Data, *Size);
813 Status = EFI_SUCCESS;
814 } else {
815 Status = EFI_INVALID_PARAMETER;
816 }
817 break;
818 }
819
820 Status = EFI_SUCCESS;
821 switch (*Size) {
822 case sizeof(UINT8):
823 *((UINT8 *) InternalData) = *((UINT8 *) Data);
824 break;
825
826 case sizeof(UINT16):
827 *((UINT16 *) InternalData) = *((UINT16 *) Data);
828 break;
829
830 case sizeof(UINT32):
831 *((UINT32 *) InternalData) = *((UINT32 *) Data);
832 break;
833
834 case sizeof(UINT64):
835 *((UINT64 *) InternalData) = *((UINT64 *) Data);
836 break;
837
838 default:
839 ASSERT (FALSE);
840 Status = EFI_NOT_FOUND;
841 break;
842 }
843 break;
844
845 default:
846 ASSERT (FALSE);
847 Status = EFI_NOT_FOUND;
848 break;
849 }
850
851 EfiReleaseLock (&mPcdDatabaseLock);
852
853 return Status;
854 }
855
856 /**
857 Wrapper function for get PCD value for dynamic-ex PCD.
858
859 @param Guid Token space guid for dynamic-ex PCD.
860 @param ExTokenNumber Token number for dynamic-ex PCD.
861 @param GetSize The size of dynamic-ex PCD value.
862
863 @return PCD entry in PCD database.
864
865 **/
866 VOID *
867 ExGetWorker (
868 IN CONST EFI_GUID *Guid,
869 IN UINTN ExTokenNumber,
870 IN UINTN GetSize
871 )
872 {
873 return GetWorker(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber), GetSize);
874 }
875
876 /**
877 Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.
878
879 @param ExTokenNumber Token number for dynamic-ex PCD.
880 @param Guid Token space guid for dynamic-ex PCD.
881 @param Data Value want to be set.
882 @param SetSize The size of value.
883
884 @return status of ExSetWorker().
885
886 **/
887 EFI_STATUS
888 ExSetValueWorker (
889 IN UINTN ExTokenNumber,
890 IN CONST EFI_GUID *Guid,
891 IN VOID *Data,
892 IN UINTN SetSize
893 )
894 {
895 return ExSetWorker (ExTokenNumber, Guid, Data, &SetSize, FALSE);
896 }
897
898 /**
899 Set value for a dynamic PCD entry.
900
901 This routine find the local token number according to dynamic-ex PCD's token
902 space guid and token number firstly, and invoke callback function if this PCD
903 entry registered callback function. Finally, invoken general SetWorker to set
904 PCD value.
905
906 @param ExTokenNumber Dynamic-ex PCD token number.
907 @param Guid Token space guid for dynamic-ex PCD.
908 @param Data PCD value want to be set
909 @param SetSize Size of value.
910 @param PtrType If TRUE, this PCD entry is pointer type.
911 If FALSE, this PCD entry is not pointer type.
912
913 @return status of SetWorker().
914
915 **/
916 EFI_STATUS
917 ExSetWorker (
918 IN UINTN ExTokenNumber,
919 IN CONST EFI_GUID *Guid,
920 IN VOID *Data,
921 IN OUT UINTN *SetSize,
922 IN BOOLEAN PtrType
923 )
924 {
925 UINTN TokenNumber;
926
927 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber);
928
929 InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, *SetSize);
930
931 return SetWorker (TokenNumber, Data, SetSize, PtrType);
932
933 }
934
935 /**
936 Set value for HII-type PCD.
937
938 A HII-type PCD's value is stored in a variable. Setting/Getting the value of
939 HII-type PCD is to visit this variable.
940
941 @param VariableGuid Guid of variable which stored value of a HII-type PCD.
942 @param VariableName Unicode name of variable which stored value of a HII-type PCD.
943 @param Data Value want to be set.
944 @param DataSize Size of value
945 @param Offset Value offset of HII-type PCD in variable.
946
947 @return status of GetVariable()/SetVariable().
948
949 **/
950 EFI_STATUS
951 SetHiiVariable (
952 IN EFI_GUID *VariableGuid,
953 IN UINT16 *VariableName,
954 IN CONST VOID *Data,
955 IN UINTN DataSize,
956 IN UINTN Offset
957 )
958 {
959 UINTN Size;
960 VOID *Buffer;
961 EFI_STATUS Status;
962 UINT32 Attribute;
963
964 Size = 0;
965
966 Status = gRT->GetVariable (
967 (UINT16 *)VariableName,
968 VariableGuid,
969 NULL,
970 &Size,
971 NULL
972 );
973
974 if (Status == EFI_BUFFER_TOO_SMALL) {
975
976 Buffer = AllocatePool (Size);
977
978 ASSERT (Buffer != NULL);
979
980 Status = gRT->GetVariable (
981 VariableName,
982 VariableGuid,
983 &Attribute,
984 &Size,
985 Buffer
986 );
987
988 ASSERT_EFI_ERROR (Status);
989
990 CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);
991
992 Status = gRT->SetVariable (
993 VariableName,
994 VariableGuid,
995 Attribute,
996 Size,
997 Buffer
998 );
999
1000 FreePool (Buffer);
1001 return Status;
1002
1003 }
1004
1005 //
1006 // If we drop to here, we don't have a Variable entry in
1007 // the variable service yet. So, we will save the data
1008 // in the PCD Database's volatile area.
1009 //
1010 return Status;
1011 }
1012
1013 /**
1014 Get local token number according to dynamic-ex PCD's {token space guid:token number}
1015
1016 A dynamic-ex type PCD, developer must provide pair of token space guid: token number
1017 in DEC file. PCD database maintain a mapping table that translate pair of {token
1018 space guid: token number} to local token number.
1019
1020 @param Guid Token space guid for dynamic-ex PCD entry.
1021 @param ExTokenNumber EDES_TODO: Add parameter description
1022
1023 @return local token number for dynamic-ex PCD.
1024
1025 **/
1026 UINTN
1027 GetExPcdTokenNumber (
1028 IN CONST EFI_GUID *Guid,
1029 IN UINT32 ExTokenNumber
1030 )
1031 {
1032 UINT32 Index;
1033 DYNAMICEX_MAPPING *ExMap;
1034 EFI_GUID *GuidTable;
1035 EFI_GUID *MatchGuid;
1036 UINTN MatchGuidIdx;
1037
1038 if (!PEI_DATABASE_EMPTY) {
1039 ExMap = mPcdDatabase->PeiDb.Init.ExMapTable;
1040 GuidTable = mPcdDatabase->PeiDb.Init.GuidTable;
1041
1042 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);
1043
1044 if (MatchGuid != NULL) {
1045
1046 MatchGuidIdx = MatchGuid - GuidTable;
1047
1048 for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
1049 if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
1050 (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
1051 return ExMap[Index].LocalTokenNumber;
1052
1053 }
1054 }
1055 }
1056 }
1057
1058 ExMap = mPcdDatabase->DxeDb.Init.ExMapTable;
1059 GuidTable = mPcdDatabase->DxeDb.Init.GuidTable;
1060
1061 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);
1062 //
1063 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
1064 // error in the BUILD system.
1065 //
1066 ASSERT (MatchGuid != NULL);
1067
1068 MatchGuidIdx = MatchGuid - GuidTable;
1069
1070 for (Index = 0; Index < DXE_EXMAPPING_TABLE_SIZE; Index++) {
1071 if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
1072 (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
1073 return ExMap[Index].LocalTokenNumber;
1074 }
1075 }
1076
1077 ASSERT (FALSE);
1078
1079 return 0;
1080 }
1081
1082 /**
1083 Get SKU ID table from PCD database.
1084
1085 @param LocalTokenNumberTableIdx Index of local token number in token number table.
1086 @param IsPeiPcd If TRUE,
1087
1088 @return Pointer to SKU ID array table
1089
1090 **/
1091 SKU_ID *
1092 GetSkuIdArray (
1093 IN UINTN LocalTokenNumberTableIdx,
1094 IN BOOLEAN IsPeiPcd
1095 )
1096 {
1097 SKU_HEAD *SkuHead;
1098 UINTN LocalTokenNumber;
1099 UINT8 *Database;
1100
1101 if (IsPeiPcd) {
1102 LocalTokenNumber = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
1103 Database = (UINT8 *) &mPcdDatabase->PeiDb;
1104 } else {
1105 LocalTokenNumber = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx - PEI_LOCAL_TOKEN_NUMBER];
1106 Database = (UINT8 *) &mPcdDatabase->DxeDb;
1107 }
1108
1109 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);
1110
1111 SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
1112
1113 return (SKU_ID *) (Database + SkuHead->SkuIdTableOffset);
1114
1115 }
1116
1117
1118 /**
1119 Get index of PCD entry in size table.
1120
1121 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
1122 @param LocalTokenNumberTable Pointer to local token number table in PCD database.
1123 @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
1124 If FALSE, the pcd entry is initialized in DXE phase.
1125
1126 @return index of PCD entry in size table.
1127
1128 **/
1129 UINTN
1130 GetSizeTableIndexA (
1131 IN UINTN LocalTokenNumberTableIdx,
1132 IN UINT32 *LocalTokenNumberTable,
1133 IN BOOLEAN IsPeiDb
1134 )
1135 {
1136 UINTN Index;
1137 UINTN SizeTableIdx;
1138 UINTN LocalTokenNumber;
1139 SKU_ID *SkuIdTable;
1140
1141 SizeTableIdx = 0;
1142
1143 for (Index=0; Index<LocalTokenNumberTableIdx; Index++) {
1144 LocalTokenNumber = LocalTokenNumberTable[Index];
1145
1146 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {
1147 //
1148 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1149 // PCD entry.
1150 //
1151 if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
1152 //
1153 // We have only one entry for VPD enabled PCD entry:
1154 // 1) MAX Size.
1155 // We consider current size is equal to MAX size.
1156 //
1157 SizeTableIdx++;
1158 } else {
1159 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
1160 //
1161 // We have only two entry for Non-Sku enabled PCD entry:
1162 // 1) MAX SIZE
1163 // 2) Current Size
1164 //
1165 SizeTableIdx += 2;
1166 } else {
1167 //
1168 // We have these entry for SKU enabled PCD entry
1169 // 1) MAX SIZE
1170 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1171 //
1172 SkuIdTable = GetSkuIdArray (Index, IsPeiDb);
1173 SizeTableIdx += (UINTN)*SkuIdTable + 1;
1174 }
1175 }
1176 }
1177
1178 }
1179
1180 return SizeTableIdx;
1181 }
1182
1183
1184
1185 /**
1186 Wrapper function of getting index of PCD entry in size table.
1187
1188 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
1189 @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
1190 If FALSE, the pcd entry is initialized in DXE phase.
1191
1192 @return index of PCD entry in size table.
1193 **/
1194 UINTN
1195 GetSizeTableIndex (
1196 IN UINTN LocalTokenNumberTableIdx,
1197 IN BOOLEAN IsPeiDb
1198 )
1199 {
1200 UINT32 *LocalTokenNumberTable;
1201
1202 if (IsPeiDb) {
1203 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
1204 } else {
1205 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
1206 }
1207 return GetSizeTableIndexA (LocalTokenNumberTableIdx,
1208 LocalTokenNumberTable,
1209 IsPeiDb);
1210 }
1211
1212 /**
1213 Get size of POINTER type PCD value.
1214
1215 @param LocalTokenNumberTableIdx Index of local token number in local token number table.
1216 @param MaxSize Maxmium size of POINTER type PCD value.
1217
1218 @return size of POINTER type PCD value.
1219
1220 **/
1221 UINTN
1222 GetPtrTypeSize (
1223 IN UINTN LocalTokenNumberTableIdx,
1224 OUT UINTN *MaxSize
1225 )
1226 {
1227 INTN SizeTableIdx;
1228 UINTN LocalTokenNumber;
1229 SKU_ID *SkuIdTable;
1230 SIZE_INFO *SizeTable;
1231 UINTN Index;
1232 BOOLEAN IsPeiDb;
1233 UINT32 *LocalTokenNumberTable;
1234
1235 // EBC compiler is very choosy. It may report warning about comparison
1236 // between UINTN and 0 . So we add 1 in each size of the
1237 // comparison.
1238 IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
1239
1240
1241 if (IsPeiDb) {
1242 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
1243 SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;
1244 } else {
1245 LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;
1246 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
1247 SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;
1248 }
1249
1250 LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];
1251
1252 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
1253
1254 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);
1255
1256 *MaxSize = SizeTable[SizeTableIdx];
1257 //
1258 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1259 // PCD entry.
1260 //
1261 if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
1262 //
1263 // We have only one entry for VPD enabled PCD entry:
1264 // 1) MAX Size.
1265 // We consider current size is equal to MAX size.
1266 //
1267 return *MaxSize;
1268 } else {
1269 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
1270 //
1271 // We have only two entry for Non-Sku enabled PCD entry:
1272 // 1) MAX SIZE
1273 // 2) Current Size
1274 //
1275 return SizeTable[SizeTableIdx + 1];
1276 } else {
1277 //
1278 // We have these entry for SKU enabled PCD entry
1279 // 1) MAX SIZE
1280 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1281 //
1282 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);
1283 for (Index = 0; Index < SkuIdTable[0]; Index++) {
1284 if (SkuIdTable[1 + Index] == mPcdDatabase->PeiDb.Init.SystemSkuId) {
1285 return SizeTable[SizeTableIdx + 1 + Index];
1286 }
1287 }
1288 return SizeTable[SizeTableIdx + 1];
1289 }
1290 }
1291 }
1292
1293 /**
1294 Set size of POINTER type PCD value. The size should not exceed the maximum size
1295 of this PCD value.
1296
1297 @param LocalTokenNumberTableIdx Index of local token number in local token number table.
1298 @param CurrentSize Size of POINTER type PCD value.
1299
1300 @retval TRUE Success to set size of PCD value.
1301 @retval FALSE Fail to set size of PCD value.
1302 **/
1303 BOOLEAN
1304 SetPtrTypeSize (
1305 IN UINTN LocalTokenNumberTableIdx,
1306 IN OUT UINTN *CurrentSize
1307 )
1308 {
1309 INTN SizeTableIdx;
1310 UINTN LocalTokenNumber;
1311 SKU_ID *SkuIdTable;
1312 SIZE_INFO *SizeTable;
1313 UINTN Index;
1314 UINTN MaxSize;
1315 BOOLEAN IsPeiDb;
1316 UINT32 *LocalTokenNumberTable;
1317
1318 //
1319 // EBC compiler is very choosy. It may report warning about comparison
1320 // between UINTN and 0 . So we add 1 in each size of the
1321 // comparison.
1322 //
1323 IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
1324
1325 if (IsPeiDb) {
1326 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
1327 SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;
1328 } else {
1329 LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;
1330 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
1331 SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;
1332 }
1333
1334 LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];
1335
1336 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
1337
1338 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);
1339
1340 MaxSize = SizeTable[SizeTableIdx];
1341 //
1342 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1343 // PCD entry.
1344 //
1345 if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
1346 //
1347 // We shouldn't come here as we don't support SET for VPD
1348 //
1349 ASSERT (FALSE);
1350 return FALSE;
1351 } else {
1352 if ((*CurrentSize > MaxSize) ||
1353 (*CurrentSize == MAX_ADDRESS)) {
1354 *CurrentSize = MaxSize;
1355 return FALSE;
1356 }
1357
1358 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
1359 //
1360 // We have only two entry for Non-Sku enabled PCD entry:
1361 // 1) MAX SIZE
1362 // 2) Current Size
1363 //
1364 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;
1365 return TRUE;
1366 } else {
1367 //
1368 // We have these entry for SKU enabled PCD entry
1369 // 1) MAX SIZE
1370 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1371 //
1372 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);
1373 for (Index = 0; Index < SkuIdTable[0]; Index++) {
1374 if (SkuIdTable[1 + Index] == mPcdDatabase->PeiDb.Init.SystemSkuId) {
1375 SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;
1376 return TRUE;
1377 }
1378 }
1379 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;
1380 return TRUE;
1381 }
1382 }
1383 }