]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EdkModulePkg/Universal/PCD/Pei/Pcd.c
Add Feature Flag PcdDxePcdDatabaseTraverseEnabled and PcdPeiPcdDatabaseTraverseEnabled
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Pei / Pcd.c
... / ...
CommitLineData
1/** @file PCD PEIM\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12\r
13Module Name: Pcd.c\r
14\r
15**/\r
16\r
17#include "Service.h"\r
18\r
19\r
20PCD_PPI mPcdPpiInstance = {\r
21 PeiPcdSetSku,\r
22\r
23 PeiPcdGet8,\r
24 PeiPcdGet16, \r
25 PeiPcdGet32, \r
26 PeiPcdGet64, \r
27 PeiPcdGetPtr, \r
28 PeiPcdGetBool, \r
29 PeiPcdGetSize,\r
30\r
31 PeiPcdGet8Ex,\r
32 PeiPcdGet16Ex, \r
33 PeiPcdGet32Ex, \r
34 PeiPcdGet64Ex, \r
35 PeiPcdGetPtrEx, \r
36 PeiPcdGetBoolEx, \r
37 PeiPcdGetSizeEx,\r
38 \r
39 PeiPcdSet8,\r
40 PeiPcdSet16, \r
41 PeiPcdSet32, \r
42 PeiPcdSet64, \r
43 PeiPcdSetPtr, \r
44 PeiPcdSetBool, \r
45\r
46 PeiPcdSet8Ex,\r
47 PeiPcdSet16Ex, \r
48 PeiPcdSet32Ex, \r
49 PeiPcdSet64Ex, \r
50 PeiPcdSetPtrEx, \r
51 PeiPcdSetBoolEx,\r
52\r
53 PeiRegisterCallBackOnSet,\r
54 PcdUnRegisterCallBackOnSet,\r
55 PeiPcdGetNextToken,\r
56 PeiPcdGetNextTokenSpace\r
57};\r
58\r
59\r
60\r
61STATIC EFI_PEI_PPI_DESCRIPTOR mPpiPCD = {\r
62 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
63 &gPcdPpiGuid,\r
64 &mPcdPpiInstance\r
65};\r
66\r
67\r
68\r
69EFI_STATUS\r
70EFIAPI\r
71PcdPeimInit (\r
72 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
73 IN EFI_PEI_SERVICES **PeiServices\r
74 )\r
75{\r
76 EFI_STATUS Status;\r
77\r
78 BuildPcdDatabase ();\r
79 \r
80 Status = PeiServicesInstallPpi (&mPpiPCD);\r
81\r
82 ASSERT_EFI_ERROR (Status);\r
83 \r
84 return EFI_SUCCESS;\r
85}\r
86\r
87VOID\r
88EFIAPI\r
89PeiPcdSetSku (\r
90 IN UINTN SkuId\r
91 )\r
92{\r
93\r
94 GetPcdDatabase()->Init.SystemSkuId = (SKU_ID) SkuId;\r
95\r
96 return;\r
97}\r
98\r
99\r
100\r
101UINT8\r
102EFIAPI\r
103PeiPcdGet8 (\r
104 IN UINTN TokenNumber\r
105 )\r
106{\r
107 return *((UINT8 *) GetWorker (TokenNumber, sizeof (UINT8)));\r
108}\r
109\r
110\r
111\r
112UINT16\r
113EFIAPI\r
114PeiPcdGet16 (\r
115 IN UINTN TokenNumber\r
116 )\r
117{\r
118 return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16)));\r
119}\r
120\r
121\r
122\r
123UINT32\r
124EFIAPI\r
125PeiPcdGet32 (\r
126 IN UINTN TokenNumber\r
127 )\r
128{\r
129 return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32)));\r
130}\r
131\r
132\r
133\r
134UINT64\r
135EFIAPI\r
136PeiPcdGet64 (\r
137 IN UINTN TokenNumber\r
138 )\r
139{\r
140 return ReadUnaligned64 (GetWorker (TokenNumber, sizeof (UINT64)));\r
141}\r
142\r
143\r
144\r
145VOID *\r
146EFIAPI\r
147PeiPcdGetPtr (\r
148 IN UINTN TokenNumber\r
149 )\r
150{\r
151 return GetWorker (TokenNumber, 0);\r
152}\r
153\r
154\r
155\r
156BOOLEAN\r
157EFIAPI\r
158PeiPcdGetBool (\r
159 IN UINTN TokenNumber\r
160 )\r
161{\r
162 return *((BOOLEAN *) GetWorker (TokenNumber, sizeof (BOOLEAN)));\r
163}\r
164\r
165\r
166\r
167UINTN\r
168EFIAPI\r
169PeiPcdGetSize (\r
170 IN UINTN TokenNumber\r
171 )\r
172{\r
173 PEI_PCD_DATABASE *PeiPcdDb;\r
174 UINTN Size;\r
175 UINTN MaxSize;\r
176\r
177 PeiPcdDb = GetPcdDatabase ();\r
178 //\r
179 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.\r
180 // We have to decrement TokenNumber by 1 to make it usable\r
181 // as the array index.\r
182 //\r
183 TokenNumber--;\r
184\r
185 // EBC compiler is very choosy. It may report warning about comparison\r
186 // between UINTN and 0 . So we add 1 in each size of the \r
187 // comparison.\r
188 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);\r
189\r
190 Size = (PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;\r
191\r
192 if (Size == 0) {\r
193 //\r
194 // For pointer type, we need to scan the SIZE_TABLE to get the current size.\r
195 //\r
196 return GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);\r
197 } else {\r
198 return Size;\r
199 }\r
200\r
201}\r
202\r
203\r
204\r
205UINT8\r
206EFIAPI\r
207PeiPcdGet8Ex (\r
208 IN CONST EFI_GUID *Guid,\r
209 IN UINTN ExTokenNumber\r
210 )\r
211{\r
212 return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof (UINT8)));\r
213}\r
214\r
215\r
216\r
217UINT16\r
218EFIAPI\r
219PeiPcdGet16Ex (\r
220 IN CONST EFI_GUID *Guid,\r
221 IN UINTN ExTokenNumber\r
222 )\r
223{\r
224 return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT16)));\r
225}\r
226\r
227\r
228\r
229UINT32\r
230EFIAPI\r
231PeiPcdGet32Ex (\r
232 IN CONST EFI_GUID *Guid,\r
233 IN UINTN ExTokenNumber\r
234 )\r
235{\r
236 return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT32)));\r
237}\r
238\r
239\r
240\r
241UINT64\r
242EFIAPI\r
243PeiPcdGet64Ex (\r
244 IN CONST EFI_GUID *Guid,\r
245 IN UINTN ExTokenNumber\r
246 )\r
247{\r
248 return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT64)));\r
249}\r
250\r
251\r
252\r
253VOID *\r
254EFIAPI\r
255PeiPcdGetPtrEx (\r
256 IN CONST EFI_GUID *Guid,\r
257 IN UINTN ExTokenNumber\r
258 )\r
259{\r
260 return ExGetWorker (Guid, ExTokenNumber, 0);\r
261}\r
262\r
263\r
264\r
265BOOLEAN\r
266EFIAPI\r
267PeiPcdGetBoolEx (\r
268 IN CONST EFI_GUID *Guid,\r
269 IN UINTN ExTokenNumber\r
270 )\r
271{\r
272 return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof (BOOLEAN)));\r
273}\r
274\r
275\r
276\r
277UINTN\r
278EFIAPI\r
279PeiPcdGetSizeEx (\r
280 IN CONST EFI_GUID *Guid,\r
281 IN UINTN ExTokenNumber\r
282 )\r
283{\r
284 return PeiPcdGetSize (GetExPcdTokenNumber (Guid, ExTokenNumber));\r
285}\r
286\r
287\r
288\r
289EFI_STATUS\r
290EFIAPI\r
291PeiPcdSet8 (\r
292 IN UINTN TokenNumber,\r
293 IN UINT8 Value\r
294 )\r
295{\r
296 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
297}\r
298\r
299\r
300\r
301EFI_STATUS\r
302EFIAPI\r
303PeiPcdSet16 (\r
304 IN UINTN TokenNumber,\r
305 IN UINT16 Value\r
306 )\r
307{\r
308 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
309}\r
310\r
311\r
312\r
313EFI_STATUS\r
314EFIAPI\r
315PeiPcdSet32 (\r
316 IN UINTN TokenNumber,\r
317 IN UINT32 Value\r
318 )\r
319{\r
320 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
321}\r
322\r
323\r
324\r
325EFI_STATUS\r
326EFIAPI\r
327PeiPcdSet64 (\r
328 IN UINTN TokenNumber,\r
329 IN UINT64 Value\r
330 )\r
331{\r
332 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
333}\r
334\r
335\r
336EFI_STATUS\r
337EFIAPI\r
338PeiPcdSetPtr (\r
339 IN UINTN TokenNumber,\r
340 IN OUT UINTN *SizeOfBuffer,\r
341 IN VOID *Buffer\r
342 )\r
343{\r
344 return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);\r
345}\r
346\r
347\r
348\r
349EFI_STATUS\r
350EFIAPI\r
351PeiPcdSetBool (\r
352 IN UINTN TokenNumber,\r
353 IN BOOLEAN Value\r
354 )\r
355{\r
356 return SetValueWorker (TokenNumber, &Value, sizeof (Value));\r
357}\r
358\r
359\r
360\r
361EFI_STATUS\r
362EFIAPI\r
363PeiPcdSet8Ex (\r
364 IN CONST EFI_GUID *Guid,\r
365 IN UINTN ExTokenNumber,\r
366 IN UINT8 Value\r
367 )\r
368{\r
369 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
370}\r
371\r
372\r
373\r
374EFI_STATUS\r
375EFIAPI\r
376PeiPcdSet16Ex (\r
377 IN CONST EFI_GUID *Guid,\r
378 IN UINTN ExTokenNumber,\r
379 IN UINT16 Value\r
380 )\r
381{\r
382 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
383}\r
384\r
385\r
386\r
387EFI_STATUS\r
388EFIAPI\r
389PeiPcdSet32Ex (\r
390 IN CONST EFI_GUID *Guid,\r
391 IN UINTN ExTokenNumber,\r
392 IN UINT32 Value\r
393 )\r
394{\r
395 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
396}\r
397\r
398\r
399\r
400EFI_STATUS\r
401EFIAPI\r
402PeiPcdSet64Ex (\r
403 IN CONST EFI_GUID *Guid,\r
404 IN UINTN ExTokenNumber,\r
405 IN UINT64 Value\r
406 )\r
407{\r
408 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
409}\r
410\r
411\r
412\r
413EFI_STATUS\r
414EFIAPI\r
415PeiPcdSetPtrEx (\r
416 IN CONST EFI_GUID *Guid,\r
417 IN UINTN ExTokenNumber,\r
418 IN UINTN *SizeOfBuffer,\r
419 IN VOID *Value\r
420 )\r
421{\r
422 return ExSetWorker (ExTokenNumber, Guid, Value, SizeOfBuffer, TRUE);\r
423}\r
424\r
425\r
426\r
427EFI_STATUS\r
428EFIAPI\r
429PeiPcdSetBoolEx (\r
430 IN CONST EFI_GUID *Guid,\r
431 IN UINTN ExTokenNumber,\r
432 IN BOOLEAN Value\r
433 )\r
434{\r
435 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));\r
436}\r
437\r
438\r
439\r
440\r
441EFI_STATUS\r
442EFIAPI\r
443PeiRegisterCallBackOnSet (\r
444 IN UINTN ExTokenNumber,\r
445 IN CONST EFI_GUID *Guid, OPTIONAL\r
446 IN PCD_PPI_CALLBACK CallBackFunction\r
447 )\r
448{\r
449 ASSERT (CallBackFunction != NULL);\r
450 \r
451 return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, TRUE);\r
452}\r
453\r
454\r
455\r
456EFI_STATUS\r
457EFIAPI\r
458PcdUnRegisterCallBackOnSet (\r
459 IN UINTN ExTokenNumber,\r
460 IN CONST EFI_GUID *Guid, OPTIONAL\r
461 IN PCD_PPI_CALLBACK CallBackFunction\r
462 )\r
463{\r
464 ASSERT (CallBackFunction != NULL);\r
465 \r
466 return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, FALSE);\r
467}\r
468\r
469\r
470\r
471EFI_STATUS\r
472EFIAPI\r
473PeiPcdGetNextToken (\r
474 IN CONST EFI_GUID *Guid, OPTIONAL\r
475 IN OUT UINTN *TokenNumber\r
476 )\r
477{\r
478 UINTN GuidTableIdx;\r
479 PEI_PCD_DATABASE *PeiPcdDb;\r
480 EFI_GUID *MatchGuid;\r
481 DYNAMICEX_MAPPING *ExMapTable;\r
482 UINTN i;\r
483 BOOLEAN Found;\r
484 \r
485 if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) {\r
486 return EFI_UNSUPPORTED;\r
487 }\r
488 \r
489 if (Guid == NULL) {\r
490 if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {\r
491 return EFI_NOT_FOUND;\r
492 }\r
493 (*TokenNumber)++;\r
494 if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {\r
495 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
496 }\r
497 return EFI_SUCCESS;\r
498 } else {\r
499 if (PEI_EXMAP_TABLE_EMPTY) {\r
500 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
501 return EFI_SUCCESS;\r
502 }\r
503 \r
504 //\r
505 // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order\r
506 // 1) ExGuid\r
507 // 2) ExTokenNumber\r
508 //\r
509 PeiPcdDb = GetPcdDatabase ();\r
510 \r
511 MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);\r
512\r
513 if (MatchGuid == NULL) {\r
514 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
515 return EFI_NOT_FOUND;\r
516 }\r
517\r
518 GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;\r
519\r
520 ExMapTable = PeiPcdDb->Init.ExMapTable;\r
521\r
522 Found = FALSE;\r
523 //\r
524 // Locate the GUID in ExMapTable first.\r
525 //\r
526 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
527 if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {\r
528 Found = TRUE;\r
529 break;\r
530 }\r
531 }\r
532\r
533 if (Found) {\r
534 if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {\r
535 *TokenNumber = ExMapTable[i].ExTokenNumber;\r
536 return EFI_SUCCESS;\r
537 }\r
538\r
539 for ( ; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
540 if (ExMapTable[i].ExTokenNumber == *TokenNumber) {\r
541 i++;\r
542 if (i == PEI_EXMAPPING_TABLE_SIZE) {\r
543 //\r
544 // Exceed the length of ExMap Table\r
545 //\r
546 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
547 return EFI_SUCCESS;\r
548 }\r
549 if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {\r
550 *TokenNumber = ExMapTable[i].ExTokenNumber;\r
551 return EFI_SUCCESS;\r
552 } else {\r
553 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;\r
554 return EFI_SUCCESS;\r
555 }\r
556 }\r
557 }\r
558 return EFI_NOT_FOUND;\r
559 }\r
560 }\r
561\r
562 return EFI_NOT_FOUND;\r
563}\r
564\r
565\r
566\r
567EFI_STATUS\r
568EFIAPI\r
569PeiPcdGetNextTokenSpace (\r
570 IN OUT CONST EFI_GUID **Guid\r
571 )\r
572{\r
573 UINTN GuidTableIdx;\r
574 EFI_GUID *MatchGuid;\r
575 PEI_PCD_DATABASE *PeiPcdDb;\r
576 DYNAMICEX_MAPPING *ExMapTable;\r
577 UINTN i;\r
578 BOOLEAN Found;\r
579\r
580 if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) {\r
581 return EFI_UNSUPPORTED;\r
582 }\r
583\r
584 ASSERT (Guid != NULL);\r
585\r
586 if (PEI_EXMAP_TABLE_EMPTY) {\r
587 if (*Guid != NULL) {\r
588 return EFI_NOT_FOUND;\r
589 } else {\r
590 return EFI_SUCCESS;\r
591 }\r
592 }\r
593\r
594 //\r
595 // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order\r
596 // 1) ExGuid\r
597 // 2) ExTokenNumber\r
598 //\r
599 PeiPcdDb = GetPcdDatabase ();\r
600\r
601 ExMapTable = PeiPcdDb->Init.ExMapTable;\r
602\r
603 if (*Guid == NULL) {\r
604 //\r
605 // return the first Token Space Guid.\r
606 //\r
607 *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[0].ExGuidIndex];\r
608 return EFI_SUCCESS;\r
609 }\r
610\r
611 MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), *Guid);\r
612\r
613 if (MatchGuid == NULL) {\r
614 return EFI_NOT_FOUND;\r
615 }\r
616 \r
617 GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;\r
618\r
619 Found = FALSE;\r
620 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {\r
621 if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {\r
622 Found = TRUE;\r
623 break;\r
624 }\r
625 }\r
626\r
627 if (Found) {\r
628 i++;\r
629 for ( ; i < PEI_EXMAPPING_TABLE_SIZE; i++ ) {\r
630 if (ExMapTable[i].ExGuidIndex != GuidTableIdx ) {\r
631 *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[i].ExGuidIndex];\r
632 return EFI_SUCCESS;\r
633 }\r
634 }\r
635 *Guid = NULL;\r
636 return EFI_SUCCESS;\r
637 }\r
638\r
639 return EFI_NOT_FOUND;\r
640\r
641}\r
642\r