]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Library/EdkDxeDebugLibReportStatusCode/DebugLib.c
Initial import.
[mirror_edk2.git] / EdkModulePkg / Library / EdkDxeDebugLibReportStatusCode / DebugLib.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 DebugLib.c\r
15\r
16Abstract:\r
17\r
18 EFI Debug Library \r
19\r
20--*/\r
21\r
22static BOOLEAN mDebugLevelInstalled = FALSE;\r
23static EFI_DEBUG_LEVEL_PROTOCOL mDebugLevel = { 0 };\r
24\r
25EFI_STATUS\r
26DebugLibConstructor (\r
27 IN EFI_HANDLE ImageHandle,\r
28 IN EFI_SYSTEM_TABLE *SystemTable\r
29 )\r
30/*++\r
31\r
32Routine Description:\r
33\r
34Arguments:\r
35\r
36Returns:\r
37\r
38--*/\r
39{\r
40 EFI_STATUS Status;\r
41\r
42 //\r
43 // Initialize Debug Level Protocol\r
44 //\r
45 mDebugLevel.DebugLevel = PcdGet32(PcdDebugPrintErrorLevel);\r
46\r
47 //\r
48 // Install Debug Level Protocol \r
49 //\r
50 Status = gBS->InstallMultipleProtocolInterfaces (\r
51 &ImageHandle,\r
52 &gEfiDebugLevelProtocolGuid, &mDebugLevel,\r
53 NULL\r
54 );\r
55 ASSERT_EFI_ERROR (Status);\r
56\r
57 //\r
58 // Set flag to show that the Debug Level Protocol has been installed\r
59 //\r
60 mDebugLevelInstalled = TRUE;\r
61\r
62 return EFI_SUCCESS;\r
63}\r
64\r
65VOID\r
66EFIAPI\r
67DebugAssert (\r
68 IN CHAR8 *FileName,\r
69 IN INTN LineNumber,\r
70 IN CHAR8 *Description\r
71 )\r
72/*++\r
73\r
74Routine Description:\r
75\r
76 Worker function for ASSERT(). If Error Logging hub is loaded log ASSERT\r
77 information. If Error Logging hub is not loaded CpuBreakpoint ().\r
78\r
79 We use UINT64 buffers due to IPF alignment concerns.\r
80\r
81Arguments:\r
82\r
83 FileName - File name of failing routine.\r
84\r
85 LineNumber - Line number of failing ASSERT().\r
86\r
87 Description - Descritption, usally the assertion,\r
88 \r
89Returns:\r
90 \r
91 None\r
92\r
93--*/\r
94{\r
95 UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof(UINT64)];\r
96 EFI_DEBUG_ASSERT_DATA *AssertData;\r
97 UINTN TotalSize;\r
98 CHAR8 *Temp;\r
99\r
100 if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) == 0) {\r
101 return;\r
102 }\r
103\r
104 //\r
105 // Make sure it will all fit in the passed in buffer\r
106 //\r
107 TotalSize = sizeof (EFI_DEBUG_ASSERT_DATA) + AsciiStrLen (FileName) + 1 + AsciiStrLen (Description) + 1;\r
108 if (TotalSize <= EFI_STATUS_CODE_DATA_MAX_SIZE) {\r
109 //\r
110 // Fill in EFI_DEBUG_ASSERT_DATA\r
111 //\r
112 AssertData = (EFI_DEBUG_ASSERT_DATA *)Buffer;\r
113 AssertData->LineNumber = (UINT32)LineNumber;\r
114\r
115 //\r
116 // Copy Ascii FileName including NULL.\r
117 //\r
118 Temp = AsciiStrCpy ((CHAR8 *)(AssertData + 1), FileName);\r
119\r
120 //\r
121 // Copy Ascii Description \r
122 //\r
123 AsciiStrCpy (Temp + AsciiStrLen(FileName) + 1, Description);\r
124\r
125 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
126 (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),\r
127 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE),\r
128 AssertData,\r
129 TotalSize\r
130 );\r
131 }\r
132\r
133 //\r
134 // Put break point in module that contained the error.\r
135 //\r
136 CpuBreakpoint ();\r
137}\r
138\r
139VOID\r
140DebugVPrint (\r
141 IN UINTN ErrorLevel,\r
142 IN CHAR8 *Format,\r
143 IN VA_LIST Marker\r
144 )\r
145/*++\r
146\r
147Routine Description:\r
148\r
149 Worker function for DEBUG(). If Error Logging hub is loaded log ASSERT\r
150 information. If Error Logging hub is not loaded do nothing.\r
151\r
152 We use UINT64 buffers due to IPF alignment concerns.\r
153\r
154Arguments:\r
155\r
156 ErrorLevel - If error level is set do the debug print.\r
157\r
158 Format - String to use for the print, followed by Print arguments.\r
159\r
160 Marker - VarArgs\r
161 \r
162Returns:\r
163 \r
164 None\r
165\r
166--*/\r
167{\r
168 UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof (UINT64)];\r
169 EFI_DEBUG_INFO *DebugInfo;\r
170 UINTN TotalSize;\r
171 UINTN Index;\r
172 UINT64 *ArgumentPointer;\r
173\r
174 //\r
175 // Check driver Debug Level value and global debug level\r
176 //\r
177 if (mDebugLevelInstalled) {\r
178 if ((ErrorLevel & mDebugLevel.DebugLevel) == 0) {\r
179 return;\r
180 }\r
181 } else {\r
182 if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) {\r
183 return;\r
184 }\r
185 }\r
186\r
187 TotalSize = sizeof (EFI_DEBUG_INFO) + 12 * sizeof (UINT64 *) + AsciiStrLen (Format) + 1;\r
188 if (TotalSize > EFI_STATUS_CODE_DATA_MAX_SIZE) {\r
189 return;\r
190 }\r
191\r
192 //\r
193 // Then EFI_DEBUG_INFO\r
194 //\r
195 DebugInfo = (EFI_DEBUG_INFO *)Buffer;\r
196 DebugInfo->ErrorLevel = (UINT32)ErrorLevel;\r
197\r
198 //\r
199 // 256 byte mini Var Arg stack. That is followed by the format string.\r
200 //\r
201 for (Index = 0, ArgumentPointer = (UINT64 *)(DebugInfo + 1); Index < 12; Index++, ArgumentPointer++) {\r
202 *ArgumentPointer = VA_ARG (Marker, UINT64);\r
203 }\r
204 AsciiStrCpy ((CHAR8 *)ArgumentPointer, Format);\r
205\r
206 //\r
207 //\r
208 //\r
209 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
210 EFI_DEBUG_CODE,\r
211 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED),\r
212 DebugInfo,\r
213 TotalSize\r
214 );\r
215}\r
216\r
217VOID\r
218EFIAPI\r
219DebugPrint (\r
220 IN UINTN ErrorLevel,\r
221 IN CHAR8 *Format,\r
222 ...\r
223 )\r
224/*++\r
225\r
226Routine Description:\r
227\r
228 Wrapper for DebugVPrint ()\r
229 \r
230Arguments:\r
231\r
232 ErrorLevel - If error level is set do the debug print.\r
233\r
234 Format - String to use for the print, followed by Print arguments.\r
235\r
236 ... - Print arguments.\r
237\r
238Returns:\r
239 \r
240 None\r
241\r
242--*/\r
243{\r
244 VA_LIST Marker;\r
245\r
246 VA_START (Marker, Format);\r
247 DebugVPrint (ErrorLevel, Format, Marker);\r
248 VA_END (Marker);\r
249}\r
250\r
251/**\r
252 Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.\r
253\r
254 This function fills Length bytes of Buffer with the value specified by \r
255 PcdDebugClearMemoryValue, and returns Buffer.\r
256\r
257 If Buffer is NULL, then ASSERT().\r
258\r
259