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