]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/PCD/Dxe/Service.c
clean up the un-suitable ';' location when declaring the functions.
[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
447 // EBC compiler is very choosy. It may report warning about comparison
448 // between UINTN and 0 . So we add 1 in each size of the
449 // comparison.
450 for (Index = 0; Index + 1 < PCD_TOTAL_TOKEN_NUMBER + 1; Index++) {
451 InitializeListHead (&mCallbackFnTable[Index]);
452 }
453 }
454
455 /**
456 Get Variable which contains HII type PCD entry.
457
458 @param VariableGuid Variable's guid
459 @param VariableName Variable's unicode name string
460 @param VariableData Variable's data pointer,
461 @param VariableSize Variable's size.
462
463 @return the status of gRT->GetVariable
464 **/
465 EFI_STATUS
466 GetHiiVariable (
467 IN EFI_GUID *VariableGuid,
468 IN UINT16 *VariableName,
469 OUT UINT8 **VariableData,
470 OUT UINTN *VariableSize
471 )
472 {
473 UINTN Size;
474 EFI_STATUS Status;
475 UINT8 *Buffer;
476
477 Size = 0;
478 Buffer = NULL;
479
480 //
481 // Firstly get the real size of HII variable
482 //
483 Status = gRT->GetVariable (
484 (UINT16 *)VariableName,
485 VariableGuid,
486 NULL,
487 &Size,
488 Buffer
489 );
490
491 //
492 // Allocate buffer to hold whole variable data according to variable size.
493 //
494 if (Status == EFI_BUFFER_TOO_SMALL) {
495 Buffer = (UINT8 *) AllocatePool (Size);
496
497 ASSERT (Buffer != NULL);
498
499 Status = gRT->GetVariable (
500 VariableName,
501 VariableGuid,
502 NULL,
503 &Size,
504 Buffer
505 );
506
507 ASSERT (Status == EFI_SUCCESS);
508 *VariableData = Buffer;
509 *VariableSize = Size;
510 }
511
512 return Status;
513 }
514
515 /**
516 Find the local token number according to system SKU ID.
517
518 @param LocalTokenNumber PCD token number
519 @param Size The size of PCD entry.
520 @param IsPeiDb If TRUE, the PCD entry is initialized in PEI phase.
521 If False, the PCD entry is initialized in DXE phase.
522
523 @return Token number according to system SKU ID.
524
525 **/
526 UINT32
527 GetSkuEnabledTokenNumber (
528 UINT32 LocalTokenNumber,
529 UINTN Size,
530 BOOLEAN IsPeiDb
531 )
532 {
533 SKU_HEAD *SkuHead;
534 SKU_ID *SkuIdTable;
535 INTN Index;
536 UINT8 *Value;
537 SKU_ID *PhaseSkuIdTable;
538 UINT8 *PcdDb;
539
540 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);
541
542 PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb;
543
544 SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
545 Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset);
546
547 PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :
548 mPcdDatabase->DxeDb.Init.SkuIdTable;
549
550 SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];
551
552 //
553 // Find the current system's SKU ID entry in SKU ID table.
554 //
555 for (Index = 0; Index < SkuIdTable[0]; Index++) {
556 if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[Index + 1]) {
557 break;
558 }
559 }
560 ASSERT (Index < SkuIdTable[0]);
561
562 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
563 case PCD_TYPE_VPD:
564 Value = (UINT8 *) &(((VPD_HEAD *) Value)[Index]);
565 return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD);
566
567 case PCD_TYPE_HII:
568 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
569 return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);
570
571 case PCD_TYPE_STRING:
572 Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);
573 return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING);
574
575 case PCD_TYPE_DATA:
576 Value += Size * Index;
577 return (UINT32) (Value - PcdDb);
578
579 default:
580 ASSERT (FALSE);
581 }
582
583 ASSERT (FALSE);
584
585 return 0;
586
587 }
588
589 /**
590 Invoke the callback function when dynamic PCD entry was set, if this PCD entry
591 has registered callback function.
592
593 @param ExTokenNumber DynamicEx PCD's token number, if this PCD entry is dyanmicEx
594 type PCD.
595 @param Guid DynamicEx PCD's guid, if this PCD entry is dynamicEx type
596 PCD.
597 @param TokenNumber PCD token number generated by build tools.
598 @param Data Value want to be set for this PCD entry
599 @param Size The size of value
600
601 **/
602 VOID
603 InvokeCallbackOnSet (
604 UINT32 ExTokenNumber,
605 CONST EFI_GUID *Guid, OPTIONAL
606 UINTN TokenNumber,
607 VOID *Data,
608 UINTN Size
609 )
610 {
611 CALLBACK_FN_ENTRY *FnTableEntry;
612 LIST_ENTRY *ListHead;
613 LIST_ENTRY *ListNode;
614
615 //
616 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
617 // We have to decrement TokenNumber by 1 to make it usable
618 // as the array index.
619 //
620 TokenNumber--;
621
622 ListHead = &mCallbackFnTable[TokenNumber];
623 ListNode = GetFirstNode (ListHead);
624
625 while (ListNode != ListHead) {
626 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);
627
628 FnTableEntry->CallbackFn(Guid,
629 (Guid == NULL) ? TokenNumber : ExTokenNumber,
630 Data,
631 Size);
632
633 ListNode = GetNextNode (ListHead, ListNode);
634 }
635
636 return;
637 }
638
639
640 /**
641 Wrapper function for setting non-pointer type value for a PCD entry.
642
643 @param TokenNumber Pcd token number autogenerated by build tools.
644 @param Data Value want to be set for PCD entry
645 @param Size Size of value.
646
647 @return status of SetWorker.
648
649 **/
650 EFI_STATUS
651 SetValueWorker (
652 IN UINTN TokenNumber,
653 IN VOID *Data,
654 IN UINTN Size
655 )
656 {
657 return SetWorker (TokenNumber, Data, &Size, FALSE);
658 }
659
660
661 /**
662 Set value for an PCD entry
663
664 @param TokenNumber Pcd token number autogenerated by build tools.
665 @param Data Value want to be set for PCD entry
666 @param Size Size of value.
667 @param PtrType If TRUE, the type of PCD entry's value is Pointer.
668 If False, the type of PCD entry's value is not Pointer.
669
670 @retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.
671 @retval EFI_INVALID_PARAMETER If Size can not be set to size table.
672 @retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in
673 range of UINT8, UINT16, UINT32, UINT64
674 @retval EFI_NOT_FOUND Can not find the PCD type according to token number.
675 **/
676 EFI_STATUS
677 SetWorker (
678 IN UINTN TokenNumber,
679 IN VOID *Data,
680 IN OUT UINTN *Size,
681 IN BOOLEAN PtrType
682 )
683 {
684 UINT32 *LocalTokenNumberTable;
685 BOOLEAN IsPeiDb;
686 UINT32 LocalTokenNumber;
687 EFI_GUID *GuidTable;
688 UINT16 *StringTable;
689 EFI_GUID *Guid;
690 UINT16 *Name;
691 UINTN VariableOffset;
692 VOID *InternalData;
693 VARIABLE_HEAD *VariableHead;
694 UINTN Offset;
695 UINT8 *PcdDb;
696 EFI_STATUS Status;
697 UINTN MaxSize;
698 UINTN TmpTokenNumber;
699
700 //
701 // Aquire lock to prevent reentrance from TPL_CALLBACK level
702 //
703 EfiAcquireLock (&mPcdDatabaseLock);
704
705 //
706 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
707 // We have to decrement TokenNumber by 1 to make it usable
708 // as the array index.
709 //
710 TokenNumber--;
711
712 TmpTokenNumber = TokenNumber;
713
714 //
715 // EBC compiler is very choosy. It may report warning about comparison
716 // between UINTN and 0 . So we add 1 in each size of the
717 // comparison.
718 //
719 ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);
720
721 if (!PtrType) {
722 ASSERT (*Size == DxePcdGetSize (TokenNumber + 1));
723 }
724
725 //
726 // EBC compiler is very choosy. It may report warning about comparison
727 // between UINTN and 0 . So we add 1 in each size of the
728 // comparison.
729 //
730 IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);
731
732 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
733 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
734
735 //
736 // EBC compiler is very choosy. It may report warning about comparison
737 // between UINTN and 0 . So we add 1 in each size of the
738 // comparison.
739 //
740 if ((TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) ||
741 (TokenNumber + 1 >= PEI_LOCAL_TOKEN_NUMBER + 1 || TokenNumber + 1 < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1))) {
742 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);
743 }
744
745 TokenNumber = IsPeiDb ? TokenNumber
746 : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
747
748 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
749
750 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
751 if (PtrType) {
752 GetPtrTypeSize (TmpTokenNumber, &MaxSize);
753 } else {
754 MaxSize = *Size;
755 }
756 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);
757 }
758
759 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
760
761 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);
762
763 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :
764 mPcdDatabase->DxeDb.Init.StringTable;
765
766 InternalData = PcdDb + Offset;
767
768 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
769 case PCD_TYPE_VPD:
770 ASSERT (FALSE);
771 Status = EFI_INVALID_PARAMETER;
772 break;
773
774 case PCD_TYPE_STRING:
775 if (SetPtrTypeSize (TmpTokenNumber, Size)) {
776 CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, *Size);
777 Status = EFI_SUCCESS;
778 } else {
779 Status = EFI_INVALID_PARAMETER;
780 }
781 break;
782
783 case PCD_TYPE_HII:
784 if (PtrType) {
785 if (!SetPtrTypeSize (TmpTokenNumber, Size)) {
786 Status = EFI_INVALID_PARAMETER;
787 break;
788 }
789 }
790
791 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :
792 mPcdDatabase->DxeDb.Init.GuidTable;
793
794 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
795
796 Guid = &(GuidTable[VariableHead->GuidTableIndex]);
797 Name = &(StringTable[VariableHead->StringIndex]);
798 VariableOffset = VariableHead->Offset;
799
800 Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset);
801
802 if (EFI_NOT_FOUND == Status) {
803 CopyMem (PcdDb + VariableHead->DefaultValueOffset, Data, *Size);
804 Status = EFI_SUCCESS;
805 }
806 break;
807
808 case PCD_TYPE_DATA:
809 if (PtrType) {
810 if (SetPtrTypeSize (TmpTokenNumber, Size)) {
811 CopyMem (InternalData, Data, *Size);
812 Status = EFI_SUCCESS;
813 } else {
814 Status = EFI_INVALID_PARAMETER;
815 }
816 break;
817 }
818
819 Status = EFI_SUCCESS;
820 switch (*Size) {
821 case sizeof(UINT8):
822 *((UINT8 *) InternalData) = *((UINT8 *) Data);
823 break;
824
825 case sizeof(UINT16):
826 *((UINT16 *) InternalData) = *((UINT16 *) Data);
827 break;
828
829 case sizeof(UINT32):
830 *((UINT32 *) InternalData) = *((UINT32 *) Data);
831 break;
832
833 case sizeof(UINT64):
834 *((UINT64 *) InternalData) = *((UINT64 *) Data);
835 break;
836
837 default:
838 ASSERT (FALSE);
839 Status = EFI_NOT_FOUND;
840 break;
841 }
842 break;
843
844 default:
845 ASSERT (FALSE);
846 Status = EFI_NOT_FOUND;
847 break;
848 }
849
850 EfiReleaseLock (&mPcdDatabaseLock);
851
852 return Status;
853 }
854
855 /**
856 Wrapper function for get PCD value for dynamic-ex PCD.
857
858 @param Guid Token space guid for dynamic-ex PCD.
859 @param ExTokenNumber Token number for dyanmic-ex PCD.
860 @param GetSize The size of dynamic-ex PCD value.
861
862 @return PCD entry in PCD database.
863
864 **/
865 VOID *
866 ExGetWorker (
867 IN CONST EFI_GUID *Guid,
868 IN UINTN ExTokenNumber,
869 IN UINTN GetSize
870 )
871 {
872 return GetWorker(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber), GetSize);
873 }
874
875 /**
876 Wrapper function for set PCD value for non-Pointer type dynamic-ex PCD.
877
878 @param ExTokenNumber Token number for dynamic-ex PCD.
879 @param Guid Token space guid for dynamic-ex PCD.
880 @param Data Value want to be set.
881 @param SetSize The size of value.
882
883 @return status of ExSetWorker().
884
885 **/
886 EFI_STATUS
887 ExSetValueWorker (
888 IN UINTN ExTokenNumber,
889 IN CONST EFI_GUID *Guid,
890 IN VOID *Data,
891 IN UINTN SetSize
892 )
893 {
894 return ExSetWorker (ExTokenNumber, Guid, Data, &SetSize, FALSE);
895 }
896
897 /**
898 Set value for a dynamic PCD entry.
899
900 This routine find the local token number according to dynamic-ex PCD's token
901 space guid and token number firstly, and invoke callback function if this PCD
902 entry registered callback function. Finally, invoken general SetWorker to set
903 PCD value.
904
905 @param ExTokenNumber Dynamic-ex PCD token number.
906 @param Guid Token space guid for dynamic-ex PCD.
907 @param Data PCD value want to be set
908 @param SetSize Size of value.
909 @param PtrType If TRUE, this PCD entry is pointer type.
910 If FALSE, this PCD entry is not pointer type.
911
912 @return status of SetWorker().
913
914 **/
915 EFI_STATUS
916 ExSetWorker (
917 IN UINTN ExTokenNumber,
918 IN CONST EFI_GUID *Guid,
919 IN VOID *Data,
920 IN OUT UINTN *SetSize,
921 IN BOOLEAN PtrType
922 )
923 {
924 UINTN TokenNumber;
925
926 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber);
927
928 InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, *SetSize);
929
930 return SetWorker (TokenNumber, Data, SetSize, PtrType);
931
932 }
933
934 /**
935 Set value for HII-type PCD.
936
937 A HII-type PCD's value is stored in a variable. Setting/Getting the value of
938 HII-type PCD is to visit this variable.
939
940 @param VariableGuid Guid of variable which stored value of a HII-type PCD.
941 @param VariableName Unicode name of variable which stored value of a HII-type PCD.
942 @param Data Value want to be set.
943 @param DataSize Size of value
944 @param Offset Value offset of HII-type PCD in variable.
945
946 @return status of GetVariable()/SetVariable().
947
948 **/
949 EFI_STATUS
950 SetHiiVariable (
951 IN EFI_GUID *VariableGuid,
952 IN UINT16 *VariableName,
953 IN CONST VOID *Data,
954 IN UINTN DataSize,
955 IN UINTN Offset
956 )
957 {
958 UINTN Size;
959 VOID *Buffer;
960 EFI_STATUS Status;
961 UINT32 Attribute;
962
963 Size = 0;
964
965 Status = gRT->GetVariable (
966 (UINT16 *)VariableName,
967 VariableGuid,
968 NULL,
969 &Size,
970 NULL
971 );
972
973 if (Status == EFI_BUFFER_TOO_SMALL) {
974
975 Buffer = AllocatePool (Size);
976
977 ASSERT (Buffer != NULL);
978
979 Status = gRT->GetVariable (
980 VariableName,
981 VariableGuid,
982 &Attribute,
983 &Size,
984 Buffer
985 );
986
987 ASSERT_EFI_ERROR (Status);
988
989 CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);
990
991 Status = gRT->SetVariable (
992 VariableName,
993 VariableGuid,
994 Attribute,
995 Size,
996 Buffer
997 );
998
999 FreePool (Buffer);
1000 return Status;
1001
1002 }
1003
1004 //
1005 // If we drop to here, we don't have a Variable entry in
1006 // the variable service yet. So, we will save the data
1007 // in the PCD Database's volatile area.
1008 //
1009 return Status;
1010 }
1011
1012 /**
1013 Get local token number according to dynamic-ex PCD's {token space guid:token number}
1014
1015 A dynamic-ex type PCD, developer must provide pair of token space guid: token number
1016 in DEC file. PCD database maintain a mapping table that translate pair of {token
1017 space guid: token number} to local token number.
1018
1019 @param Guid Token space guid for dynamic-ex PCD entry.
1020 @param ExTokenNumber EDES_TODO: Add parameter description
1021
1022 @return local token number for dynamic-ex PCD.
1023
1024 **/
1025 UINTN
1026 GetExPcdTokenNumber (
1027 IN CONST EFI_GUID *Guid,
1028 IN UINT32 ExTokenNumber
1029 )
1030 {
1031 UINT32 Index;
1032 DYNAMICEX_MAPPING *ExMap;
1033 EFI_GUID *GuidTable;
1034 EFI_GUID *MatchGuid;
1035 UINTN MatchGuidIdx;
1036
1037 if (!PEI_DATABASE_EMPTY) {
1038 ExMap = mPcdDatabase->PeiDb.Init.ExMapTable;
1039 GuidTable = mPcdDatabase->PeiDb.Init.GuidTable;
1040
1041 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);
1042
1043 if (MatchGuid != NULL) {
1044
1045 MatchGuidIdx = MatchGuid - GuidTable;
1046
1047 for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
1048 if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
1049 (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
1050 return ExMap[Index].LocalTokenNumber;
1051
1052 }
1053 }
1054 }
1055 }
1056
1057 ExMap = mPcdDatabase->DxeDb.Init.ExMapTable;
1058 GuidTable = mPcdDatabase->DxeDb.Init.GuidTable;
1059
1060 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);
1061 //
1062 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a
1063 // error in the BUILD system.
1064 //
1065 ASSERT (MatchGuid != NULL);
1066
1067 MatchGuidIdx = MatchGuid - GuidTable;
1068
1069 for (Index = 0; Index < DXE_EXMAPPING_TABLE_SIZE; Index++) {
1070 if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
1071 (MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
1072 return ExMap[Index].LocalTokenNumber;
1073 }
1074 }
1075
1076 ASSERT (FALSE);
1077
1078 return 0;
1079 }
1080
1081 /**
1082 Get SKU ID tabble from PCD database.
1083
1084 @param LocalTokenNumberTableIdx Index of local token number in token number table.
1085 @param IsPeiPcd If TRUE,
1086
1087 @return Pointer to SKU ID array table
1088
1089 **/
1090 SKU_ID *
1091 GetSkuIdArray (
1092 IN UINTN LocalTokenNumberTableIdx,
1093 IN BOOLEAN IsPeiPcd
1094 )
1095 {
1096 SKU_HEAD *SkuHead;
1097 UINTN LocalTokenNumber;
1098 UINT8 *Database;
1099
1100 if (IsPeiPcd) {
1101 LocalTokenNumber = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
1102 Database = (UINT8 *) &mPcdDatabase->PeiDb;
1103 } else {
1104 LocalTokenNumber = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx - PEI_LOCAL_TOKEN_NUMBER];
1105 Database = (UINT8 *) &mPcdDatabase->DxeDb;
1106 }
1107
1108 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);
1109
1110 SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
1111
1112 return (SKU_ID *) (Database + SkuHead->SkuIdTableOffset);
1113
1114 }
1115
1116
1117 /**
1118 Get index of PCD entry in size table.
1119
1120 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
1121 @param LocalTokenNumberTable Pointer to local token number table in PCD database.
1122 @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
1123 If FALSE, the pcd entry is initialized in DXE phase.
1124
1125 @return index of PCD entry in size table.
1126
1127 **/
1128 UINTN
1129 GetSizeTableIndexA (
1130 IN UINTN LocalTokenNumberTableIdx,
1131 IN UINT32 *LocalTokenNumberTable,
1132 IN BOOLEAN IsPeiDb
1133 )
1134 {
1135 UINTN Index;
1136 UINTN SizeTableIdx;
1137 UINTN LocalTokenNumber;
1138 SKU_ID *SkuIdTable;
1139
1140 SizeTableIdx = 0;
1141
1142 for (Index=0; Index<LocalTokenNumberTableIdx; Index++) {
1143 LocalTokenNumber = LocalTokenNumberTable[Index];
1144
1145 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {
1146 //
1147 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1148 // PCD entry.
1149 //
1150 if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
1151 //
1152 // We have only one entry for VPD enabled PCD entry:
1153 // 1) MAX Size.
1154 // We consider current size is equal to MAX size.
1155 //
1156 SizeTableIdx++;
1157 } else {
1158 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
1159 //
1160 // We have only two entry for Non-Sku enabled PCD entry:
1161 // 1) MAX SIZE
1162 // 2) Current Size
1163 //
1164 SizeTableIdx += 2;
1165 } else {
1166 //
1167 // We have these entry for SKU enabled PCD entry
1168 // 1) MAX SIZE
1169 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1170 //
1171 SkuIdTable = GetSkuIdArray (Index, IsPeiDb);
1172 SizeTableIdx += (UINTN)*SkuIdTable + 1;
1173 }
1174 }
1175 }
1176
1177 }
1178
1179 return SizeTableIdx;
1180 }
1181
1182
1183
1184 /**
1185 Wrapper function of getting index of PCD entry in size table.
1186
1187 @param LocalTokenNumberTableIdx Index of this PCD in local token number table.
1188 @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
1189 If FALSE, the pcd entry is initialized in DXE phase.
1190
1191 @return index of PCD entry in size table.
1192 **/
1193 UINTN
1194 GetSizeTableIndex (
1195 IN UINTN LocalTokenNumberTableIdx,
1196 IN BOOLEAN IsPeiDb
1197 )
1198 {
1199 UINT32 *LocalTokenNumberTable;
1200
1201 if (IsPeiDb) {
1202 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
1203 } else {
1204 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
1205 }
1206 return GetSizeTableIndexA (LocalTokenNumberTableIdx,
1207 LocalTokenNumberTable,
1208 IsPeiDb);
1209 }
1210
1211 /**
1212 Get size of POINTER type PCD value.
1213
1214 @param LocalTokenNumberTableIdx Index of local token number in local token number table.
1215 @param MaxSize Maxmium size of POINTER type PCD value.
1216
1217 @return size of POINTER type PCD value.
1218
1219 **/
1220 UINTN
1221 GetPtrTypeSize (
1222 IN UINTN LocalTokenNumberTableIdx,
1223 OUT UINTN *MaxSize
1224 )
1225 {
1226 INTN SizeTableIdx;
1227 UINTN LocalTokenNumber;
1228 SKU_ID *SkuIdTable;
1229 SIZE_INFO *SizeTable;
1230 UINTN Index;
1231 BOOLEAN IsPeiDb;
1232 UINT32 *LocalTokenNumberTable;
1233
1234 // EBC compiler is very choosy. It may report warning about comparison
1235 // between UINTN and 0 . So we add 1 in each size of the
1236 // comparison.
1237 IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
1238
1239
1240 if (IsPeiDb) {
1241 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
1242 SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;
1243 } else {
1244 LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;
1245 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
1246 SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;
1247 }
1248
1249 LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];
1250
1251 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
1252
1253 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);
1254
1255 *MaxSize = SizeTable[SizeTableIdx];
1256 //
1257 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1258 // PCD entry.
1259 //
1260 if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
1261 //
1262 // We have only one entry for VPD enabled PCD entry:
1263 // 1) MAX Size.
1264 // We consider current size is equal to MAX size.
1265 //
1266 return *MaxSize;
1267 } else {
1268 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
1269 //
1270 // We have only two entry for Non-Sku enabled PCD entry:
1271 // 1) MAX SIZE
1272 // 2) Current Size
1273 //
1274 return SizeTable[SizeTableIdx + 1];
1275 } else {
1276 //
1277 // We have these entry for SKU enabled PCD entry
1278 // 1) MAX SIZE
1279 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1280 //
1281 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);
1282 for (Index = 0; Index < SkuIdTable[0]; Index++) {
1283 if (SkuIdTable[1 + Index] == mPcdDatabase->PeiDb.Init.SystemSkuId) {
1284 return SizeTable[SizeTableIdx + 1 + Index];
1285 }
1286 }
1287 return SizeTable[SizeTableIdx + 1];
1288 }
1289 }
1290 }
1291
1292 /**
1293 Set size of POINTER type PCD value. The size should not exceed the maxmium size
1294 of this PCD value.
1295
1296 @param LocalTokenNumberTableIdx Index of local token number in local token number table.
1297 @param CurrentSize Size of POINTER type PCD value.
1298
1299 @retval TRUE Success to set size of PCD value.
1300 @retval FALSE Fail to set size of PCD value.
1301 **/
1302 BOOLEAN
1303 SetPtrTypeSize (
1304 IN UINTN LocalTokenNumberTableIdx,
1305 IN OUT UINTN *CurrentSize
1306 )
1307 {
1308 INTN SizeTableIdx;
1309 UINTN LocalTokenNumber;
1310 SKU_ID *SkuIdTable;
1311 SIZE_INFO *SizeTable;
1312 UINTN Index;
1313 UINTN MaxSize;
1314 BOOLEAN IsPeiDb;
1315 UINT32 *LocalTokenNumberTable;
1316
1317 //
1318 // EBC compiler is very choosy. It may report warning about comparison
1319 // between UINTN and 0 . So we add 1 in each size of the
1320 // comparison.
1321 //
1322 IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
1323
1324 if (IsPeiDb) {
1325 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
1326 SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;
1327 } else {
1328 LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;
1329 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
1330 SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;
1331 }
1332
1333 LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];
1334
1335 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
1336
1337 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);
1338
1339 MaxSize = SizeTable[SizeTableIdx];
1340 //
1341 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
1342 // PCD entry.
1343 //
1344 if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
1345 //
1346 // We shouldn't come here as we don't support SET for VPD
1347 //
1348 ASSERT (FALSE);
1349 return FALSE;
1350 } else {
1351 if ((*CurrentSize > MaxSize) ||
1352 (*CurrentSize == MAX_ADDRESS)) {
1353 *CurrentSize = MaxSize;
1354 return FALSE;
1355 }
1356
1357 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
1358 //
1359 // We have only two entry for Non-Sku enabled PCD entry:
1360 // 1) MAX SIZE
1361 // 2) Current Size
1362 //
1363 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;
1364 return TRUE;
1365 } else {
1366 //
1367 // We have these entry for SKU enabled PCD entry
1368 // 1) MAX SIZE
1369 // 2) Current Size for each SKU_ID (It is equal to MaxSku).
1370 //
1371 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);
1372 for (Index = 0; Index < SkuIdTable[0]; Index++) {
1373 if (SkuIdTable[1 + Index] == mPcdDatabase->PeiDb.Init.SystemSkuId) {
1374 SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;
1375 return TRUE;
1376 }
1377 }
1378 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;
1379 return TRUE;
1380 }
1381 }
1382 }