]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c
Add some definitions for efi event in Uefi/UefiSpec.h to follow spec.
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / PciBus / Dxe / PciHotPlugSupport.c
CommitLineData
878ddf1f 1/*++\r
2\r
93b0fbc8 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
878ddf1f 11\r
12Module Name:\r
13\r
14 PciHotPlugSupport.c\r
93b0fbc8 15\r
878ddf1f 16Abstract:\r
17\r
93b0fbc8 18\r
878ddf1f 19\r
20Revision History\r
21\r
22--*/\r
23\r
d97430c5 24#include "Pcibus.h"\r
878ddf1f 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
93b0fbc8 257 EVT_NOTIFY_SIGNAL,\r
258 TPL_CALLBACK,\r
878ddf1f 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
d97430c5 273 IN UINTN TimeoutInMicroSeconds\r
878ddf1f 274 )\r
275/*++\r
276\r
277Routine Description:\r
278\r
279Arguments:\r
d97430c5 280 TimeoutInMicroSeconds - microseconds to wait for all root hpc's initialization\r
878ddf1f 281\r
282Returns:\r
d97430c5 283 EFI_SUCCESS - All root hpc's initialization is finished before the timeout\r
284 EFI_TIMEOUT - Time out\r
878ddf1f 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
d97430c5 294 Delay = (UINT32) ((TimeoutInMicroSeconds / 30) + 1);\r
878ddf1f 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