TianoCore EDK2 master
Loading...
Searching...
No Matches
PciBus.c
Go to the documentation of this file.
1
16#include "PciBus.h"
17
18//
19// PCI Bus Driver Global Variables
20//
21EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {
25 0xa,
26 NULL,
27 NULL
28};
29
30EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];
31EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gIncompatiblePciDeviceSupport = NULL;
32UINTN gPciHostBridgeNumber = 0;
33BOOLEAN gFullEnumeration = TRUE;
34UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;
35UINT64 gAllZero = 0;
36
37EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
38EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol;
39EDKII_IOMMU_PROTOCOL *mIoMmuProtocol;
40EDKII_DEVICE_SECURITY_PROTOCOL *mDeviceSecurityProtocol;
41
44};
45
62EFIAPI
64 IN EFI_HANDLE ImageHandle,
65 IN EFI_SYSTEM_TABLE *SystemTable
66 )
67{
68 EFI_STATUS Status;
69 EFI_HANDLE Handle;
70
71 //
72 // Initializes PCI devices pool
73 //
75
76 //
77 // Install driver model protocol(s).
78 //
80 ImageHandle,
81 SystemTable,
82 &gPciBusDriverBinding,
83 ImageHandle,
84 &gPciBusComponentName,
85 &gPciBusComponentName2
86 );
87 ASSERT_EFI_ERROR (Status);
88
89 if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
90 //
91 // If Hot Plug is supported, install EFI PCI Hot Plug Request protocol.
92 //
93 Handle = NULL;
94 Status = gBS->InstallProtocolInterface (
95 &Handle,
96 &gEfiPciHotPlugRequestProtocolGuid,
98 &mPciHotPlugRequest
99 );
100 }
101
102 return Status;
103}
104
120EFIAPI
123 IN EFI_HANDLE Controller,
124 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
125 )
126{
127 EFI_STATUS Status;
128 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
129 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
130 EFI_DEV_PATH_PTR Node;
131
132 //
133 // Check RemainingDevicePath validation
134 //
135 if (RemainingDevicePath != NULL) {
136 //
137 // Check if RemainingDevicePath is the End of Device Path Node,
138 // if yes, go on checking other conditions
139 //
140 if (!IsDevicePathEnd (RemainingDevicePath)) {
141 //
142 // If RemainingDevicePath isn't the End of Device Path Node,
143 // check its validation
144 //
145 Node.DevPath = RemainingDevicePath;
146 if ((Node.DevPath->Type != HARDWARE_DEVICE_PATH) ||
147 (Node.DevPath->SubType != HW_PCI_DP) ||
148 (DevicePathNodeLength (Node.DevPath) != sizeof (PCI_DEVICE_PATH)))
149 {
150 return EFI_UNSUPPORTED;
151 }
152 }
153 }
154
155 //
156 // Check if Pci Root Bridge IO protocol is installed by platform
157 //
158 Status = gBS->OpenProtocol (
159 Controller,
160 &gEfiPciRootBridgeIoProtocolGuid,
161 (VOID **)&PciRootBridgeIo,
162 This->DriverBindingHandle,
163 Controller,
164 EFI_OPEN_PROTOCOL_BY_DRIVER
165 );
166 if (Status == EFI_ALREADY_STARTED) {
167 return EFI_SUCCESS;
168 }
169
170 if (EFI_ERROR (Status)) {
171 return Status;
172 }
173
174 //
175 // Close the I/O Abstraction(s) used to perform the supported test
176 //
177 gBS->CloseProtocol (
178 Controller,
179 &gEfiPciRootBridgeIoProtocolGuid,
180 This->DriverBindingHandle,
181 Controller
182 );
183
184 //
185 // Open the EFI Device Path protocol needed to perform the supported test
186 //
187 Status = gBS->OpenProtocol (
188 Controller,
189 &gEfiDevicePathProtocolGuid,
190 (VOID **)&ParentDevicePath,
191 This->DriverBindingHandle,
192 Controller,
193 EFI_OPEN_PROTOCOL_BY_DRIVER
194 );
195 if (Status == EFI_ALREADY_STARTED) {
196 return EFI_SUCCESS;
197 }
198
199 if (EFI_ERROR (Status)) {
200 return Status;
201 }
202
203 //
204 // Close protocol, don't use device path protocol in the Support() function
205 //
206 gBS->CloseProtocol (
207 Controller,
208 &gEfiDevicePathProtocolGuid,
209 This->DriverBindingHandle,
210 Controller
211 );
212
213 return EFI_SUCCESS;
214}
215
231EFIAPI
234 IN EFI_HANDLE Controller,
235 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
236 )
237{
238 EFI_STATUS Status;
239 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
240 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
241
242 //
243 // Initialize PciRootBridgeIo to suppress incorrect compiler warning.
244 //
245 PciRootBridgeIo = NULL;
246
247 //
248 // Check RemainingDevicePath validation
249 //
250 if (RemainingDevicePath != NULL) {
251 //
252 // Check if RemainingDevicePath is the End of Device Path Node,
253 // if yes, return EFI_SUCCESS
254 //
255 if (IsDevicePathEnd (RemainingDevicePath)) {
256 return EFI_SUCCESS;
257 }
258 }
259
260 gBS->LocateProtocol (
261 &gEfiIncompatiblePciDeviceSupportProtocolGuid,
262 NULL,
263 (VOID **)&gIncompatiblePciDeviceSupport
264 );
265
266 //
267 // If PCI Platform protocol is available, get it now.
268 // If the platform implements this, it must be installed before BDS phase
269 //
270 gPciPlatformProtocol = NULL;
271 gBS->LocateProtocol (
272 &gEfiPciPlatformProtocolGuid,
273 NULL,
274 (VOID **)&gPciPlatformProtocol
275 );
276
277 //
278 // If PCI Platform protocol doesn't exist, try to Pci Override Protocol.
279 //
280 if (gPciPlatformProtocol == NULL) {
281 gPciOverrideProtocol = NULL;
282 gBS->LocateProtocol (
283 &gEfiPciOverrideProtocolGuid,
284 NULL,
285 (VOID **)&gPciOverrideProtocol
286 );
287 }
288
289 if (mIoMmuProtocol == NULL) {
290 gBS->LocateProtocol (
292 NULL,
293 (VOID **)&mIoMmuProtocol
294 );
295 }
296
297 if (mDeviceSecurityProtocol == NULL) {
298 gBS->LocateProtocol (
300 NULL,
301 (VOID **)&mDeviceSecurityProtocol
302 );
303 }
304
305 if (PcdGetBool (PcdPciDisableBusEnumeration)) {
306 gFullEnumeration = FALSE;
307 } else {
308 gFullEnumeration = (BOOLEAN)((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));
309 }
310
311 //
312 // Open Device Path Protocol for PCI root bridge
313 //
314 Status = gBS->OpenProtocol (
315 Controller,
316 &gEfiDevicePathProtocolGuid,
317 (VOID **)&ParentDevicePath,
318 This->DriverBindingHandle,
319 Controller,
320 EFI_OPEN_PROTOCOL_GET_PROTOCOL
321 );
322 ASSERT_EFI_ERROR (Status);
323
324 //
325 // Report Status Code to indicate PCI bus starts
326 //
329 (EFI_IO_BUS_PCI | EFI_IOB_PC_INIT),
330 ParentDevicePath
331 );
332
333 Status = EFI_SUCCESS;
334 //
335 // Enumerate the entire host bridge
336 // After enumeration, a database that records all the device information will be created
337 //
338 //
339 if (gFullEnumeration) {
340 //
341 // Get the rootbridge Io protocol to find the host bridge handle
342 //
343 Status = gBS->OpenProtocol (
344 Controller,
345 &gEfiPciRootBridgeIoProtocolGuid,
346 (VOID **)&PciRootBridgeIo,
347 gPciBusDriverBinding.DriverBindingHandle,
348 Controller,
349 EFI_OPEN_PROTOCOL_GET_PROTOCOL
350 );
351
352 if (!EFI_ERROR (Status)) {
353 Status = PciEnumerator (Controller, PciRootBridgeIo->ParentHandle);
354 }
355 } else {
356 //
357 // If PCI bus has already done the full enumeration, never do it again
358 //
359 Status = PciEnumeratorLight (Controller);
360 }
361
362 if (EFI_ERROR (Status)) {
363 return Status;
364 }
365
366 //
367 // Start all the devices under the entire host bridge.
368 //
369 StartPciDevices (Controller);
370
371 if (gFullEnumeration) {
372 gFullEnumeration = FALSE;
373
374 Status = gBS->InstallProtocolInterface (
375 &PciRootBridgeIo->ParentHandle,
376 &gEfiPciEnumerationCompleteProtocolGuid,
378 NULL
379 );
380 ASSERT_EFI_ERROR (Status);
381 }
382
383 return Status;
384}
385
401EFIAPI
404 IN EFI_HANDLE Controller,
405 IN UINTN NumberOfChildren,
406 IN EFI_HANDLE *ChildHandleBuffer
407 )
408{
409 EFI_STATUS Status;
410 UINTN Index;
411 BOOLEAN AllChildrenStopped;
412
413 if (NumberOfChildren == 0) {
414 //
415 // Close the bus driver
416 //
417 gBS->CloseProtocol (
418 Controller,
419 &gEfiDevicePathProtocolGuid,
420 This->DriverBindingHandle,
421 Controller
422 );
423 gBS->CloseProtocol (
424 Controller,
425 &gEfiPciRootBridgeIoProtocolGuid,
426 This->DriverBindingHandle,
427 Controller
428 );
429
431 Controller
432 );
433
434 return EFI_SUCCESS;
435 }
436
437 //
438 // Stop all the children
439 //
440
441 AllChildrenStopped = TRUE;
442
443 for (Index = 0; Index < NumberOfChildren; Index++) {
444 //
445 // De register all the pci device
446 //
447 Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);
448
449 if (EFI_ERROR (Status)) {
450 AllChildrenStopped = FALSE;
451 }
452 }
453
454 if (!AllChildrenStopped) {
455 return EFI_DEVICE_ERROR;
456 }
457
458 return EFI_SUCCESS;
459}
UINT64 UINTN
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define HW_PCI_DP
Definition: DevicePath.h:73
UINTN EFIAPI DevicePathNodeLength(IN CONST VOID *Node)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_GUID gEdkiiDeviceSecurityProtocolGuid
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define REPORT_STATUS_CODE_WITH_DEVICE_PATH(Type, Value, DevicePathParameter)
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
EFI_STATUS EFIAPI PciBusDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: PciBus.c:232
EFI_STATUS EFIAPI PciBusDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: PciBus.c:121
EFI_STATUS EFIAPI PciBusEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: PciBus.c:63
EFI_STATUS EFIAPI PciBusDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: PciBus.c:402
EFI_STATUS DeRegisterPciDevice(IN EFI_HANDLE Controller, IN EFI_HANDLE Handle)
EFI_STATUS DestroyRootBridgeByHandle(IN EFI_HANDLE Controller)
VOID InitializePciDevicePool(VOID)
EFI_STATUS StartPciDevices(IN EFI_HANDLE Controller)
EFI_STATUS EFIAPI PciHotPlugRequestNotify(IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL *This, IN EFI_PCI_HOTPLUG_OPERATION Operation, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, IN OUT UINT8 *NumberOfChildren, IN OUT EFI_HANDLE *ChildHandleBuffer)
BOOLEAN SearchHostBridgeHandle(IN EFI_HANDLE RootBridgeHandle)
EFI_STATUS PciEnumerator(IN EFI_HANDLE Controller, IN EFI_HANDLE HostBridgeHandle)
Definition: PciEnumerator.c:24
EFI_STATUS PciEnumeratorLight(IN EFI_HANDLE Controller)
#define EFI_IOB_PC_INIT
Definition: PiStatusCode.h:549
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
EFI_GUID gEdkiiIoMmuProtocolGuid
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193