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