2 Debug Print Error Level library instance that provide compatibility with the
3 "err" shell command. This includes support for the Debug Mask Protocol
4 supports for global debug print error level mask stored in an EFI Variable.
5 This library instance only support DXE Phase modules.
7 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
14 #include <Library/DebugPrintErrorLevelLib.h>
15 #include <Library/PcdLib.h>
16 #include <Library/HobLib.h>
18 #include <Guid/DebugMask.h>
21 /// Debug Mask Protocol function prototypes
25 Retrieves the current debug print error level mask for a module are returns
26 it in CurrentDebugMask.
28 @param This The protocol instance pointer.
29 @param CurrentDebugMask Pointer to the debug print error level mask that
32 @retval EFI_SUCCESS The current debug print error level mask was
33 returned in CurrentDebugMask.
34 @retval EFI_INVALID_PARAMETER CurrentDebugMask is NULL.
35 @retval EFI_DEVICE_ERROR The current debug print error level mask could
42 IN EFI_DEBUG_MASK_PROTOCOL
*This
,
43 IN OUT UINTN
*CurrentDebugMask
47 Sets the current debug print error level mask for a module to the value
48 specified by NewDebugMask.
50 @param This The protocol instance pointer.
51 @param NewDebugMask The new debug print error level mask for this module.
53 @retval EFI_SUCCESS The current debug print error level mask was
54 set to the value specified by NewDebugMask.
55 @retval EFI_DEVICE_ERROR The current debug print error level mask could
56 not be set to the value specified by NewDebugMask.
62 IN EFI_DEBUG_MASK_PROTOCOL
*This
,
67 /// Debug Mask Protocol instance
69 EFI_DEBUG_MASK_PROTOCOL mDebugMaskProtocol
= {
70 EFI_DEBUG_MASK_REVISION
,
76 /// Global variable that is set to TRUE after the first attempt is made to
77 /// retrieve the global error level mask through the EFI Varibale Services.
78 /// This variable prevents the EFI Variable Services from being called fort
79 /// every DEBUG() macro.
81 BOOLEAN mGlobalErrorLevelInitialized
= FALSE
;
84 /// Global variable that contains the current debug error level mask for the
85 /// module that is using this library instance. This variable is initially
86 /// set to the PcdDebugPrintErrorLevel value. If the EFI Variable exists that
87 /// contains the global debug print error level mask, then that overrides the
88 /// PcdDebugPrintErrorLevel value. The EFI Variable can optionally be
89 /// discovered via a HOB so early DXE drivers can access the variable. If the
90 /// Debug Mask Protocol SetDebugMask() service is called, then that overrides
91 /// the PcdDebugPrintErrorLevel and the EFI Variable setting.
93 UINT32 mDebugPrintErrorLevel
= 0;
96 /// Global variable that is used to cache a pointer to the EFI System Table
97 /// that is required to access the EFI Variable Services to get and set
98 /// the global debug print error level mask value. The UefiBootServicesTableLib
99 /// is not used to prevent a circular dependency between these libraries.
101 EFI_SYSTEM_TABLE
*mSystemTable
= NULL
;
104 The constructor function caches the PCI Express Base Address and creates a
105 Set Virtual Address Map event to convert physical address to virtual addresses.
107 @param ImageHandle The firmware allocated handle for the EFI image.
108 @param SystemTable A pointer to the EFI System Table.
110 @retval EFI_SUCCESS The constructor completed successfully.
111 @retval Other value The constructor did not complete successfully.
116 DxeDebugPrintErrorLevelLibConstructor (
117 IN EFI_HANDLE ImageHandle
,
118 IN EFI_SYSTEM_TABLE
*SystemTable
124 // Initialize the error level mask from PCD setting.
126 mDebugPrintErrorLevel
= PcdGet32 (PcdDebugPrintErrorLevel
);
129 // Install Debug Mask Protocol onto ImageHandle
131 mSystemTable
= SystemTable
;
132 Status
= SystemTable
->BootServices
->InstallMultipleProtocolInterfaces (
134 &gEfiDebugMaskProtocolGuid
, &mDebugMaskProtocol
,
139 // Attempt to retrieve the global debug print error level mask from the EFI Variable
140 // If the EFI Variable can not be accessed when this module's library constructors are
141 // executed a HOB can be used to set the global debug print error level. If no value
142 // was found then the EFI Variable access will be reattempted on every DEBUG() print
143 // from this module until the EFI Variable services are available.
145 GetDebugPrintErrorLevel ();
151 The destructor function frees any allocated buffers and closes the Set Virtual
154 @param ImageHandle The firmware allocated handle for the EFI image.
155 @param SystemTable A pointer to the EFI System Table.
157 @retval EFI_SUCCESS The destructor completed successfully.
158 @retval Other value The destructor did not complete successfully.
163 DxeDebugPrintErrorLevelLibDestructor (
164 IN EFI_HANDLE ImageHandle
,
165 IN EFI_SYSTEM_TABLE
*SystemTable
169 // Uninstall the Debug Mask Protocol from ImageHandle
171 return SystemTable
->BootServices
->UninstallMultipleProtocolInterfaces (
173 &gEfiDebugMaskProtocolGuid
, &mDebugMaskProtocol
,
179 Returns the debug print error level mask for the current module.
181 @return Debug print error level mask for the current module.
186 GetDebugPrintErrorLevel (
193 UINTN GlobalErrorLevel
;
197 // If the constructor has not been executed yet, then just return the PCD value.
198 // This case should only occur if debug print is generated by a library
199 // constructor for this module
201 if (mSystemTable
== NULL
) {
202 return PcdGet32 (PcdDebugPrintErrorLevel
);
206 // Check to see if an attempt has been made to retrieve the global debug print
207 // error level mask. Since this library instance stores the global debug print
208 // error level mask in an EFI Variable, the EFI Variable should only be accessed
209 // once to reduce the overhead of reading the EFI Variable on every debug print
211 if (!mGlobalErrorLevelInitialized
) {
213 // Make sure the TPL Level is low enough for EFI Variable Services to be called
215 CurrentTpl
= mSystemTable
->BootServices
->RaiseTPL (TPL_HIGH_LEVEL
);
216 mSystemTable
->BootServices
->RestoreTPL (CurrentTpl
);
217 if (CurrentTpl
<= TPL_CALLBACK
) {
219 // Attempt to retrieve the global debug print error level mask from the
222 Size
= sizeof (GlobalErrorLevel
);
223 Status
= mSystemTable
->RuntimeServices
->GetVariable (
224 DEBUG_MASK_VARIABLE_NAME
,
225 &gEfiGenericVariableGuid
,
230 if (Status
!= EFI_NOT_AVAILABLE_YET
) {
232 // If EFI Variable Services are available, then set a flag so the EFI
233 // Variable will not be read again by this module.
235 mGlobalErrorLevelInitialized
= TRUE
;
236 if (!EFI_ERROR (Status
)) {
238 // If the EFI Varible exists, then set this module's module's mask to
239 // the global debug print error level mask value.
241 mDebugPrintErrorLevel
= (UINT32
)GlobalErrorLevel
;
245 // If variable services are not yet available optionally get the global
246 // debug print error level mask from a HOB.
248 Hob
= GetFirstGuidHob (&gEfiGenericVariableGuid
);
250 if (GET_GUID_HOB_DATA_SIZE (Hob
) == sizeof (UINT32
)) {
251 mDebugPrintErrorLevel
= *(UINT32
*)GET_GUID_HOB_DATA (Hob
);
252 mGlobalErrorLevelInitialized
= TRUE
;
260 // Return the current mask value for this module.
262 return mDebugPrintErrorLevel
;
266 Sets the global debug print error level mask fpr the entire platform.
268 @param ErrorLevel Global debug print error level
270 @retval TRUE The debug print error level mask was sucessfully set.
271 @retval FALSE The debug print error level mask could not be set.
276 SetDebugPrintErrorLevel (
283 UINTN GlobalErrorLevel
;
286 // Make sure the constructor has been executed
288 if (mSystemTable
!= NULL
) {
290 // Make sure the TPL Level is low enough for EFI Variable Services
292 CurrentTpl
= mSystemTable
->BootServices
->RaiseTPL (TPL_HIGH_LEVEL
);
293 mSystemTable
->BootServices
->RestoreTPL (CurrentTpl
);
294 if (CurrentTpl
<= TPL_CALLBACK
) {
296 // Attempt to store the global debug print error level mask in an EFI Variable
298 GlobalErrorLevel
= (UINTN
)ErrorLevel
;
299 Size
= sizeof (GlobalErrorLevel
);
300 Status
= mSystemTable
->RuntimeServices
->SetVariable (
301 DEBUG_MASK_VARIABLE_NAME
,
302 &gEfiGenericVariableGuid
,
303 (EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
),
307 if (!EFI_ERROR (Status
)) {
309 // If the EFI Variable was updated, then update the mask value for this
310 // module and return TRUE.
312 mGlobalErrorLevelInitialized
= TRUE
;
313 mDebugPrintErrorLevel
= ErrorLevel
;
319 // Return FALSE since the EFI Variable could not be updated.
325 Retrieves the current debug print error level mask for a module are returns
326 it in CurrentDebugMask.
328 @param This The protocol instance pointer.
329 @param CurrentDebugMask Pointer to the debug print error level mask that
332 @retval EFI_SUCCESS The current debug print error level mask was
333 returned in CurrentDebugMask.
334 @retval EFI_INVALID_PARAMETER CurrentDebugMask is NULL.
335 @retval EFI_DEVICE_ERROR The current debug print error level mask could
342 IN EFI_DEBUG_MASK_PROTOCOL
*This
,
343 IN OUT UINTN
*CurrentDebugMask
346 if (CurrentDebugMask
== NULL
) {
347 return EFI_INVALID_PARAMETER
;
351 // Retrieve the current debug mask from mDebugPrintErrorLevel
353 *CurrentDebugMask
= (UINTN
)mDebugPrintErrorLevel
;
358 Sets the current debug print error level mask for a module to the value
359 specified by NewDebugMask.
361 @param This The protocol instance pointer.
362 @param NewDebugMask The new debug print error level mask for this module.
364 @retval EFI_SUCCESS The current debug print error level mask was
365 set to the value specified by NewDebugMask.
366 @retval EFI_DEVICE_ERROR The current debug print error level mask could
367 not be set to the value specified by NewDebugMask.
373 IN EFI_DEBUG_MASK_PROTOCOL
*This
,
374 IN UINTN NewDebugMask
378 // Store the new debug mask into mDebugPrintErrorLevel
380 mDebugPrintErrorLevel
= (UINT32
)NewDebugMask
;