]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/PciBusNoEnumerationDxe/PciEnumeratorSupport.c
ShellPkg Build failure of AllocateZeroPool usage. This patch updates AllocateZeroPool...
[mirror_edk2.git] / DuetPkg / PciBusNoEnumerationDxe / PciEnumeratorSupport.c
CommitLineData
10590588 1/*++\r
2\r
ae837d36 3Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
b1f700a8 4This program and the accompanying materials \r
10590588 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 PciEnumeratorSupport.c\r
15 \r
16Abstract:\r
17\r
18 PCI Bus Driver\r
19\r
20Revision History\r
21\r
22--*/\r
23\r
d8bee43c 24#include "PciBus.h"\r
10590588 25\r
26EFI_STATUS \r
27InitializePPB (\r
28 IN PCI_IO_DEVICE *PciIoDevice \r
29);\r
30\r
31EFI_STATUS \r
32InitializeP2C (\r
33 IN PCI_IO_DEVICE *PciIoDevice \r
34);\r
35\r
36PCI_IO_DEVICE* \r
37CreatePciIoDevice (\r
38 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
39 IN PCI_TYPE00 *Pci,\r
40 UINT8 Bus,\r
41 UINT8 Device,\r
42 UINT8 Func\r
43);\r
44\r
45\r
46PCI_IO_DEVICE*\r
47GatherP2CInfo (\r
48 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
49 IN PCI_TYPE00 *Pci,\r
50 UINT8 Bus,\r
51 UINT8 Device,\r
52 UINT8 Func\r
53);\r
54\r
55UINTN\r
56PciParseBar (\r
57 IN PCI_IO_DEVICE *PciIoDevice,\r
58 IN UINTN Offset,\r
59 IN UINTN BarIndex\r
60);\r
61\r
62\r
63EFI_STATUS\r
64PciSearchDevice (\r
65 IN PCI_IO_DEVICE *Bridge,\r
66 PCI_TYPE00 *Pci,\r
67 UINT8 Bus,\r
68 UINT8 Device,\r
69 UINT8 Func,\r
70 PCI_IO_DEVICE **PciDevice\r
71);\r
72\r
73\r
74EFI_STATUS \r
75DetermineDeviceAttribute (\r
76 IN PCI_IO_DEVICE *PciIoDevice\r
77);\r
78\r
79EFI_STATUS \r
80BarExisted (\r
81 IN PCI_IO_DEVICE *PciIoDevice,\r
82 IN UINTN Offset,\r
83 OUT UINT32 *BarLengthValue,\r
84 OUT UINT32 *OriginalBarValue\r
85 );\r
86\r
87\r
88\r
89EFI_DEVICE_PATH_PROTOCOL*\r
90CreatePciDevicePath(\r
91 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
92 IN PCI_IO_DEVICE *PciIoDevice \r
93);\r
94\r
95PCI_IO_DEVICE* \r
96GatherDeviceInfo (\r
97 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
98 IN PCI_TYPE00 *Pci,\r
99 UINT8 Bus,\r
100 UINT8 Device,\r
101 UINT8 Func\r
102);\r
103\r
104PCI_IO_DEVICE* \r
105GatherPPBInfo (\r
106 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
107 IN PCI_TYPE00 *Pci,\r
108 UINT8 Bus,\r
109 UINT8 Device,\r
110 UINT8 Func\r
111);\r
112\r
113EFI_STATUS\r
114PciDevicePresent (\r
115 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
116 PCI_TYPE00 *Pci,\r
117 UINT8 Bus,\r
118 UINT8 Device,\r
119 UINT8 Func\r
120 )\r
121/*++\r
122\r
123Routine Description:\r
124\r
125 This routine is used to check whether the pci device is present\r
126\r
127Arguments:\r
128\r
129Returns:\r
130\r
131 None\r
132\r
133--*/\r
134{\r
135 UINT64 Address;\r
136 EFI_STATUS Status;\r
137\r
138 //\r
139 // Create PCI address map in terms of Bus, Device and Func\r
140 //\r
141 Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);\r
142\r
143 //\r
144 // Read the Vendor Id register\r
145 //\r
146 Status = PciRootBridgeIo->Pci.Read (\r
147 PciRootBridgeIo,\r
148 EfiPciWidthUint32,\r
149 Address,\r
150 1,\r
151 Pci\r
152 );\r
153\r
154 if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {\r
155\r
156 //\r
157 // Read the entire config header for the device\r
158 //\r
159\r
160 Status = PciRootBridgeIo->Pci.Read (\r
161 PciRootBridgeIo,\r
162 EfiPciWidthUint32,\r
163 Address,\r
164 sizeof (PCI_TYPE00) / sizeof (UINT32),\r
165 Pci\r
166 );\r
167\r
168 return EFI_SUCCESS;\r
169 }\r
170\r
171 return EFI_NOT_FOUND;\r
172}\r
173\r
174EFI_STATUS\r
175PciPciDeviceInfoCollector (\r
176 IN PCI_IO_DEVICE *Bridge,\r
177 UINT8 StartBusNumber\r
178 )\r
179/*++\r
180\r
181Routine Description:\r
182\r
183Arguments:\r
184\r
185Returns:\r
186\r
187 None\r
188\r
189--*/\r
190{\r
191 EFI_STATUS Status;\r
192 PCI_TYPE00 Pci;\r
193 UINT8 Device;\r
194 UINT8 Func;\r
195 UINT8 SecBus;\r
196 PCI_IO_DEVICE *PciIoDevice;\r
197 EFI_PCI_IO_PROTOCOL *PciIo;\r
198\r
199 Status = EFI_SUCCESS;\r
200 SecBus = 0;\r
201\r
202 for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
203\r
204 for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
205\r
206 //\r
207 // Check to see whether PCI device is present\r
208 //\r
209\r
210 Status = PciDevicePresent (\r
211 Bridge->PciRootBridgeIo,\r
212 &Pci,\r
213 (UINT8) StartBusNumber,\r
214 (UINT8) Device,\r
215 (UINT8) Func\r
216 );\r
217\r
218 if (!EFI_ERROR (Status)) {\r
219\r
220 //\r
221 // Collect all the information about the PCI device discovered\r
222 //\r
223 Status = PciSearchDevice (\r
224 Bridge,\r
225 &Pci,\r
226 (UINT8) StartBusNumber,\r
227 Device,\r
228 Func,\r
229 &PciIoDevice\r
230 );\r
231\r
232 //\r
233 // Recursively scan PCI busses on the other side of PCI-PCI bridges\r
234 //\r
235 //\r
236\r
237 if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
238\r
239 //\r
240 // If it is PPB, we need to get the secondary bus to continue the enumeration\r
241 //\r
242 PciIo = &(PciIoDevice->PciIo);\r
243\r
244 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &SecBus);\r
245\r
246 if (EFI_ERROR (Status)) {\r
247 return Status;\r
248 }\r
249 \r
250 //\r
251 // Deep enumerate the next level bus\r
252 //\r
253 Status = PciPciDeviceInfoCollector (\r
254 PciIoDevice,\r
255 (UINT8) (SecBus)\r
256 );\r
257\r
258 }\r
259\r
260 if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
261\r
262 //\r
263 // Skip sub functions, this is not a multi function device\r
264 //\r
265 Func = PCI_MAX_FUNC;\r
266 }\r
267 }\r
268\r
269 }\r
270 }\r
271\r
272 return EFI_SUCCESS;\r
273}\r
274\r
275EFI_STATUS\r
276PciSearchDevice (\r
277 IN PCI_IO_DEVICE *Bridge,\r
278 IN PCI_TYPE00 *Pci,\r
279 IN UINT8 Bus,\r
280 IN UINT8 Device,\r
281 IN UINT8 Func,\r
282 OUT PCI_IO_DEVICE **PciDevice\r
283 )\r
284/*++\r
285\r
286Routine Description:\r
287\r
288 Search required device.\r
289\r
290Arguments:\r
291\r
292 Bridge - A pointer to the PCI_IO_DEVICE.\r
293 Pci - A pointer to the PCI_TYPE00.\r
294 Bus - Bus number.\r
295 Device - Device number.\r
296 Func - Function number.\r
297 PciDevice - The Required pci device.\r
298\r
299Returns:\r
300\r
301 Status code.\r
302\r
303--*/\r
304{\r
305 PCI_IO_DEVICE *PciIoDevice;\r
306\r
307 PciIoDevice = NULL;\r
308\r
309 if (!IS_PCI_BRIDGE (Pci)) {\r
310\r
311 if (IS_CARDBUS_BRIDGE (Pci)) {\r
312 PciIoDevice = GatherP2CInfo (\r
313 Bridge->PciRootBridgeIo,\r
314 Pci,\r
315 Bus,\r
316 Device,\r
317 Func\r
318 );\r
319 if ((PciIoDevice != NULL) && (gFullEnumeration == TRUE)) {\r
320 InitializeP2C (PciIoDevice);\r
321 }\r
322 } else {\r
323\r
324 //\r
325 // Create private data for Pci Device\r
326 //\r
327 PciIoDevice = GatherDeviceInfo (\r
328 Bridge->PciRootBridgeIo,\r
329 Pci,\r
330 Bus,\r
331 Device,\r
332 Func\r
333 );\r
334\r
335 }\r
336\r
337 } else {\r
338\r
339 //\r
340 // Create private data for PPB\r
341 //\r
342 PciIoDevice = GatherPPBInfo (\r
343 Bridge->PciRootBridgeIo,\r
344 Pci,\r
345 Bus,\r
346 Device,\r
347 Func\r
348 );\r
349\r
350 //\r
351 // Special initialization for PPB including making the PPB quiet\r
352 //\r
353 if ((PciIoDevice != NULL) && (gFullEnumeration == TRUE)) {\r
354 InitializePPB (PciIoDevice);\r
355 }\r
356 }\r
357\r
358 if (!PciIoDevice) {\r
359 return EFI_OUT_OF_RESOURCES;\r
360 }\r
361 \r
362 //\r
363 // Create a device path for this PCI device and store it into its private data\r
364 //\r
365 CreatePciDevicePath(\r
366 Bridge->DevicePath,\r
367 PciIoDevice \r
368 );\r
369 \r
370 //\r
371 // Detect this function has option rom\r
372 //\r
373 if (gFullEnumeration) {\r
374\r
375 if (!IS_CARDBUS_BRIDGE (Pci)) {\r
376\r
377 GetOpRomInfo (PciIoDevice);\r
378\r
379 }\r
380\r
381 ResetPowerManagementFeature (PciIoDevice);\r
382 \r
383 } \r
384 else {\r
385 PciRomGetRomResourceFromPciOptionRomTable (\r
386 &gPciBusDriverBinding,\r
387 PciIoDevice->PciRootBridgeIo,\r
388 PciIoDevice\r
389 );\r
390 }\r
391\r
392 \r
393 //\r
394 // Insert it into a global tree for future reference\r
395 //\r
396 InsertPciDevice (Bridge, PciIoDevice);\r
397\r
398 //\r
399 // Determine PCI device attributes\r
400 //\r
401 DetermineDeviceAttribute (PciIoDevice);\r
402\r
403 if (PciDevice != NULL) {\r
404 *PciDevice = PciIoDevice;\r
405 }\r
406\r
407 return EFI_SUCCESS;\r
408}\r
409\r
410PCI_IO_DEVICE *\r
411GatherDeviceInfo (\r
412 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
413 IN PCI_TYPE00 *Pci,\r
414 UINT8 Bus,\r
415 UINT8 Device,\r
416 UINT8 Func\r
417 )\r
418/*++\r
419\r
420Routine Description:\r
421\r
422Arguments:\r
423\r
424Returns:\r
425\r
426 None\r
427\r
428--*/\r
429{\r
430 UINTN Offset;\r
431 UINTN BarIndex;\r
432 PCI_IO_DEVICE *PciIoDevice;\r
433\r
434 PciIoDevice = CreatePciIoDevice (\r
435 PciRootBridgeIo,\r
436 Pci,\r
437 Bus,\r
438 Device,\r
439 Func\r
440 );\r
441\r
442 if (!PciIoDevice) {\r
443 return NULL;\r
444 }\r
445\r
446 //\r
447 // If it is a full enumeration, disconnect the device in advance\r
448 //\r
449 if (gFullEnumeration) {\r
450\r
451 PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
452\r
453 }\r
454\r
455 //\r
456 // Start to parse the bars\r
457 //\r
458 for (Offset = 0x10, BarIndex = 0; Offset <= 0x24; BarIndex++) {\r
459 Offset = PciParseBar (PciIoDevice, Offset, BarIndex);\r
460 }\r
461\r
462 return PciIoDevice;\r
463}\r
464\r
465PCI_IO_DEVICE *\r
466GatherPPBInfo (\r
467 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
468 IN PCI_TYPE00 *Pci,\r
469 UINT8 Bus,\r
470 UINT8 Device,\r
471 UINT8 Func\r
472 )\r
473/*++\r
474\r
475Routine Description:\r
476\r
477Arguments:\r
478\r
479Returns:\r
480\r
481 None\r
482\r
483--*/\r
484{\r
485 PCI_IO_DEVICE *PciIoDevice;\r
486 EFI_STATUS Status;\r
7e7e7fec 487 UINT8 Value;\r
10590588 488 EFI_PCI_IO_PROTOCOL *PciIo;\r
489 UINT8 Temp;\r
490\r
491 PciIoDevice = CreatePciIoDevice (\r
492 PciRootBridgeIo,\r
493 Pci,\r
494 Bus,\r
495 Device,\r
496 Func\r
497 );\r
498\r
499 if (!PciIoDevice) {\r
500 return NULL;\r
501 }\r
502 \r
503 if (gFullEnumeration) {\r
504 PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
505\r
506 //\r
507 // Initalize the bridge control register\r
508 //\r
509 PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED);\r
510 }\r
511\r
512 PciIo = &PciIoDevice->PciIo;\r
513\r
514 //\r
515 // Test whether it support 32 decode or not\r
516 //\r
517 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
518 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
519 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);\r
520 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
521\r
522 if (Value) {\r
523 if (Value & 0x01) {\r
524 PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
525 } else {\r
526 PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
527 }\r
528 }\r
529\r
530 Status = BarExisted (\r
531 PciIoDevice,\r
532 0x24,\r
533 NULL,\r
534 NULL\r
535 );\r
536\r
537 //\r
538 // test if it supports 64 memory or not\r
539 //\r
540 if (!EFI_ERROR (Status)) {\r
541\r
542 Status = BarExisted (\r
543 PciIoDevice,\r
544 0x28,\r
545 NULL,\r
546 NULL\r
547 );\r
548\r
549 if (!EFI_ERROR (Status)) {\r
550 PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
551 PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
552 } else {\r
553 PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
554 }\r
555 }\r
556\r
557 //\r
558 // Memory 32 code is required for ppb\r
559 //\r
560 PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
561\r
562 return PciIoDevice;\r
563}\r
564\r
565PCI_IO_DEVICE *\r
566GatherP2CInfo (\r
567 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
568 IN PCI_TYPE00 *Pci,\r
569 UINT8 Bus,\r
570 UINT8 Device,\r
571 UINT8 Func\r
572 )\r
573/*++\r
574\r
575Routine Description:\r
576\r
577Arguments:\r
578\r
579Returns:\r
580\r
581 None\r
582\r
583--*/\r
584{\r
585 PCI_IO_DEVICE *PciIoDevice;\r
586 \r
587 PciIoDevice = CreatePciIoDevice (\r
588 PciRootBridgeIo,\r
589 Pci,\r
590 Bus,\r
591 Device,\r
592 Func\r
593 );\r
594\r
595 if (!PciIoDevice) {\r
596 return NULL;\r
597 }\r
598\r
599 if (gFullEnumeration) {\r
600 PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
601\r
602 //\r
603 // Initalize the bridge control register\r
604 //\r
605 PciDisableBridgeControlRegister (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED);\r
606\r
607 }\r
608 //\r
609 // P2C only has one bar that is in 0x10\r
610 //\r
611 PciParseBar(PciIoDevice, 0x10, 0);\r
612 \r
613 PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED |\r
614 EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |\r
615 EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
616\r
617 return PciIoDevice;\r
618}\r
619\r
620EFI_DEVICE_PATH_PROTOCOL *\r
621CreatePciDevicePath (\r
622 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
623 IN PCI_IO_DEVICE *PciIoDevice\r
624 )\r
625/*++\r
626\r
627Routine Description:\r
628\r
629Arguments:\r
630\r
631Returns:\r
632\r
633 None\r
634\r
635--*/\r
636{\r
637\r
638 PCI_DEVICE_PATH PciNode;\r
639\r
640 //\r
641 // Create PCI device path\r
642 //\r
643 PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
644 PciNode.Header.SubType = HW_PCI_DP;\r
645 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
646\r
647 PciNode.Device = PciIoDevice->DeviceNumber;\r
648 PciNode.Function = PciIoDevice->FunctionNumber;\r
649 PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header);\r
650\r
651 return PciIoDevice->DevicePath;\r
652}\r
653\r
654EFI_STATUS\r
655BarExisted (\r
656 IN PCI_IO_DEVICE *PciIoDevice,\r
657 IN UINTN Offset,\r
658 OUT UINT32 *BarLengthValue,\r
659 OUT UINT32 *OriginalBarValue\r
660 )\r
661/*++\r
662\r
663Routine Description:\r
664\r
665 Check the bar is existed or not.\r
666\r
667Arguments:\r
668\r
669 PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
670 Offset - The offset.\r
671 BarLengthValue - The bar length value.\r
672 OriginalBarValue - The original bar value.\r
673\r
674Returns:\r
675\r
676 EFI_NOT_FOUND - The bar don't exist.\r
677 EFI_SUCCESS - The bar exist.\r
678\r
679--*/\r
680{\r
681 EFI_PCI_IO_PROTOCOL *PciIo;\r
682 UINT32 OriginalValue;\r
683 UINT32 Value;\r
684 EFI_TPL OldTpl;\r
685\r
686 PciIo = &PciIoDevice->PciIo;\r
687\r
688 //\r
689 // Preserve the original value\r
690 //\r
691\r
692 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
693\r
694 //\r
695 // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
696 //\r
697 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
698\r
699 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);\r
700 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);\r
701\r
702 //\r
703 // Write back the original value\r
704 //\r
705 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
706\r
707 //\r
708 // Restore TPL to its original level\r
709 //\r
710 gBS->RestoreTPL (OldTpl);\r
711\r
712 if (BarLengthValue != NULL) {\r
713 *BarLengthValue = Value;\r
714 }\r
715\r
716 if (OriginalBarValue != NULL) {\r
717 *OriginalBarValue = OriginalValue;\r
718 }\r
719\r
720 if (Value == 0) {\r
721 return EFI_NOT_FOUND;\r
722 } else {\r
723 return EFI_SUCCESS;\r
724 }\r
725}\r
726\r
727\r
728EFI_STATUS\r
729DetermineDeviceAttribute (\r
730 IN PCI_IO_DEVICE *PciIoDevice\r
731 )\r
732/*++\r
733\r
734Routine Description:\r
735 \r
736 Determine the related attributes of all devices under a Root Bridge\r
737\r
738Arguments:\r
739\r
740Returns:\r
741\r
742 None\r
743\r
744--*/\r
745{\r
746 UINT16 Command;\r
747 UINT16 BridgeControl;\r
748\r
749 Command = 0;\r
750\r
751 PciIoDevice->Supports |= EFI_PCI_DEVICE_ENABLE;\r
752 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
753\r
754 if (IS_PCI_VGA (&(PciIoDevice->Pci))){\r
755\r
756 //\r
757 // If the device is VGA, VGA related Attributes are supported\r
758 //\r
759 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO ;\r
760 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY ;\r
761 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_IO ;\r
762 }\r
763\r
764 if(IS_ISA_BRIDGE(&(PciIoDevice->Pci)) || IS_INTEL_ISA_BRIDGE(&(PciIoDevice->Pci))) {\r
765 //\r
766 // If the devie is a ISA Bridge, set the two attributes\r
767 //\r
768 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
769 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
770 }\r
771\r
772 if (IS_PCI_GFX (&(PciIoDevice->Pci))) {\r
773\r
774 //\r
775 // If the device is GFX, then only set the EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO\r
776 // attribute\r
777 //\r
778 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO ;\r
779 }\r
780\r
781\r
782 //\r
783 // If the device is IDE, IDE related attributes are supported\r
784 //\r
785 if (IS_PCI_IDE (&(PciIoDevice->Pci))) {\r
786 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO ;\r
787 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO ;\r
788 }\r
789\r
790 PciReadCommandRegister(PciIoDevice, &Command);\r
791\r
792 \r
793 if (Command & EFI_PCI_COMMAND_IO_SPACE) {\r
794 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;\r
795 }\r
796\r
797 if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {\r
798 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY;\r
799 }\r
800\r
801 if (Command & EFI_PCI_COMMAND_BUS_MASTER) {\r
802 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;\r
803 }\r
804\r
805 if (IS_PCI_BRIDGE (&(PciIoDevice->Pci)) || \r
806 IS_CARDBUS_BRIDGE (&(PciIoDevice->Pci))){\r
807\r
808 //\r
809 // If it is a PPB, read the Bridge Control Register to determine\r
810 // the relevant attributes\r
811 //\r
812 BridgeControl = 0;\r
813 PciReadBridgeControlRegister(PciIoDevice, &BridgeControl);\r
814\r
815 //\r
816 // Determine whether the ISA bit is set\r
817 // If ISA Enable on Bridge is set, the PPB\r
818 // will block forwarding 0x100-0x3ff for each 1KB in the \r
819 // first 64KB I/O range.\r
820 //\r
1c8bea11 821 if ((BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) != 0) {\r
10590588 822 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
823 } \r
824\r
825 //\r
826 // Determine whether the VGA bit is set\r
827 // If it is set, the bridge is set to decode VGA memory range\r
828 // and palette register range\r
829 //\r
830 if (IS_PCI_VGA (&(PciIoDevice->Pci)) &&BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) {\r
831 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
832 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
833 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
834 }\r
835\r
836 //\r
837 // if the palette snoop bit is set, then the brige is set to \r
838 // decode palette IO write\r
839 //\r
840 if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
841 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
842 }\r
843 } \r
844\r
845 return EFI_SUCCESS;\r
846}\r
847\r
848UINTN\r
849PciParseBar (\r
850 IN PCI_IO_DEVICE *PciIoDevice,\r
851 IN UINTN Offset,\r
852 IN UINTN BarIndex\r
853 )\r
854/*++\r
855\r
856Routine Description:\r
857\r
858Arguments:\r
859\r
860Returns:\r
861\r
862 None\r
863\r
864--*/\r
865{\r
866 UINT32 Value;\r
10590588 867 UINT32 OriginalValue;\r
868 UINT32 Mask;\r
10590588 869 EFI_STATUS Status;\r
870\r
871 OriginalValue = 0;\r
872 Value = 0;\r
10590588 873\r
874 Status = BarExisted (\r
875 PciIoDevice,\r
876 Offset,\r
877 &Value,\r
878 &OriginalValue\r
879 );\r
880\r
881 if (EFI_ERROR (Status)) {\r
882 PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
883 PciIoDevice->PciBar[BarIndex].Length = 0;\r
884 PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
885\r
886 //\r
887 // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway\r
888 //\r
889 PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
890 return Offset + 4;\r
891 }\r
892\r
893 PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
894 if (Value & 0x01) {\r
895 //\r
896 // Device I/Os\r
897 //\r
898 Mask = 0xfffffffc;\r
899\r
900 if (Value & 0xFFFF0000) {\r
901 //\r
902 // It is a IO32 bar\r
903 //\r
904 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32;\r
905 PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1);\r
906 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
907\r
908 } else {\r
909 //\r
910 // It is a IO16 bar\r
911 //\r
912 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16;\r
913 PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1);\r
914 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
915\r
916 }\r
917 //\r
918 // Workaround. Some platforms inplement IO bar with 0 length\r
919 // Need to treat it as no-bar\r
920 //\r
921 if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
9c83c97a 922 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
10590588 923 }\r
924\r
925 PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE;\r
926 PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
927\r
928 } else {\r
929\r
930 Mask = 0xfffffff0;\r
931\r
932 PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
933\r
934 switch (Value & 0x07) {\r
935\r
936 //\r
937 //memory space; anywhere in 32 bit address space\r
938 //\r
939 case 0x00:\r
940 if (Value & 0x08) {\r
941 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
942 } else {\r
943 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
944 }\r
945\r
946 PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
947 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
948\r
949 break;\r
950\r
951 //\r
952 // memory space; anywhere in 64 bit address space\r
953 //\r
954 case 0x04:\r
955 if (Value & 0x08) {\r
956 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;\r
957 } else {\r
958 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;\r
959 }\r
960\r
961 //\r
962 // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
963 // is regarded as an extension for the first bar. As a result\r
964 // the sizing will be conducted on combined 64 bit value\r
965 // Here just store the masked first 32bit value for future size\r
966 // calculation\r
967 //\r
968 PciIoDevice->PciBar[BarIndex].Length = Value & Mask;\r
969 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
970\r
971 //\r
972 // Increment the offset to point to next DWORD\r
973 //\r
974 Offset += 4;\r
975\r
976 Status = BarExisted (\r
977 PciIoDevice,\r
978 Offset,\r
979 &Value,\r
980 &OriginalValue\r
981 );\r
982\r
983 if (EFI_ERROR (Status)) {\r
984 return Offset + 4;\r
985 }\r
986\r
987 //\r
988 // Fix the length to support some spefic 64 bit BAR\r
989 //\r
ae837d36 990 Value |= ((UINT32)(-1) << HighBitSet32 (Value)); \r
10590588 991\r
992 //\r
993 // Calculate the size of 64bit bar\r
994 //\r
995 PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
996\r
997 PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
998 PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
999 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
1000\r
1001 break;\r
1002\r
1003 //\r
1004 // reserved\r
1005 //\r
1006 default:\r
1007 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
1008 PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
1009 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
1010\r
1011 break;\r
1012 }\r
1013 }\r
1014 \r
1015 //\r
1016 // Check the length again so as to keep compatible with some special bars\r
1017 //\r
1018 if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
1019 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
1020 PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
1021 PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
1022 }\r
1023 \r
1024 //\r
1025 // Increment number of bar\r
1026 //\r
1027 return Offset + 4;\r
1028}\r
1029\r
1030EFI_STATUS\r
1031InitializePPB (\r
1032 IN PCI_IO_DEVICE *PciIoDevice\r
1033 )\r
1034/*++\r
1035\r
1036Routine Description:\r
1037\r
1038Arguments:\r
1039\r
1040Returns:\r
1041\r
1042 None\r
1043\r
1044--*/\r
1045{\r
1046 EFI_PCI_IO_PROTOCOL *PciIo;\r
1047\r
1048 PciIo = &(PciIoDevice->PciIo);\r
1049\r
1050 //\r
1051 // Put all the resource apertures including IO16\r
1052 // Io32, pMem32, pMem64 to quiescent state\r
1053 // Resource base all ones, Resource limit all zeros\r
1054 //\r
1055 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
1056 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero);\r
1057\r
1058 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne);\r
1059 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero);\r
1060\r
1061 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne);\r
1062 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero);\r
1063\r
1064 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne);\r
1065 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero);\r
1066\r
1067 //\r
1068 // don't support use io32 as for now\r
1069 //\r
1070 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne);\r
1071 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero);\r
1072\r
1073 return EFI_SUCCESS;\r
1074}\r
1075\r
1076EFI_STATUS\r
1077InitializeP2C (\r
1078 IN PCI_IO_DEVICE *PciIoDevice\r
1079 )\r
1080/*++\r
1081\r
1082Routine Description:\r
1083\r
1084Arguments:\r
1085\r
1086Returns:\r
1087\r
1088 None\r
1089\r
1090--*/\r
1091{\r
1092 EFI_PCI_IO_PROTOCOL *PciIo;\r
1093\r
1094 PciIo = &(PciIoDevice->PciIo);\r
1095\r
1096 //\r
1097 // Put all the resource apertures including IO16\r
1098 // Io32, pMem32, pMem64 to quiescent state(\r
1099 // Resource base all ones, Resource limit all zeros\r
1100 //\r
1101 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne);\r
1102 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero);\r
1103\r
1104 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne);\r
1105 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero);\r
1106\r
1107 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne);\r
1108 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero);\r
1109\r
1110 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne);\r
1111 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero);\r
1112\r
1113 return EFI_SUCCESS;\r
1114}\r
1115\r
1116PCI_IO_DEVICE *\r
1117CreatePciIoDevice (\r
1118 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
1119 IN PCI_TYPE00 *Pci,\r
1120 UINT8 Bus,\r
1121 UINT8 Device,\r
1122 UINT8 Func\r
1123 )\r
1124/*++\r
1125\r
1126Routine Description:\r
1127\r
1128Arguments:\r
1129\r
1130Returns:\r
1131\r
1132 None\r
1133\r
1134--*/\r
1135{\r
1136\r
1137 EFI_STATUS Status;\r
1138 PCI_IO_DEVICE *PciIoDevice;\r
1139\r
1140 PciIoDevice = NULL;\r
1141\r
1142 Status = gBS->AllocatePool (\r
1143 EfiBootServicesData,\r
1144 sizeof (PCI_IO_DEVICE),\r
1145 (VOID **) &PciIoDevice\r
1146 );\r
1147\r
1148 if (EFI_ERROR (Status)) {\r
1149 return NULL;\r
1150 }\r
1151\r
1152 ZeroMem (PciIoDevice, sizeof (PCI_IO_DEVICE));\r
1153\r
1154 PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE;\r
1155 PciIoDevice->Handle = NULL;\r
1156 PciIoDevice->PciRootBridgeIo = PciRootBridgeIo;\r
1157 PciIoDevice->DevicePath = NULL;\r
1158 PciIoDevice->BusNumber = Bus;\r
1159 PciIoDevice->DeviceNumber = Device;\r
1160 PciIoDevice->FunctionNumber = Func;\r
1161 PciIoDevice->Decodes = 0;\r
1162 if (gFullEnumeration) {\r
1163 PciIoDevice->Allocated = FALSE;\r
1164 } else {\r
1165 PciIoDevice->Allocated = TRUE;\r
1166 }\r
1167\r
1168 PciIoDevice->Attributes = 0;\r
1169 PciIoDevice->Supports = 0;\r
1170 PciIoDevice->BusOverride = FALSE;\r
1171 PciIoDevice->IsPciExp = FALSE;\r
1172\r
1173 CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01));\r
1174\r
1175 //\r
1176 // Initialize the PCI I/O instance structure\r
1177 //\r
1178\r
1179 Status = InitializePciIoInstance (PciIoDevice);\r
1180 Status = InitializePciDriverOverrideInstance (PciIoDevice);\r
1181\r
1182 if (EFI_ERROR (Status)) {\r
1183 gBS->FreePool (PciIoDevice);\r
1184 return NULL;\r
1185 }\r
1186\r
1187 //\r
1188 // Initialize the reserved resource list\r
1189 //\r
1190 InitializeListHead (&PciIoDevice->ReservedResourceList);\r
1191\r
1192 //\r
1193 // Initialize the driver list\r
1194 //\r
1195 InitializeListHead (&PciIoDevice->OptionRomDriverList);\r
1196\r
1197 //\r
1198 // Initialize the child list\r
1199 //\r
1200 InitializeListHead (&PciIoDevice->ChildList);\r
1201\r
1202 return PciIoDevice;\r
1203}\r
1204\r
1205EFI_STATUS\r
1206PciEnumeratorLight (\r
1207 IN EFI_HANDLE Controller\r
1208 )\r
1209/*++\r
1210\r
1211Routine Description:\r
1212\r
1213 This routine is used to enumerate entire pci bus system \r
1214 in a given platform\r
1215\r
1216Arguments:\r
1217\r
1218Returns:\r
1219\r
1220 None\r
1221\r
1222--*/\r
1223{\r
1224\r
1225 EFI_STATUS Status;\r
1226 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
1227 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
1228 PCI_IO_DEVICE *RootBridgeDev;\r
1229 UINT16 MinBus;\r
1230 UINT16 MaxBus;\r
1231 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
1232\r
1233 MinBus = 0;\r
1234 MaxBus = PCI_MAX_BUS;\r
1235 Descriptors = NULL;\r
1236\r
1237 //\r
1238 // If this host bridge has been already enumerated, then return successfully\r
1239 //\r
1240 if (RootBridgeExisted (Controller)) {\r
1241 return EFI_SUCCESS;\r
1242 }\r
1243\r
1244 //\r
1245 // Open the IO Abstraction(s) needed to perform the supported test\r
1246 //\r
1247 Status = gBS->OpenProtocol (\r
1248 Controller , \r
1249 &gEfiDevicePathProtocolGuid, \r
1250 (VOID **)&ParentDevicePath,\r
1251 gPciBusDriverBinding.DriverBindingHandle, \r
1252 Controller, \r
1253 EFI_OPEN_PROTOCOL_BY_DRIVER\r
1254 );\r
1255 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
1256 return Status;\r
1257 }\r
1258\r
1259 //\r
1260 // Open pci root bridge io protocol\r
1261 //\r
1262 Status = gBS->OpenProtocol (\r
1263 Controller,\r
1264 &gEfiPciRootBridgeIoProtocolGuid,\r
1265 (VOID **) &PciRootBridgeIo,\r
1266 gPciBusDriverBinding.DriverBindingHandle,\r
1267 Controller,\r
1268 EFI_OPEN_PROTOCOL_BY_DRIVER\r
1269 );\r
1270 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
1271 return Status;\r
1272 }\r
1273\r
1274 //\r
1275 // Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge \r
1276 //\r
1277 Status = PciRomLoadEfiDriversFromOptionRomTable (&gPciBusDriverBinding, PciRootBridgeIo);\r
1278\r
1279 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
1280\r
1281 if (EFI_ERROR (Status)) {\r
1282 return Status;\r
1283 }\r
1284\r
a5f2a205 1285 while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {\r
10590588 1286\r
1287 //\r
1288 // Create a device node for root bridge device with a NULL host bridge controller handle\r
1289 //\r
1290 RootBridgeDev = CreateRootBridge (Controller);\r
1291\r
1292 //\r
1293 // Record the root bridge device path\r
1294 //\r
1295 RootBridgeDev->DevicePath = ParentDevicePath;\r
1296\r
1297 //\r
1298 // Record the root bridge io protocol\r
1299 //\r
1300 RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
1301\r
1302 Status = PciPciDeviceInfoCollector (\r
1303 RootBridgeDev,\r
1304 (UINT8) MinBus\r
1305 );\r
1306\r
1307 if (!EFI_ERROR (Status)) {\r
1308\r
1309 //\r
1310 // If successfully, insert the node into device pool\r
1311 //\r
1312 InsertRootBridge (RootBridgeDev);\r
1313 } else {\r
1314\r
1315 //\r
1316 // If unsuccessly, destroy the entire node\r
1317 //\r
1318 DestroyRootBridge (RootBridgeDev);\r
1319 }\r
1320\r
1321 Descriptors++;\r
1322 }\r
1323\r
1324 return EFI_SUCCESS;\r
1325}\r
1326\r
1327EFI_STATUS\r
1328PciGetBusRange (\r
a5f2a205 1329 IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,\r
10590588 1330 OUT UINT16 *MinBus,\r
1331 OUT UINT16 *MaxBus,\r
1332 OUT UINT16 *BusRange\r
1333 )\r
1334/*++\r
1335\r
1336Routine Description:\r
1337\r
1338 Get the bus range.\r
1339\r
1340Arguments:\r
1341\r
1342 Descriptors - A pointer to the address space descriptor.\r
1343 MinBus - The min bus.\r
1344 MaxBus - The max bus.\r
1345 BusRange - The bus range.\r
1346 \r
1347Returns:\r
1348 \r
1349 Status Code.\r
1350\r
1351--*/\r
1352{\r
1353\r
a5f2a205 1354 while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
1355 if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {\r
10590588 1356 if (MinBus != NULL) {\r
a5f2a205 1357 *MinBus = (UINT16)(*Descriptors)->AddrRangeMin;\r
10590588 1358 }\r
1359\r
1360 if (MaxBus != NULL) {\r
a5f2a205 1361 *MaxBus = (UINT16)(*Descriptors)->AddrRangeMax;\r
10590588 1362 }\r
1363\r
1364 if (BusRange != NULL) {\r
a5f2a205 1365 *BusRange = (UINT16)(*Descriptors)->AddrLen;\r
10590588 1366 }\r
1367 return EFI_SUCCESS;\r
1368 }\r
1369\r
a5f2a205 1370 (*Descriptors)++;\r
10590588 1371 }\r
1372\r
1373 return EFI_NOT_FOUND;\r
1374}\r
1375\r