]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/ReportStatusCode.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / EfiDriverLib / ReportStatusCode.c
CommitLineData
3eb9473e 1/*++\r
2\r
3e99020d 3Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
4ea9375a 4This program and the accompanying materials \r
3eb9473e 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 ReportStatusCode.c\r
15\r
16Abstract:\r
17\r
18--*/\r
19\r
20#include "Tiano.h"\r
21#include "EfiDriverLib.h"\r
3e99020d 22#include "PeiHob.h"\r
3eb9473e 23#include EFI_PROTOCOL_DEFINITION (DevicePath)\r
3e99020d 24#include EFI_GUID_DEFINITION (Hob)\r
3eb9473e 25#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)\r
26#include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode)\r
27\r
ce7a12fb 28#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
3e99020d
LG
29\r
30EFI_REPORT_STATUS_CODE gReportStatusCode = NULL;\r
31\r
32VOID\r
33EFIAPI\r
34OnStatusCodeInstall (\r
35 IN EFI_EVENT Event,\r
36 IN VOID *Context\r
37 )\r
38{\r
39 EFI_STATUS Status;\r
40 EFI_STATUS_CODE_PROTOCOL *StatusCode;\r
41\r
42 Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID **) &StatusCode);\r
43 if (!EFI_ERROR (Status)) {\r
44 gReportStatusCode = StatusCode->ReportStatusCode;\r
45 }\r
46}\r
47\r
48EFI_STATUS\r
49GetPeiProtocol (\r
50 IN EFI_GUID *ProtocolGuid,\r
51 IN VOID **Interface\r
52 )\r
53/*++\r
54\r
55Routine Description:\r
56\r
57 Searches for a Protocol Interface passed from PEI through a HOB\r
58\r
59Arguments:\r
60\r
61 ProtocolGuid - The Protocol GUID to search for in the HOB List\r
62 Interface - A pointer to the interface for the Protocol GUID\r
63\r
64Returns:\r
65\r
66 EFI_SUCCESS - The Protocol GUID was found and its interface is returned in Interface\r
67 EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List\r
68\r
69--*/\r
70{\r
71 EFI_STATUS Status;\r
72 EFI_PEI_HOB_POINTERS GuidHob;\r
73\r
74 //\r
75 // Get Hob list\r
76 //\r
77 Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **) &GuidHob.Raw);\r
78 if (EFI_ERROR (Status)) {\r
79 return Status;\r
80 }\r
81\r
82 for (Status = EFI_NOT_FOUND; EFI_ERROR (Status);) {\r
83 if (END_OF_HOB_LIST (GuidHob)) {\r
84 Status = EFI_NOT_FOUND;\r
85 break;\r
86 }\r
87\r
88 if (GET_HOB_TYPE (GuidHob) == EFI_HOB_TYPE_GUID_EXTENSION) {\r
89 if (EfiCompareGuid (ProtocolGuid, &GuidHob.Guid->Name)) {\r
90 Status = EFI_SUCCESS;\r
91 *Interface = (VOID *) *(UINTN *) ((UINT8 *) (&GuidHob.Guid->Name) + sizeof (EFI_GUID));\r
92 }\r
93 }\r
94\r
95 GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
96 }\r
97\r
98 return Status;\r
99}\r
100\r
ce7a12fb 101#endif\r
3eb9473e 102\r
103EFI_STATUS\r
104EfiLibReportStatusCode (\r
105 IN EFI_STATUS_CODE_TYPE Type,\r
106 IN EFI_STATUS_CODE_VALUE Value,\r
107 IN UINT32 Instance,\r
108 IN EFI_GUID *CallerId OPTIONAL,\r
109 IN EFI_STATUS_CODE_DATA *Data OPTIONAL \r
110 )\r
111/*++\r
112\r
113Routine Description:\r
114\r
115 Report device path through status code.\r
116\r
117Arguments:\r
118\r
119 Type - Code type\r
120 Value - Code value\r
121 Instance - Instance number\r
122 CallerId - Caller name\r
123 DevicePath - Device path that to be reported\r
124\r
125Returns:\r
126\r
127 Status code.\r
128\r
129 EFI_OUT_OF_RESOURCES - No enough buffer could be allocated\r
130\r
131--*/\r
132{\r
133 EFI_STATUS Status;\r
bdabfae7 134\r
3e99020d
LG
135#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
136 if (gReportStatusCode == NULL) {\r
137 //\r
138 // Because we've installed the protocol notification on EfiStatusCodeRuntimeProtocol,\r
139 // running here indicates that the StatusCode driver has not started yet.\r
140 //\r
ce7a12fb 141 if (gBS == NULL) {\r
3e99020d
LG
142 //\r
143 // Running here only when StatusCode driver never starts.\r
144 //\r
ce7a12fb 145 return EFI_UNSUPPORTED;\r
146 }\r
3e99020d
LG
147\r
148 //\r
149 // Try to get the PEI version of ReportStatusCode.\r
150 // \r
151 Status = GetPeiProtocol (&gEfiStatusCodeRuntimeProtocolGuid, (VOID **) &gReportStatusCode);\r
152 if (EFI_ERROR (Status)) {\r
ce7a12fb 153 return EFI_UNSUPPORTED;\r
154 }\r
155 }\r
3e99020d 156 Status = gReportStatusCode (Type, Value, Instance, CallerId, Data);\r
ce7a12fb 157#else\r
158 if (gRT == NULL) {\r
159 return EFI_UNSUPPORTED;\r
160 }\r
161 //\r
162 // Check whether EFI_RUNTIME_SERVICES has Tiano Extension\r
163 //\r
164 Status = EFI_UNSUPPORTED;\r
165 if (gRT->Hdr.Revision == EFI_SPECIFICATION_VERSION &&\r
166 gRT->Hdr.HeaderSize == sizeof (EFI_RUNTIME_SERVICES) &&\r
167 gRT->ReportStatusCode != NULL) {\r
168 Status = gRT->ReportStatusCode (Type, Value, Instance, CallerId, Data);\r
169 }\r
ce7a12fb 170#endif\r
3e99020d 171 return Status;\r
3eb9473e 172}\r
173\r
174EFI_STATUS\r
175ReportStatusCodeWithDevicePath (\r
176 IN EFI_STATUS_CODE_TYPE Type,\r
177 IN EFI_STATUS_CODE_VALUE Value,\r
178 IN UINT32 Instance,\r
179 IN EFI_GUID * CallerId OPTIONAL,\r
180 IN EFI_DEVICE_PATH_PROTOCOL * DevicePath\r
181 )\r
182/*++\r
183\r
184Routine Description:\r
185\r
186 Report device path through status code.\r
187\r
188Arguments:\r
189\r
190 Type - Code type\r
191 Value - Code value\r
192 Instance - Instance number\r
193 CallerId - Caller name\r
194 DevicePath - Device path that to be reported\r
195\r
196Returns:\r
197\r
198 Status code.\r
199\r
200 EFI_OUT_OF_RESOURCES - No enough buffer could be allocated\r
201\r
202--*/\r
203{\r
204 UINT16 Size;\r
205 UINT16 DevicePathSize;\r
206 EFI_STATUS_CODE_DATA *ExtendedData;\r
207 EFI_DEVICE_PATH_PROTOCOL *ExtendedDevicePath;\r
208 EFI_STATUS Status;\r
209\r
210 DevicePathSize = (UINT16) EfiDevicePathSize (DevicePath);\r
8e986445 211 Size = (UINT16) (DevicePathSize + sizeof (EFI_STATUS_CODE_DATA));\r
3eb9473e 212 ExtendedData = (EFI_STATUS_CODE_DATA *) EfiLibAllocatePool (Size);\r
213 if (ExtendedData == NULL) {\r
214 return EFI_OUT_OF_RESOURCES;\r
215 }\r
216\r
217 ExtendedDevicePath = EfiConstructStatusCodeData (Size, &gEfiStatusCodeSpecificDataGuid, ExtendedData);\r
218 EfiCopyMem (ExtendedDevicePath, DevicePath, DevicePathSize);\r
219\r
220 Status = EfiLibReportStatusCode (Type, Value, Instance, CallerId, (EFI_STATUS_CODE_DATA *) ExtendedData);\r
221\r
222 gBS->FreePool (ExtendedData);\r
223 return Status;\r
224}\r