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