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