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
,
140 // Attempt to retrieve the global debug print error level mask from the EFI Variable
141 // If the EFI Variable can not be accessed when this module's library constructors are
142 // executed a HOB can be used to set the global debug print error level. If no value
143 // was found then the EFI Variable access will be reattempted on every DEBUG() print
144 // from this module until the EFI Variable services are available.
146 GetDebugPrintErrorLevel ();
152 The destructor function frees any allocated buffers and closes the Set Virtual
155 @param ImageHandle The firmware allocated handle for the EFI image.
156 @param SystemTable A pointer to the EFI System Table.
158 @retval EFI_SUCCESS The destructor completed successfully.
159 @retval Other value The destructor did not complete successfully.
164 DxeDebugPrintErrorLevelLibDestructor (
165 IN EFI_HANDLE ImageHandle
,
166 IN EFI_SYSTEM_TABLE
*SystemTable
170 // Uninstall the Debug Mask Protocol from ImageHandle
172 return SystemTable
->BootServices
->UninstallMultipleProtocolInterfaces (
174 &gEfiDebugMaskProtocolGuid
,
181 Returns the debug print error level mask for the current module.
183 @return Debug print error level mask for the current module.
188 GetDebugPrintErrorLevel (
195 UINTN GlobalErrorLevel
;
199 // If the constructor has not been executed yet, then just return the PCD value.
200 // This case should only occur if debug print is generated by a library
201 // constructor for this module
203 if (mSystemTable
== NULL
) {
204 return PcdGet32 (PcdDebugPrintErrorLevel
);
208 // Check to see if an attempt has been made to retrieve the global debug print
209 // error level mask. Since this library instance stores the global debug print
210 // error level mask in an EFI Variable, the EFI Variable should only be accessed
211 // once to reduce the overhead of reading the EFI Variable on every debug print
213 if (!mGlobalErrorLevelInitialized
) {
215 // Make sure the TPL Level is low enough for EFI Variable Services to be called
217 CurrentTpl
= mSystemTable
->BootServices
->RaiseTPL (TPL_HIGH_LEVEL
);
218 mSystemTable
->BootServices
->RestoreTPL (CurrentTpl
);
219 if (CurrentTpl
<= TPL_CALLBACK
) {
221 // Attempt to retrieve the global debug print error level mask from the
224 Size
= sizeof (GlobalErrorLevel
);
225 Status
= mSystemTable
->RuntimeServices
->GetVariable (
226 DEBUG_MASK_VARIABLE_NAME
,
227 &gEfiGenericVariableGuid
,
232 if (Status
!= EFI_NOT_AVAILABLE_YET
) {
234 // If EFI Variable Services are available, then set a flag so the EFI
235 // Variable will not be read again by this module.
237 mGlobalErrorLevelInitialized
= TRUE
;
238 if (!EFI_ERROR (Status
)) {
240 // If the EFI Varible exists, then set this module's module's mask to
241 // the global debug print error level mask value.
243 mDebugPrintErrorLevel
= (UINT32
)GlobalErrorLevel
;
247 // If variable services are not yet available optionally get the global
248 // debug print error level mask from a HOB.
250 Hob
= GetFirstGuidHob (&gEfiGenericVariableGuid
);
252 if (GET_GUID_HOB_DATA_SIZE (Hob
) == sizeof (UINT32
)) {
253 mDebugPrintErrorLevel
= *(UINT32
*)GET_GUID_HOB_DATA (Hob
);
254 mGlobalErrorLevelInitialized
= TRUE
;
262 // Return the current mask value for this module.
264 return mDebugPrintErrorLevel
;
268 Sets the global debug print error level mask fpr the entire platform.
270 @param ErrorLevel Global debug print error level
272 @retval TRUE The debug print error level mask was sucessfully set.
273 @retval FALSE The debug print error level mask could not be set.
278 SetDebugPrintErrorLevel (
285 UINTN GlobalErrorLevel
;
288 // Make sure the constructor has been executed
290 if (mSystemTable
!= NULL
) {
292 // Make sure the TPL Level is low enough for EFI Variable Services
294 CurrentTpl
= mSystemTable
->BootServices
->RaiseTPL (TPL_HIGH_LEVEL
);
295 mSystemTable
->BootServices
->RestoreTPL (CurrentTpl
);
296 if (CurrentTpl
<= TPL_CALLBACK
) {
298 // Attempt to store the global debug print error level mask in an EFI Variable
300 GlobalErrorLevel
= (UINTN
)ErrorLevel
;
301 Size
= sizeof (GlobalErrorLevel
);
302 Status
= mSystemTable
->RuntimeServices
->SetVariable (
303 DEBUG_MASK_VARIABLE_NAME
,
304 &gEfiGenericVariableGuid
,
305 (EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
),
309 if (!EFI_ERROR (Status
)) {
311 // If the EFI Variable was updated, then update the mask value for this
312 // module and return TRUE.
314 mGlobalErrorLevelInitialized
= TRUE
;
315 mDebugPrintErrorLevel
= ErrorLevel
;
322 // Return FALSE since the EFI Variable could not be updated.
328 Retrieves the current debug print error level mask for a module are returns
329 it in CurrentDebugMask.
331 @param This The protocol instance pointer.
332 @param CurrentDebugMask Pointer to the debug print error level mask that
335 @retval EFI_SUCCESS The current debug print error level mask was
336 returned in CurrentDebugMask.
337 @retval EFI_INVALID_PARAMETER CurrentDebugMask is NULL.
338 @retval EFI_DEVICE_ERROR The current debug print error level mask could
345 IN EFI_DEBUG_MASK_PROTOCOL
*This
,
346 IN OUT UINTN
*CurrentDebugMask
349 if (CurrentDebugMask
== NULL
) {
350 return EFI_INVALID_PARAMETER
;
354 // Retrieve the current debug mask from mDebugPrintErrorLevel
356 *CurrentDebugMask
= (UINTN
)mDebugPrintErrorLevel
;
361 Sets the current debug print error level mask for a module to the value
362 specified by NewDebugMask.
364 @param This The protocol instance pointer.
365 @param NewDebugMask The new debug print error level mask for this module.
367 @retval EFI_SUCCESS The current debug print error level mask was
368 set to the value specified by NewDebugMask.
369 @retval EFI_DEVICE_ERROR The current debug print error level mask could
370 not be set to the value specified by NewDebugMask.
376 IN EFI_DEBUG_MASK_PROTOCOL
*This
,
377 IN UINTN NewDebugMask
381 // Store the new debug mask into mDebugPrintErrorLevel
383 mDebugPrintErrorLevel
= (UINT32
)NewDebugMask
;