]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Bus/Pci/PciBusDxe/pcibus.c
ebf817b96fd1f327c9064c3cccc8d200fcae298d
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBusDxe / pcibus.c
1 /**@file
2
3 Copyright (c) 2006, 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 **/
13
14
15 #include "pcibus.h"
16
17 //
18 // PCI Bus Driver Global Variables
19 //
20
21 EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {
22 PciBusDriverBindingSupported,
23 PciBusDriverBindingStart,
24 PciBusDriverBindingStop,
25 0xa,
26 NULL,
27 NULL
28 };
29
30 EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM];
31 UINTN gPciHostBridgeNumber;
32 BOOLEAN gFullEnumeration;
33 UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL;
34 UINT64 gAllZero = 0;
35
36 EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol;
37
38 //
39 // PCI Bus Driver Support Functions
40 //
41 EFI_STATUS
42 EFIAPI
43 PciBusEntryPoint (
44 IN EFI_HANDLE ImageHandle,
45 IN EFI_SYSTEM_TABLE *SystemTable
46 )
47 /*++
48
49 Routine Description:
50
51 Initialize the global variables
52 publish the driver binding protocol
53
54 Arguments:
55
56 IN EFI_HANDLE ImageHandle,
57 IN EFI_SYSTEM_TABLE *SystemTable
58
59 Returns:
60
61 EFI_SUCCESS
62 EFI_DEVICE_ERROR
63
64 --*/
65 // TODO: ImageHandle - add argument and description to function comment
66 // TODO: SystemTable - add argument and description to function comment
67 {
68 EFI_STATUS Status;
69
70 InitializePciDevicePool ();
71
72 gFullEnumeration = TRUE;
73
74 gPciHostBridgeNumber = 0;
75
76 //
77 // Install driver model protocol(s).
78 //
79 Status = EfiLibInstallDriverBindingComponentName2 (
80 ImageHandle,
81 SystemTable,
82 &gPciBusDriverBinding,
83 ImageHandle,
84 &gPciBusComponentName,
85 &gPciBusComponentName2
86 );
87 ASSERT_EFI_ERROR (Status);
88
89 InstallHotPlugRequestProtocol (&Status);
90
91 return Status;
92 }
93
94 EFI_STATUS
95 EFIAPI
96 PciBusDriverBindingSupported (
97 IN EFI_DRIVER_BINDING_PROTOCOL *This,
98 IN EFI_HANDLE Controller,
99 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
100 )
101 /*++
102
103 Routine Description:
104
105 Check to see if pci bus driver supports the given controller
106
107 Arguments:
108
109 IN EFI_DRIVER_BINDING_PROTOCOL *This,
110 IN EFI_HANDLE Controller,
111 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
112
113 Returns:
114
115 EFI_SUCCESS
116
117 --*/
118 // TODO: This - add argument and description to function comment
119 // TODO: Controller - add argument and description to function comment
120 // TODO: RemainingDevicePath - add argument and description to function comment
121 // TODO: EFI_UNSUPPORTED - add return value to function comment
122 {
123 EFI_STATUS Status;
124 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
125 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
126 EFI_DEV_PATH_PTR Node;
127
128 if (RemainingDevicePath != NULL) {
129 Node.DevPath = RemainingDevicePath;
130 if (Node.DevPath->Type != HARDWARE_DEVICE_PATH ||
131 Node.DevPath->SubType != HW_PCI_DP ||
132 DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) {
133 return EFI_UNSUPPORTED;
134 }
135 }
136 //
137 // Open the IO Abstraction(s) needed to perform the supported test
138 //
139 Status = gBS->OpenProtocol (
140 Controller,
141 &gEfiDevicePathProtocolGuid,
142 (VOID **) &ParentDevicePath,
143 This->DriverBindingHandle,
144 Controller,
145 EFI_OPEN_PROTOCOL_BY_DRIVER
146 );
147 if (Status == EFI_ALREADY_STARTED) {
148 return EFI_SUCCESS;
149 }
150
151 if (EFI_ERROR (Status)) {
152 return Status;
153 }
154
155 gBS->CloseProtocol (
156 Controller,
157 &gEfiDevicePathProtocolGuid,
158 This->DriverBindingHandle,
159 Controller
160 );
161
162 Status = gBS->OpenProtocol (
163 Controller,
164 &gEfiPciRootBridgeIoProtocolGuid,
165 (VOID **) &PciRootBridgeIo,
166 This->DriverBindingHandle,
167 Controller,
168 EFI_OPEN_PROTOCOL_BY_DRIVER
169 );
170 if (Status == EFI_ALREADY_STARTED) {
171 return EFI_SUCCESS;
172 }
173
174 if (EFI_ERROR (Status)) {
175 return Status;
176 }
177
178 gBS->CloseProtocol (
179 Controller,
180 &gEfiPciRootBridgeIoProtocolGuid,
181 This->DriverBindingHandle,
182 Controller
183 );
184
185 return EFI_SUCCESS;
186 }
187
188 EFI_STATUS
189 EFIAPI
190 PciBusDriverBindingStart (
191 IN EFI_DRIVER_BINDING_PROTOCOL *This,
192 IN EFI_HANDLE Controller,
193 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
194 )
195 /*++
196
197 Routine Description:
198
199 Start to management the controller passed in
200
201 Arguments:
202
203 IN EFI_DRIVER_BINDING_PROTOCOL *This,
204 IN EFI_HANDLE Controller,
205 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
206
207 Returns:
208
209
210 --*/
211 // TODO: This - add argument and description to function comment
212 // TODO: Controller - add argument and description to function comment
213 // TODO: RemainingDevicePath - add argument and description to function comment
214 // TODO: EFI_SUCCESS - add return value to function comment
215 {
216 EFI_STATUS Status;
217
218 //
219 // If PCI Platform protocol is available, get it now.
220 // If the platform implements this, it must be installed before BDS phase
221 //
222 gPciPlatformProtocol = NULL;
223 gBS->LocateProtocol (
224 &gEfiPciPlatformProtocolGuid,
225 NULL,
226 (VOID **) &gPciPlatformProtocol
227 );
228
229 gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE));
230
231 //
232 // Enumerate the entire host bridge
233 // After enumeration, a database that records all the device information will be created
234 //
235 //
236 Status = PciEnumerator (Controller);
237
238 if (EFI_ERROR (Status)) {
239 return Status;
240 }
241
242 //
243 // Enable PCI device specified by remaining device path. BDS or other driver can call the
244 // start more than once.
245 //
246
247 StartPciDevices (Controller, RemainingDevicePath);
248
249 return EFI_SUCCESS;
250 }
251
252 EFI_STATUS
253 EFIAPI
254 PciBusDriverBindingStop (
255 IN EFI_DRIVER_BINDING_PROTOCOL *This,
256 IN EFI_HANDLE Controller,
257 IN UINTN NumberOfChildren,
258 IN EFI_HANDLE *ChildHandleBuffer
259 )
260 /*++
261
262 Routine Description:
263
264 Stop one or more children created at start of pci bus driver
265 if all the the children get closed, close the protocol
266
267 Arguments:
268
269 IN EFI_DRIVER_BINDING_PROTOCOL *This,
270 IN EFI_HANDLE Controller,
271 IN UINTN NumberOfChildren,
272 IN EFI_HANDLE *ChildHandleBuffer
273
274 Returns:
275
276
277 --*/
278 // TODO: This - add argument and description to function comment
279 // TODO: Controller - add argument and description to function comment
280 // TODO: NumberOfChildren - add argument and description to function comment
281 // TODO: ChildHandleBuffer - add argument and description to function comment
282 // TODO: EFI_SUCCESS - add return value to function comment
283 // TODO: EFI_DEVICE_ERROR - add return value to function comment
284 // TODO: EFI_SUCCESS - add return value to function comment
285 {
286 EFI_STATUS Status;
287 UINTN Index;
288 BOOLEAN AllChildrenStopped;
289
290 if (NumberOfChildren == 0) {
291 //
292 // Close the bus driver
293 //
294 gBS->CloseProtocol (
295 Controller,
296 &gEfiDevicePathProtocolGuid,
297 This->DriverBindingHandle,
298 Controller
299 );
300 gBS->CloseProtocol (
301 Controller,
302 &gEfiPciRootBridgeIoProtocolGuid,
303 This->DriverBindingHandle,
304 Controller
305 );
306
307 DestroyRootBridgeByHandle (
308 Controller
309 );
310
311 return EFI_SUCCESS;
312 }
313
314 //
315 // Stop all the children
316 //
317
318 AllChildrenStopped = TRUE;
319
320 for (Index = 0; Index < NumberOfChildren; Index++) {
321
322 //
323 // De register all the pci device
324 //
325 Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]);
326
327 if (EFI_ERROR (Status)) {
328 AllChildrenStopped = FALSE;
329 }
330 }
331
332 if (!AllChildrenStopped) {
333 return EFI_DEVICE_ERROR;
334 }
335
336 return EFI_SUCCESS;
337 }