]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Bus/Pci/PciBus/Dxe/PciHotPlugSupport.c
• BaseMemoryLib:
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / PciBus / Dxe / PciHotPlugSupport.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 PciHotPlugSupport.c\r
15 \r
16Abstract:\r
17\r
18 \r
19\r
20Revision History\r
21\r
22--*/\r
23\r
f0ec738d 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
257 EFI_EVENT_NOTIFY_SIGNAL,\r
258 EFI_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 TimeoutInMilliSeconds\r
274 )\r
275/*++\r
276\r
277Routine Description:\r
278\r
279Arguments:\r
280\r
281Returns:\r
282\r
283 None\r
284\r
285--*/\r
286// TODO: TimeoutInMilliSeconds - add argument and description to function comment\r
287// TODO: EFI_SUCCESS - add return value to function comment\r
288// TODO: EFI_TIMEOUT - add return value to function comment\r
289{\r
290 UINT32 Delay;\r
291 UINTN Index;\r
292\r
293 Delay = (UINT32) (((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 30) + 1);\r
294 do {\r
295\r
296 for (Index = 0; Index < gPciRootHpcCount; Index++) {\r
297\r
298 if (!gPciRootHpcData[Index].Initialized) {\r
299 break;\r
300 }\r
301 }\r
302\r
303 if (Index == gPciRootHpcCount) {\r
304 return EFI_SUCCESS;\r
305 }\r
306\r
307 //\r
308 // Stall for 30 us\r
309 //\r
310 gBS->Stall (30);\r
311\r
312 Delay--;\r
313\r
314 } while (Delay);\r
315\r
316 return EFI_TIMEOUT;\r
317}\r
318\r
319EFI_STATUS\r
320IsSHPC (\r
321 PCI_IO_DEVICE *PciIoDevice\r
322 )\r
323/*++\r
324\r
325Routine Description:\r
326\r
327Arguments:\r
328\r
329Returns:\r
330\r
331 None\r
332\r
333--*/\r
334// TODO: PciIoDevice - add argument and description to function comment\r
335// TODO: EFI_NOT_FOUND - add return value to function comment\r
336// TODO: EFI_SUCCESS - add return value to function comment\r
337// TODO: EFI_NOT_FOUND - add return value to function comment\r
338{\r
339\r
340 EFI_STATUS Status;\r
341 UINT8 Offset;\r
342\r
343 if (!PciIoDevice) {\r
344 return EFI_NOT_FOUND;\r
345 }\r
346\r
347 Offset = 0;\r
348 Status = LocateCapabilityRegBlock (\r
349 PciIoDevice,\r
350 EFI_PCI_CAPABILITY_ID_HOTPLUG,\r
351 &Offset,\r
352 NULL\r
353 );\r
354\r
355 //\r
356 // If the PPB has the hot plug controller build-in,\r
357 // then return TRUE;\r
358 //\r
359 if (!EFI_ERROR (Status)) {\r
360 return EFI_SUCCESS;\r
361 }\r
362\r
363 return EFI_NOT_FOUND;\r
364}\r
365\r
366EFI_STATUS\r
367GetResourcePaddingForHpb (\r
368 IN PCI_IO_DEVICE *PciIoDevice\r
369 )\r
370/*++\r
371\r
372Routine Description:\r
373\r
374Arguments:\r
375\r
376Returns:\r
377\r
378 None\r
379\r
380--*/\r
381// TODO: PciIoDevice - add argument and description to function comment\r
382// TODO: EFI_SUCCESS - add return value to function comment\r
383// TODO: EFI_NOT_FOUND - add return value to function comment\r
384{\r
385 EFI_STATUS Status;\r
386 EFI_HPC_STATE State;\r
387 UINT64 PciAddress;\r
388 EFI_HPC_PADDING_ATTRIBUTES Attributes;\r
389 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
390\r
391 Status = IsPciHotPlugBus (PciIoDevice);\r
392\r
393 if (!EFI_ERROR (Status)) {\r
394 PciAddress = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);\r
395 Status = gPciHotPlugInit->GetResourcePadding (\r
396 gPciHotPlugInit,\r
397 PciIoDevice->DevicePath,\r
398 PciAddress,\r
399 &State,\r
400 (VOID **) &Descriptors,\r
401 &Attributes\r
402 );\r
403\r
404 if (EFI_ERROR (Status)) {\r
405 return Status;\r
406 }\r
407\r
408 if ((State & EFI_HPC_STATE_ENABLED) && (State & EFI_HPC_STATE_INITIALIZED)) {\r
409 PciIoDevice->ResourcePaddingDescriptors = Descriptors;\r
410 PciIoDevice->PaddingAttributes = Attributes;\r
411 }\r
412\r
413 return EFI_SUCCESS;\r
414 }\r
415\r
416 return EFI_NOT_FOUND;\r
417}\r
418\r
419EFI_STATUS\r
420IsPciHotPlugBus (\r
421 PCI_IO_DEVICE *PciIoDevice\r
422 )\r
423/*++\r
424\r
425Routine Description:\r
426\r
427Arguments:\r
428\r
429Returns:\r
430\r
431 None\r
432\r
433--*/\r
434// TODO: PciIoDevice - add argument and description to function comment\r
435// TODO: EFI_SUCCESS - add return value to function comment\r
436// TODO: EFI_SUCCESS - add return value to function comment\r
437// TODO: EFI_NOT_FOUND - add return value to function comment\r
438{\r
439 BOOLEAN Result;\r
440 EFI_STATUS Status;\r
441\r
442 Status = IsSHPC (PciIoDevice);\r
443\r
444 //\r
445 // If the PPB has the hot plug controller build-in,\r
446 // then return TRUE;\r
447 //\r
448 if (!EFI_ERROR (Status)) {\r
449 return EFI_SUCCESS;\r
450 }\r
451\r
452 //\r
453 // Otherwise, see if it is a Root HPC\r
454 //\r
455 Result = IsRootPciHotPlugBus (PciIoDevice->DevicePath, NULL);\r
456\r
457 if (Result) {\r
458 return EFI_SUCCESS;\r
459 }\r
460\r
461 return EFI_NOT_FOUND;\r
462}\r