]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c
Add PciBus & IdeBus
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / PciBus / Dxe / PciHotPlugSupport.c
CommitLineData
ead42efc 1/*++\r
2\r
3Copyright (c) 2006 - 2007, 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 PciHotPlugSupport.c\r
15\r
16Abstract:\r
17\r
18\r
19\r
20Revision History\r
21\r
22--*/\r
23\r
24#include "Pcibus.h"\r
25#include "PciHotPlugSupport.h"\r
26\r
27EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit;\r
28EFI_HPC_LOCATION *gPciRootHpcPool;\r
29UINTN gPciRootHpcCount;\r
30ROOT_HPC_DATA *gPciRootHpcData;\r
31\r
32VOID\r
33EFIAPI\r
34PciHPCInitialized (\r
35 IN EFI_EVENT Event,\r
36 IN VOID *Context\r
37 )\r
38/*++\r
39\r
40Routine Description:\r
41\r
42Arguments:\r
43\r
44Returns:\r
45\r
46 None\r
47\r
48--*/\r
49// TODO: Event - add argument and description to function comment\r
50// TODO: Context - add argument and description to function comment\r
51{\r
52 ROOT_HPC_DATA *HpcData;\r
53\r
54 HpcData = (ROOT_HPC_DATA *) Context;\r
55 HpcData->Initialized = TRUE;\r
56\r
57}\r
58\r
59BOOLEAN\r
60EfiCompareDevicePath (\r
61 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,\r
62 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2\r
63 )\r
64/*++\r
65\r
66Routine Description:\r
67\r
68Arguments:\r
69\r
70Returns:\r
71\r
72 None\r
73\r
74--*/\r
75// TODO: DevicePath1 - add argument and description to function comment\r
76// TODO: DevicePath2 - add argument and description to function comment\r
77{\r
78 UINTN Size1;\r
79 UINTN Size2;\r
80\r
81 Size1 = GetDevicePathSize (DevicePath1);\r
82 Size2 = GetDevicePathSize (DevicePath2);\r
83\r
84 if (Size1 != Size2) {\r
85 return FALSE;\r
86 }\r
87\r
88 if (CompareMem (DevicePath1, DevicePath2, Size1)) {\r
89 return FALSE;\r
90 }\r
91\r
92 return TRUE;\r
93}\r
94\r
95EFI_STATUS\r
96InitializeHotPlugSupport (\r
97 VOID\r
98 )\r
99/*++\r
100\r
101Routine Description:\r
102\r
103Arguments:\r
104\r
105Returns:\r
106\r
107 None\r
108\r
109--*/\r
110// TODO: EFI_UNSUPPORTED - add return value to function comment\r
111// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
112// TODO: EFI_SUCCESS - add return value to function comment\r
113{\r
114 EFI_STATUS Status;\r
115 EFI_HPC_LOCATION *HpcList;\r
116 UINTN HpcCount;\r
117\r
118 //\r
119 // Locate the PciHotPlugInit Protocol\r
120 // If it doesn't exist, that means there is no\r
121 // hot plug controller supported on the platform\r
122 // the PCI Bus driver is running on. HotPlug Support\r
123 // is an optional feature, so absence of the protocol\r
124 // won't incur the penalty\r
125 //\r
126 gPciHotPlugInit = NULL;\r
127 gPciRootHpcPool = NULL;\r
128 gPciRootHpcCount = 0;\r
129 gPciRootHpcData = NULL;\r
130\r
131 Status = gBS->LocateProtocol (\r
132 &gEfiPciHotPlugInitProtocolGuid,\r
133 NULL,\r
134 (VOID **) &gPciHotPlugInit\r
135 );\r
136\r
137 if (EFI_ERROR (Status)) {\r
138 return EFI_UNSUPPORTED;\r
139 }\r
140\r
141 Status = gPciHotPlugInit->GetRootHpcList (\r
142 gPciHotPlugInit,\r
143 &HpcCount,\r
144 &HpcList\r
145 );\r
146\r
147 if (!EFI_ERROR (Status)) {\r
148\r
149 gPciRootHpcPool = HpcList;\r
150 gPciRootHpcCount = HpcCount;\r
151 gPciRootHpcData = AllocateZeroPool (sizeof (ROOT_HPC_DATA) * gPciRootHpcCount);\r
152 if (gPciRootHpcData == NULL) {\r
153 return EFI_OUT_OF_RESOURCES;\r
154 }\r
155 }\r
156\r
157 return EFI_SUCCESS;\r
158}\r
159\r
160BOOLEAN\r
161IsRootPciHotPlugBus (\r
162 IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath,\r
163 OUT UINTN *HpIndex\r
164 )\r
165/*++\r
166\r
167Routine Description:\r
168\r
169Arguments:\r
170\r
171 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
172 HpIndex - A pointer to the Index.\r
173\r
174Returns:\r
175\r
176 None\r
177\r
178--*/\r
179// TODO: HpbDevicePath - add argument and description to function comment\r
180{\r
181 UINTN Index;\r
182\r
183 for (Index = 0; Index < gPciRootHpcCount; Index++) {\r
184\r
185 if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpbDevicePath, HpbDevicePath)) {\r
186\r
187 if (HpIndex != NULL) {\r
188 *HpIndex = Index;\r
189 }\r
190\r
191 return TRUE;\r
192 }\r
193 }\r
194\r
195 return FALSE;\r
196}\r
197\r
198BOOLEAN\r
199IsRootPciHotPlugController (\r
200 IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,\r
201 OUT UINTN *HpIndex\r
202 )\r
203/*++\r
204\r
205Routine Description:\r
206\r
207Arguments:\r
208\r
209 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.\r
210 HpIndex - A pointer to the Index.\r
211\r
212Returns:\r
213\r
214 None\r
215\r
216--*/\r
217{\r
218 UINTN Index;\r
219\r
220 for (Index = 0; Index < gPciRootHpcCount; Index++) {\r
221\r
222 if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpcDevicePath, HpcDevicePath)) {\r
223\r
224 if (HpIndex != NULL) {\r
225 *HpIndex = Index;\r
226 }\r
227\r
228 return TRUE;\r
229 }\r
230 }\r
231\r
232 return FALSE;\r
233}\r
234\r
235EFI_STATUS\r
236CreateEventForHpc (\r
237 IN UINTN HpIndex,\r
238 OUT EFI_EVENT *Event\r
239 )\r
240/*++\r
241\r
242Routine Description:\r
243\r
244Arguments:\r
245\r
246Returns:\r
247\r
248 None\r
249\r
250--*/\r
251// TODO: HpIndex - add argument and description to function comment\r
252// TODO: Event - add argument and description to function comment\r
253{\r
254 EFI_STATUS Status;\r
255\r
256 Status = gBS->CreateEvent (\r
257 EVT_NOTIFY_SIGNAL,\r
258 TPL_CALLBACK,\r
259 PciHPCInitialized,\r
260 gPciRootHpcData + HpIndex,\r
261 &((gPciRootHpcData + HpIndex)->Event)\r
262 );\r
263\r
264 if (!EFI_ERROR (Status)) {\r
265 *Event = (gPciRootHpcData + HpIndex)->Event;\r
266 }\r
267\r
268 return Status;\r
269}\r
270\r
271EFI_STATUS\r
272AllRootHPCInitialized (\r
273 IN UINTN TimeoutInMicroSeconds\r
274 )\r
275/*++\r
276\r
277Routine Description:\r
278\r
279Arguments:\r
280 TimeoutInMicroSeconds - microseconds to wait for all root hpc's initialization\r
281\r
282Returns:\r
283 EFI_SUCCESS - All root hpc's initialization is finished before the timeout\r
284 EFI_TIMEOUT - Time out\r
285\r
286--*/\r
287// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
288// TODO: EFI_SUCCESS - add return value to function comment\r
289// TODO: EFI_TIMEOUT - add return value to function comment\r
290{\r
291 UINT32 Delay;\r
292 UINTN Index;\r
293\r
294 Delay = (UINT32) ((TimeoutInMicroSeconds / 30) + 1);\r
295 do {\r
296\r
297 for (Index = 0; Index < gPciRootHpcCount; Index++) {\r
298\r
299 if (!gPciRootHpcData[Index].Initialized) {\r
300 break;\r
301 }\r
302 }\r
303\r
304 if (Index == gPciRootHpcCount) {\r
305 return EFI_SUCCESS;\r
306 }\r
307\r
308 //\r
309 // Stall for 30 us\r
310 //\r
311 gBS->Stall (30);\r
312\r
313 Delay--;\r
314\r
315 } while (Delay);\r
316\r
317 return EFI_TIMEOUT;\r
318}\r
319\r
320EFI_STATUS\r
321IsSHPC (\r
322 PCI_IO_DEVICE *PciIoDevice\r
323 )\r
324/*++\r
325\r
326Routine Description:\r
327\r
328Arguments:\r
329\r
330Returns:\r
331\r
332 None\r
333\r
334--*/\r
335// TODO: PciIoDevice - add argument and description to function comment\r
336// TODO: EFI_NOT_FOUND - add return value to function comment\r
337// TODO: EFI_SUCCESS - add return value to function comment\r
338// TODO: EFI_NOT_FOUND - add return value to function comment\r
339{\r
340\r
341 EFI_STATUS Status;\r
342 UINT8 Offset;\r
343\r
344 if (!PciIoDevice) {\r
345 return EFI_NOT_FOUND;\r
346 }\r
347\r
348 Offset = 0;\r
349 Status = LocateCapabilityRegBlock (\r
350 PciIoDevice,\r
351 EFI_PCI_CAPABILITY_ID_HOTPLUG,\r
352 &Offset,\r
353 NULL\r
354 );\r
355\r
356 //\r
357 // If the PPB has the hot plug controller build-in,\r
358 // then return TRUE;\r
359 //\r
360 if (!EFI_ERROR (Status)) {\r
361 return EFI_SUCCESS;\r
362 }\r
363\r
364 return EFI_NOT_FOUND;\r
365}\r
366\r
367EFI_STATUS\r
368GetResourcePaddingForHpb (\r
369 IN PCI_IO_DEVICE *PciIoDevice\r
370 )\r
371/*++\r
372\r
373Routine Description:\r
374\r
375Arguments:\r
376\r
377Returns:\r
378\r
379 None\r
380\r
381--*/\r
382// TODO: PciIoDevice - add argument and description to function comment\r
383// TODO: EFI_SUCCESS - add return value to function comment\r
384// TODO: EFI_NOT_FOUND - add return value to function comment\r
385{\r
386 EFI_STATUS Status;\r
387 EFI_HPC_STATE State;\r
388 UINT64 PciAddress;\r
389 EFI_HPC_PADDING_ATTRIBUTES Attributes;\r
390 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
391\r
392 Status = IsPciHotPlugBus (PciIoDevice);\r
393\r
394 if (!EFI_ERROR (Status)) {\r
395 PciAddress = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);\r
396 Status = gPciHotPlugInit->GetResourcePadding (\r
397 gPciHotPlugInit,\r
398 PciIoDevice->DevicePath,\r
399 PciAddress,\r
400 &State,\r
401 (VOID **) &Descriptors,\r
402 &Attributes\r
403 );\r
404\r
405 if (EFI_ERROR (Status)) {\r
406 return Status;\r
407 }\r
408\r
409 if ((State & EFI_HPC_STATE_ENABLED) && (State & EFI_HPC_STATE_INITIALIZED)) {\r
410 PciIoDevice->ResourcePaddingDescriptors = Descriptors;\r
411 PciIoDevice->PaddingAttributes = Attributes;\r
412 }\r
413\r
414 return EFI_SUCCESS;\r
415 }\r
416\r
417 return EFI_NOT_FOUND;\r
418}\r
419\r
420EFI_STATUS\r
421IsPciHotPlugBus (\r
422 PCI_IO_DEVICE *PciIoDevice\r
423 )\r
424/*++\r
425\r
426Routine Description:\r
427\r
428Arguments:\r
429\r
430Returns:\r
431\r
432 None\r
433\r
434--*/\r
435// TODO: PciIoDevice - add argument and description to function comment\r
436// TODO: EFI_SUCCESS - add return value to function comment\r
437// TODO: EFI_SUCCESS - add return value to function comment\r
438// TODO: EFI_NOT_FOUND - add return value to function comment\r
439{\r
440 BOOLEAN Result;\r
441 EFI_STATUS Status;\r
442\r
443 Status = IsSHPC (PciIoDevice);\r
444\r
445 //\r
446 // If the PPB has the hot plug controller build-in,\r
447 // then return TRUE;\r
448 //\r
449 if (!EFI_ERROR (Status)) {\r
450 return EFI_SUCCESS;\r
451 }\r
452\r
453 //\r
454 // Otherwise, see if it is a Root HPC\r
455 //\r
456 Result = IsRootPciHotPlugBus (PciIoDevice->DevicePath, NULL);\r
457\r
458 if (Result) {\r
459 return EFI_SUCCESS;\r
460 }\r
461\r
462 return EFI_NOT_FOUND;\r
463}\r