1) If DebugAssertEnabled is TRUE, we still need to provide the GET size
[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 //
178 // If DebugAssertEnabled is TRUE, we still need to provide the GET size
179 // function as GetWorker and SetWoker need this function to do ASSERT.
180 //
181 if ((!FeaturePcdGet(PcdPeiPcdDatabaseGetSizeEnabled)) &&
182 (!DebugAssertEnabled ())) {
183 return 0;
184 }
185
186 PeiPcdDb = GetPcdDatabase ();
187 //
188 // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
189 // We have to decrement TokenNumber by 1 to make it usable
190 // as the array index.
191 //
192 TokenNumber--;
193
194 // EBC compiler is very choosy. It may report warning about comparison
195 // between UINTN and 0 . So we add 1 in each size of the
196 // comparison.
197 ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
198
199 Size = (PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
200
201 if (Size == 0) {
202 //
203 // For pointer type, we need to scan the SIZE_TABLE to get the current size.
204 //
205 return GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);
206 } else {
207 return Size;
208 }
209
210 }
211
212
213
214 UINT8
215 EFIAPI
216 PeiPcdGet8Ex (
217 IN CONST EFI_GUID *Guid,
218 IN UINTN ExTokenNumber
219 )
220 {
221 return *((UINT8 *) ExGetWorker (Guid, ExTokenNumber, sizeof (UINT8)));
222 }
223
224
225
226 UINT16
227 EFIAPI
228 PeiPcdGet16Ex (
229 IN CONST EFI_GUID *Guid,
230 IN UINTN ExTokenNumber
231 )
232 {
233 return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT16)));
234 }
235
236
237
238 UINT32
239 EFIAPI
240 PeiPcdGet32Ex (
241 IN CONST EFI_GUID *Guid,
242 IN UINTN ExTokenNumber
243 )
244 {
245 return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT32)));
246 }
247
248
249
250 UINT64
251 EFIAPI
252 PeiPcdGet64Ex (
253 IN CONST EFI_GUID *Guid,
254 IN UINTN ExTokenNumber
255 )
256 {
257 return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT64)));
258 }
259
260
261
262 VOID *
263 EFIAPI
264 PeiPcdGetPtrEx (
265 IN CONST EFI_GUID *Guid,
266 IN UINTN ExTokenNumber
267 )
268 {
269 return ExGetWorker (Guid, ExTokenNumber, 0);
270 }
271
272
273
274 BOOLEAN
275 EFIAPI
276 PeiPcdGetBoolEx (
277 IN CONST EFI_GUID *Guid,
278 IN UINTN ExTokenNumber
279 )
280 {
281 return *((BOOLEAN *) ExGetWorker (Guid, ExTokenNumber, sizeof (BOOLEAN)));
282 }
283
284
285
286 UINTN
287 EFIAPI
288 PeiPcdGetSizeEx (
289 IN CONST EFI_GUID *Guid,
290 IN UINTN ExTokenNumber
291 )
292 {
293 if ((!FeaturePcdGet (PcdPeiPcdDatabaseGetSizeEnabled)) || !FeaturePcdGet (PcdPeiPcdDatabaseExEnabled)) {
294 return 0;
295 }
296
297 return PeiPcdGetSize (GetExPcdTokenNumber (Guid, ExTokenNumber));
298 }
299
300
301
302 EFI_STATUS
303 EFIAPI
304 PeiPcdSet8 (
305 IN UINTN TokenNumber,
306 IN UINT8 Value
307 )
308 {
309 return SetValueWorker (TokenNumber, &Value, sizeof (Value));
310 }
311
312
313
314 EFI_STATUS
315 EFIAPI
316 PeiPcdSet16 (
317 IN UINTN TokenNumber,
318 IN UINT16 Value
319 )
320 {
321 return SetValueWorker (TokenNumber, &Value, sizeof (Value));
322 }
323
324
325
326 EFI_STATUS
327 EFIAPI
328 PeiPcdSet32 (
329 IN UINTN TokenNumber,
330 IN UINT32 Value
331 )
332 {
333 return SetValueWorker (TokenNumber, &Value, sizeof (Value));
334 }
335
336
337
338 EFI_STATUS
339 EFIAPI
340 PeiPcdSet64 (
341 IN UINTN TokenNumber,
342 IN UINT64 Value
343 )
344 {
345 return SetValueWorker (TokenNumber, &Value, sizeof (Value));
346 }
347
348
349 EFI_STATUS
350 EFIAPI
351 PeiPcdSetPtr (
352 IN UINTN TokenNumber,
353 IN OUT UINTN *SizeOfBuffer,
354 IN VOID *Buffer
355 )
356 {
357 return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE);
358 }
359
360
361
362 EFI_STATUS
363 EFIAPI
364 PeiPcdSetBool (
365 IN UINTN TokenNumber,
366 IN BOOLEAN Value
367 )
368 {
369 return SetValueWorker (TokenNumber, &Value, sizeof (Value));
370 }
371
372
373
374 EFI_STATUS
375 EFIAPI
376 PeiPcdSet8Ex (
377 IN CONST EFI_GUID *Guid,
378 IN UINTN ExTokenNumber,
379 IN UINT8 Value
380 )
381 {
382 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));
383 }
384
385
386
387 EFI_STATUS
388 EFIAPI
389 PeiPcdSet16Ex (
390 IN CONST EFI_GUID *Guid,
391 IN UINTN ExTokenNumber,
392 IN UINT16 Value
393 )
394 {
395 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));
396 }
397
398
399
400 EFI_STATUS
401 EFIAPI
402 PeiPcdSet32Ex (
403 IN CONST EFI_GUID *Guid,
404 IN UINTN ExTokenNumber,
405 IN UINT32 Value
406 )
407 {
408 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));
409 }
410
411
412
413 EFI_STATUS
414 EFIAPI
415 PeiPcdSet64Ex (
416 IN CONST EFI_GUID *Guid,
417 IN UINTN ExTokenNumber,
418 IN UINT64 Value
419 )
420 {
421 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));
422 }
423
424
425
426 EFI_STATUS
427 EFIAPI
428 PeiPcdSetPtrEx (
429 IN CONST EFI_GUID *Guid,
430 IN UINTN ExTokenNumber,
431 IN UINTN *SizeOfBuffer,
432 IN VOID *Value
433 )
434 {
435 return ExSetWorker (ExTokenNumber, Guid, Value, SizeOfBuffer, TRUE);
436 }
437
438
439
440 EFI_STATUS
441 EFIAPI
442 PeiPcdSetBoolEx (
443 IN CONST EFI_GUID *Guid,
444 IN UINTN ExTokenNumber,
445 IN BOOLEAN Value
446 )
447 {
448 return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value));
449 }
450
451
452
453
454 EFI_STATUS
455 EFIAPI
456 PeiRegisterCallBackOnSet (
457 IN CONST EFI_GUID *Guid, OPTIONAL
458 IN UINTN ExTokenNumber,
459 IN PCD_PPI_CALLBACK CallBackFunction
460 )
461 {
462 if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled)) {
463 return EFI_UNSUPPORTED;
464 }
465
466 ASSERT (CallBackFunction != NULL);
467
468 return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, TRUE);
469 }
470
471
472
473 EFI_STATUS
474 EFIAPI
475 PcdUnRegisterCallBackOnSet (
476 IN CONST EFI_GUID *Guid, OPTIONAL
477 IN UINTN ExTokenNumber,
478 IN PCD_PPI_CALLBACK CallBackFunction
479 )
480 {
481 if (!FeaturePcdGet(PcdPeiPcdDatabaseCallbackOnSetEnabled)) {
482 return EFI_UNSUPPORTED;
483 }
484
485 ASSERT (CallBackFunction != NULL);
486
487 return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction, FALSE);
488 }
489
490
491
492 EFI_STATUS
493 EFIAPI
494 PeiPcdGetNextToken (
495 IN CONST EFI_GUID *Guid, OPTIONAL
496 IN OUT UINTN *TokenNumber
497 )
498 {
499 UINTN GuidTableIdx;
500 PEI_PCD_DATABASE *PeiPcdDb;
501 EFI_GUID *MatchGuid;
502 DYNAMICEX_MAPPING *ExMapTable;
503 UINTN i;
504 BOOLEAN Found;
505
506 if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) {
507 return EFI_UNSUPPORTED;
508 }
509
510 if (Guid == NULL) {
511 if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {
512 return EFI_NOT_FOUND;
513 }
514 (*TokenNumber)++;
515 if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {
516 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
517 }
518 return EFI_SUCCESS;
519 } else {
520 if (PEI_EXMAP_TABLE_EMPTY) {
521 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
522 return EFI_SUCCESS;
523 }
524
525 //
526 // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order
527 // 1) ExGuid
528 // 2) ExTokenNumber
529 //
530 PeiPcdDb = GetPcdDatabase ();
531
532 MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);
533
534 if (MatchGuid == NULL) {
535 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
536 return EFI_NOT_FOUND;
537 }
538
539 GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;
540
541 ExMapTable = PeiPcdDb->Init.ExMapTable;
542
543 Found = FALSE;
544 //
545 // Locate the GUID in ExMapTable first.
546 //
547 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {
548 if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {
549 Found = TRUE;
550 break;
551 }
552 }
553
554 if (Found) {
555 if (*TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
556 *TokenNumber = ExMapTable[i].ExTokenNumber;
557 return EFI_SUCCESS;
558 }
559
560 for ( ; i < PEI_EXMAPPING_TABLE_SIZE; i++) {
561 if (ExMapTable[i].ExTokenNumber == *TokenNumber) {
562 i++;
563 if (i == PEI_EXMAPPING_TABLE_SIZE) {
564 //
565 // Exceed the length of ExMap Table
566 //
567 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
568 return EFI_SUCCESS;
569 }
570 if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {
571 *TokenNumber = ExMapTable[i].ExTokenNumber;
572 return EFI_SUCCESS;
573 } else {
574 *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
575 return EFI_SUCCESS;
576 }
577 }
578 }
579 return EFI_NOT_FOUND;
580 }
581 }
582
583 return EFI_NOT_FOUND;
584 }
585
586
587
588 EFI_STATUS
589 EFIAPI
590 PeiPcdGetNextTokenSpace (
591 IN OUT CONST EFI_GUID **Guid
592 )
593 {
594 UINTN GuidTableIdx;
595 EFI_GUID *MatchGuid;
596 PEI_PCD_DATABASE *PeiPcdDb;
597 DYNAMICEX_MAPPING *ExMapTable;
598 UINTN i;
599 BOOLEAN Found;
600
601 if (!FeaturePcdGet (PcdPeiPcdDatabaseTraverseEnabled)) {
602 return EFI_UNSUPPORTED;
603 }
604
605 ASSERT (Guid != NULL);
606
607 if (PEI_EXMAP_TABLE_EMPTY) {
608 if (*Guid != NULL) {
609 return EFI_NOT_FOUND;
610 } else {
611 return EFI_SUCCESS;
612 }
613 }
614
615 //
616 // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order
617 // 1) ExGuid
618 // 2) ExTokenNumber
619 //
620 PeiPcdDb = GetPcdDatabase ();
621
622 ExMapTable = PeiPcdDb->Init.ExMapTable;
623
624 if (*Guid == NULL) {
625 //
626 // return the first Token Space Guid.
627 //
628 *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[0].ExGuidIndex];
629 return EFI_SUCCESS;
630 }
631
632 MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), *Guid);
633
634 if (MatchGuid == NULL) {
635 return EFI_NOT_FOUND;
636 }
637
638 GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;
639
640 Found = FALSE;
641 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {
642 if (ExMapTable[i].ExGuidIndex == GuidTableIdx) {
643 Found = TRUE;
644 break;
645 }
646 }
647
648 if (Found) {
649 i++;
650 for ( ; i < PEI_EXMAPPING_TABLE_SIZE; i++ ) {
651 if (ExMapTable[i].ExGuidIndex != GuidTableIdx ) {
652 *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[i].ExGuidIndex];
653 return EFI_SUCCESS;
654 }
655 }
656 *Guid = NULL;
657 return EFI_SUCCESS;
658 }
659
660 return EFI_NOT_FOUND;
661
662 }
663