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