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