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