]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/PCD/Pei/Service.c
Add in feature flag PcdPeiPcdDatabaseSetEnabled, PcdPeiPcdDatabaseGetSizeEnabled...
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Pei / Service.c
CommitLineData
878ddf1f 1/** @file\r
2Private functions used by PCD PEIM.\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 The function registers the CallBackOnSet fucntion\r
21 according to TokenNumber and EFI_GUID space.\r
878ddf1f 22\r
a7c5092f 23 @param TokenNumber The token number.\r
24 @param Guid The GUID space.\r
25 @param CallBackFunction The Callback function to be registered.\r
26 @param Register To register or unregister the callback function.\r
878ddf1f 27\r
52e1905d 28 @retval EFI_SUCCESS If the Callback function is registered.\r
29 @retval EFI_NOT_FOUND If the PCD Entry is not found according to Token Number and GUID space.\r
a7c5092f 30 @retval EFI_OUT_OF_RESOURCES If the callback function can't be registered because there is not free\r
31 slot left in the CallbackFnTable.\r
878ddf1f 32--*/\r
52e1905d 33EFI_STATUS\r
34PeiRegisterCallBackWorker (\r
8a43e8dd 35 IN UINTN ExTokenNumber,\r
52e1905d 36 IN CONST EFI_GUID *Guid, OPTIONAL\r
37 IN PCD_PPI_CALLBACK CallBackFunction,\r
38 IN BOOLEAN Register\r
878ddf1f 39)\r
40{\r
52e1905d 41 EFI_HOB_GUID_TYPE *GuidHob;\r
42 PCD_PPI_CALLBACK *CallbackTable;\r
43 PCD_PPI_CALLBACK Compare;\r
44 PCD_PPI_CALLBACK Assign;\r
45 UINT32 LocalTokenNumber;\r
8a43e8dd 46 UINTN TokenNumber;\r
52e1905d 47 UINTN Idx;\r
878ddf1f 48\r
52e1905d 49 if (Guid == NULL) {\r
50 TokenNumber = ExTokenNumber;\r
58f1099f 51\r
52 //\r
53 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
54 // We have to decrement TokenNumber by 1 to make it usable\r
55 // as the array index.\r
56 //\r
57 TokenNumber--;\r
4f914125 58 ASSERT (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1);\r
52e1905d 59 } else {\r
9d6d8b24 60 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
58f1099f 61\r
62 //\r
63 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
64 // We have to decrement TokenNumber by 1 to make it usable\r
65 // as the array index.\r
66 //\r
67 TokenNumber--;\r
4f914125 68 // EBC compiler is very choosy. It may report warning about comparison\r
69 // between UINTN and 0 . So we add 1 in each size of the \r
70 // comparison.\r
71 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
52e1905d 72 }\r
878ddf1f 73\r
58f1099f 74\r
9d6d8b24 75 LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber];\r
76\r
1de04b4f 77 //\r
78 // We don't support SET for HII and VPD type PCD entry in PEI phase.\r
79 // So we will assert if any register callback for such PCD entry.\r
80 //\r
52e1905d 81 ASSERT ((LocalTokenNumber & PCD_TYPE_HII) == 0);\r
82 ASSERT ((LocalTokenNumber & PCD_TYPE_VPD) == 0);\r
878ddf1f 83\r
52e1905d 84 GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
878ddf1f 85 ASSERT (GuidHob != NULL);\r
52e1905d 86 \r
87 CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
0653eb89 88 CallbackTable = CallbackTable + (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
878ddf1f 89\r
52e1905d 90 Compare = Register? NULL: CallBackFunction;\r
91 Assign = Register? CallBackFunction: NULL;\r
878ddf1f 92\r
0653eb89 93\r
52e1905d 94 for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
95 if (CallbackTable[Idx] == Compare) {\r
96 CallbackTable[Idx] = Assign;\r
97 return EFI_SUCCESS;\r
98 }\r
99 }\r
878ddf1f 100\r
52e1905d 101 return Register? EFI_OUT_OF_RESOURCES : EFI_NOT_FOUND;\r
878ddf1f 102\r
878ddf1f 103}\r
104\r
105\r
878ddf1f 106\r
878ddf1f 107\r
52e1905d 108/**\r
a7c5092f 109 The function builds the PCD database.\r
878ddf1f 110\r
a7c5092f 111 @param VOID\r
878ddf1f 112\r
52e1905d 113 @retval VOID\r
878ddf1f 114--*/\r
52e1905d 115VOID\r
116BuildPcdDatabase (\r
117 VOID\r
878ddf1f 118 )\r
119{\r
52e1905d 120 PEI_PCD_DATABASE *Database;\r
121 VOID *CallbackFnTable;\r
122 UINTN SizeOfCallbackFnTable;\r
123 \r
124 Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE));\r
878ddf1f 125\r
52e1905d 126 ZeroMem (Database, sizeof (PEI_PCD_DATABASE));\r
878ddf1f 127\r
128 //\r
52e1905d 129 // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE\r
878ddf1f 130 //\r
878ddf1f 131 \r
52e1905d 132 CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit));\r
878ddf1f 133\r
52e1905d 134 SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry);\r
878ddf1f 135\r
52e1905d 136 CallbackFnTable = BuildGuidHob (&gPcdPeiCallbackFnTableHobGuid, SizeOfCallbackFnTable);\r
137 \r
138 ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);\r
139 \r
140 return;\r
878ddf1f 141}\r
142\r
143\r
144\r
145/**\r
52e1905d 146 The function is provided by PCD PEIM and PCD DXE driver to\r
147 do the work of reading a HII variable from variable service.\r
878ddf1f 148\r
a7c5092f 149 @param VariableGuid The Variable GUID.\r
150 @param VariableName The Variable Name.\r
151 @param VariableData The output data.\r
152 @param VariableSize The size of the variable.\r
878ddf1f 153\r
52e1905d 154 @retval EFI_SUCCESS Operation successful.\r
a7c5092f 155 @retval EFI_NOT_FOUND Variablel not found.\r
878ddf1f 156--*/\r
157EFI_STATUS\r
52e1905d 158GetHiiVariable (\r
159 IN CONST EFI_GUID *VariableGuid,\r
160 IN UINT16 *VariableName,\r
161 OUT VOID **VariableData,\r
162 OUT UINTN *VariableSize\r
878ddf1f 163 )\r
164{\r
52e1905d 165 UINTN Size;\r
166 EFI_STATUS Status;\r
167 VOID *Buffer;\r
168 EFI_PEI_READ_ONLY_VARIABLE_PPI *VariablePpi;\r
878ddf1f 169\r
84a99d48 170 Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, (VOID **) &VariablePpi);\r
52e1905d 171 ASSERT_EFI_ERROR (Status);\r
878ddf1f 172\r
52e1905d 173 Size = 0;\r
52e1905d 174 Status = VariablePpi->PeiGetVariable (\r
175 GetPeiServicesTablePointer (),\r
176 VariableName,\r
177 (EFI_GUID *) VariableGuid,\r
178 NULL,\r
179 &Size,\r
180 NULL\r
181 );\r
c0e96fed 182 if (Status == EFI_BUFFER_TOO_SMALL) {\r
52e1905d 183\r
52e1905d 184\r
c0e96fed 185 Status = PeiServicesAllocatePool (Size, &Buffer);\r
186 ASSERT_EFI_ERROR (Status);\r
52e1905d 187\r
c0e96fed 188 Status = VariablePpi->PeiGetVariable (\r
189 GetPeiServicesTablePointer (),\r
190 (UINT16 *) VariableName,\r
191 (EFI_GUID *) VariableGuid,\r
192 NULL,\r
193 &Size,\r
194 Buffer\r
195 );\r
196 ASSERT_EFI_ERROR (Status);\r
197\r
198 *VariableSize = Size;\r
199 *VariableData = Buffer;\r
200\r
201 return EFI_SUCCESS;\r
202 } else {\r
203 return EFI_NOT_FOUND;\r
204 }\r
878ddf1f 205\r
878ddf1f 206}\r
207\r
208\r
52e1905d 209UINT32\r
210GetSkuEnabledTokenNumber (\r
211 UINT32 LocalTokenNumber,\r
212 UINTN Size\r
213 ) \r
878ddf1f 214{\r
52e1905d 215 PEI_PCD_DATABASE *PeiPcdDb;\r
216 SKU_HEAD *SkuHead;\r
217 SKU_ID *SkuIdTable;\r
218 INTN i;\r
219 UINT8 *Value;\r
220\r
221 PeiPcdDb = GetPcdDatabase ();\r
222\r
223 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);\r
224\r
225 SkuHead = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
226 Value = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));\r
227 SkuIdTable = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));\r
228 \r
229 for (i = 0; i < SkuIdTable[0]; i++) {\r
230 if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[i + 1]) {\r
231 break;\r
232 }\r
233 }\r
878ddf1f 234\r
1de04b4f 235 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 236 case PCD_TYPE_VPD:\r
1de04b4f 237 Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);\r
4f914125 238 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_VPD);\r
52e1905d 239\r
240 case PCD_TYPE_HII:\r
1de04b4f 241 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);\r
4f914125 242 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);\r
52e1905d 243 \r
1de04b4f 244 case PCD_TYPE_STRING:\r
245 Value = (UINT8 *) &(((STRING_HEAD *) Value)[i]);\r
4f914125 246 return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);\r
1de04b4f 247\r
00b7af13 248 case PCD_TYPE_DATA:\r
52e1905d 249 Value += Size * i;\r
4f914125 250 return (UINT32) (Value - (UINT8 *) PeiPcdDb);\r
1de04b4f 251\r
52e1905d 252 default:\r
253 ASSERT (FALSE);\r
254 }\r
878ddf1f 255\r
52e1905d 256 ASSERT (FALSE);\r
878ddf1f 257\r
52e1905d 258 return 0;\r
259 \r
878ddf1f 260}\r
261\r
262\r
263\r
878ddf1f 264\r
52e1905d 265VOID\r
266InvokeCallbackOnSet (\r
4f914125 267 UINTN ExTokenNumber,\r
52e1905d 268 CONST EFI_GUID *Guid, OPTIONAL\r
269 UINTN TokenNumber,\r
270 VOID *Data,\r
271 UINTN Size\r
272 )\r
878ddf1f 273{\r
878ddf1f 274 EFI_HOB_GUID_TYPE *GuidHob;\r
878ddf1f 275 PCD_PPI_CALLBACK *CallbackTable;\r
52e1905d 276 UINTN Idx;\r
878ddf1f 277\r
58f1099f 278 //\r
279 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
280 // We have to decrement TokenNumber by 1 to make it usable\r
281 // as the array index.\r
282 //\r
283 TokenNumber--;\r
284 \r
4f914125 285 if (Guid == NULL) {\r
286 // EBC compiler is very choosy. It may report warning about comparison\r
287 // between UINTN and 0 . So we add 1 in each size of the \r
288 // comparison.\r
289 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
290 }\r
52e1905d 291\r
292 GuidHob = GetFirstGuidHob (&gPcdPeiCallbackFnTableHobGuid);\r
878ddf1f 293 ASSERT (GuidHob != NULL);\r
294 \r
52e1905d 295 CallbackTable = GET_GUID_HOB_DATA (GuidHob);\r
878ddf1f 296\r
52e1905d 297 CallbackTable += (TokenNumber * FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry));\r
878ddf1f 298\r
52e1905d 299 for (Idx = 0; Idx < FixedPcdGet32(PcdMaxPeiPcdCallBackNumberPerPcdEntry); Idx++) {\r
300 if (CallbackTable[Idx] != NULL) {\r
301 CallbackTable[Idx] (Guid,\r
302 (Guid == NULL)? TokenNumber: ExTokenNumber,\r
303 Data,\r
304 Size\r
305 );\r
878ddf1f 306 }\r
307 }\r
52e1905d 308 \r
878ddf1f 309}\r
310\r
9d6d8b24 311\r
312\r
1de04b4f 313EFI_STATUS\r
314SetValueWorker (\r
315 IN UINTN TokenNumber,\r
316 IN VOID *Data,\r
317 IN UINTN Size\r
318 )\r
319{\r
320 return SetWorker (TokenNumber, Data, &Size, FALSE);\r
321}\r
322\r
323\r
9d6d8b24 324\r
878ddf1f 325EFI_STATUS\r
52e1905d 326SetWorker (\r
1de04b4f 327 IN UINTN TokenNumber,\r
328 IN OUT VOID *Data,\r
329 IN OUT UINTN *Size,\r
330 IN BOOLEAN PtrType\r
878ddf1f 331 )\r
332{\r
52e1905d 333 UINT32 LocalTokenNumber;\r
334 PEI_PCD_DATABASE *PeiPcdDb;\r
9d6d8b24 335 UINT16 StringTableIdx;\r
336 UINTN Offset;\r
337 VOID *InternalData;\r
1de04b4f 338 UINTN MaxSize;\r
878ddf1f 339\r
f89f5802 340 if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {\r
341 return EFI_UNSUPPORTED;\r
342 }\r
343 \r
58f1099f 344 //\r
345 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
346 // We have to decrement TokenNumber by 1 to make it usable\r
347 // as the array index.\r
348 //\r
349 TokenNumber--;\r
350\r
4f914125 351 // EBC compiler is very choosy. It may report warning about comparison\r
352 // between UINTN and 0 . So we add 1 in each size of the \r
353 // comparison.\r
354 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
52e1905d 355 \r
356 PeiPcdDb = GetPcdDatabase ();\r
878ddf1f 357\r
52e1905d 358 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
878ddf1f 359\r
1de04b4f 360 if (!PtrType) {\r
361 ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size);\r
52e1905d 362 }\r
878ddf1f 363\r
9d6d8b24 364 //\r
365 // We only invoke the callback function for Dynamic Type PCD Entry.\r
366 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX\r
367 // type PCD entry in ExSetWorker.\r
368 //\r
4f914125 369 if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {\r
1de04b4f 370 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
9d6d8b24 371 }\r
878ddf1f 372\r
52e1905d 373 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
1de04b4f 374 if (PtrType) {\r
375 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
376 } else {\r
377 MaxSize = *Size;\r
378 }\r
379 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
52e1905d 380 }\r
878ddf1f 381\r
52e1905d 382 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
9d6d8b24 383 InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);\r
878ddf1f 384 \r
1de04b4f 385 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 386 case PCD_TYPE_VPD:\r
387 case PCD_TYPE_HII:\r
388 {\r
389 ASSERT (FALSE);\r
390 return EFI_INVALID_PARAMETER;\r
391 }\r
878ddf1f 392\r
52e1905d 393 case PCD_TYPE_STRING:\r
1de04b4f 394 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
395 StringTableIdx = *((UINT16 *)InternalData);\r
396 CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);\r
397 return EFI_SUCCESS;\r
398 } else {\r
399 return EFI_INVALID_PARAMETER;\r
400 }\r
878ddf1f 401\r
52e1905d 402 case PCD_TYPE_DATA:\r
403 {\r
52e1905d 404 if (PtrType) {\r
1de04b4f 405 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
406 CopyMem (InternalData, Data, *Size);\r
407 return EFI_SUCCESS;\r
408 } else {\r
409 return EFI_INVALID_PARAMETER;\r
410 }\r
52e1905d 411 }\r
878ddf1f 412\r
1de04b4f 413 switch (*Size) {\r
52e1905d 414 case sizeof(UINT8):\r
415 *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
416 return EFI_SUCCESS;\r
878ddf1f 417\r
52e1905d 418 case sizeof(UINT16):\r
419 *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
420 return EFI_SUCCESS;\r
878ddf1f 421\r
52e1905d 422 case sizeof(UINT32):\r
423 *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
424 return EFI_SUCCESS;\r
878ddf1f 425\r
52e1905d 426 case sizeof(UINT64):\r
427 *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
428 return EFI_SUCCESS;\r
878ddf1f 429\r
52e1905d 430 default:\r
431 ASSERT (FALSE);\r
432 return EFI_NOT_FOUND;\r
433 }\r
434 }\r
435 \r
878ddf1f 436 }\r
437\r
52e1905d 438 ASSERT (FALSE);\r
439 return EFI_NOT_FOUND;\r
9d6d8b24 440\r
441}\r
442\r
443\r
444\r
1de04b4f 445EFI_STATUS\r
446ExSetValueWorker (\r
447 IN UINTN ExTokenNumber,\r
448 IN CONST EFI_GUID *Guid,\r
449 IN VOID *Data,\r
450 IN UINTN Size\r
451 )\r
452{\r
453 return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);\r
454}\r
455\r
456\r
9d6d8b24 457\r
458EFI_STATUS\r
459ExSetWorker (\r
1de04b4f 460 IN UINTN ExTokenNumber,\r
461 IN CONST EFI_GUID *Guid,\r
462 IN VOID *Data,\r
463 IN OUT UINTN *Size,\r
464 IN BOOLEAN PtrType\r
9d6d8b24 465 )\r
466{\r
8a43e8dd 467 UINTN TokenNumber;\r
9d6d8b24 468\r
f89f5802 469 if (!FeaturePcdGet(PcdPeiPcdDatabaseSetEnabled)) {\r
470 return EFI_UNSUPPORTED;\r
471 }\r
472\r
9d6d8b24 473 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
474\r
1de04b4f 475 InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);\r
9d6d8b24 476\r
1de04b4f 477 return SetWorker (TokenNumber, Data, Size, PtrType);\r
9d6d8b24 478\r
9d6d8b24 479}\r
480\r
481\r
482\r
483\r
484VOID *\r
485ExGetWorker (\r
486 IN CONST EFI_GUID *Guid,\r
8a43e8dd 487 IN UINTN ExTokenNumber,\r
9d6d8b24 488 IN UINTN GetSize\r
489 )\r
490{\r
f89f5802 491 if (!FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) {\r
492 ASSERT (FALSE);\r
493 return 0;\r
494 }\r
495 \r
9d6d8b24 496 return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);\r
878ddf1f 497}\r
498\r
499\r
9d6d8b24 500\r
501\r
52e1905d 502VOID *\r
9d6d8b24 503GetWorker (\r
8a43e8dd 504 UINTN TokenNumber,\r
9d6d8b24 505 UINTN GetSize\r
878ddf1f 506 )\r
507{\r
52e1905d 508 UINT32 Offset;\r
509 EFI_GUID *Guid;\r
510 UINT16 *Name;\r
511 VARIABLE_HEAD *VariableHead;\r
512 EFI_STATUS Status;\r
513 UINTN DataSize;\r
514 VOID *Data;\r
515 UINT16 *StringTable;\r
516 UINT16 StringTableIdx;\r
9d6d8b24 517 PEI_PCD_DATABASE *PeiPcdDb;\r
518 UINT32 LocalTokenNumber;\r
1de04b4f 519 UINTN MaxSize;\r
9d6d8b24 520\r
58f1099f 521 //\r
522 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
523 // We have to decrement TokenNumber by 1 to make it usable\r
524 // as the array index.\r
525 //\r
526 TokenNumber--;\r
527\r
4f914125 528 // EBC compiler is very choosy. It may report warning about comparison\r
529 // between UINTN and 0 . So we add 1 in each size of the \r
530 // comparison.\r
531 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
9d6d8b24 532\r
1de04b4f 533 ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));\r
9d6d8b24 534\r
52e1905d 535 PeiPcdDb = GetPcdDatabase ();\r
536\r
9d6d8b24 537 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
538\r
52e1905d 539 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
1de04b4f 540 if (GetSize == 0) {\r
541 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
542 } else {\r
543 MaxSize = GetSize;\r
544 }\r
545 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
52e1905d 546 }\r
878ddf1f 547\r
52e1905d 548 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
549 StringTable = PeiPcdDb->Init.StringTable;\r
550 \r
1de04b4f 551 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 552 case PCD_TYPE_VPD:\r
553 {\r
554 VPD_HEAD *VpdHead;\r
555 VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
4f914125 556 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
52e1905d 557 }\r
558 \r
559 case PCD_TYPE_HII:\r
560 {\r
561 VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
562 \r
563 Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);\r
564 Name = &StringTable[VariableHead->StringIndex];\r
565\r
566 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
52e1905d 567\r
c0e96fed 568 if (Status == EFI_SUCCESS) {\r
c0e96fed 569 return (VOID *) ((UINT8 *) Data + VariableHead->Offset);\r
570 } else {\r
571 //\r
58f1099f 572 // Return the default value specified by Platform Integrator \r
573 //\r
574 return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset);\r
c0e96fed 575 }\r
52e1905d 576 }\r
878ddf1f 577\r
52e1905d 578 case PCD_TYPE_DATA:\r
579 return (VOID *) ((UINT8 *)PeiPcdDb + Offset);\r
878ddf1f 580\r
52e1905d 581 case PCD_TYPE_STRING:\r
582 StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);\r
583 return (VOID *) (&StringTable[StringTableIdx]);\r
878ddf1f 584\r
52e1905d 585 default:\r
586 ASSERT (FALSE);\r
587 break;\r
588 \r
589 }\r
878ddf1f 590\r
52e1905d 591 ASSERT (FALSE);\r
592 \r
593 return NULL;\r
594 \r
595}\r
878ddf1f 596\r
878ddf1f 597\r
a7c5092f 598\r
8a43e8dd 599UINTN \r
9d6d8b24 600GetExPcdTokenNumber (\r
52e1905d 601 IN CONST EFI_GUID *Guid,\r
4f914125 602 IN UINTN ExTokenNumber\r
52e1905d 603 )\r
604{\r
605 UINT32 i;\r
606 DYNAMICEX_MAPPING *ExMap;\r
607 EFI_GUID *GuidTable;\r
9d6d8b24 608 EFI_GUID *MatchGuid;\r
609 UINTN MatchGuidIdx;\r
52e1905d 610 PEI_PCD_DATABASE *PeiPcdDb;\r
878ddf1f 611\r
52e1905d 612 PeiPcdDb = GetPcdDatabase();\r
613 \r
614 ExMap = PeiPcdDb->Init.ExMapTable;\r
615 GuidTable = PeiPcdDb->Init.GuidTable;\r
9d6d8b24 616\r
617 MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);\r
bb5545b6 618 //\r
619 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
620 // error in the BUILD system.\r
621 //\r
9d6d8b24 622 ASSERT (MatchGuid != NULL);\r
623 \r
624 MatchGuidIdx = MatchGuid - GuidTable;\r
52e1905d 625 \r
626 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
627 if ((ExTokenNumber == ExMap[i].ExTokenNumber) && \r
9d6d8b24 628 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
629 return ExMap[i].LocalTokenNumber;\r
52e1905d 630 }\r
631 }\r
632 \r
633 ASSERT (FALSE);\r
634 \r
9d6d8b24 635 return 0;\r
878ddf1f 636}\r
637\r
638\r
639\r
52e1905d 640PEI_PCD_DATABASE *\r
641GetPcdDatabase (\r
642 VOID\r
878ddf1f 643 )\r
644{\r
52e1905d 645 EFI_HOB_GUID_TYPE *GuidHob;\r
878ddf1f 646\r
52e1905d 647 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
648 ASSERT (GuidHob != NULL);\r
649 \r
650 return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
651}\r
878ddf1f 652\r
1de04b4f 653\r
a7c5092f 654\r
1de04b4f 655SKU_ID *\r
656GetSkuIdArray (\r
657 IN UINTN LocalTokenNumberTableIdx,\r
658 IN PEI_PCD_DATABASE *Database\r
659 )\r
660{\r
661 SKU_HEAD *SkuHead;\r
662 UINTN LocalTokenNumber;\r
663\r
664 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
665\r
666 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
667\r
668 SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
669\r
670 return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);\r
671 \r
672}\r
673\r
674\r
675\r
676UINTN\r
677GetSizeTableIndex (\r
678 IN UINTN LocalTokenNumberTableIdx,\r
679 IN PEI_PCD_DATABASE *Database\r
680 )\r
681{\r
682 UINTN i;\r
683 UINTN SizeTableIdx;\r
684 UINTN LocalTokenNumber;\r
685 SKU_ID *SkuIdTable;\r
686 \r
687 SizeTableIdx = 0;\r
688\r
689 for (i=0; i<LocalTokenNumberTableIdx; i++) {\r
690 LocalTokenNumber = Database->Init.LocalTokenNumberTable[i];\r
691\r
692 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {\r
693 //\r
694 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
695 // PCD entry.\r
696 //\r
697 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
698 //\r
699 // We have only one entry for VPD enabled PCD entry:\r
700 // 1) MAX Size.\r
701 // We consider current size is equal to MAX size.\r
702 //\r
703 SizeTableIdx++;\r
704 } else {\r
705 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
706 //\r
707 // We have only two entry for Non-Sku enabled PCD entry:\r
708 // 1) MAX SIZE\r
709 // 2) Current Size\r
710 //\r
711 SizeTableIdx += 2;\r
712 } else {\r
713 //\r
714 // We have these entry for SKU enabled PCD entry\r
715 // 1) MAX SIZE\r
716 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
717 //\r
718 SkuIdTable = GetSkuIdArray (i, Database);\r
719 SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
720 }\r
721 }\r
722 }\r
723\r
724 }\r
725\r
726 return SizeTableIdx;\r
727}\r
728\r
729\r
730\r
731\r
732UINTN\r
733GetPtrTypeSize (\r
734 IN UINTN LocalTokenNumberTableIdx,\r
735 OUT UINTN *MaxSize,\r
736 IN PEI_PCD_DATABASE *Database\r
737 )\r
738{\r
739 INTN SizeTableIdx;\r
740 UINTN LocalTokenNumber;\r
741 SKU_ID *SkuIdTable;\r
742 SIZE_INFO *SizeTable;\r
743 UINTN i;\r
744\r
745 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
746\r
747 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
748\r
749 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
750 \r
751 SizeTable = Database->Init.SizeTable;\r
752\r
753 *MaxSize = SizeTable[SizeTableIdx];\r
754 //\r
755 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
756 // PCD entry.\r
757 //\r
758 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
759 //\r
760 // We have only one entry for VPD enabled PCD entry:\r
761 // 1) MAX Size.\r
762 // We consider current size is equal to MAX size.\r
763 //\r
764 return *MaxSize;\r
765 } else {\r
766 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
767 //\r
768 // We have only two entry for Non-Sku enabled PCD entry:\r
769 // 1) MAX SIZE\r
770 // 2) Current Size\r
771 //\r
772 return SizeTable[SizeTableIdx + 1];\r
773 } else {\r
774 //\r
775 // We have these entry for SKU enabled PCD entry\r
776 // 1) MAX SIZE\r
777 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
778 //\r
779 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);\r
780 for (i = 0; i < SkuIdTable[0]; i++) {\r
781 if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) {\r
782 return SizeTable[SizeTableIdx + 1 + i];\r
783 }\r
784 }\r
785 return SizeTable[SizeTableIdx + 1];\r
786 }\r
787 }\r
788}\r
789\r
790\r
791\r
792BOOLEAN\r
793SetPtrTypeSize (\r
794 IN UINTN LocalTokenNumberTableIdx,\r
795 IN OUT UINTN *CurrentSize,\r
796 IN PEI_PCD_DATABASE *Database\r
797 )\r
798{\r
799 INTN SizeTableIdx;\r
800 UINTN LocalTokenNumber;\r
801 SKU_ID *SkuIdTable;\r
802 SIZE_INFO *SizeTable;\r
803 UINTN i;\r
804 UINTN MaxSize;\r
805 \r
806 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
807\r
808 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
809\r
810 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
811 \r
812 SizeTable = Database->Init.SizeTable;\r
813\r
814 MaxSize = SizeTable[SizeTableIdx];\r
815 //\r
816 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
817 // PCD entry.\r
818 //\r
819 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
820 //\r
821 // We shouldn't come here as we don't support SET for VPD\r
822 //\r
823 ASSERT (FALSE);\r
824 return FALSE;\r
825 } else {\r
826 if ((*CurrentSize > MaxSize) ||\r
827 (*CurrentSize == MAX_ADDRESS)) {\r
828 *CurrentSize = MaxSize;\r
829 return FALSE;\r
830 } \r
831 \r
832 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
833 //\r
834 // We have only two entry for Non-Sku enabled PCD entry:\r
835 // 1) MAX SIZE\r
836 // 2) Current Size\r
837 //\r
838 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
839 return TRUE;\r
840 } else {\r
841 //\r
842 // We have these entry for SKU enabled PCD entry\r
843 // 1) MAX SIZE\r
844 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
845 //\r
846 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);\r
847 for (i = 0; i < SkuIdTable[0]; i++) {\r
848 if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) {\r
849 SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize;\r
850 return TRUE;\r
851 }\r
852 }\r
853 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
854 return TRUE;\r
855 }\r
856 }\r
857\r
858}\r