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