]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/PciBusNoEnumerationDxe/PciDriverOverride.c
Fix build issue in linux environment.
[mirror_edk2.git] / DuetPkg / PciBusNoEnumerationDxe / PciDriverOverride.c
1 /*++
2
3 Copyright (c) 2005 - 2007, Intel Corporation
4 All rights reserved. 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 PciDriverOverride.c
15
16 Abstract:
17
18 PCI Bus Driver
19
20 Revision History
21
22 --*/
23
24 #include "PciBus.h"
25
26 EFI_STATUS
27 EFIAPI
28 GetDriver(
29 IN struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,
30 IN OUT EFI_HANDLE *DriverImageHandle
31 );
32
33
34
35 EFI_STATUS
36 InitializePciDriverOverrideInstance (
37 PCI_IO_DEVICE *PciIoDevice
38 )
39 /*++
40
41 Routine Description:
42
43 Initializes a PCI Driver Override Instance
44
45 Arguments:
46
47 Returns:
48
49 None
50
51 --*/
52
53 {
54 PciIoDevice->PciDriverOverride.GetDriver = GetDriver;
55 return EFI_SUCCESS;
56 }
57
58 EFI_STATUS
59 EFIAPI
60 GetDriver (
61 IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,
62 IN OUT EFI_HANDLE *DriverImageHandle
63 )
64 /*++
65
66 Routine Description:
67
68 Get a overriding driver image
69
70 Arguments:
71
72 Returns:
73
74 None
75
76 --*/
77 {
78 PCI_IO_DEVICE *PciIoDevice;
79 LIST_ENTRY *CurrentLink;
80 PCI_DRIVER_OVERRIDE_LIST *Node;
81
82 PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);
83
84 CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;
85
86 while (CurrentLink && CurrentLink != &PciIoDevice->OptionRomDriverList) {
87
88 Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);
89
90 if (*DriverImageHandle == NULL) {
91
92 *DriverImageHandle = Node->DriverImageHandle;
93 return EFI_SUCCESS;
94 }
95
96 if (*DriverImageHandle == Node->DriverImageHandle) {
97
98 if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||
99 CurrentLink->ForwardLink == NULL) {
100 return EFI_NOT_FOUND;
101 }
102
103 //
104 // Get next node
105 //
106 Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);
107 *DriverImageHandle = Node->DriverImageHandle;
108 return EFI_SUCCESS;
109 }
110
111 CurrentLink = CurrentLink->ForwardLink;
112 }
113
114 return EFI_INVALID_PARAMETER;
115 }
116
117 EFI_STATUS
118 AddDriver (
119 IN PCI_IO_DEVICE *PciIoDevice,
120 IN EFI_HANDLE DriverImageHandle
121 )
122 /*++
123
124 Routine Description:
125
126 Add a overriding driver image
127
128 Arguments:
129
130 Returns:
131
132 None
133
134 --*/
135
136 {
137 EFI_STATUS Status;
138 EFI_IMAGE_DOS_HEADER *DosHdr;
139 EFI_IMAGE_NT_HEADERS *PeHdr;
140 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
141 PCI_DRIVER_OVERRIDE_LIST *Node;
142 #if (EFI_SPECIFICATION_VERSION < 0x00020000)
143 EFI_DRIVER_OS_HANDOFF_HEADER *DriverOsHandoffHeader;
144 EFI_DRIVER_OS_HANDOFF_HEADER *NewDriverOsHandoffHeader;
145 EFI_DRIVER_OS_HANDOFF *DriverOsHandoff;
146 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
147 EFI_HANDLE DeviceHandle;
148 UINTN NumberOfEntries;
149 UINTN Size;
150 UINTN Index;
151 #endif
152
153 Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
154 if (EFI_ERROR (Status)) {
155 return Status;
156 }
157
158 Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));
159 if (Node == NULL) {
160 return EFI_OUT_OF_RESOURCES;
161 }
162
163 Node->Signature = DRIVER_OVERRIDE_SIGNATURE;
164 Node->DriverImageHandle = DriverImageHandle;
165
166 InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));
167
168 PciIoDevice->BusOverride = TRUE;
169
170 DosHdr = (EFI_IMAGE_DOS_HEADER *) LoadedImage->ImageBase;
171 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
172 return EFI_SUCCESS;
173 }
174
175 PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) LoadedImage->ImageBase + DosHdr->e_lfanew);
176
177 if (PeHdr->FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) {
178 return EFI_SUCCESS;
179 }
180
181 #if (EFI_SPECIFICATION_VERSION < 0x00020000)
182 DriverOsHandoffHeader = NULL;
183 Status = EfiLibGetSystemConfigurationTable (&gEfiUgaIoProtocolGuid, (VOID **) &DriverOsHandoffHeader);
184 if (!EFI_ERROR (Status) && DriverOsHandoffHeader != NULL) {
185 for (Index = 0; Index < DriverOsHandoffHeader->NumberOfEntries; Index++) {
186 DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)((UINTN)(DriverOsHandoffHeader) +
187 DriverOsHandoffHeader->HeaderSize +
188 Index * DriverOsHandoffHeader->SizeOfEntries);
189 DevicePath = DriverOsHandoff->DevicePath;
190 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle);
191 if (!EFI_ERROR (Status) && DeviceHandle != NULL && IsDevicePathEnd (DevicePath)) {
192 if (DeviceHandle == PciIoDevice->Handle) {
193 return EFI_SUCCESS;
194 }
195 }
196 }
197
198 NumberOfEntries = DriverOsHandoffHeader->NumberOfEntries + 1;
199 } else {
200 NumberOfEntries = 1;
201 }
202
203 Status = gBS->AllocatePool (
204 EfiRuntimeServicesData,
205 sizeof (EFI_DRIVER_OS_HANDOFF_HEADER) + NumberOfEntries * sizeof (EFI_DRIVER_OS_HANDOFF),
206 (VOID **) &NewDriverOsHandoffHeader
207 );
208 if (EFI_ERROR (Status)) {
209 return Status;
210 }
211
212 if (DriverOsHandoffHeader == NULL) {
213 NewDriverOsHandoffHeader->Version = 0;
214 NewDriverOsHandoffHeader->HeaderSize = sizeof (EFI_DRIVER_OS_HANDOFF_HEADER);
215 NewDriverOsHandoffHeader->SizeOfEntries = sizeof (EFI_DRIVER_OS_HANDOFF);
216 NewDriverOsHandoffHeader->NumberOfEntries = (UINT32) NumberOfEntries;
217 } else {
218 gBS->CopyMem (
219 NewDriverOsHandoffHeader,
220 DriverOsHandoffHeader,
221 DriverOsHandoffHeader->HeaderSize + (NumberOfEntries - 1) * DriverOsHandoffHeader->SizeOfEntries
222 );
223 NewDriverOsHandoffHeader->NumberOfEntries = (UINT32) NumberOfEntries;
224 }
225
226 DriverOsHandoff = (EFI_DRIVER_OS_HANDOFF *)((UINTN)NewDriverOsHandoffHeader +
227 NewDriverOsHandoffHeader->HeaderSize +
228 (NumberOfEntries - 1) * NewDriverOsHandoffHeader->SizeOfEntries);
229
230 //
231 // Fill in the EFI_DRIVER_OS_HANDOFF structure
232 //
233 DriverOsHandoff->Type = EfiUgaDriverFromPciRom;
234
235 //
236 // Compute the size of the device path
237 //
238 Size = EfiDevicePathSize (PciIoDevice->DevicePath);
239 if (Size == 0) {
240 DriverOsHandoff->DevicePath = NULL;
241 } else {
242
243 //
244 // Allocate space for duplicate device path
245 //
246 Status = gBS->AllocatePool (
247 EfiRuntimeServicesData,
248 Size,
249 (VOID **) &DriverOsHandoff->DevicePath
250 );
251 if (EFI_ERROR (Status)) {
252 gBS->FreePool (NewDriverOsHandoffHeader);
253 return Status;
254 }
255
256 //
257 // Make copy of device path
258 //
259 CopyMem (DriverOsHandoff->DevicePath, PciIoDevice->DevicePath, Size);
260 }
261
262 DriverOsHandoff->PciRomSize = (UINT64) PciIoDevice->PciIo.RomSize;
263 Status = gBS->AllocatePool (
264 EfiRuntimeServicesData,
265 (UINTN) DriverOsHandoff->PciRomSize,
266 (VOID **) &DriverOsHandoff->PciRomImage
267 );
268 if (EFI_ERROR (Status)) {
269 gBS->FreePool (NewDriverOsHandoffHeader);
270 return Status;
271 }
272
273 gBS->CopyMem (
274 DriverOsHandoff->PciRomImage,
275 PciIoDevice->PciIo.RomImage,
276 (UINTN) DriverOsHandoff->PciRomSize
277 );
278
279 Status = gBS->InstallConfigurationTable (&gEfiUgaIoProtocolGuid, NewDriverOsHandoffHeader);
280 if (EFI_ERROR (Status)) {
281 return Status;
282 }
283
284 if (DriverOsHandoffHeader != NULL) {
285 gBS->FreePool (DriverOsHandoffHeader);
286 }
287 #endif
288
289 return EFI_SUCCESS;
290 }