]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/PCD/Pei/Service.c
Add in function description and comments.
[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
58f1099f 340 //\r
341 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
342 // We have to decrement TokenNumber by 1 to make it usable\r
343 // as the array index.\r
344 //\r
345 TokenNumber--;\r
346\r
4f914125 347 // EBC compiler is very choosy. It may report warning about comparison\r
348 // between UINTN and 0 . So we add 1 in each size of the \r
349 // comparison.\r
350 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
52e1905d 351 \r
352 PeiPcdDb = GetPcdDatabase ();\r
878ddf1f 353\r
52e1905d 354 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
878ddf1f 355\r
1de04b4f 356 if (!PtrType) {\r
357 ASSERT (PeiPcdGetSize(TokenNumber + 1) == *Size);\r
52e1905d 358 }\r
878ddf1f 359\r
9d6d8b24 360 //\r
361 // We only invoke the callback function for Dynamic Type PCD Entry.\r
362 // For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX\r
363 // type PCD entry in ExSetWorker.\r
364 //\r
4f914125 365 if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {\r
1de04b4f 366 InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);\r
9d6d8b24 367 }\r
878ddf1f 368\r
52e1905d 369 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
1de04b4f 370 if (PtrType) {\r
371 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
372 } else {\r
373 MaxSize = *Size;\r
374 }\r
375 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
52e1905d 376 }\r
878ddf1f 377\r
52e1905d 378 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
9d6d8b24 379 InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);\r
878ddf1f 380 \r
1de04b4f 381 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 382 case PCD_TYPE_VPD:\r
383 case PCD_TYPE_HII:\r
384 {\r
385 ASSERT (FALSE);\r
386 return EFI_INVALID_PARAMETER;\r
387 }\r
878ddf1f 388\r
52e1905d 389 case PCD_TYPE_STRING:\r
1de04b4f 390 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
391 StringTableIdx = *((UINT16 *)InternalData);\r
392 CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);\r
393 return EFI_SUCCESS;\r
394 } else {\r
395 return EFI_INVALID_PARAMETER;\r
396 }\r
878ddf1f 397\r
52e1905d 398 case PCD_TYPE_DATA:\r
399 {\r
52e1905d 400 if (PtrType) {\r
1de04b4f 401 if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {\r
402 CopyMem (InternalData, Data, *Size);\r
403 return EFI_SUCCESS;\r
404 } else {\r
405 return EFI_INVALID_PARAMETER;\r
406 }\r
52e1905d 407 }\r
878ddf1f 408\r
1de04b4f 409 switch (*Size) {\r
52e1905d 410 case sizeof(UINT8):\r
411 *((UINT8 *) InternalData) = *((UINT8 *) Data);\r
412 return EFI_SUCCESS;\r
878ddf1f 413\r
52e1905d 414 case sizeof(UINT16):\r
415 *((UINT16 *) InternalData) = *((UINT16 *) Data);\r
416 return EFI_SUCCESS;\r
878ddf1f 417\r
52e1905d 418 case sizeof(UINT32):\r
419 *((UINT32 *) InternalData) = *((UINT32 *) Data);\r
420 return EFI_SUCCESS;\r
878ddf1f 421\r
52e1905d 422 case sizeof(UINT64):\r
423 *((UINT64 *) InternalData) = *((UINT64 *) Data);\r
424 return EFI_SUCCESS;\r
878ddf1f 425\r
52e1905d 426 default:\r
427 ASSERT (FALSE);\r
428 return EFI_NOT_FOUND;\r
429 }\r
430 }\r
431 \r
878ddf1f 432 }\r
433\r
52e1905d 434 ASSERT (FALSE);\r
435 return EFI_NOT_FOUND;\r
9d6d8b24 436\r
437}\r
438\r
439\r
440\r
1de04b4f 441EFI_STATUS\r
442ExSetValueWorker (\r
443 IN UINTN ExTokenNumber,\r
444 IN CONST EFI_GUID *Guid,\r
445 IN VOID *Data,\r
446 IN UINTN Size\r
447 )\r
448{\r
449 return ExSetWorker (ExTokenNumber, Guid, Data, &Size, FALSE);\r
450}\r
451\r
452\r
9d6d8b24 453\r
454EFI_STATUS\r
455ExSetWorker (\r
1de04b4f 456 IN UINTN ExTokenNumber,\r
457 IN CONST EFI_GUID *Guid,\r
458 IN VOID *Data,\r
459 IN OUT UINTN *Size,\r
460 IN BOOLEAN PtrType\r
9d6d8b24 461 )\r
462{\r
8a43e8dd 463 UINTN TokenNumber;\r
9d6d8b24 464\r
465 TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);\r
466\r
1de04b4f 467 InvokeCallbackOnSet (ExTokenNumber, Guid, TokenNumber, Data, *Size);\r
9d6d8b24 468\r
1de04b4f 469 return SetWorker (TokenNumber, Data, Size, PtrType);\r
9d6d8b24 470\r
9d6d8b24 471}\r
472\r
473\r
474\r
475\r
476VOID *\r
477ExGetWorker (\r
478 IN CONST EFI_GUID *Guid,\r
8a43e8dd 479 IN UINTN ExTokenNumber,\r
9d6d8b24 480 IN UINTN GetSize\r
481 )\r
482{\r
483 return GetWorker (GetExPcdTokenNumber (Guid, ExTokenNumber), GetSize);\r
878ddf1f 484}\r
485\r
486\r
9d6d8b24 487\r
488\r
52e1905d 489VOID *\r
9d6d8b24 490GetWorker (\r
8a43e8dd 491 UINTN TokenNumber,\r
9d6d8b24 492 UINTN GetSize\r
878ddf1f 493 )\r
494{\r
52e1905d 495 UINT32 Offset;\r
496 EFI_GUID *Guid;\r
497 UINT16 *Name;\r
498 VARIABLE_HEAD *VariableHead;\r
499 EFI_STATUS Status;\r
500 UINTN DataSize;\r
501 VOID *Data;\r
502 UINT16 *StringTable;\r
503 UINT16 StringTableIdx;\r
9d6d8b24 504 PEI_PCD_DATABASE *PeiPcdDb;\r
505 UINT32 LocalTokenNumber;\r
1de04b4f 506 UINTN MaxSize;\r
9d6d8b24 507\r
58f1099f 508 //\r
509 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
510 // We have to decrement TokenNumber by 1 to make it usable\r
511 // as the array index.\r
512 //\r
513 TokenNumber--;\r
514\r
4f914125 515 // EBC compiler is very choosy. It may report warning about comparison\r
516 // between UINTN and 0 . So we add 1 in each size of the \r
517 // comparison.\r
518 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
9d6d8b24 519\r
1de04b4f 520 ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));\r
9d6d8b24 521\r
52e1905d 522 PeiPcdDb = GetPcdDatabase ();\r
523\r
9d6d8b24 524 LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];\r
525\r
52e1905d 526 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {\r
1de04b4f 527 if (GetSize == 0) {\r
528 MaxSize = GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
529 } else {\r
530 MaxSize = GetSize;\r
531 }\r
532 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);\r
52e1905d 533 }\r
878ddf1f 534\r
52e1905d 535 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;\r
536 StringTable = PeiPcdDb->Init.StringTable;\r
537 \r
1de04b4f 538 switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {\r
52e1905d 539 case PCD_TYPE_VPD:\r
540 {\r
541 VPD_HEAD *VpdHead;\r
542 VpdHead = (VPD_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
4f914125 543 return (VOID *) (UINTN) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);\r
52e1905d 544 }\r
545 \r
546 case PCD_TYPE_HII:\r
547 {\r
548 VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);\r
549 \r
550 Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);\r
551 Name = &StringTable[VariableHead->StringIndex];\r
552\r
553 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);\r
52e1905d 554\r
c0e96fed 555 if (Status == EFI_SUCCESS) {\r
c0e96fed 556 return (VOID *) ((UINT8 *) Data + VariableHead->Offset);\r
557 } else {\r
558 //\r
58f1099f 559 // Return the default value specified by Platform Integrator \r
560 //\r
561 return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset);\r
c0e96fed 562 }\r
52e1905d 563 }\r
878ddf1f 564\r
52e1905d 565 case PCD_TYPE_DATA:\r
566 return (VOID *) ((UINT8 *)PeiPcdDb + Offset);\r
878ddf1f 567\r
52e1905d 568 case PCD_TYPE_STRING:\r
569 StringTableIdx = (UINT16) *((UINT8 *) PeiPcdDb + Offset);\r
570 return (VOID *) (&StringTable[StringTableIdx]);\r
878ddf1f 571\r
52e1905d 572 default:\r
573 ASSERT (FALSE);\r
574 break;\r
575 \r
576 }\r
878ddf1f 577\r
52e1905d 578 ASSERT (FALSE);\r
579 \r
580 return NULL;\r
581 \r
582}\r
878ddf1f 583\r
878ddf1f 584\r
a7c5092f 585\r
8a43e8dd 586UINTN \r
9d6d8b24 587GetExPcdTokenNumber (\r
52e1905d 588 IN CONST EFI_GUID *Guid,\r
4f914125 589 IN UINTN ExTokenNumber\r
52e1905d 590 )\r
591{\r
592 UINT32 i;\r
593 DYNAMICEX_MAPPING *ExMap;\r
594 EFI_GUID *GuidTable;\r
9d6d8b24 595 EFI_GUID *MatchGuid;\r
596 UINTN MatchGuidIdx;\r
52e1905d 597 PEI_PCD_DATABASE *PeiPcdDb;\r
878ddf1f 598\r
52e1905d 599 PeiPcdDb = GetPcdDatabase();\r
600 \r
601 ExMap = PeiPcdDb->Init.ExMapTable;\r
602 GuidTable = PeiPcdDb->Init.GuidTable;\r
9d6d8b24 603\r
604 MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);\r
bb5545b6 605 //\r
606 // We need to ASSERT here. If GUID can't be found in GuidTable, this is a\r
607 // error in the BUILD system.\r
608 //\r
9d6d8b24 609 ASSERT (MatchGuid != NULL);\r
610 \r
611 MatchGuidIdx = MatchGuid - GuidTable;\r
52e1905d 612 \r
613 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
614 if ((ExTokenNumber == ExMap[i].ExTokenNumber) && \r
9d6d8b24 615 (MatchGuidIdx == ExMap[i].ExGuidIndex)) {\r
616 return ExMap[i].LocalTokenNumber;\r
52e1905d 617 }\r
618 }\r
619 \r
620 ASSERT (FALSE);\r
621 \r
9d6d8b24 622 return 0;\r
878ddf1f 623}\r
624\r
625\r
626\r
52e1905d 627PEI_PCD_DATABASE *\r
628GetPcdDatabase (\r
629 VOID\r
878ddf1f 630 )\r
631{\r
52e1905d 632 EFI_HOB_GUID_TYPE *GuidHob;\r
878ddf1f 633\r
52e1905d 634 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);\r
635 ASSERT (GuidHob != NULL);\r
636 \r
637 return (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);\r
638}\r
878ddf1f 639\r
1de04b4f 640\r
a7c5092f 641\r
1de04b4f 642SKU_ID *\r
643GetSkuIdArray (\r
644 IN UINTN LocalTokenNumberTableIdx,\r
645 IN PEI_PCD_DATABASE *Database\r
646 )\r
647{\r
648 SKU_HEAD *SkuHead;\r
649 UINTN LocalTokenNumber;\r
650\r
651 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
652\r
653 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);\r
654\r
655 SkuHead = (SKU_HEAD *) ((UINT8 *)Database + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));\r
656\r
657 return (SKU_ID *) ((UINT8 *)Database + SkuHead->SkuIdTableOffset);\r
658 \r
659}\r
660\r
661\r
662\r
663UINTN\r
664GetSizeTableIndex (\r
665 IN UINTN LocalTokenNumberTableIdx,\r
666 IN PEI_PCD_DATABASE *Database\r
667 )\r
668{\r
669 UINTN i;\r
670 UINTN SizeTableIdx;\r
671 UINTN LocalTokenNumber;\r
672 SKU_ID *SkuIdTable;\r
673 \r
674 SizeTableIdx = 0;\r
675\r
676 for (i=0; i<LocalTokenNumberTableIdx; i++) {\r
677 LocalTokenNumber = Database->Init.LocalTokenNumberTable[i];\r
678\r
679 if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {\r
680 //\r
681 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
682 // PCD entry.\r
683 //\r
684 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
685 //\r
686 // We have only one entry for VPD enabled PCD entry:\r
687 // 1) MAX Size.\r
688 // We consider current size is equal to MAX size.\r
689 //\r
690 SizeTableIdx++;\r
691 } else {\r
692 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
693 //\r
694 // We have only two entry for Non-Sku enabled PCD entry:\r
695 // 1) MAX SIZE\r
696 // 2) Current Size\r
697 //\r
698 SizeTableIdx += 2;\r
699 } else {\r
700 //\r
701 // We have these entry for SKU enabled PCD entry\r
702 // 1) MAX SIZE\r
703 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
704 //\r
705 SkuIdTable = GetSkuIdArray (i, Database);\r
706 SizeTableIdx += (UINTN)*SkuIdTable + 1;\r
707 }\r
708 }\r
709 }\r
710\r
711 }\r
712\r
713 return SizeTableIdx;\r
714}\r
715\r
716\r
717\r
718\r
719UINTN\r
720GetPtrTypeSize (\r
721 IN UINTN LocalTokenNumberTableIdx,\r
722 OUT UINTN *MaxSize,\r
723 IN PEI_PCD_DATABASE *Database\r
724 )\r
725{\r
726 INTN SizeTableIdx;\r
727 UINTN LocalTokenNumber;\r
728 SKU_ID *SkuIdTable;\r
729 SIZE_INFO *SizeTable;\r
730 UINTN i;\r
731\r
732 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
733\r
734 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
735\r
736 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
737 \r
738 SizeTable = Database->Init.SizeTable;\r
739\r
740 *MaxSize = SizeTable[SizeTableIdx];\r
741 //\r
742 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
743 // PCD entry.\r
744 //\r
745 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
746 //\r
747 // We have only one entry for VPD enabled PCD entry:\r
748 // 1) MAX Size.\r
749 // We consider current size is equal to MAX size.\r
750 //\r
751 return *MaxSize;\r
752 } else {\r
753 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
754 //\r
755 // We have only two entry for Non-Sku enabled PCD entry:\r
756 // 1) MAX SIZE\r
757 // 2) Current Size\r
758 //\r
759 return SizeTable[SizeTableIdx + 1];\r
760 } else {\r
761 //\r
762 // We have these entry for SKU enabled PCD entry\r
763 // 1) MAX SIZE\r
764 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
765 //\r
766 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);\r
767 for (i = 0; i < SkuIdTable[0]; i++) {\r
768 if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) {\r
769 return SizeTable[SizeTableIdx + 1 + i];\r
770 }\r
771 }\r
772 return SizeTable[SizeTableIdx + 1];\r
773 }\r
774 }\r
775}\r
776\r
777\r
778\r
779BOOLEAN\r
780SetPtrTypeSize (\r
781 IN UINTN LocalTokenNumberTableIdx,\r
782 IN OUT UINTN *CurrentSize,\r
783 IN PEI_PCD_DATABASE *Database\r
784 )\r
785{\r
786 INTN SizeTableIdx;\r
787 UINTN LocalTokenNumber;\r
788 SKU_ID *SkuIdTable;\r
789 SIZE_INFO *SizeTable;\r
790 UINTN i;\r
791 UINTN MaxSize;\r
792 \r
793 SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);\r
794\r
795 LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];\r
796\r
797 ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);\r
798 \r
799 SizeTable = Database->Init.SizeTable;\r
800\r
801 MaxSize = SizeTable[SizeTableIdx];\r
802 //\r
803 // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type \r
804 // PCD entry.\r
805 //\r
806 if (LocalTokenNumber & PCD_TYPE_VPD) {\r
807 //\r
808 // We shouldn't come here as we don't support SET for VPD\r
809 //\r
810 ASSERT (FALSE);\r
811 return FALSE;\r
812 } else {\r
813 if ((*CurrentSize > MaxSize) ||\r
814 (*CurrentSize == MAX_ADDRESS)) {\r
815 *CurrentSize = MaxSize;\r
816 return FALSE;\r
817 } \r
818 \r
819 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {\r
820 //\r
821 // We have only two entry for Non-Sku enabled PCD entry:\r
822 // 1) MAX SIZE\r
823 // 2) Current Size\r
824 //\r
825 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
826 return TRUE;\r
827 } else {\r
828 //\r
829 // We have these entry for SKU enabled PCD entry\r
830 // 1) MAX SIZE\r
831 // 2) Current Size for each SKU_ID (It is equal to MaxSku).\r
832 //\r
833 SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);\r
834 for (i = 0; i < SkuIdTable[0]; i++) {\r
835 if (SkuIdTable[1 + i] == Database->Init.SystemSkuId) {\r
836 SizeTable[SizeTableIdx + 1 + i] = (SIZE_INFO) *CurrentSize;\r
837 return TRUE;\r
838 }\r
839 }\r
840 SizeTable[SizeTableIdx + 1] = (SIZE_INFO) *CurrentSize;\r
841 return TRUE;\r
842 }\r
843 }\r
844\r
845}\r