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