2 Private functions used by PCD DXE driver.s
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
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.
14 Module Name: Service.c
21 // Build Tool will generate DXE_PCD_DB_INIT_VALUE in Autogen.h
22 // Compression Algorithm will take care of the size optimization.
25 PCD_DATABASE
* mPcdDatabase
;
27 LIST_ENTRY mCallbackFnTable
[PCD_TOTAL_TOKEN_NUMBER
];
30 GetWorkerByLocalTokenNumber (
31 UINT32 LocalTokenNumber
,
41 VARIABLE_HEAD
*VariableHead
;
47 UINT16 StringTableIdx
;
49 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == PCD_TYPE_SKU_ENABLED
) {
50 LocalTokenNumber
= GetSkuEnabledTokenNumber (LocalTokenNumber
& ~PCD_TYPE_SKU_ENABLED
, Size
, IsPeiDb
);
53 PcdDb
= IsPeiDb
? ((UINT8
*) &mPcdDatabase
->PeiDb
) : ((UINT8
*) &mPcdDatabase
->DxeDb
);
54 StringTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.StringTable
:
55 mPcdDatabase
->DxeDb
.Init
.StringTable
;
57 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
59 switch (LocalTokenNumber
& ~PCD_DATABASE_OFFSET_MASK
) {
61 VpdHead
= (VPD_HEAD
*) ((UINT8
*) PcdDb
+ Offset
);
62 return (VOID
*) (FixedPcdGet32(PcdVpdBaseAddress
) + VpdHead
->Offset
);
65 GuidTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.GuidTable
:
66 mPcdDatabase
->DxeDb
.Init
.GuidTable
;
68 VariableHead
= (VARIABLE_HEAD
*) (PcdDb
+ Offset
);
70 Guid
= &(GuidTable
[VariableHead
->GuidTableIndex
]);
71 Name
= &(StringTable
[VariableHead
->StringIndex
]);
73 Status
= GetHiiVariable (Guid
, Name
, &Data
, &DataSize
);
74 ASSERT_EFI_ERROR (Status
);
75 ASSERT (DataSize
>= (UINTN
) (VariableHead
->Offset
+ Size
));
77 return (UINT8
*) Data
+ VariableHead
->Offset
;
80 StringTableIdx
= (UINT16
) *((UINT8
*) PcdDb
+ Offset
);
81 return (VOID
*) &StringTable
[StringTableIdx
];
84 return (VOID
*) ((UINT8
*) PcdDb
+ Offset
);
103 UINT32
*LocalTokenNumberTable
;
107 ASSERT (TokenNumber
< PCD_TOTAL_TOKEN_NUMBER
);
109 IsPeiDb
= (TokenNumber
<= PEI_LOCAL_TOKEN_NUMBER
) ? TRUE
: FALSE
;
111 LocalTokenNumberTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.LocalTokenNumberTable
:
112 mPcdDatabase
->DxeDb
.Init
.LocalTokenNumberTable
;
114 SizeTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.SizeTable
:
115 mPcdDatabase
->DxeDb
.Init
.SizeTable
;
117 TokenNumber
= IsPeiDb
? TokenNumber
:
118 TokenNumber
- PEI_LOCAL_TOKEN_NUMBER
;
119 return GetWorkerByLocalTokenNumber (LocalTokenNumberTable
[TokenNumber
], IsPeiDb
, SizeTable
[TokenNumber
]);
125 DxeRegisterCallBackWorker (
126 IN UINTN TokenNumber
,
127 IN CONST GUID
*Guid
, OPTIONAL
128 IN PCD_PROTOCOL_CALLBACK CallBackFunction
131 CALLBACK_FN_ENTRY
*FnTableEntry
;
132 EX_PCD_ENTRY_ATTRIBUTE ExAttr
;
133 LIST_ENTRY
*ListHead
;
134 LIST_ENTRY
*ListNode
;
137 GetExPcdTokenAttributes (Guid
, TokenNumber
, &ExAttr
);
138 TokenNumber
= ExAttr
.LocalTokenNumberAlias
;
141 ListHead
= &mCallbackFnTable
[TokenNumber
];
142 ListNode
= GetFirstNode (ListHead
);
144 while (ListNode
!= ListHead
) {
145 FnTableEntry
= CR_FNENTRY_FROM_LISTNODE(ListNode
, CALLBACK_FN_ENTRY
, Node
);
147 if (FnTableEntry
->CallbackFn
== CallBackFunction
) {
149 // We only allow a Callback function to be register once
150 // for a TokenNumber. So just return EFI_SUCCESS
154 ListNode
= GetNextNode (ListHead
, ListNode
);
157 FnTableEntry
= AllocatePool (sizeof(CALLBACK_FN_ENTRY
));
158 ASSERT (FnTableEntry
!= NULL
);
160 FnTableEntry
->CallbackFn
= CallBackFunction
;
161 InsertTailList (ListHead
, &FnTableEntry
->Node
);
170 DxeUnRegisterCallBackWorker (
171 IN UINTN TokenNumber
,
172 IN CONST GUID
*Guid
, OPTIONAL
173 IN PCD_PROTOCOL_CALLBACK CallBackFunction
176 CALLBACK_FN_ENTRY
*FnTableEntry
;
177 EX_PCD_ENTRY_ATTRIBUTE ExAttr
;
178 LIST_ENTRY
*ListHead
;
179 LIST_ENTRY
*ListNode
;
182 GetExPcdTokenAttributes (Guid
, TokenNumber
, &ExAttr
);
183 TokenNumber
= ExAttr
.LocalTokenNumberAlias
;
186 ListHead
= &mCallbackFnTable
[TokenNumber
];
187 ListNode
= GetFirstNode (ListHead
);
189 while (ListNode
!= ListHead
) {
190 FnTableEntry
= CR_FNENTRY_FROM_LISTNODE(ListNode
, CALLBACK_FN_ENTRY
, Node
);
192 if (FnTableEntry
->CallbackFn
== CallBackFunction
) {
194 // We only allow a Callback function to be register once
195 // for a TokenNumber. So we can safely remove the Node from
196 // the Link List and return EFI_SUCCESS.
198 RemoveEntryList (ListNode
);
199 FreePool (FnTableEntry
);
203 ListNode
= GetNextNode (ListHead
, ListNode
);
206 return EFI_INVALID_PARAMETER
;
212 ExGetNextTokeNumber (
213 IN CONST EFI_GUID
*Guid
,
214 IN PCD_TOKEN_NUMBER TokenNumber
,
215 IN EFI_GUID
*GuidTable
,
216 IN UINTN SizeOfGuidTable
,
217 IN DYNAMICEX_MAPPING
*ExMapTable
,
218 IN UINTN SizeOfExMapTable
226 MatchGuid
= ScanGuid (GuidTable
, SizeOfGuidTable
, Guid
);
227 if (MatchGuid
== NULL
) {
228 return PCD_INVALID_TOKEN_NUMBER
;
232 GuidTableIdx
= MatchGuid
- GuidTable
;
233 for (Idx
= 0; Idx
< SizeOfExMapTable
; Idx
++) {
234 if (ExMapTable
[Idx
].ExGuidIndex
== GuidTableIdx
) {
241 if (TokenNumber
== PCD_INVALID_TOKEN_NUMBER
) {
242 return ExMapTable
[Idx
].ExTokenNumber
;
245 for ( ; Idx
< SizeOfExMapTable
; Idx
++) {
246 if (ExMapTable
[Idx
].ExTokenNumber
== TokenNumber
) {
248 if (Idx
== SizeOfExMapTable
) {
250 // Exceed the length of ExMap Table
252 return PCD_INVALID_TOKEN_NUMBER
;
253 } else if (ExMapTable
[Idx
].ExGuidIndex
== GuidTableIdx
) {
255 // Found the next match
257 return ExMapTable
[Idx
].ExTokenNumber
;
260 // Guid has been changed. It is the next Token Space Guid.
261 // We should flag no more TokenNumber.
263 return PCD_INVALID_TOKEN_NUMBER
;
269 return PCD_INVALID_TOKEN_NUMBER
;
276 BuildPcdDxeDataBase (
280 PEI_PCD_DATABASE
*PeiDatabase
;
281 EFI_HOB_GUID_TYPE
*GuidHob
;
284 mPcdDatabase
= AllocateZeroPool (sizeof(PCD_DATABASE
));
285 ASSERT (mPcdDatabase
!= NULL
);
287 GuidHob
= GetFirstGuidHob (&gPcdDataBaseHobGuid
);
288 ASSERT (GuidHob
!= NULL
);
290 PeiDatabase
= (PEI_PCD_DATABASE
*) GET_GUID_HOB_DATA (GuidHob
);
292 // Copy PCD Entries refereneced in PEI phase to PCD DATABASE
294 CopyMem (&mPcdDatabase
->PeiDb
, PeiDatabase
, sizeof (PEI_PCD_DATABASE
));
297 // Copy PCD Entries with default value to PCD DATABASE
299 CopyMem (&mPcdDatabase
->DxeDb
.Init
, &gDXEPcdDbInit
, sizeof(DXE_PCD_DATABASE_INIT
));
303 // Initialized the Callback Function Table
305 for (Idx
= 0; Idx
< PCD_TOTAL_TOKEN_NUMBER
; Idx
++) {
306 InitializeListHead (&mCallbackFnTable
[Idx
]);
316 IN EFI_GUID
*VariableGuid
,
317 IN UINT16
*VariableName
,
318 OUT VOID
** VariableData
,
319 OUT UINTN
*VariableSize
326 Status
= EfiGetVariable (
327 (UINT16
*)VariableName
,
333 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
335 Buffer
= AllocatePool (Size
);
337 ASSERT (Buffer
!= NULL
);
339 Status
= EfiGetVariable (
353 GetSkuEnabledTokenNumber (
354 UINT32 LocalTokenNumber
,
363 SKU_ID
*PhaseSkuIdTable
;
366 ASSERT ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == 0);
368 PcdDb
= IsPeiDb
? (UINT8
*) &mPcdDatabase
->PeiDb
: (UINT8
*) &mPcdDatabase
->DxeDb
;
370 SkuHead
= (SKU_HEAD
*) (PcdDb
+ (LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
));
371 Value
= (UINT8
*) (PcdDb
+ SkuHead
->SkuDataStartOffset
);
373 PhaseSkuIdTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.SkuIdTable
:
374 mPcdDatabase
->DxeDb
.Init
.SkuIdTable
;
376 SkuIdTable
= &PhaseSkuIdTable
[SkuHead
->SkuIdTableOffset
];
378 for (i
= 0; i
< SkuIdTable
[0]; i
++) {
379 if (mPcdDatabase
->PeiDb
.Init
.SystemSkuId
== SkuIdTable
[i
+ 1]) {
383 ASSERT (i
< SkuIdTable
[0]);
385 switch (LocalTokenNumber
& ~PCD_DATABASE_OFFSET_MASK
) {
387 Value
= (UINT8
*) &(((VPD_HEAD
*) Value
)[i
]);
388 return ((Value
- PcdDb
) | PCD_TYPE_VPD
);
391 Value
= (UINT8
*) &(((VARIABLE_HEAD
*) Value
)[i
]);
392 return ((Value
- PcdDb
) | PCD_TYPE_HII
);
396 return (Value
- PcdDb
);
413 InvokeCallbackOnSet (
414 UINT32 ExTokenNumber
,
415 CONST EFI_GUID
*Guid
, OPTIONAL
421 CALLBACK_FN_ENTRY
*FnTableEntry
;
422 LIST_ENTRY
*ListHead
;
423 LIST_ENTRY
*ListNode
;
425 ListHead
= &mCallbackFnTable
[TokenNumber
];
426 ListNode
= GetFirstNode (ListHead
);
428 while (ListNode
!= ListHead
) {
429 FnTableEntry
= CR_FNENTRY_FROM_LISTNODE(ListNode
, CALLBACK_FN_ENTRY
, Node
);
431 FnTableEntry
->CallbackFn(Guid
,
432 (Guid
== NULL
) ? TokenNumber
: ExTokenNumber
,
436 ListNode
= GetNextNode (ListHead
, ListNode
);
447 PCD_TOKEN_NUMBER TokenNumber
,
453 UINT32
*LocalTokenNumberTable
;
457 ASSERT (TokenNumber
< PCD_TOTAL_TOKEN_NUMBER
);
460 ASSERT (Size
<= DxePcdGetSize (TokenNumber
));
462 ASSERT (Size
== DxePcdGetSize (TokenNumber
));
465 IsPeiDb
= (TokenNumber
<= PEI_LOCAL_TOKEN_NUMBER
) ? TRUE
: FALSE
;
467 LocalTokenNumberTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.LocalTokenNumberTable
:
468 mPcdDatabase
->DxeDb
.Init
.LocalTokenNumberTable
;
470 InvokeCallbackOnSet (0, NULL
, TokenNumber
, Data
, Size
);
472 TokenNumber
= IsPeiDb
? TokenNumber
473 : TokenNumber
- PEI_LOCAL_TOKEN_NUMBER
;
475 return SetWorkerByLocalTokenNumber (LocalTokenNumberTable
[TokenNumber
], Data
, Size
, PtrType
, IsPeiDb
);
485 IN CONST EFI_GUID
*Guid
,
486 IN UINTN ExTokenNumber
,
490 EX_PCD_ENTRY_ATTRIBUTE Attr
;
492 GetExPcdTokenAttributes (Guid
, ExTokenNumber
, &Attr
);
494 ASSERT ((GetSize
== Attr
.Size
) || (GetSize
== 0));
496 return GetWorkerByLocalTokenNumber (Attr
.LocalTokenNumberAlias
,
508 IN PCD_TOKEN_NUMBER ExTokenNumber
,
509 IN CONST EFI_GUID
*Guid
,
515 EX_PCD_ENTRY_ATTRIBUTE Attr
;
517 GetExPcdTokenAttributes (Guid
, ExTokenNumber
, &Attr
);
519 ASSERT (!PtrType
&& (SetSize
== Attr
.Size
));
521 ASSERT (PtrType
&& (SetSize
<= Attr
.Size
));
523 InvokeCallbackOnSet (ExTokenNumber
, Guid
, Attr
.TokenNumber
, Data
, Attr
.Size
);
525 SetWorkerByLocalTokenNumber (Attr
.LocalTokenNumberAlias
, Data
, Attr
.Size
, PtrType
, Attr
.IsPeiDb
);
535 SetWorkerByLocalTokenNumber (
536 UINT32 LocalTokenNumber
,
548 VARIABLE_HEAD
*VariableHead
;
553 if ((LocalTokenNumber
& PCD_TYPE_SKU_ENABLED
) == PCD_TYPE_SKU_ENABLED
) {
554 LocalTokenNumber
= GetSkuEnabledTokenNumber (LocalTokenNumber
& ~PCD_TYPE_SKU_ENABLED
, Size
, IsPeiDb
);
557 Offset
= LocalTokenNumber
& PCD_DATABASE_OFFSET_MASK
;
559 PcdDb
= IsPeiDb
? ((UINT8
*) &mPcdDatabase
->PeiDb
) : ((UINT8
*) &mPcdDatabase
->DxeDb
);
561 StringTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.StringTable
:
562 mPcdDatabase
->DxeDb
.Init
.StringTable
;
564 InternalData
= PcdDb
+ Offset
;
566 switch (LocalTokenNumber
& ~PCD_DATABASE_OFFSET_MASK
) {
569 return EFI_INVALID_PARAMETER
;
571 case PCD_TYPE_STRING
:
572 CopyMem (&StringTable
[*((UINT16
*)InternalData
)], Data
, Size
);
577 // Bug Bug: Please implement this
579 GuidTable
= IsPeiDb
? mPcdDatabase
->PeiDb
.Init
.GuidTable
:
580 mPcdDatabase
->DxeDb
.Init
.GuidTable
;
582 VariableHead
= (VARIABLE_HEAD
*) (PcdDb
+ Offset
);
584 Guid
= &(GuidTable
[VariableHead
->GuidTableIndex
]);
585 Name
= &(StringTable
[VariableHead
->StringIndex
]);
591 CopyMem (InternalData
, Data
, Size
);
597 *((UINT8
*) InternalData
) = *((UINT8
*) Data
);
601 *((UINT16
*) InternalData
) = *((UINT16
*) Data
);
605 *((UINT32
*) InternalData
) = *((UINT32
*) Data
);
609 *((UINT64
*) InternalData
) = *((UINT64
*) Data
);
614 return EFI_NOT_FOUND
;
623 return EFI_NOT_FOUND
;
630 IN EFI_GUID
*VariableGuid
,
631 IN UINT16
*VariableName
,
644 Status
= EfiGetVariable (
645 (UINT16
*)VariableName
,
652 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
654 Buffer
= AllocatePool (Size
);
656 ASSERT (Buffer
!= NULL
);
658 Status
= EfiGetVariable (
667 CopyMem ((UINT8
*)Buffer
+ Offset
, Data
, DataSize
);
669 return EfiSetVariable (
684 GetExPcdTokenAttributes (
685 IN CONST EFI_GUID
*Guid
,
686 IN PCD_TOKEN_NUMBER ExTokenNumber
,
687 OUT EX_PCD_ENTRY_ATTRIBUTE
*ExAttr
691 DYNAMICEX_MAPPING
*ExMap
;
695 ExMap
= mPcdDatabase
->PeiDb
.Init
.ExMapTable
;
696 GuidTable
= mPcdDatabase
->PeiDb
.Init
.GuidTable
;
697 SizeTable
= mPcdDatabase
->PeiDb
.Init
.SizeTable
;
699 for (i
= 0; i
< PEI_EXMAPPING_TABLE_SIZE
; i
++) {
700 if ((ExTokenNumber
== ExMap
[i
].ExTokenNumber
) &&
701 CompareGuid (Guid
, (CONST EFI_GUID
*) &GuidTable
[ExMap
[i
].ExGuidIndex
])
704 ExAttr
->IsPeiDb
= TRUE
;
705 ExAttr
->Size
= SizeTable
[i
+ PEI_NEX_TOKEN_NUMBER
];
706 ExAttr
->TokenNumber
= i
+ PEI_NEX_TOKEN_NUMBER
;
707 ExAttr
->LocalTokenNumberAlias
= ExMap
[i
].LocalTokenNumber
;
713 ExMap
= mPcdDatabase
->DxeDb
.Init
.ExMapTable
;
714 GuidTable
= mPcdDatabase
->DxeDb
.Init
.GuidTable
;
715 SizeTable
= mPcdDatabase
->DxeDb
.Init
.SizeTable
;
717 for (i
= 0; i
< DXE_EXMAPPING_TABLE_SIZE
; i
++) {
718 if ((ExTokenNumber
== ExMap
[i
].ExTokenNumber
) &&
719 CompareGuid (Guid
, (CONST EFI_GUID
*) &GuidTable
[ExMap
[i
].ExGuidIndex
])
722 ExAttr
->IsPeiDb
= FALSE
;
723 ExAttr
->Size
= SizeTable
[i
+ DXE_NEX_TOKEN_NUMBER
];
724 ExAttr
->TokenNumber
= i
+ PEI_LOCAL_TOKEN_NUMBER
;
725 ExAttr
->LocalTokenNumberAlias
= ExMap
[i
].LocalTokenNumber
;