]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/PCD/Dxe/Service.c
In AsciiStrncmp(), if length=0, should return 0
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Dxe / Service.c
CommitLineData
878ddf1f 1/** @file\r
2Private functions used by PCD DXE driver.s\r
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
52e1905d 20//\r
21// Build Tool will generate DXE_PCD_DB_INIT_VALUE in Autogen.h\r
22// Compression Algorithm will take care of the size optimization.\r
23//\r
878ddf1f 24\r
4c114006 25PCD_DATABASE * mPcdDatabase;\r
878ddf1f 26\r
abc25afa 27LIST_ENTRY *mCallbackFnTable;\r
878ddf1f 28\r
52e1905d 29VOID *\r
9d6d8b24 30GetWorker (\r
8a43e8dd 31 UINTN TokenNumber,\r
9d6d8b24 32 UINTN GetSize\r
33 )\r
878ddf1f 34{\r
9d6d8b24 35 UINT32 *LocalTokenNumberTable;\r
36 UINT16 *SizeTable;\r
37 BOOLEAN IsPeiDb;\r
52e1905d 38 UINT32 Offset;\r
39 EFI_GUID *GuidTable;\r
40 UINT16 *StringTable;\r
41 EFI_GUID *Guid;\r
42 UINT16 *Name;\r
43 VARIABLE_HEAD *VariableHead;\r
1de04b4f 44 UINT8 *VaraiableDefaultBuffer;\r
52e1905d 45 EFI_STATUS Status;\r
46 UINTN DataSize;\r
1de04b4f 47 UINT8 *Data;\r
52e1905d 48 VPD_HEAD *VpdHead;\r
49 UINT8 *PcdDb;\r
50 UINT16 StringTableIdx; \r
9d6d8b24 51 UINT32 LocalTokenNumber;\r
1de04b4f 52 UINTN MaxSize;\r
53 UINTN TmpTokenNumber;\r
9d6d8b24 54\r
58f1099f 55 //\r
56 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
57 // We have to decrement TokenNumber by 1 to make it usable\r
58 // as the array index.\r
59 //\r
60 TokenNumber--;\r
1de04b4f 61\r
62 TmpTokenNumber = TokenNumber;\r
58f1099f 63 \r
4f914125 64 //\r
65 // PCD_TOTAL_TOKEN_NUMBER is a auto-generated constant.\r
66 // It could be zero. EBC compiler is very choosy. It may\r
67 // report warning. So we add 1 in each size of the \r
68 // comparison.\r
69 //\r
70 ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);\r
9d6d8b24 71\r
1de04b4f 72 ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0));\r
52e1905d 73\r
4f914125 74 // EBC compiler is very choosy. It may report warning about comparison\r
75 // between UINTN and 0 . So we add 1 in each size of the \r
76 // comparison.\r
77 IsPeiDb = (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE;\r
9d6d8b24 78\r
79 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
80 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
81\r
82 SizeTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SizeTable: \r
83 mPcdDatabase->DxeDb.Init.SizeTable;\r
84\r
85 TokenNumber = IsPeiDb ? TokenNumber :\r
86 TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
87\r
88 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
89 \r
52e1905d 90 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
1de04b4f 91 if (GetSize == 0) {\r
92 GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
93 } else {\r
94 MaxSize = GetSize;\r
95 }\r
96 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);\r
52e1905d 97 }\r
98\r
4c114006 99 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
100 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :\r
101 mPcdDatabase->DxeDb.Init.StringTable;\r
52e1905d 102 \r
103 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
104 \r
1de04b4f 105 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 106 case PCD_TYPE_VPD:\r
107 VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset);\r
4f242357 108 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
52e1905d 109 \r
110 case PCD_TYPE_HII:\r
4c114006 111 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :\r
112 mPcdDatabase->DxeDb.Init.GuidTable;\r
52e1905d 113 \r
114 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
115 \r
116 Guid = &(GuidTable[VariableHead->GuidTableIndex]);\r
117 Name = &(StringTable[VariableHead->StringIndex]);\r
1de04b4f 118 VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset;\r
878ddf1f 119\r
2b21a971 120 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
c0e96fed 121 if (Status == EFI_SUCCESS) {\r
1de04b4f 122 if (GetSize == 0) {\r
123 //\r
124 // It is a pointer type. So get the MaxSize reserved for\r
125 // this PCD entry.\r
126 //\r
127 GetPtrTypeSize (TokenNumber, &GetSize);\r
128 }\r
129 CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);\r
130 FreePool (Data);\r
131 }\r
132 //\r
133 // If the operation is successful, we copy the data\r
134 // to the default value buffer in the PCD Database.\r
135 // So that we can free the Data allocated in GetHiiVariable.\r
136 //\r
137 //\r
138 // If the operation is not successful, \r
139 // Return 1) either the default value specified by Platform Integrator \r
140 // 2) Or the value Set by a PCD set operation.\r
141 //\r
142 return (VOID *) VaraiableDefaultBuffer;\r
878ddf1f 143\r
52e1905d 144 case PCD_TYPE_STRING:\r
145 StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset);\r
146 return (VOID *) &StringTable[StringTableIdx];\r
878ddf1f 147\r
52e1905d 148 case PCD_TYPE_DATA:\r
149 return (VOID *) ((UINT8 *) PcdDb + Offset);\r
150 break;\r
878ddf1f 151\r
52e1905d 152 default:\r
153 ASSERT (FALSE);\r
154 break;\r
155 \r
156 }\r
878ddf1f 157\r
52e1905d 158 ASSERT (FALSE);\r
159 \r
160 return NULL;\r
52e1905d 161 \r
52e1905d 162}\r
878ddf1f 163\r
878ddf1f 164\r
165\r
52e1905d 166EFI_STATUS\r
167DxeRegisterCallBackWorker (\r
8a43e8dd 168 IN UINTN TokenNumber,\r
52e1905d 169 IN CONST GUID *Guid, OPTIONAL\r
4c114006 170 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
52e1905d 171)\r
172{\r
4c114006 173 CALLBACK_FN_ENTRY *FnTableEntry;\r
4c114006 174 LIST_ENTRY *ListHead;\r
175 LIST_ENTRY *ListNode;\r
176\r
177 if (Guid != NULL) {\r
4f242357 178 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
4c114006 179 }\r
180\r
58f1099f 181 //\r
182 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
183 // We have to decrement TokenNumber by 1 to make it usable\r
184 // as the array index.\r
185 //\r
186 TokenNumber--;\r
187\r
4c114006 188 ListHead = &mCallbackFnTable[TokenNumber];\r
189 ListNode = GetFirstNode (ListHead);\r
190\r
191 while (ListNode != ListHead) {\r
192 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
193\r
194 if (FnTableEntry->CallbackFn == CallBackFunction) {\r
195 //\r
196 // We only allow a Callback function to be register once\r
197 // for a TokenNumber. So just return EFI_SUCCESS\r
198 //\r
199 return EFI_SUCCESS;\r
200 }\r
201 ListNode = GetNextNode (ListHead, ListNode);\r
202 }\r
203\r
204 FnTableEntry = AllocatePool (sizeof(CALLBACK_FN_ENTRY));\r
205 ASSERT (FnTableEntry != NULL);\r
206\r
207 FnTableEntry->CallbackFn = CallBackFunction;\r
208 InsertTailList (ListHead, &FnTableEntry->Node);\r
52e1905d 209 \r
210 return EFI_SUCCESS;\r
878ddf1f 211}\r
212\r
213\r
4c114006 214\r
215\r
52e1905d 216EFI_STATUS\r
4c114006 217DxeUnRegisterCallBackWorker (\r
8a43e8dd 218 IN UINTN TokenNumber,\r
4c114006 219 IN CONST GUID *Guid, OPTIONAL\r
220 IN PCD_PROTOCOL_CALLBACK CallBackFunction\r
221)\r
222{\r
223 CALLBACK_FN_ENTRY *FnTableEntry;\r
4c114006 224 LIST_ENTRY *ListHead;\r
225 LIST_ENTRY *ListNode;\r
226\r
227 if (Guid != NULL) {\r
4f242357 228 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) TokenNumber);\r
4c114006 229 }\r
230\r
58f1099f 231 //\r
232 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
233 // We have to decrement TokenNumber by 1 to make it usable\r
234 // as the array index.\r
235 //\r
236 TokenNumber--;\r
237\r
4c114006 238 ListHead = &mCallbackFnTable[TokenNumber];\r
239 ListNode = GetFirstNode (ListHead);\r
240\r
241 while (ListNode != ListHead) {\r
242 FnTableEntry = CR_FNENTRY_FROM_LISTNODE(ListNode, CALLBACK_FN_ENTRY, Node);\r
243\r
244 if (FnTableEntry->CallbackFn == CallBackFunction) {\r
245 //\r
246 // We only allow a Callback function to be register once\r
247 // for a TokenNumber. So we can safely remove the Node from\r
248 // the Link List and return EFI_SUCCESS.\r
249 //\r
250 RemoveEntryList (ListNode);\r
251 FreePool (FnTableEntry);\r
252 \r
253 return EFI_SUCCESS;\r
254 }\r
255 ListNode = GetNextNode (ListHead, ListNode);\r
256 }\r
257\r
258 return EFI_INVALID_PARAMETER;\r
259}\r
260\r
261\r
262\r
2b21a971 263EFI_STATUS\r
4c114006 264ExGetNextTokeNumber (\r
2b21a971 265 IN CONST EFI_GUID *Guid,\r
266 IN OUT UINTN *TokenNumber,\r
267 IN EFI_GUID *GuidTable,\r
268 IN UINTN SizeOfGuidTable,\r
269 IN DYNAMICEX_MAPPING *ExMapTable,\r
270 IN UINTN SizeOfExMapTable\r
878ddf1f 271 )\r
272{\r
4c114006 273 EFI_GUID *MatchGuid;\r
274 UINTN Idx;\r
275 UINTN GuidTableIdx;\r
276 BOOLEAN Found;\r
277\r
278 MatchGuid = ScanGuid (GuidTable, SizeOfGuidTable, Guid);\r
279 if (MatchGuid == NULL) {\r
2b21a971 280 return EFI_NOT_FOUND;\r
4c114006 281 }\r
282\r
283 Found = FALSE;\r
284 GuidTableIdx = MatchGuid - GuidTable;\r
285 for (Idx = 0; Idx < SizeOfExMapTable; Idx++) {\r
286 if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) {\r
287 Found = TRUE;\r
288 break;\r
289 }\r
290 }\r
291\r
292 if (Found) {\r
2b21a971 293 if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
294 *TokenNumber = ExMapTable[Idx].ExTokenNumber;\r
295 return EFI_SUCCESS;\r
4c114006 296 }\r
4276d5da 297\r
4c114006 298 for ( ; Idx < SizeOfExMapTable; Idx++) {\r
2b21a971 299 if (ExMapTable[Idx].ExTokenNumber == *TokenNumber) {\r
4c114006 300 Idx++;\r
301 if (Idx == SizeOfExMapTable) {\r
302 //\r
303 // Exceed the length of ExMap Table\r
304 //\r
2b21a971 305 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
306 return EFI_SUCCESS;\r
4c114006 307 } else if (ExMapTable[Idx].ExGuidIndex == GuidTableIdx) {\r
308 //\r
309 // Found the next match\r
310 //\r
2b21a971 311 *TokenNumber = ExMapTable[Idx].ExTokenNumber;\r
312 return EFI_SUCCESS;\r
4c114006 313 } else {\r
314 //\r
315 // Guid has been changed. It is the next Token Space Guid.\r
316 // We should flag no more TokenNumber.\r
317 //\r
2b21a971 318 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
319 return EFI_SUCCESS;\r
4c114006 320 }\r
321 }\r
322 }\r
323 }\r
324 \r
2b21a971 325 return EFI_NOT_FOUND;\r
878ddf1f 326}\r
4c114006 327 \r
878ddf1f 328\r
329\r
330\r
52e1905d 331VOID\r
332BuildPcdDxeDataBase (\r
333 VOID\r
8a43e8dd 334 )\r
878ddf1f 335{\r
52e1905d 336 PEI_PCD_DATABASE *PeiDatabase;\r
337 EFI_HOB_GUID_TYPE *GuidHob;\r
4c114006 338 UINTN Idx;\r
878ddf1f 339\r
4c114006 340 mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));\r
341 ASSERT (mPcdDatabase != NULL);\r
878ddf1f 342\r
52e1905d 343 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
878ddf1f 344\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
878ddf1f 495\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
58f1099f 569 //\r
570 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
571 // We have to decrement TokenNumber by 1 to make it usable\r
572 // as the array index.\r
573 //\r
574 TokenNumber--;\r
1de04b4f 575\r
576 TmpTokenNumber = TokenNumber;\r
58f1099f 577 \r
4f914125 578 // EBC compiler is very choosy. It may report warning about comparison\r
579 // between UINTN and 0 . So we add 1 in each size of the \r
580 // comparison.\r
581\r
582 ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);\r
878ddf1f 583\r
1de04b4f 584 if (!PtrType) {\r
585 ASSERT (*Size == DxePcdGetSize (TokenNumber + 1));\r
878ddf1f 586 }\r
878ddf1f 587 \r
4f914125 588 // EBC compiler is very choosy. It may report warning about comparison\r
589 // between UINTN and 0 . So we add 1 in each size of the \r
590 // comparison.\r
591 IsPeiDb = (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE;\r
878ddf1f 592\r
4c114006 593 LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable : \r
594 mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
878ddf1f 595\r
4f914125 596 // EBC compiler is very choosy. It may report warning about comparison\r
597 // between UINTN and 0 . So we add 1 in each size of the \r
598 // comparison.\r
599 if ((TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) ||\r
600 (TokenNumber + 1 >= PEI_LOCAL_TOKEN_NUMBER + 1 || TokenNumber + 1 < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1))) {\r
1de04b4f 601 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
9d6d8b24 602 }\r
0653eb89 603\r
52e1905d 604 TokenNumber = IsPeiDb ? TokenNumber\r
605 : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;\r
878ddf1f 606\r
9d6d8b24 607 LocalTokenNumber = LocalTokenNumberTable[TokenNumber];\r
52e1905d 608 \r
52e1905d 609 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
1de04b4f 610 if (PtrType) {\r
611 GetPtrTypeSize (TmpTokenNumber, &MaxSize);\r
612 } else {\r
613 MaxSize = *Size;\r
614 }\r
615 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);\r
52e1905d 616 }\r
878ddf1f 617\r
52e1905d 618 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
878ddf1f 619\r
4c114006 620 PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);\r
878ddf1f 621\r
4c114006 622 StringTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.StringTable :\r
623 mPcdDatabase->DxeDb.Init.StringTable;\r
52e1905d 624 \r
625 InternalData = PcdDb + Offset;\r
878ddf1f 626\r
1de04b4f 627 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 628 case PCD_TYPE_VPD:\r
629 ASSERT (FALSE);\r
630 return EFI_INVALID_PARAMETER;\r
631 \r
632 case PCD_TYPE_STRING:\r
1de04b4f 633 if (SetPtrTypeSize (TokenNumber, Size)) {\r
634 CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, *Size);\r
635 return EFI_SUCCESS;\r
636 } else {\r
637 return EFI_INVALID_PARAMETER;\r
638 }\r
878ddf1f 639\r
52e1905d 640 case PCD_TYPE_HII:\r
1de04b4f 641 if (PtrType) {\r
642 if (!SetPtrTypeSize (TokenNumber, Size)) {\r
643 return EFI_INVALID_PARAMETER;\r
644 }\r
645 }\r
646 \r
4c114006 647 GuidTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.GuidTable :\r
648 mPcdDatabase->DxeDb.Init.GuidTable;\r
52e1905d 649 \r
650 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);\r
651 \r
652 Guid = &(GuidTable[VariableHead->GuidTableIndex]);\r
653 Name = &(StringTable[VariableHead->StringIndex]);\r
c0e96fed 654 VariableOffset = VariableHead->Offset;\r
878ddf1f 655\r
1de04b4f 656 Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset);\r
657\r
658 if (EFI_NOT_FOUND == Status) {\r
659 CopyMem (PcdDb + VariableHead->DefaultValueOffset, Data, *Size);\r
660 return EFI_SUCCESS;\r
661 } else {\r
662 return Status;\r
663 }\r
664 \r
665 //\r
666 // Bug Bug: Please implement this\r
667 //\r
878ddf1f 668\r
52e1905d 669 case PCD_TYPE_DATA:\r
670 if (PtrType) {\r
1de04b4f 671 if (SetPtrTypeSize (TokenNumber, Size)) {\r
672 CopyMem (InternalData, Data, *Size);\r
673 return EFI_SUCCESS;\r
674 } else {\r
675 return EFI_INVALID_PARAMETER;\r
676 }\r
52e1905d 677 }\r
878ddf1f 678\r
1de04b4f 679 switch (*Size) {\r
52e1905d 680 case sizeof(UINT8):\r
681 *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
682 return EFI_SUCCESS;\r
878ddf1f 683\r
52e1905d 684 case sizeof(UINT16):\r
685 *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
686 return EFI_SUCCESS;\r
687\r
688 case sizeof(UINT32):\r
689 *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
690 return EFI_SUCCESS;\r
691\r
692 case sizeof(UINT64):\r
693 *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
694 return EFI_SUCCESS;\r
878ddf1f 695\r
52e1905d 696 default:\r
697 ASSERT (FALSE);\r
698 return EFI_NOT_FOUND;\r
699 }\r
700\r
701 default:\r
702 ASSERT (FALSE);\r
703 break;\r
704 }\r
705 \r
706 ASSERT (FALSE);\r
707 return EFI_NOT_FOUND;\r
878ddf1f 708}\r
709\r
710\r
711\r
9d6d8b24 712\r
713\r
714VOID *\r
715ExGetWorker (\r
716 IN CONST EFI_GUID *Guid,\r
717 IN UINTN ExTokenNumber,\r
718 IN UINTN GetSize\r
719 ) \r
720{\r
4f242357 721 return GetWorker(GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber), GetSize);\r
9d6d8b24 722}\r
723\r
724\r
725\r
726\r
1de04b4f 727EFI_STATUS\r
728ExSetValueWorker (\r
729 IN UINTN ExTokenNumber,\r
730 IN CONST EFI_GUID *Guid,\r
731 IN VOID *Data,\r
732 IN UINTN SetSize\r
733 )\r
734{\r
735 return ExSetWorker (ExTokenNumber, Guid, Data, &SetSize, FALSE);\r
736}\r
737\r
9d6d8b24 738\r
739EFI_STATUS\r
740ExSetWorker (\r
1de04b4f 741 IN UINTN ExTokenNumber,\r
742 IN CONST EFI_GUID *Guid,\r
743 IN VOID *Data,\r
744 IN OUT UINTN *SetSize,\r
745 IN BOOLEAN PtrType\r
9d6d8b24 746 )\r
747{\r
8a43e8dd 748 UINTN TokenNumber;\r
9d6d8b24 749 \r
4f242357 750 TokenNumber = GetExPcdTokenNumber (Guid, (UINT32) ExTokenNumber);\r
9d6d8b24 751\r
1de04b4f 752 InvokeCallbackOnSet ((UINT32) ExTokenNumber, Guid, TokenNumber, Data, *SetSize);\r
9d6d8b24 753\r
1de04b4f 754 return SetWorker (TokenNumber, Data, SetSize, PtrType);\r
9d6d8b24 755\r
9d6d8b24 756}\r
757\r
758\r
759\r
760\r
878ddf1f 761EFI_STATUS\r
762SetHiiVariable (\r
763 IN EFI_GUID *VariableGuid,\r
764 IN UINT16 *VariableName,\r
765 IN CONST VOID *Data,\r
766 IN UINTN DataSize,\r
767 IN UINTN Offset\r
768 )\r
769{\r
52e1905d 770 UINTN Size;\r
771 VOID *Buffer;\r
772 EFI_STATUS Status;\r
773 UINT32 Attribute;\r
878ddf1f 774\r
775 Size = 0;\r
776\r
4f914125 777 Status = gRT->GetVariable (\r
878ddf1f 778 (UINT16 *)VariableName,\r
779 VariableGuid,\r
52e1905d 780 &Attribute,\r
878ddf1f 781 &Size,\r
782 NULL\r
783 );\r
784\r
c0e96fed 785 if (Status == EFI_BUFFER_TOO_SMALL) {\r
878ddf1f 786\r
c0e96fed 787 Buffer = AllocatePool (Size);\r
878ddf1f 788\r
c0e96fed 789 ASSERT (Buffer != NULL);\r
878ddf1f 790\r
4f914125 791 Status = gRT->GetVariable (\r
c0e96fed 792 VariableName,\r
793 VariableGuid,\r
794 &Attribute,\r
795 &Size,\r
796 Buffer\r
797 );\r
798 \r
799 ASSERT_EFI_ERROR (Status);\r
878ddf1f 800\r
c0e96fed 801 CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);\r
878ddf1f 802\r
4f914125 803 Status = gRT->SetVariable (\r
1de04b4f 804 VariableName,\r
805 VariableGuid,\r
806 Attribute,\r
807 Size,\r
808 Buffer\r
809 );\r
878ddf1f 810\r
1de04b4f 811 FreePool (Buffer);\r
812 return Status;\r
878ddf1f 813\r
1de04b4f 814 } \r
815 \r
816 //\r
817 // If we drop to here, we don't have a Variable entry in\r
818 // the variable service yet. So, we will save the data\r
819 // in the PCD Database's volatile area.\r
820 //\r
821 return Status;\r
878ddf1f 822}\r
823\r
52e1905d 824\r
825\r
826\r
827\r
8a43e8dd 828UINTN \r
9d6d8b24 829GetExPcdTokenNumber (\r
52e1905d 830 IN CONST EFI_GUID *Guid,\r
4f242357 831 IN UINT32 ExTokenNumber\r
52e1905d 832 )\r
833{\r
834 UINT32 i;\r
835 DYNAMICEX_MAPPING *ExMap;\r
836 EFI_GUID *GuidTable;\r
9d6d8b24 837 EFI_GUID *MatchGuid;\r
838 UINTN MatchGuidIdx;\r
52e1905d 839\r
bb5545b6 840 if (!PEI_DATABASE_EMPTY) {\r
841 ExMap = mPcdDatabase->PeiDb.Init.ExMapTable;\r
842 GuidTable = mPcdDatabase->PeiDb.Init.GuidTable;\r
843 \r
844 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);\r
845 \r
846 if (MatchGuid != NULL) {\r
9d6d8b24 847\r
bb5545b6 848 MatchGuidIdx = MatchGuid - GuidTable;\r
849 \r
850 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
851 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
852 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
853 return ExMap[i].LocalTokenNumber;\r
52e1905d 854\r
bb5545b6 855 }\r
856 }\r
52e1905d 857 }\r
858 }\r
859 \r
4c114006 860 ExMap = mPcdDatabase->DxeDb.Init.ExMapTable;\r
861 GuidTable = mPcdDatabase->DxeDb.Init.GuidTable;\r
9d6d8b24 862\r
863 MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);\r
bb5545b6 864 //\r
865 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
866 // error in the BUILD system.\r
867 //\r
9d6d8b24 868 ASSERT (MatchGuid != NULL);\r
869\r
870 MatchGuidIdx = MatchGuid - GuidTable;\r
52e1905d 871 \r
872 for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) {\r
873 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&\r
9d6d8b24 874 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
bb5545b6 875 return ExMap[i].LocalTokenNumber;\r
52e1905d 876 }\r
877 }\r
878\r
879 ASSERT (FALSE);\r
880\r
9d6d8b24 881 return 0;\r
52e1905d 882}\r
883\r
1de04b4f 884\r
885\r
886SKU_ID *\r
887GetSkuIdArray (\r
888 IN UINTN LocalTokenNumberTableIdx,\r
889 IN BOOLEAN IsPeiPcd\r
890 )\r
891{\r
892 SKU_HEAD *SkuHead;\r
893 UINTN LocalTokenNumber;\r
894 UINT8 *Database;\r
895\r
896 if (IsPeiPcd) {\r
897 LocalTokenNumber = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
898 Database = (UINT8 *) &mPcdDatabase->PeiDb;\r
899 } else {\r
900 LocalTokenNumber = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx - PEI_LOCAL_TOKEN_NUMBER];\r
901 Database = (UINT8 *) &mPcdDatabase->DxeDb;\r
902 }\r
903\r
904 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
905\r
906 SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
907\r
908 return (SKU_ID *) (Database + SkuHead->SkuIdTableOffset);\r
909 \r
910}\r
911\r
912\r
913\r
914UINTN\r
915GetSizeTableIndexA (\r
916 IN UINTN LocalTokenNumberTableIdx,\r
917 IN UINT32 *LocalTokenNumberTable,\r
918 IN BOOLEAN IsPeiDb\r
919 )\r
920{\r
921 UINTN i;\r
922 UINTN SizeTableIdx;\r
923 UINTN LocalTokenNumber;\r
924 SKU_ID *SkuIdTable;\r
925 \r
926 SizeTableIdx = 0;\r
927\r
928 for (i=0; i<LocalTokenNumberTableIdx; i++) {\r
929 LocalTokenNumber = LocalTokenNumberTable[i];\r
930\r
931 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {\r
932 //\r
933 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
934 // PCD entry.\r
935 //\r
936 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
937 //\r
938 // We have only one entry for VPD enabled PCD entry:\r
939 // 1) MAX Size.\r
940 // We consider current size is equal to MAX size.\r
941 //\r
942 SizeTableIdx++;\r
943 } else {\r
944 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
945 //\r
946 // We have only two entry for Non-Sku enabled PCD entry:\r
947 // 1) MAX SIZE\r
948 // 2) Current Size\r
949 //\r
950 SizeTableIdx += 2;\r
951 } else {\r
952 //\r
953 // We have these entry for SKU enabled PCD entry\r
954 // 1) MAX SIZE\r
955 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
956 //\r
957 SkuIdTable = GetSkuIdArray (i, IsPeiDb);\r
958 SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
959 }\r
960 }\r
961 }\r
962\r
963 }\r
964\r
965 return SizeTableIdx;\r
966}\r
967\r
968\r
969\r
970\r
971UINTN\r
972GetSizeTableIndex (\r
973 IN UINTN LocalTokenNumberTableIdx,\r
974 IN BOOLEAN IsPeiDb\r
975 )\r
976{\r
977 UINT32 *LocalTokenNumberTable;\r
978 \r
979 if (IsPeiDb) {\r
980 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
981 } else {\r
982 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
983 }\r
984 return GetSizeTableIndexA (LocalTokenNumberTableIdx, \r
985 LocalTokenNumberTable,\r
986 IsPeiDb);\r
987}\r
988\r
989\r
990\r
991UINTN\r
992GetPtrTypeSize (\r
993 IN UINTN LocalTokenNumberTableIdx,\r
994 OUT UINTN *MaxSize\r
995 )\r
996{\r
997 INTN SizeTableIdx;\r
998 UINTN LocalTokenNumber;\r
999 SKU_ID *SkuIdTable;\r
1000 SIZE_INFO *SizeTable;\r
1001 UINTN i;\r
1002 BOOLEAN IsPeiDb;\r
1003 UINT32 *LocalTokenNumberTable;\r
1004\r
4f914125 1005 // EBC compiler is very choosy. It may report warning about comparison\r
1006 // between UINTN and 0 . So we add 1 in each size of the \r
1007 // comparison.\r
1008 IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
1de04b4f 1009\r
1010\r
1011 if (IsPeiDb) {\r
1012 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
1013 SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;\r
1014 } else {\r
1015 LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;\r
1016 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
1017 SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;\r
1018 }\r
1019\r
1020 LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
1021\r
1022 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
1023 \r
1024 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);\r
1025\r
1026 *MaxSize = SizeTable[SizeTableIdx];\r
1027 //\r
1028 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
1029 // PCD entry.\r
1030 //\r
1031 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
1032 //\r
1033 // We have only one entry for VPD enabled PCD entry:\r
1034 // 1) MAX Size.\r
1035 // We consider current size is equal to MAX size.\r
1036 //\r
1037 return *MaxSize;\r
1038 } else {\r
1039 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
1040 //\r
1041 // We have only two entry for Non-Sku enabled PCD entry:\r
1042 // 1) MAX SIZE\r
1043 // 2) Current Size\r
1044 //\r
1045 return SizeTable[SizeTableIdx + 1];\r
1046 } else {\r
1047 //\r
1048 // We have these entry for SKU enabled PCD entry\r
1049 // 1) MAX SIZE\r
1050 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
1051 //\r
1052 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);\r
1053 for (i = 0; i < SkuIdTable[0]; i++) {\r
1054 if (SkuIdTable[1 + i] == mPcdDatabase->PeiDb.Init.SystemSkuId) {\r
1055 return SizeTable[SizeTableIdx + 1 + i];\r
1056 }\r
1057 }\r
1058 return SizeTable[SizeTableIdx + 1];\r
1059 }\r
1060 }\r
1061}\r
1062\r
1063\r
1064\r
1065BOOLEAN\r
1066SetPtrTypeSize (\r
1067 IN UINTN LocalTokenNumberTableIdx,\r
1068 IN OUT UINTN *CurrentSize\r
1069 )\r
1070{\r
1071 INTN SizeTableIdx;\r
1072 UINTN LocalTokenNumber;\r
1073 SKU_ID *SkuIdTable;\r
1074 SIZE_INFO *SizeTable;\r
1075 UINTN i;\r
1076 UINTN MaxSize;\r
1077 BOOLEAN IsPeiDb;\r
1078 UINT32 *LocalTokenNumberTable;\r
1079\r
4f914125 1080 // EBC compiler is very choosy. It may report warning about comparison\r
1081 // between UINTN and 0 . So we add 1 in each size of the \r
1082 // comparison.\r
1083 IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
1de04b4f 1084\r
1085 if (IsPeiDb) {\r
1086 LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;\r
1087 SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;\r
1088 } else {\r
1089 LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;\r
1090 LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;\r
1091 SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;\r
1092 }\r
1093\r
1094 LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
1095\r
1096 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
1097 \r
1098 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, IsPeiDb);\r
1099\r
1100 MaxSize = SizeTable[SizeTableIdx];\r
1101 //\r
1102 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
1103 // PCD entry.\r
1104 //\r
1105 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
1106 //\r
1107 // We shouldn't come here as we don't support SET for VPD\r
1108 //\r
1109 ASSERT (FALSE);\r
1110 return FALSE;\r
1111 } else {\r
1112 if ((*CurrentSize > MaxSize) ||\r
1113 (*CurrentSize == MAX_ADDRESS)) {\r
1114 *CurrentSize = MaxSize;\r
1115 return FALSE;\r
1116 } \r
1117 \r
1118 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
1119 //\r
1120 // We have only two entry for Non-Sku enabled PCD entry:\r
1121 // 1) MAX SIZE\r
1122 // 2) Current Size\r
1123 //\r
1124 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
1125 return TRUE;\r
1126 } else {\r
1127 //\r
1128 // We have these entry for SKU enabled PCD entry\r
1129 // 1) MAX SIZE\r
1130 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
1131 //\r
1132 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);\r
1133 for (i = 0; i < SkuIdTable[0]; i++) {\r
1134 if (SkuIdTable[1 + i] == mPcdDatabase->PeiDb.Init.SystemSkuId) {\r
1135 SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize;\r
1136 return TRUE;\r
1137 }\r
1138 }\r
1139 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
1140 return TRUE;\r
1141 }\r
1142 }\r
1143}\r
1144\r