1) Use FeatureFlag PcdPciBusHotplugDeviceSupport to merge LightPciLib.c with PcdLib.c.
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Dxe / Service.c
CommitLineData
878ddf1f 1/** @file\r
a7c5092f 2Private functions used by PCD DXE driver.\r
878ddf1f 3\r
4Copyright (c) 2006, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13\r
14Module Name: Service.c\r
15\r
16**/\r
878ddf1f 17#include "Service.h"\r
18\r
878ddf1f 19\r
4c114006 20PCD_DATABASE * mPcdDatabase;\r
878ddf1f 21\r
abc25afa 22LIST_ENTRY *mCallbackFnTable;\r
878ddf1f 23\r
52e1905d 24VOID *\r
9d6d8b24 25GetWorker (\r
8a43e8dd 26 UINTN TokenNumber,\r
9d6d8b24 27 UINTN GetSize\r
28 )\r
878ddf1f 29{\r
9d6d8b24 30 UINT32 *LocalTokenNumberTable;\r
31 UINT16 *SizeTable;\r
32 BOOLEAN IsPeiDb;\r
52e1905d 33 UINT32 Offset;\r
34 EFI_GUID *GuidTable;\r
35 UINT16 *StringTable;\r
36 EFI_GUID *Guid;\r
37 UINT16 *Name;\r
38 VARIABLE_HEAD *VariableHead;\r
1de04b4f 39 UINT8 *VaraiableDefaultBuffer;\r
52e1905d 40 EFI_STATUS Status;\r
41 UINTN DataSize;\r
1de04b4f 42 UINT8 *Data;\r
52e1905d 43 VPD_HEAD *VpdHead;\r
44 UINT8 *PcdDb;\r
45 UINT16 StringTableIdx; \r
9d6d8b24 46 UINT32 LocalTokenNumber;\r
1de04b4f 47 UINTN MaxSize;\r
48 UINTN TmpTokenNumber;\r
9d6d8b24 49\r
58f1099f 50 //\r
51 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
52 // We have to decrement TokenNumber by 1 to make it usable\r
53 // as the array index.\r
54 //\r
55 TokenNumber--;\r
1de04b4f 56\r
57 TmpTokenNumber = TokenNumber;\r
58f1099f 58 \r
4f914125 59 //\r
60 // PCD_TOTAL_TOKEN_NUMBER is a auto-generated constant.\r
61 // It could be zero. EBC compiler is very choosy. It may\r
62 // report warning. So we add 1 in each size of the \r
63 // comparison.\r
64 //\r
65 ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);\r
9d6d8b24 66\r
1de04b4f 67 ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0));\r
52e1905d 68\r
4f914125 69 // EBC compiler is very choosy. It may report warning about comparison\r
70 // between UINTN and 0 . So we add 1 in each size of the \r
71 // comparison.\r
72 IsPeiDb = (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE;\r
9d6d8b24 73\r
74 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
75 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
76\r
77 SizeTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SizeTable: \r
78 mPcdDatabase->DxeDb.Init.SizeTable;\r
79\r
80 TokenNumber = IsPeiDb ? TokenNumber :\r
81 TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
82\r
83 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
84 \r
52e1905d 85 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
1de04b4f 86 if (GetSize == 0) {\r
87 GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
88 } else {\r
89 MaxSize = GetSize;\r
90 }\r
91 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);\r
52e1905d 92 }\r
93\r
4c114006 94 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
95 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :\r
96 mPcdDatabase->DxeDb.Init.StringTable;\r
52e1905d 97 \r
98 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
99 \r
1de04b4f 100 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 101 case PCD_TYPE_VPD:\r
102 VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset);\r
4f242357 103 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
52e1905d 104 \r
105 case PCD_TYPE_HII:\r
4c114006 106 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :\r
107 mPcdDatabase->DxeDb.Init.GuidTable;\r
52e1905d 108 \r
109 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
110 \r
111 Guid = &(GuidTable[VariableHead->GuidTableIndex]);\r
112 Name = &(StringTable[VariableHead->StringIndex]);\r
1de04b4f 113 VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset;\r
878ddf1f 114\r
2b21a971 115 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
c0e96fed 116 if (Status == EFI_SUCCESS) {\r
1de04b4f 117 if (GetSize == 0) {\r
118 //\r
119 // It is a pointer type. So get the MaxSize reserved for\r
120 // this PCD entry.\r
121 //\r
4c29d433 122 GetPtrTypeSize (TmpTokenNumber, &GetSize);\r
1de04b4f 123 }\r
124 CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);\r
125 FreePool (Data);\r
126 }\r
127 //\r
128 // If the operation is successful, we copy the data\r
129 // to the default value buffer in the PCD Database.\r
130 // So that we can free the Data allocated in GetHiiVariable.\r
131 //\r
132 //\r
133 // If the operation is not successful, \r
134 // Return 1) either the default value specified by Platform Integrator \r
135 // 2) Or the value Set by a PCD set operation.\r
136 //\r
137 return (VOID *) VaraiableDefaultBuffer;\r
878ddf1f 138\r
52e1905d 139 case PCD_TYPE_STRING:\r
140 StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset);\r
141 return (VOID *) &StringTable[StringTableIdx];\r
878ddf1f 142\r
52e1905d 143 case PCD_TYPE_DATA:\r
144 return (VOID *) ((UINT8 *) PcdDb + Offset);\r
145 break;\r
878ddf1f 146\r
52e1905d 147 default:\r
148 ASSERT (FALSE);\r
149 break;\r
150 \r
151 }\r
878ddf1f 152\r
52e1905d 153 ASSERT (FALSE);\r
154 \r
155 return NULL;\r
52e1905d 156 \r
52e1905d 157}\r
878ddf1f 158\r
878ddf1f 159\r
160\r
52e1905d 161EFI_STATUS\r
162DxeRegisterCallBackWorker (\r
8a43e8dd 163 IN UINTN TokenNumber,\r
52e1905d 164 IN CONST GUID *Guid, OPTIONAL\r
4c114006 165 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
52e1905d 166)\r
167{\r
4c114006 168 CALLBACK_FN_ENTRY *FnTableEntry;\r
4c114006 169 LIST_ENTRY *ListHead;\r
170 LIST_ENTRY *ListNode;\r
171\r
172 if (Guid != NULL) {\r
4f242357 173 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
4c114006 174 }\r
175\r
58f1099f 176 //\r
177 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
178 // We have to decrement TokenNumber by 1 to make it usable\r
179 // as the array index.\r
180 //\r
181 TokenNumber--;\r
182\r
4c114006 183 ListHead = &mCallbackFnTable[TokenNumber];\r
184 ListNode = GetFirstNode (ListHead);\r
185\r
186 while (ListNode != ListHead) {\r
187 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
188\r
189 if (FnTableEntry->CallbackFn == CallBackFunction) {\r
190 //\r
191 // We only allow a Callback function to be register once\r
192 // for a TokenNumber. So just return EFI_SUCCESS\r
193 //\r
194 return EFI_SUCCESS;\r
195 }\r
196 ListNode = GetNextNode (ListHead, ListNode);\r
197 }\r
198\r
199 FnTableEntry = AllocatePool (sizeof(CALLBACK_FN_ENTRY));\r
200 ASSERT (FnTableEntry != NULL);\r
201\r
202 FnTableEntry->CallbackFn = CallBackFunction;\r
203 InsertTailList (ListHead, &FnTableEntry->Node);\r
52e1905d 204 \r
205 return EFI_SUCCESS;\r
878ddf1f 206}\r
207\r
208\r
4c114006 209\r
210\r
52e1905d 211EFI_STATUS\r
4c114006 212DxeUnRegisterCallBackWorker (\r
8a43e8dd 213 IN UINTN TokenNumber,\r
4c114006 214 IN CONST GUID *Guid, OPTIONAL\r
215 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
216)\r
217{\r
218 CALLBACK_FN_ENTRY *FnTableEntry;\r
4c114006 219 LIST_ENTRY *ListHead;\r
220 LIST_ENTRY *ListNode;\r
221\r
222 if (Guid != NULL) {\r
4f242357 223 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
4c114006 224 }\r
225\r
58f1099f 226 //\r
227 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
228 // We have to decrement TokenNumber by 1 to make it usable\r
229 // as the array index.\r
230 //\r
231 TokenNumber--;\r
232\r
4c114006 233 ListHead = &mCallbackFnTable[TokenNumber];\r
234 ListNode = GetFirstNode (ListHead);\r
235\r
236 while (ListNode != ListHead) {\r
237 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
238\r
239 if (FnTableEntry->CallbackFn == CallBackFunction) {\r
240 //\r
241 // We only allow a Callback function to be register once\r
242 // for a TokenNumber. So we can safely remove the Node from\r
243 // the Link List and return EFI_SUCCESS.\r
244 //\r
245 RemoveEntryList (ListNode);\r
246 FreePool (FnTableEntry);\r
247 \r
248 return EFI_SUCCESS;\r
249 }\r
250 ListNode = GetNextNode (ListHead, ListNode);\r
251 }\r
252\r
253 return EFI_INVALID_PARAMETER;\r
254}\r
255\r
256\r
257\r
2b21a971 258EFI_STATUS\r
4c114006 259ExGetNextTokeNumber (\r
2b21a971 260 IN CONST EFI_GUID *Guid,\r
261 IN OUT UINTN *TokenNumber,\r
262 IN EFI_GUID *GuidTable,\r
263 IN UINTN SizeOfGuidTable,\r
264 IN DYNAMICEX_MAPPING *ExMapTable,\r
265 IN UINTN SizeOfExMapTable\r
878ddf1f 266 )\r
267{\r
4c114006 268 EFI_GUID *MatchGuid;\r
269 UINTN Idx;\r
270 UINTN GuidTableIdx;\r
271 BOOLEAN Found;\r
272\r
273 MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid);\r
274 if (MatchGuid == NULL) {\r
2b21a971 275 return EFI_NOT_FOUND;\r
4c114006 276 }\r
277\r
278 Found = FALSE;\r
279 GuidTableIdx = MatchGuid - GuidTable;\r
280 for (Idx = 0; Idx < SizeOfExMapTable; Idx++) {\r
281 if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) {\r
282 Found = TRUE;\r
283 break;\r
284 }\r
285 }\r
286\r
287 if (Found) {\r
2b21a971 288 if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
289 *TokenNumber = ExMapTable[Idx].ExTokenNumber;\r
290 return EFI_SUCCESS;\r
4c114006 291 }\r
4276d5da 292\r
4c114006 293 for ( ; Idx < SizeOfExMapTable; Idx++) {\r
2b21a971 294 if (ExMapTable[Idx].ExTokenNumber == *TokenNumber) {\r
4c114006 295 Idx++;\r
296 if (Idx == SizeOfExMapTable) {\r
297 //\r
298 // Exceed the length of ExMap Table\r
299 //\r
2b21a971 300 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
301 return EFI_SUCCESS;\r
4c114006 302 } else if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) {\r
303 //\r
304 // Found the next match\r
305 //\r
2b21a971 306 *TokenNumber = ExMapTable[Idx].ExTokenNumber;\r
307 return EFI_SUCCESS;\r
4c114006 308 } else {\r
309 //\r
310 // Guid has been changed. It is the next Token Space Guid.\r
311 // We should flag no more TokenNumber.\r
312 //\r
2b21a971 313 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
314 return EFI_SUCCESS;\r
4c114006 315 }\r
316 }\r
317 }\r
318 }\r
319 \r
2b21a971 320 return EFI_NOT_FOUND;\r
878ddf1f 321}\r
4c114006 322 \r
878ddf1f 323\r
324\r
325\r
52e1905d 326VOID\r
327BuildPcdDxeDataBase (\r
328 VOID\r
8a43e8dd 329 )\r
878ddf1f 330{\r
52e1905d 331 PEI_PCD_DATABASE *PeiDatabase;\r
332 EFI_HOB_GUID_TYPE *GuidHob;\r
4c114006 333 UINTN Idx;\r
878ddf1f 334\r
4c114006 335 mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));\r
336 ASSERT (mPcdDatabase != NULL);\r
878ddf1f 337\r
52e1905d 338 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
3496595d 339 if (GuidHob != NULL) {\r
340\r
341 //\r
342 // We will copy over the PEI phase's PCD Database.\r
343 // \r
344 // If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM\r
345 // should not be included at all. So the GuidHob could\r
346 // be NULL. If it is NULL, we just copy over the DXE Default\r
347 // Value to PCD Database.\r
348 //\r
349 \r
350 PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
351 //\r
352 // Copy PCD Entries refereneced in PEI phase to PCD DATABASE\r
353 //\r
354 CopyMem (&mPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE));\r
355 }\r
52e1905d 356\r
357 //\r
358 // Copy PCD Entries with default value to PCD DATABASE\r
359 //\r
4c114006 360 CopyMem (&mPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT));\r
361\r
362\r
363 //\r
364 // Initialized the Callback Function Table\r
365 //\r
abc25afa 366\r
4f914125 367 mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY));\r
abc25afa 368 \r
4f914125 369 // EBC compiler is very choosy. It may report warning about comparison\r
370 // between UINTN and 0 . So we add 1 in each size of the \r
371 // comparison.\r
372 for (Idx = 0; Idx + 1 < PCD_TOTAL_TOKEN_NUMBER + 1; Idx++) {\r
4c114006 373 InitializeListHead (&mCallbackFnTable[Idx]);\r
374 }\r
52e1905d 375 \r
376 return;\r
878ddf1f 377}\r
378\r
379\r
380\r
52e1905d 381EFI_STATUS\r
382GetHiiVariable (\r
383 IN EFI_GUID *VariableGuid,\r
384 IN UINT16 *VariableName,\r
2b21a971 385 OUT UINT8 **VariableData,\r
52e1905d 386 OUT UINTN *VariableSize\r
878ddf1f 387 )\r
388{\r
52e1905d 389 UINTN Size;\r
390 EFI_STATUS Status;\r
2b21a971 391 UINT8 *Buffer;\r
878ddf1f 392\r
58f1099f 393 Size = 0;\r
394 Buffer = NULL;\r
395 \r
4f914125 396 Status = gRT->GetVariable (\r
52e1905d 397 (UINT16 *)VariableName,\r
398 VariableGuid,\r
399 NULL,\r
400 &Size,\r
58f1099f 401 Buffer\r
52e1905d 402 );\r
58f1099f 403 \r
c0e96fed 404 if (Status == EFI_BUFFER_TOO_SMALL) {\r
2b21a971 405 Buffer = (UINT8 *) AllocatePool (Size);\r
878ddf1f 406\r
c0e96fed 407 ASSERT (Buffer != NULL);\r
878ddf1f 408\r
4f914125 409 Status = gRT->GetVariable (\r
c0e96fed 410 VariableName,\r
411 VariableGuid,\r
412 NULL,\r
413 &Size,\r
414 Buffer\r
415 );\r
416\r
417 ASSERT (Status == EFI_SUCCESS);\r
1de04b4f 418 *VariableData = Buffer;\r
419 *VariableSize = Size;\r
c0e96fed 420 }\r
878ddf1f 421\r
52e1905d 422 return Status;\r
878ddf1f 423}\r
424\r
425\r
52e1905d 426UINT32\r
427GetSkuEnabledTokenNumber (\r
428 UINT32 LocalTokenNumber,\r
429 UINTN Size,\r
430 BOOLEAN IsPeiDb\r
431 ) \r
432{\r
433 SKU_HEAD *SkuHead;\r
434 SKU_ID *SkuIdTable;\r
435 INTN i;\r
436 UINT8 *Value;\r
437 SKU_ID *PhaseSkuIdTable;\r
438 UINT8 *PcdDb;\r
878ddf1f 439\r
52e1905d 440 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
878ddf1f 441\r
4c114006 442 PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb;\r
878ddf1f 443\r
52e1905d 444 SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
445 Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset); \r
878ddf1f 446\r
4c114006 447 PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :\r
448 mPcdDatabase->DxeDb.Init.SkuIdTable;\r
52e1905d 449 \r
450 SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];\r
451 \r
452 for (i = 0; i < SkuIdTable[0]; i++) {\r
4c114006 453 if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[i + 1]) {\r
52e1905d 454 break;\r
878ddf1f 455 }\r
878ddf1f 456 }\r
52e1905d 457 ASSERT (i < SkuIdTable[0]);\r
878ddf1f 458\r
1de04b4f 459 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 460 case PCD_TYPE_VPD:\r
461 Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);\r
4f242357 462 return (UINT32) ((Value - PcdDb) | PCD_TYPE_VPD);\r
878ddf1f 463\r
52e1905d 464 case PCD_TYPE_HII:\r
465 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);\r
4f242357 466 return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);\r
1de04b4f 467\r
468 case PCD_TYPE_STRING:\r
469 Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]);\r
470 return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING);\r
52e1905d 471 \r
472 case PCD_TYPE_DATA:\r
473 Value += Size * i;\r
4f242357 474 return (UINT32) (Value - PcdDb);\r
1de04b4f 475\r
52e1905d 476 default:\r
477 ASSERT (FALSE);\r
478 }\r
479\r
480 ASSERT (FALSE);\r
481\r
482 return 0;\r
878ddf1f 483 \r
484}\r
485\r
878ddf1f 486\r
878ddf1f 487\r
878ddf1f 488\r
878ddf1f 489\r
52e1905d 490VOID\r
491InvokeCallbackOnSet (\r
492 UINT32 ExTokenNumber,\r
493 CONST EFI_GUID *Guid, OPTIONAL\r
494 UINTN TokenNumber,\r
495 VOID *Data,\r
496 UINTN Size\r
497 )\r
498{\r
4c114006 499 CALLBACK_FN_ENTRY *FnTableEntry;\r
500 LIST_ENTRY *ListHead;\r
501 LIST_ENTRY *ListNode;\r
502\r
58f1099f 503 //\r
504 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
505 // We have to decrement TokenNumber by 1 to make it usable\r
506 // as the array index.\r
507 //\r
508 TokenNumber--;\r
509 \r
4c114006 510 ListHead = &mCallbackFnTable[TokenNumber];\r
511 ListNode = GetFirstNode (ListHead);\r
512\r
513 while (ListNode != ListHead) {\r
514 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
515\r
516 FnTableEntry->CallbackFn(Guid, \r
517 (Guid == NULL) ? TokenNumber : ExTokenNumber,\r
518 Data,\r
519 Size);\r
520 \r
521 ListNode = GetNextNode (ListHead, ListNode);\r
522 }\r
523 \r
52e1905d 524 return;\r
878ddf1f 525}\r
526\r
527\r
1de04b4f 528EFI_STATUS\r
529SetValueWorker (\r
530 IN UINTN TokenNumber,\r
531 IN VOID *Data,\r
532 IN UINTN Size\r
533 )\r
534{\r
535 return SetWorker (TokenNumber, Data, &Size, FALSE);\r
536}\r
878ddf1f 537\r
52e1905d 538\r
878ddf1f 539EFI_STATUS\r
52e1905d 540SetWorker (\r
1de04b4f 541 IN UINTN TokenNumber,\r
542 IN VOID *Data,\r
543 IN OUT UINTN *Size,\r
544 IN BOOLEAN PtrType\r
878ddf1f 545 )\r
546{\r
52e1905d 547 UINT32 *LocalTokenNumberTable;\r
548 BOOLEAN IsPeiDb;\r
9d6d8b24 549 UINT32 LocalTokenNumber;\r
550 EFI_GUID *GuidTable;\r
551 UINT16 *StringTable;\r
552 EFI_GUID *Guid;\r
553 UINT16 *Name;\r
c0e96fed 554 UINTN VariableOffset;\r
9d6d8b24 555 VOID *InternalData;\r
556 VARIABLE_HEAD *VariableHead;\r
557 UINTN Offset;\r
558 UINT8 *PcdDb;\r
1de04b4f 559 EFI_STATUS Status;\r
560 UINTN MaxSize;\r
561 UINTN TmpTokenNumber;\r
878ddf1f 562\r
58f1099f 563 //\r
564 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
565 // We have to decrement TokenNumber by 1 to make it usable\r
566 // as the array index.\r
567 //\r
568 TokenNumber--;\r
1de04b4f 569\r
570 TmpTokenNumber = TokenNumber;\r
58f1099f 571 \r
4f914125 572 // EBC compiler is very choosy. It may report warning about comparison\r
573 // between UINTN and 0 . So we add 1 in each size of the \r
574 // comparison.\r
575\r
576 ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);\r
878ddf1f 577\r
1de04b4f 578 if (!PtrType) {\r
579 ASSERT (*Size == DxePcdGetSize (TokenNumber + 1));\r
878ddf1f 580 }\r
878ddf1f 581 \r
4f914125 582 // EBC compiler is very choosy. It may report warning about comparison\r
583 // between UINTN and 0 . So we add 1 in each size of the \r
584 // comparison.\r
585 IsPeiDb = (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE;\r
878ddf1f 586\r
4c114006 587 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
588 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
878ddf1f 589\r
4f914125 590 // EBC compiler is very choosy. It may report warning about comparison\r
591 // between UINTN and 0 . So we add 1 in each size of the \r
592 // comparison.\r
593 if ((TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) ||\r
594 (TokenNumber + 1 >= PEI_LOCAL_TOKEN_NUMBER + 1 || TokenNumber + 1 < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1))) {\r
1de04b4f 595 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
9d6d8b24 596 }\r
0653eb89 597\r
52e1905d 598 TokenNumber = IsPeiDb ? TokenNumber\r
599 : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
878ddf1f 600\r
9d6d8b24 601 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
52e1905d 602 \r
52e1905d 603 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
1de04b4f 604 if (PtrType) {\r
605 GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
606 } else {\r
607 MaxSize = *Size;\r
608 }\r
609 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);\r
52e1905d 610 }\r
878ddf1f 611\r
52e1905d 612 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
878ddf1f 613\r
4c114006 614 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
878ddf1f 615\r
4c114006 616 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :\r
617 mPcdDatabase->DxeDb.Init.StringTable;\r
52e1905d 618 \r
619 InternalData = PcdDb + Offset;\r
878ddf1f 620\r
1de04b4f 621 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 622 case PCD_TYPE_VPD:\r
623 ASSERT (FALSE);\r
624 return EFI_INVALID_PARAMETER;\r
625 \r
626 case PCD_TYPE_STRING:\r
4c29d433 627 if (SetPtrTypeSize (TmpTokenNumber, Size)) {\r
1de04b4f 628 CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, *Size);\r
629 return EFI_SUCCESS;\r
630 } else {\r
631 return EFI_INVALID_PARAMETER;\r
632 }\r
878ddf1f 633\r
52e1905d 634 case PCD_TYPE_HII:\r
1de04b4f 635 if (PtrType) {\r
4c29d433 636 if (!SetPtrTypeSize (TmpTokenNumber, Size)) {\r
1de04b4f 637 return EFI_INVALID_PARAMETER;\r
638 }\r
639 }\r
640 \r
4c114006 641 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :\r
642 mPcdDatabase->DxeDb.Init.GuidTable;\r
52e1905d 643 \r
644 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
645 \r
646 Guid = &(GuidTable[VariableHead->GuidTableIndex]);\r
647 Name = &(StringTable[VariableHead->StringIndex]);\r
c0e96fed 648 VariableOffset = VariableHead->Offset;\r
878ddf1f 649\r
1de04b4f 650 Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset);\r
651\r
652 if (EFI_NOT_FOUND == Status) {\r
653 CopyMem (PcdDb + VariableHead->DefaultValueOffset, Data, *Size);\r
654 return EFI_SUCCESS;\r
655 } else {\r
656 return Status;\r
657 }\r
658 \r
52e1905d 659 case PCD_TYPE_DATA:\r
660 if (PtrType) {\r
4c29d433 661 if (SetPtrTypeSize (TmpTokenNumber, Size)) {\r
1de04b4f 662 CopyMem (InternalData, Data, *Size);\r
663 return EFI_SUCCESS;\r
664 } else {\r
665 return EFI_INVALID_PARAMETER;\r
666 }\r
52e1905d 667 }\r
878ddf1f 668\r
1de04b4f 669 switch (*Size) {\r
52e1905d 670 case sizeof(UINT8):\r
671 *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
672 return EFI_SUCCESS;\r
878ddf1f 673\r
52e1905d 674 case sizeof(UINT16):\r
675 *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
676 return EFI_SUCCESS;\r
677\r
678 case sizeof(UINT32):\r
679 *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
680 return EFI_SUCCESS;\r
681\r
682 case sizeof(UINT64):\r
683 *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
684 return EFI_SUCCESS;\r
878ddf1f 685\r
52e1905d 686 default:\r
687 ASSERT (FALSE);\r
688 return EFI_NOT_FOUND;\r
689 }\r
690\r
691 default:\r
692 ASSERT (FALSE);\r
693 break;\r
694 }\r
695 \r
696 ASSERT (FALSE);\r
697 return EFI_NOT_FOUND;\r
878ddf1f 698}\r
699\r
700\r
701\r
9d6d8b24 702\r
703\r
704VOID *\r
705ExGetWorker (\r
706 IN CONST EFI_GUID *Guid,\r
707 IN UINTN ExTokenNumber,\r
708 IN UINTN GetSize\r
709 ) \r
710{\r
4f242357 711 return GetWorker(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber), GetSize);\r
9d6d8b24 712}\r
713\r
714\r
715\r
716\r
1de04b4f 717EFI_STATUS\r
718ExSetValueWorker (\r
719 IN UINTN ExTokenNumber,\r
720 IN CONST EFI_GUID *Guid,\r
721 IN VOID *Data,\r
722 IN UINTN SetSize\r
723 )\r
724{\r
725 return ExSetWorker (ExTokenNumber, Guid, Data, &SetSize, FALSE);\r
726}\r
727\r
9d6d8b24 728\r
729EFI_STATUS\r
730ExSetWorker (\r
1de04b4f 731 IN UINTN ExTokenNumber,\r
732 IN CONST EFI_GUID *Guid,\r
733 IN VOID *Data,\r
734 IN OUT UINTN *SetSize,\r
735 IN BOOLEAN PtrType\r
9d6d8b24 736 )\r
737{\r
8a43e8dd 738 UINTN TokenNumber;\r
9d6d8b24 739 \r
4f242357 740 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber);\r
9d6d8b24 741\r
1de04b4f 742 InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, *SetSize);\r
9d6d8b24 743\r
1de04b4f 744 return SetWorker (TokenNumber, Data, SetSize, PtrType);\r
9d6d8b24 745\r
9d6d8b24 746}\r
747\r
748\r
749\r
750\r
878ddf1f 751EFI_STATUS\r
752SetHiiVariable (\r
753 IN EFI_GUID *VariableGuid,\r
754 IN UINT16 *VariableName,\r
755 IN CONST VOID *Data,\r
756 IN UINTN DataSize,\r
757 IN UINTN Offset\r
758 )\r
759{\r
52e1905d 760 UINTN Size;\r
761 VOID *Buffer;\r
762 EFI_STATUS Status;\r
763 UINT32 Attribute;\r
878ddf1f 764\r
765 Size = 0;\r
766\r
4f914125 767 Status = gRT->GetVariable (\r
878ddf1f 768 (UINT16 *)VariableName,\r
769 VariableGuid,\r
6874dbd0 770 NULL,\r
878ddf1f 771 &Size,\r
772 NULL\r
773 );\r
774\r
c0e96fed 775 if (Status == EFI_BUFFER_TOO_SMALL) {\r
878ddf1f 776\r
c0e96fed 777 Buffer = AllocatePool (Size);\r
878ddf1f 778\r
c0e96fed 779 ASSERT (Buffer != NULL);\r
878ddf1f 780\r
4f914125 781 Status = gRT->GetVariable (\r
c0e96fed 782 VariableName,\r
783 VariableGuid,\r
784 &Attribute,\r
785 &Size,\r
786 Buffer\r
787 );\r
788 \r
789 ASSERT_EFI_ERROR (Status);\r
878ddf1f 790\r
c0e96fed 791 CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);\r
878ddf1f 792\r
4f914125 793 Status = gRT->SetVariable (\r
1de04b4f 794 VariableName,\r
795 VariableGuid,\r
796 Attribute,\r
797 Size,\r
798 Buffer\r
799 );\r
878ddf1f 800\r
1de04b4f 801 FreePool (Buffer);\r
802 return Status;\r
878ddf1f 803\r
1de04b4f 804 } \r
805 \r
806 //\r
807 // If we drop to here, we don't have a Variable entry in\r
808 // the variable service yet. So, we will save the data\r
809 // in the PCD Database's volatile area.\r
810 //\r
811 return Status;\r
878ddf1f 812}\r
813\r
52e1905d 814\r
815\r
816\r
817\r
8a43e8dd 818UINTN \r
9d6d8b24 819GetExPcdTokenNumber (\r
52e1905d 820 IN CONST EFI_GUID *Guid,\r
4f242357 821 IN UINT32 ExTokenNumber\r
52e1905d 822 )\r
823{\r
824 UINT32 i;\r
825 DYNAMICEX_MAPPING *ExMap;\r
826 EFI_GUID *GuidTable;\r
9d6d8b24 827 EFI_GUID *MatchGuid;\r
828 UINTN MatchGuidIdx;\r
52e1905d 829\r
bb5545b6 830 if (!PEI_DATABASE_EMPTY) {\r
831 ExMap = mPcdDatabase->PeiDb.Init.ExMapTable;\r
832 GuidTable = mPcdDatabase->PeiDb.Init.GuidTable;\r
833 \r
834 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);\r
835 \r
836 if (MatchGuid != NULL) {\r
9d6d8b24 837\r
bb5545b6 838 MatchGuidIdx = MatchGuid - GuidTable;\r
839 \r
840 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
841 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
842 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
843 return ExMap[i].LocalTokenNumber;\r
52e1905d 844\r
bb5545b6 845 }\r
846 }\r
52e1905d 847 }\r
848 }\r
849 \r
4c114006 850 ExMap = mPcdDatabase->DxeDb.Init.ExMapTable;\r
851 GuidTable = mPcdDatabase->DxeDb.Init.GuidTable;\r
9d6d8b24 852\r
853 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);\r
bb5545b6 854 //\r
855 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
856 // error in the BUILD system.\r
857 //\r
9d6d8b24 858 ASSERT (MatchGuid != NULL);\r
859\r
860 MatchGuidIdx = MatchGuid - GuidTable;\r
52e1905d 861 \r
862 for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) {\r
863 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
9d6d8b24 864 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
bb5545b6 865 return ExMap[i].LocalTokenNumber;\r
52e1905d 866 }\r
867 }\r
868\r
869 ASSERT (FALSE);\r
870\r
9d6d8b24 871 return 0;\r
52e1905d 872}\r
873\r
1de04b4f 874\r
875\r
876SKU_ID *\r
877GetSkuIdArray (\r
878 IN UINTN LocalTokenNumberTableIdx,\r
879 IN BOOLEAN IsPeiPcd\r
880 )\r
881{\r
882 SKU_HEAD *SkuHead;\r
883 UINTN LocalTokenNumber;\r
884 UINT8 *Database;\r
885\r
886 if (IsPeiPcd) {\r
887 LocalTokenNumber = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
888 Database = (UINT8 *) &mPcdDatabase->PeiDb;\r
889 } else {\r
890 LocalTokenNumber = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx - PEI_LOCAL_TOKEN_NUMBER];\r
891 Database = (UINT8 *) &mPcdDatabase->DxeDb;\r
892 }\r
893\r
894 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
895\r
896 SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
897\r
898 return (SKU_ID *) (Database + SkuHead->SkuIdTableOffset);\r
899 \r
900}\r
901\r
902\r
903\r
904UINTN\r
905GetSizeTableIndexA (\r
906 IN UINTN LocalTokenNumberTableIdx,\r
907 IN UINT32 *LocalTokenNumberTable,\r
908 IN BOOLEAN IsPeiDb\r
909 )\r
910{\r
911 UINTN i;\r
912 UINTN SizeTableIdx;\r
913 UINTN LocalTokenNumber;\r
914 SKU_ID *SkuIdTable;\r
915 \r
916 SizeTableIdx = 0;\r
917\r
918 for (i=0; i<LocalTokenNumberTableIdx; i++) {\r
919 LocalTokenNumber = LocalTokenNumberTable[i];\r
920\r
921 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {\r
922 //\r
923 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
924 // PCD entry.\r
925 //\r
926 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
927 //\r
928 // We have only one entry for VPD enabled PCD entry:\r
929 // 1) MAX Size.\r
930 // We consider current size is equal to MAX size.\r
931 //\r
932 SizeTableIdx++;\r
933 } else {\r
934 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
935 //\r
936 // We have only two entry for Non-Sku enabled PCD entry:\r
937 // 1) MAX SIZE\r
938 // 2) Current Size\r
939 //\r
940 SizeTableIdx += 2;\r
941 } else {\r
942 //\r
943 // We have these entry for SKU enabled PCD entry\r
944 // 1) MAX SIZE\r
945 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
946 //\r
947 SkuIdTable = GetSkuIdArray (i, IsPeiDb);\r
948 SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
949 }\r
950 }\r
951 }\r
952\r
953 }\r
954\r
955 return SizeTableIdx;\r
956}\r
957\r
958\r
959\r
960\r
961UINTN\r
962GetSizeTableIndex (\r
963 IN UINTN LocalTokenNumberTableIdx,\r
964 IN BOOLEAN IsPeiDb\r
965 )\r
966{\r
967 UINT32 *LocalTokenNumberTable;\r
968 \r
969 if (IsPeiDb) {\r
970 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
971 } else {\r
972 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
973 }\r
974 return GetSizeTableIndexA (LocalTokenNumberTableIdx, \r
975 LocalTokenNumberTable,\r
976 IsPeiDb);\r
977}\r
978\r
979\r
980\r
981UINTN\r
982GetPtrTypeSize (\r
983 IN UINTN LocalTokenNumberTableIdx,\r
984 OUT UINTN *MaxSize\r
985 )\r
986{\r
987 INTN SizeTableIdx;\r
988 UINTN LocalTokenNumber;\r
989 SKU_ID *SkuIdTable;\r
990 SIZE_INFO *SizeTable;\r
991 UINTN i;\r
992 BOOLEAN IsPeiDb;\r
993 UINT32 *LocalTokenNumberTable;\r
994\r
4f914125 995 // EBC compiler is very choosy. It may report warning about comparison\r
996 // between UINTN and 0 . So we add 1 in each size of the \r
997 // comparison.\r
998 IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
1de04b4f 999\r
1000\r
1001 if (IsPeiDb) {\r
1002 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
1003 SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;\r
1004 } else {\r
1005 LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;\r
1006 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
1007 SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;\r
1008 }\r
1009\r
1010 LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
1011\r
1012 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
1013 \r
1014 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);\r
1015\r
1016 *MaxSize = SizeTable[SizeTableIdx];\r
1017 //\r
1018 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
1019 // PCD entry.\r
1020 //\r
1021 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
1022 //\r
1023 // We have only one entry for VPD enabled PCD entry:\r
1024 // 1) MAX Size.\r
1025 // We consider current size is equal to MAX size.\r
1026 //\r
1027 return *MaxSize;\r
1028 } else {\r
1029 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
1030 //\r
1031 // We have only two entry for Non-Sku enabled PCD entry:\r
1032 // 1) MAX SIZE\r
1033 // 2) Current Size\r
1034 //\r
1035 return SizeTable[SizeTableIdx + 1];\r
1036 } else {\r
1037 //\r
1038 // We have these entry for SKU enabled PCD entry\r
1039 // 1) MAX SIZE\r
1040 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
1041 //\r
1042 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);\r
1043 for (i = 0; i < SkuIdTable[0]; i++) {\r
1044 if (SkuIdTable[1 + i] == mPcdDatabase->PeiDb.Init.SystemSkuId) {\r
1045 return SizeTable[SizeTableIdx + 1 + i];\r
1046 }\r
1047 }\r
1048 return SizeTable[SizeTableIdx + 1];\r
1049 }\r
1050 }\r
1051}\r
1052\r
1053\r
1054\r
1055BOOLEAN\r
1056SetPtrTypeSize (\r
1057 IN UINTN LocalTokenNumberTableIdx,\r
1058 IN OUT UINTN *CurrentSize\r
1059 )\r
1060{\r
1061 INTN SizeTableIdx;\r
1062 UINTN LocalTokenNumber;\r
1063 SKU_ID *SkuIdTable;\r
1064 SIZE_INFO *SizeTable;\r
1065 UINTN i;\r
1066 UINTN MaxSize;\r
1067 BOOLEAN IsPeiDb;\r
1068 UINT32 *LocalTokenNumberTable;\r
1069\r
4f914125 1070 // EBC compiler is very choosy. It may report warning about comparison\r
1071 // between UINTN and 0 . So we add 1 in each size of the \r
1072 // comparison.\r
1073 IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
1de04b4f 1074\r
1075 if (IsPeiDb) {\r
1076 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
1077 SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;\r
1078 } else {\r
1079 LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;\r
1080 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
1081 SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;\r
1082 }\r
1083\r
1084 LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
1085\r
1086 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
1087 \r
1088 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);\r
1089\r
1090 MaxSize = SizeTable[SizeTableIdx];\r
1091 //\r
1092 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
1093 // PCD entry.\r
1094 //\r
1095 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
1096 //\r
1097 // We shouldn't come here as we don't support SET for VPD\r
1098 //\r
1099 ASSERT (FALSE);\r
1100 return FALSE;\r
1101 } else {\r
1102 if ((*CurrentSize > MaxSize) ||\r
1103 (*CurrentSize == MAX_ADDRESS)) {\r
1104 *CurrentSize = MaxSize;\r
1105 return FALSE;\r
1106 } \r
1107 \r
1108 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
1109 //\r
1110 // We have only two entry for Non-Sku enabled PCD entry:\r
1111 // 1) MAX SIZE\r
1112 // 2) Current Size\r
1113 //\r
1114 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
1115 return TRUE;\r
1116 } else {\r
1117 //\r
1118 // We have these entry for SKU enabled PCD entry\r
1119 // 1) MAX SIZE\r
1120 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
1121 //\r
1122 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);\r
1123 for (i = 0; i < SkuIdTable[0]; i++) {\r
1124 if (SkuIdTable[1 + i] == mPcdDatabase->PeiDb.Init.SystemSkuId) {\r
1125 SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize;\r
1126 return TRUE;\r
1127 }\r
1128 }\r
1129 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
1130 return TRUE;\r
1131 }\r
1132 }\r
1133}\r
1134\r