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