Check in the Pcd service Driver/PEIM according to the new way of generating PCD Database
[mirror_edk2.git] / EdkModulePkg / Universal / PCD / Dxe / Service.c
1 /** @file
2 Private functions used by PCD DXE driver.s
3
4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13
14 Module Name: Service.c
15
16 **/
17 #include "Service.h"
18
19
20 //
21 // Build Tool will generate DXE_PCD_DB_INIT_VALUE in Autogen.h
22 // Compression Algorithm will take care of the size optimization.
23 //
24
25 /*
26 DXE_PCD_DATABASE_INIT gDXEPcdDbInit = {
27 DXE_PCD_DB_INIT_VALUE
28 };
29 */
30
31 PCD_DATABASE * gPcdDatabase;
32
33 VOID *
34 GetWorkerByLocalTokenNumber (
35 UINT32 LocalTokenNumber,
36 BOOLEAN IsPeiDb,
37 UINTN Size
38 )
39 {
40 UINT32 Offset;
41 EFI_GUID *GuidTable;
42 UINT16 *StringTable;
43 EFI_GUID *Guid;
44 UINT16 *Name;
45 VARIABLE_HEAD *VariableHead;
46 EFI_STATUS Status;
47 UINTN DataSize;
48 VOID *Data;
49 VPD_HEAD *VpdHead;
50 UINT8 *PcdDb;
51 UINT16 StringTableIdx;
52
53 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
54 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb);
55 }
56
57 PcdDb = IsPeiDb ? ((UINT8 *) &gPcdDatabase->PeiDb) : ((UINT8 *) &gPcdDatabase->DxeDb);
58 StringTable = IsPeiDb ? gPcdDatabase->PeiDb.Init.StringTable :
59 gPcdDatabase->DxeDb.Init.StringTable;
60
61 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
62
63 switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {
64 case PCD_TYPE_VPD:
65 VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset);
66 return (VOID *) (FixedPcdGet32(PcdVpdBaseAddress) + VpdHead->Offset);
67
68 case PCD_TYPE_HII:
69 GuidTable = IsPeiDb ? gPcdDatabase->PeiDb.Init.GuidTable :
70 gPcdDatabase->DxeDb.Init.GuidTable;
71
72 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
73
74 Guid = &(GuidTable[VariableHead->GuidTableIndex]);
75 Name = &(StringTable[VariableHead->StringIndex]);
76
77 Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
78 ASSERT_EFI_ERROR (Status);
79 ASSERT (DataSize >= (UINTN) (VariableHead->Offset + Size));
80
81 return (UINT8 *) Data + VariableHead->Offset;
82
83 case PCD_TYPE_STRING:
84 StringTableIdx = (UINT16) *((UINT8 *) PcdDb + Offset);
85 return (VOID *) &StringTable[StringTableIdx];
86
87 case PCD_TYPE_DATA:
88 return (VOID *) ((UINT8 *) PcdDb + Offset);
89 break;
90
91 default:
92 ASSERT (FALSE);
93 break;
94
95 }
96
97 ASSERT (FALSE);
98
99 return NULL;
100 }
101
102 VOID *
103 GetWorker (
104 UINTN TokenNumber
105 )
106 {
107 UINT32 *LocalTokenNumberTable;
108 UINT16 *SizeTable;
109 BOOLEAN IsPeiDb;
110
111 ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);
112
113 IsPeiDb = (TokenNumber <= PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;
114
115 LocalTokenNumberTable = IsPeiDb ? gPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
116 gPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
117
118 SizeTable = IsPeiDb ? gPcdDatabase->PeiDb.Init.SizeTable:
119 gPcdDatabase->DxeDb.Init.SizeTable;
120
121 TokenNumber = IsPeiDb ? TokenNumber :
122 TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
123 return GetWorkerByLocalTokenNumber (LocalTokenNumberTable[TokenNumber], IsPeiDb, SizeTable[TokenNumber]);
124 }
125
126
127
128 EFI_STATUS
129 DxeRegisterCallBackWorker (
130 IN UINTN TokenNumber,
131 IN CONST GUID *Guid, OPTIONAL
132 IN PCD_PROTOCOL_CALLBACK CallBackFunction,
133 IN BOOLEAN Register
134 )
135 {
136
137 return EFI_SUCCESS;
138 }
139
140
141 EFI_STATUS
142 DxeGetNextTokenWorker (
143 IN OUT UINTN *TokenNumber,
144 IN CONST GUID *Guid OPTIONAL
145 )
146 {
147 return EFI_SUCCESS;
148 }
149
150
151
152 VOID
153 BuildPcdDxeDataBase (
154 VOID
155 )
156 {
157 PEI_PCD_DATABASE *PeiDatabase;
158 EFI_HOB_GUID_TYPE *GuidHob;
159
160 gPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));
161 ASSERT (gPcdDatabase != NULL);
162
163 GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
164 ASSERT (GuidHob != NULL);
165
166 PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
167 //
168 // Copy PCD Entries refereneced in PEI phase to PCD DATABASE
169 //
170 CopyMem (&gPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE));
171
172 //
173 // Copy PCD Entries with default value to PCD DATABASE
174 //
175 CopyMem (&gPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT));
176
177 return;
178 }
179
180
181
182 EFI_STATUS
183 GetHiiVariable (
184 IN EFI_GUID *VariableGuid,
185 IN UINT16 *VariableName,
186 OUT VOID ** VariableData,
187 OUT UINTN *VariableSize
188 )
189 {
190 UINTN Size;
191 EFI_STATUS Status;
192 VOID *Buffer;
193
194 Status = EfiGetVariable (
195 (UINT16 *)VariableName,
196 VariableGuid,
197 NULL,
198 &Size,
199 NULL
200 );
201 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
202
203 Buffer = AllocatePool (Size);
204
205 ASSERT (Buffer != NULL);
206
207 Status = EfiGetVariable (
208 VariableName,
209 VariableGuid,
210 NULL,
211 &Size,
212 Buffer
213 );
214
215 return Status;
216
217 }
218
219
220 UINT32
221 GetSkuEnabledTokenNumber (
222 UINT32 LocalTokenNumber,
223 UINTN Size,
224 BOOLEAN IsPeiDb
225 )
226 {
227 SKU_HEAD *SkuHead;
228 SKU_ID *SkuIdTable;
229 INTN i;
230 UINT8 *Value;
231 SKU_ID *PhaseSkuIdTable;
232 UINT8 *PcdDb;
233
234 ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);
235
236 PcdDb = IsPeiDb ? (UINT8 *) &gPcdDatabase->PeiDb : (UINT8 *) &gPcdDatabase->DxeDb;
237
238 SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
239 Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset);
240
241 PhaseSkuIdTable = IsPeiDb ? gPcdDatabase->PeiDb.Init.SkuIdTable :
242 gPcdDatabase->DxeDb.Init.SkuIdTable;
243
244 SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];
245
246 for (i = 0; i < SkuIdTable[0]; i++) {
247 if (gPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[i + 1]) {
248 break;
249 }
250 }
251 ASSERT (i < SkuIdTable[0]);
252
253 switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {
254 case PCD_TYPE_VPD:
255 Value = (UINT8 *) &(((VPD_HEAD *) Value)[i]);
256 return ((Value - PcdDb) | PCD_TYPE_VPD);
257
258 case PCD_TYPE_HII:
259 Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[i]);
260 return ((Value - PcdDb) | PCD_TYPE_HII);
261
262 case PCD_TYPE_DATA:
263 Value += Size * i;
264 return (Value - PcdDb);
265
266 default:
267 ASSERT (FALSE);
268 }
269
270 ASSERT (FALSE);
271
272 return 0;
273
274 }
275
276
277
278
279
280 VOID
281 InvokeCallbackOnSet (
282 UINT32 ExTokenNumber,
283 CONST EFI_GUID *Guid, OPTIONAL
284 UINTN TokenNumber,
285 VOID *Data,
286 UINTN Size
287 )
288 {
289 return;
290 }
291
292
293
294
295 EFI_STATUS
296 SetWorker (
297 UINTN TokenNumber,
298 VOID *Data,
299 UINTN Size,
300 BOOLEAN PtrType
301 )
302 {
303 UINT32 *LocalTokenNumberTable;
304 BOOLEAN IsPeiDb;
305
306
307 ASSERT (TokenNumber < PCD_TOTAL_TOKEN_NUMBER);
308
309 if (PtrType) {
310 ASSERT (Size <= DxePcdGetSize (TokenNumber));
311 } else {
312 ASSERT (Size == DxePcdGetSize (TokenNumber));
313 }
314
315 IsPeiDb = (TokenNumber <= PEI_LOCAL_TOKEN_NUMBER) ? TRUE : FALSE;
316
317 LocalTokenNumberTable = IsPeiDb ? gPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
318 gPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
319
320 TokenNumber = IsPeiDb ? TokenNumber
321 : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
322
323 InvokeCallbackOnSet (0, NULL, TokenNumber, Data, Size);
324
325 return SetWorkerByLocalTokenNumber (LocalTokenNumberTable[TokenNumber], Data, Size, PtrType, IsPeiDb);
326
327 }
328
329
330
331
332
333 VOID *
334 ExGetWorker (
335 IN CONST EFI_GUID *Guid,
336 IN UINTN ExTokenNumber,
337 IN UINTN GetSize
338 )
339 {
340 EX_PCD_ENTRY_ATTRIBUTE Attr;
341
342 GetExPcdTokenAttributes (Guid, ExTokenNumber, &Attr);
343
344 ASSERT ((GetSize == Attr.Size) || (GetSize == 0));
345
346 return GetWorkerByLocalTokenNumber (Attr.LocalTokenNumberAlias,
347 Attr.IsPeiDb,
348 Attr.Size
349 );
350 }
351
352
353
354
355
356 EFI_STATUS
357 ExSetWorker (
358 IN UINT32 ExTokenNumber,
359 IN CONST EFI_GUID *Guid,
360 VOID *Data,
361 UINTN SetSize,
362 BOOLEAN PtrType
363 )
364 {
365 EX_PCD_ENTRY_ATTRIBUTE Attr;
366
367 GetExPcdTokenAttributes (Guid, ExTokenNumber, &Attr);
368
369 ASSERT (!PtrType && (SetSize == Attr.Size));
370
371 ASSERT (PtrType && (SetSize <= Attr.Size));
372
373 InvokeCallbackOnSet (ExTokenNumber, Guid, Attr.TokenNumber, Data, Attr.Size);
374
375 SetWorkerByLocalTokenNumber (Attr.LocalTokenNumberAlias, Data, Attr.Size, PtrType, Attr.IsPeiDb);
376
377 return EFI_SUCCESS;
378
379 }
380
381
382
383
384 EFI_STATUS
385 SetWorkerByLocalTokenNumber (
386 UINT32 LocalTokenNumber,
387 VOID *Data,
388 UINTN Size,
389 BOOLEAN PtrType,
390 BOOLEAN IsPeiDb
391 )
392 {
393 EFI_GUID *GuidTable;
394 UINT16 *StringTable;
395 EFI_GUID *Guid;
396 UINT16 *Name;
397 VOID *InternalData;
398 VARIABLE_HEAD *VariableHead;
399 UINTN Offset;
400 UINT8 *PcdDb;
401
402
403 if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
404 LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, Size, IsPeiDb);
405 }
406
407 Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
408
409 PcdDb = IsPeiDb ? ((UINT8 *) &gPcdDatabase->PeiDb) : ((UINT8 *) &gPcdDatabase->DxeDb);
410
411 StringTable = IsPeiDb ? gPcdDatabase->PeiDb.Init.StringTable :
412 gPcdDatabase->DxeDb.Init.StringTable;
413
414 InternalData = PcdDb + Offset;
415
416 switch (LocalTokenNumber & ~PCD_DATABASE_OFFSET_MASK) {
417 case PCD_TYPE_VPD:
418 ASSERT (FALSE);
419 return EFI_INVALID_PARAMETER;
420
421 case PCD_TYPE_STRING:
422 CopyMem (&StringTable[*((UINT16 *)InternalData)], Data, Size);
423 break;
424
425 case PCD_TYPE_HII:
426 //
427 // Bug Bug: Please implement this
428 //
429 GuidTable = IsPeiDb ? gPcdDatabase->PeiDb.Init.GuidTable :
430 gPcdDatabase->DxeDb.Init.GuidTable;
431
432 VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
433
434 Guid = &(GuidTable[VariableHead->GuidTableIndex]);
435 Name = &(StringTable[VariableHead->StringIndex]);
436
437 return EFI_SUCCESS;
438
439 case PCD_TYPE_DATA:
440 if (PtrType) {
441 CopyMem (InternalData, Data, Size);
442 return EFI_SUCCESS;
443 }
444
445 switch (Size) {
446 case sizeof(UINT8):
447 *((UINT8 *) InternalData) = *((UINT8 *) Data);
448 return EFI_SUCCESS;
449
450 case sizeof(UINT16):
451 *((UINT16 *) InternalData) = *((UINT16 *) Data);
452 return EFI_SUCCESS;
453
454 case sizeof(UINT32):
455 *((UINT32 *) InternalData) = *((UINT32 *) Data);
456 return EFI_SUCCESS;
457
458 case sizeof(UINT64):
459 *((UINT64 *) InternalData) = *((UINT64 *) Data);
460 return EFI_SUCCESS;
461
462 default:
463 ASSERT (FALSE);
464 return EFI_NOT_FOUND;
465 }
466
467 default:
468 ASSERT (FALSE);
469 break;
470 }
471
472 ASSERT (FALSE);
473 return EFI_NOT_FOUND;
474 }
475
476
477
478 EFI_STATUS
479 SetHiiVariable (
480 IN EFI_GUID *VariableGuid,
481 IN UINT16 *VariableName,
482 IN CONST VOID *Data,
483 IN UINTN DataSize,
484 IN UINTN Offset
485 )
486 {
487 UINTN Size;
488 VOID *Buffer;
489 EFI_STATUS Status;
490 UINT32 Attribute;
491
492 Size = 0;
493
494 Status = EfiGetVariable (
495 (UINT16 *)VariableName,
496 VariableGuid,
497 &Attribute,
498 &Size,
499 NULL
500 );
501
502 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
503
504 Buffer = AllocatePool (Size);
505
506 ASSERT (Buffer != NULL);
507
508 Status = EfiGetVariable (
509 VariableName,
510 VariableGuid,
511 &Attribute,
512 &Size,
513 Buffer
514 );
515
516
517 CopyMem ((UINT8 *)Buffer + Offset, Data, DataSize);
518
519 return EfiSetVariable (
520 VariableName,
521 VariableGuid,
522 Attribute,
523 Size,
524 Buffer
525 );
526
527 }
528
529
530
531
532
533 VOID
534 GetExPcdTokenAttributes (
535 IN CONST EFI_GUID *Guid,
536 IN UINT32 ExTokenNumber,
537 OUT EX_PCD_ENTRY_ATTRIBUTE *ExAttr
538 )
539 {
540 UINT32 i;
541 DYNAMICEX_MAPPING *ExMap;
542 EFI_GUID *GuidTable;
543 UINT16 *SizeTable;
544
545 ExMap = gPcdDatabase->PeiDb.Init.ExMapTable;
546 GuidTable = gPcdDatabase->PeiDb.Init.GuidTable;
547 SizeTable = gPcdDatabase->PeiDb.Init.SizeTable;
548
549 for (i = 0; i < PEI_EXMAPPING_TABLE_SIZE; i++) {
550 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&
551 CompareGuid (Guid, (CONST EFI_GUID *) &GuidTable[ExMap[i].ExGuidIndex])
552 ) {
553
554 ExAttr->IsPeiDb = TRUE;
555 ExAttr->Size = SizeTable[i + PEI_NEX_TOKEN_NUMBER];
556 ExAttr->TokenNumber = i + PEI_NEX_TOKEN_NUMBER;
557 ExAttr->LocalTokenNumberAlias = ExMap[i].LocalTokenNumber;
558 return;
559
560 }
561 }
562
563 ExMap = gPcdDatabase->DxeDb.Init.ExMapTable;
564 GuidTable = gPcdDatabase->DxeDb.Init.GuidTable;
565 SizeTable = gPcdDatabase->DxeDb.Init.SizeTable;
566
567 for (i = 0; i < DXE_EXMAPPING_TABLE_SIZE; i++) {
568 if ((ExTokenNumber == ExMap[i].ExTokenNumber) &&
569 CompareGuid (Guid, (CONST EFI_GUID *) &GuidTable[ExMap[i].ExGuidIndex])
570 ) {
571
572 ExAttr->IsPeiDb = FALSE;
573 ExAttr->Size = SizeTable[i + DXE_NEX_TOKEN_NUMBER];
574 ExAttr->TokenNumber = i + DXE_NEX_TOKEN_NUMBER;
575 ExAttr->LocalTokenNumberAlias = ExMap[i].LocalTokenNumber;
576 return;
577
578 }
579 }
580
581 ASSERT (FALSE);
582
583 return;
584 }
585