]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/DxeDebugPrintErrorLevelLib/DxeDebugPrintErrorLevelLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Library / DxeDebugPrintErrorLevelLib / DxeDebugPrintErrorLevelLib.c
CommitLineData
62a5bf63 1/** @file\r
d1102dba 2 Debug Print Error Level library instance that provide compatibility with the\r
62a5bf63 3 "err" shell command. This includes support for the Debug Mask Protocol\r
4 supports for global debug print error level mask stored in an EFI Variable.\r
5 This library instance only support DXE Phase modules.\r
6\r
d1102dba 7 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
62a5bf63 9\r
10**/\r
11\r
12#include <PiDxe.h>\r
13\r
14#include <Library/DebugPrintErrorLevelLib.h>\r
15#include <Library/PcdLib.h>\r
d4a78455 16#include <Library/HobLib.h>\r
62a5bf63 17\r
18#include <Guid/DebugMask.h>\r
19\r
20///\r
21/// Debug Mask Protocol function prototypes\r
22///\r
d4e0afd8
ED
23\r
24/**\r
25 Retrieves the current debug print error level mask for a module are returns\r
26 it in CurrentDebugMask.\r
27\r
28 @param This The protocol instance pointer.\r
d1102dba 29 @param CurrentDebugMask Pointer to the debug print error level mask that\r
d4e0afd8
ED
30 is returned.\r
31\r
32 @retval EFI_SUCCESS The current debug print error level mask was\r
33 returned in CurrentDebugMask.\r
34 @retval EFI_INVALID_PARAMETER CurrentDebugMask is NULL.\r
35 @retval EFI_DEVICE_ERROR The current debug print error level mask could\r
36 not be retrieved.\r
37\r
38**/\r
62a5bf63 39EFI_STATUS\r
40EFIAPI\r
41GetDebugMask (\r
d1102dba
LG
42 IN EFI_DEBUG_MASK_PROTOCOL *This,\r
43 IN OUT UINTN *CurrentDebugMask\r
62a5bf63 44 );\r
45\r
d4e0afd8
ED
46/**\r
47 Sets the current debug print error level mask for a module to the value\r
48 specified by NewDebugMask.\r
49\r
50 @param This The protocol instance pointer.\r
51 @param NewDebugMask The new debug print error level mask for this module.\r
52\r
53 @retval EFI_SUCCESS The current debug print error level mask was\r
54 set to the value specified by NewDebugMask.\r
55 @retval EFI_DEVICE_ERROR The current debug print error level mask could\r
56 not be set to the value specified by NewDebugMask.\r
57\r
58**/\r
62a5bf63 59EFI_STATUS\r
60EFIAPI\r
61SetDebugMask (\r
62 IN EFI_DEBUG_MASK_PROTOCOL *This,\r
63 IN UINTN NewDebugMask\r
64 );\r
65\r
66///\r
67/// Debug Mask Protocol instance\r
68///\r
69EFI_DEBUG_MASK_PROTOCOL mDebugMaskProtocol = {\r
70 EFI_DEBUG_MASK_REVISION,\r
71 GetDebugMask,\r
72 SetDebugMask\r
73};\r
74\r
75///\r
d1102dba 76/// Global variable that is set to TRUE after the first attempt is made to\r
62a5bf63 77/// retrieve the global error level mask through the EFI Varibale Services.\r
78/// This variable prevents the EFI Variable Services from being called fort\r
79/// every DEBUG() macro.\r
80///\r
1436aea4 81BOOLEAN mGlobalErrorLevelInitialized = FALSE;\r
62a5bf63 82\r
83///\r
84/// Global variable that contains the current debug error level mask for the\r
85/// module that is using this library instance. This variable is initially\r
86/// set to the PcdDebugPrintErrorLevel value. If the EFI Variable exists that\r
d4a78455 87/// contains the global debug print error level mask, then that overrides the\r
d1102dba 88/// PcdDebugPrintErrorLevel value. The EFI Variable can optionally be\r
d4a78455 89/// discovered via a HOB so early DXE drivers can access the variable. If the\r
d1102dba 90/// Debug Mask Protocol SetDebugMask() service is called, then that overrides\r
d4a78455 91/// the PcdDebugPrintErrorLevel and the EFI Variable setting.\r
62a5bf63 92///\r
1436aea4 93UINT32 mDebugPrintErrorLevel = 0;\r
62a5bf63 94\r
95///\r
96/// Global variable that is used to cache a pointer to the EFI System Table\r
97/// that is required to access the EFI Variable Services to get and set\r
98/// the global debug print error level mask value. The UefiBootServicesTableLib\r
99/// is not used to prevent a circular dependency between these libraries.\r
100///\r
1436aea4 101EFI_SYSTEM_TABLE *mSystemTable = NULL;\r
62a5bf63 102\r
103/**\r
d1102dba 104 The constructor function caches the PCI Express Base Address and creates a\r
62a5bf63 105 Set Virtual Address Map event to convert physical address to virtual addresses.\r
d1102dba 106\r
62a5bf63 107 @param ImageHandle The firmware allocated handle for the EFI image.\r
108 @param SystemTable A pointer to the EFI System Table.\r
d1102dba 109\r
62a5bf63 110 @retval EFI_SUCCESS The constructor completed successfully.\r
111 @retval Other value The constructor did not complete successfully.\r
112\r
113**/\r
114EFI_STATUS\r
115EFIAPI\r
116DxeDebugPrintErrorLevelLibConstructor (\r
117 IN EFI_HANDLE ImageHandle,\r
118 IN EFI_SYSTEM_TABLE *SystemTable\r
119 )\r
120{\r
1436aea4 121 EFI_STATUS Status;\r
d1102dba 122\r
62a5bf63 123 //\r
124 // Initialize the error level mask from PCD setting.\r
125 //\r
126 mDebugPrintErrorLevel = PcdGet32 (PcdDebugPrintErrorLevel);\r
d1102dba 127\r
62a5bf63 128 //\r
129 // Install Debug Mask Protocol onto ImageHandle\r
d1102dba 130 //\r
d4e0afd8 131 mSystemTable = SystemTable;\r
1436aea4
MK
132 Status = SystemTable->BootServices->InstallMultipleProtocolInterfaces (\r
133 &ImageHandle,\r
134 &gEfiDebugMaskProtocolGuid,\r
135 &mDebugMaskProtocol,\r
136 NULL\r
137 );\r
62a5bf63 138\r
139 //\r
140 // Attempt to retrieve the global debug print error level mask from the EFI Variable\r
141 // If the EFI Variable can not be accessed when this module's library constructors are\r
d1102dba 142 // executed a HOB can be used to set the global debug print error level. If no value\r
d4a78455 143 // was found then the EFI Variable access will be reattempted on every DEBUG() print\r
62a5bf63 144 // from this module until the EFI Variable services are available.\r
145 //\r
146 GetDebugPrintErrorLevel ();\r
d1102dba 147\r
62a5bf63 148 return Status;\r
149}\r
150\r
151/**\r
d1102dba 152 The destructor function frees any allocated buffers and closes the Set Virtual\r
62a5bf63 153 Address Map event.\r
d1102dba 154\r
62a5bf63 155 @param ImageHandle The firmware allocated handle for the EFI image.\r
156 @param SystemTable A pointer to the EFI System Table.\r
d1102dba 157\r
62a5bf63 158 @retval EFI_SUCCESS The destructor completed successfully.\r
159 @retval Other value The destructor did not complete successfully.\r
160\r
161**/\r
162EFI_STATUS\r
163EFIAPI\r
164DxeDebugPrintErrorLevelLibDestructor (\r
165 IN EFI_HANDLE ImageHandle,\r
166 IN EFI_SYSTEM_TABLE *SystemTable\r
167 )\r
168{\r
169 //\r
170 // Uninstall the Debug Mask Protocol from ImageHandle\r
d1102dba 171 //\r
62a5bf63 172 return SystemTable->BootServices->UninstallMultipleProtocolInterfaces (\r
173 ImageHandle,\r
1436aea4
MK
174 &gEfiDebugMaskProtocolGuid,\r
175 &mDebugMaskProtocol,\r
62a5bf63 176 NULL\r
177 );\r
178}\r
179\r
180/**\r
181 Returns the debug print error level mask for the current module.\r
182\r
183 @return Debug print error level mask for the current module.\r
184\r
185**/\r
186UINT32\r
187EFIAPI\r
188GetDebugPrintErrorLevel (\r
189 VOID\r
190 )\r
191{\r
192 EFI_STATUS Status;\r
193 EFI_TPL CurrentTpl;\r
194 UINTN Size;\r
195 UINTN GlobalErrorLevel;\r
d4a78455 196 VOID *Hob;\r
62a5bf63 197\r
198 //\r
199 // If the constructor has not been executed yet, then just return the PCD value.\r
200 // This case should only occur if debug print is generated by a library\r
201 // constructor for this module\r
202 //\r
d4e0afd8 203 if (mSystemTable == NULL) {\r
62a5bf63 204 return PcdGet32 (PcdDebugPrintErrorLevel);\r
205 }\r
d1102dba 206\r
62a5bf63 207 //\r
d1102dba 208 // Check to see if an attempt has been made to retrieve the global debug print\r
d4a78455 209 // error level mask. Since this library instance stores the global debug print\r
62a5bf63 210 // error level mask in an EFI Variable, the EFI Variable should only be accessed\r
211 // once to reduce the overhead of reading the EFI Variable on every debug print\r
d1102dba 212 //\r
62a5bf63 213 if (!mGlobalErrorLevelInitialized) {\r
214 //\r
215 // Make sure the TPL Level is low enough for EFI Variable Services to be called\r
216 //\r
d4e0afd8
ED
217 CurrentTpl = mSystemTable->BootServices->RaiseTPL (TPL_HIGH_LEVEL);\r
218 mSystemTable->BootServices->RestoreTPL (CurrentTpl);\r
62a5bf63 219 if (CurrentTpl <= TPL_CALLBACK) {\r
220 //\r
d1102dba 221 // Attempt to retrieve the global debug print error level mask from the\r
62a5bf63 222 // EFI Variable\r
223 //\r
1436aea4 224 Size = sizeof (GlobalErrorLevel);\r
d4e0afd8 225 Status = mSystemTable->RuntimeServices->GetVariable (\r
1436aea4
MK
226 DEBUG_MASK_VARIABLE_NAME,\r
227 &gEfiGenericVariableGuid,\r
228 NULL,\r
229 &Size,\r
230 &GlobalErrorLevel\r
231 );\r
62a5bf63 232 if (Status != EFI_NOT_AVAILABLE_YET) {\r
233 //\r
234 // If EFI Variable Services are available, then set a flag so the EFI\r
235 // Variable will not be read again by this module.\r
236 //\r
237 mGlobalErrorLevelInitialized = TRUE;\r
238 if (!EFI_ERROR (Status)) {\r
239 //\r
240 // If the EFI Varible exists, then set this module's module's mask to\r
241 // the global debug print error level mask value.\r
242 //\r
243 mDebugPrintErrorLevel = (UINT32)GlobalErrorLevel;\r
244 }\r
d4a78455 245 } else {\r
246 //\r
3b28e744 247 // If variable services are not yet available optionally get the global\r
d4a78455 248 // debug print error level mask from a HOB.\r
249 //\r
250 Hob = GetFirstGuidHob (&gEfiGenericVariableGuid);\r
251 if (Hob != NULL) {\r
252 if (GET_GUID_HOB_DATA_SIZE (Hob) == sizeof (UINT32)) {\r
1436aea4 253 mDebugPrintErrorLevel = *(UINT32 *)GET_GUID_HOB_DATA (Hob);\r
d4a78455 254 mGlobalErrorLevelInitialized = TRUE;\r
255 }\r
256 }\r
62a5bf63 257 }\r
258 }\r
259 }\r
260\r
261 //\r
262 // Return the current mask value for this module.\r
263 //\r
264 return mDebugPrintErrorLevel;\r
265}\r
266\r
267/**\r
268 Sets the global debug print error level mask fpr the entire platform.\r
d1102dba 269\r
d4e0afd8 270 @param ErrorLevel Global debug print error level\r
d1102dba 271\r
d4e0afd8
ED
272 @retval TRUE The debug print error level mask was sucessfully set.\r
273 @retval FALSE The debug print error level mask could not be set.\r
62a5bf63 274\r
275**/\r
276BOOLEAN\r
277EFIAPI\r
278SetDebugPrintErrorLevel (\r
279 UINT32 ErrorLevel\r
280 )\r
281{\r
282 EFI_STATUS Status;\r
283 EFI_TPL CurrentTpl;\r
284 UINTN Size;\r
285 UINTN GlobalErrorLevel;\r
286\r
287 //\r
288 // Make sure the constructor has been executed\r
289 //\r
d4e0afd8 290 if (mSystemTable != NULL) {\r
62a5bf63 291 //\r
292 // Make sure the TPL Level is low enough for EFI Variable Services\r
293 //\r
d4e0afd8
ED
294 CurrentTpl = mSystemTable->BootServices->RaiseTPL (TPL_HIGH_LEVEL);\r
295 mSystemTable->BootServices->RestoreTPL (CurrentTpl);\r
62a5bf63 296 if (CurrentTpl <= TPL_CALLBACK) {\r
297 //\r
298 // Attempt to store the global debug print error level mask in an EFI Variable\r
299 //\r
300 GlobalErrorLevel = (UINTN)ErrorLevel;\r
1436aea4
MK
301 Size = sizeof (GlobalErrorLevel);\r
302 Status = mSystemTable->RuntimeServices->SetVariable (\r
303 DEBUG_MASK_VARIABLE_NAME,\r
304 &gEfiGenericVariableGuid,\r
305 (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),\r
306 Size,\r
307 &GlobalErrorLevel\r
308 );\r
62a5bf63 309 if (!EFI_ERROR (Status)) {\r
310 //\r
d1102dba 311 // If the EFI Variable was updated, then update the mask value for this\r
62a5bf63 312 // module and return TRUE.\r
313 //\r
d1102dba 314 mGlobalErrorLevelInitialized = TRUE;\r
1436aea4 315 mDebugPrintErrorLevel = ErrorLevel;\r
62a5bf63 316 return TRUE;\r
317 }\r
318 }\r
319 }\r
1436aea4 320\r
62a5bf63 321 //\r
322 // Return FALSE since the EFI Variable could not be updated.\r
323 //\r
324 return FALSE;\r
325}\r
326\r
327/**\r
328 Retrieves the current debug print error level mask for a module are returns\r
329 it in CurrentDebugMask.\r
330\r
331 @param This The protocol instance pointer.\r
d1102dba 332 @param CurrentDebugMask Pointer to the debug print error level mask that\r
62a5bf63 333 is returned.\r
334\r
335 @retval EFI_SUCCESS The current debug print error level mask was\r
336 returned in CurrentDebugMask.\r
337 @retval EFI_INVALID_PARAMETER CurrentDebugMask is NULL.\r
338 @retval EFI_DEVICE_ERROR The current debug print error level mask could\r
339 not be retrieved.\r
340\r
341**/\r
342EFI_STATUS\r
343EFIAPI\r
344GetDebugMask (\r
d1102dba
LG
345 IN EFI_DEBUG_MASK_PROTOCOL *This,\r
346 IN OUT UINTN *CurrentDebugMask\r
62a5bf63 347 )\r
348{\r
349 if (CurrentDebugMask == NULL) {\r
350 return EFI_INVALID_PARAMETER;\r
351 }\r
d1102dba 352\r
62a5bf63 353 //\r
354 // Retrieve the current debug mask from mDebugPrintErrorLevel\r
355 //\r
356 *CurrentDebugMask = (UINTN)mDebugPrintErrorLevel;\r
357 return EFI_SUCCESS;\r
358}\r
359\r
360/**\r
361 Sets the current debug print error level mask for a module to the value\r
362 specified by NewDebugMask.\r
363\r
364 @param This The protocol instance pointer.\r
365 @param NewDebugMask The new debug print error level mask for this module.\r
366\r
367 @retval EFI_SUCCESS The current debug print error level mask was\r
368 set to the value specified by NewDebugMask.\r
369 @retval EFI_DEVICE_ERROR The current debug print error level mask could\r
370 not be set to the value specified by NewDebugMask.\r
371\r
372**/\r
373EFI_STATUS\r
374EFIAPI\r
375SetDebugMask (\r
376 IN EFI_DEBUG_MASK_PROTOCOL *This,\r
377 IN UINTN NewDebugMask\r
378 )\r
379{\r
380 //\r
381 // Store the new debug mask into mDebugPrintErrorLevel\r
382 //\r
383 mDebugPrintErrorLevel = (UINT32)NewDebugMask;\r
384 return EFI_SUCCESS;\r
385}\r