]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/PciBusNoEnumerationDxe/PciEnumeratorSupport.c
Update the copyright notice format
[mirror_edk2.git] / DuetPkg / PciBusNoEnumerationDxe / PciEnumeratorSupport.c
CommitLineData
10590588 1/*++\r
2\r
b1f700a8
HT
3Copyright (c) 2005 - 2009, Intel Corporation. All rights reserved.<BR>\r
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
9c83c97a 867 //UINT64 BarValue64;\r
10590588 868 UINT32 OriginalValue;\r
869 UINT32 Mask;\r
870 UINT32 Data;\r
871 UINT8 Index;\r
872 EFI_STATUS Status;\r
873\r
874 OriginalValue = 0;\r
875 Value = 0;\r
9c83c97a 876 //BarValue64 = 0;\r
10590588 877\r
878 Status = BarExisted (\r
879 PciIoDevice,\r
880 Offset,\r
881 &Value,\r
882 &OriginalValue\r
883 );\r
884\r
885 if (EFI_ERROR (Status)) {\r
886 PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
887 PciIoDevice->PciBar[BarIndex].Length = 0;\r
888 PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
889\r
890 //\r
891 // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway\r
892 //\r
893 PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
894 return Offset + 4;\r
895 }\r
896\r
897 PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
898 if (Value & 0x01) {\r
899 //\r
900 // Device I/Os\r
901 //\r
902 Mask = 0xfffffffc;\r
903\r
904 if (Value & 0xFFFF0000) {\r
905 //\r
906 // It is a IO32 bar\r
907 //\r
908 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32;\r
909 PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1);\r
910 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
911\r
912 } else {\r
913 //\r
914 // It is a IO16 bar\r
915 //\r
916 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16;\r
917 PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1);\r
918 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
919\r
920 }\r
921 //\r
922 // Workaround. Some platforms inplement IO bar with 0 length\r
923 // Need to treat it as no-bar\r
924 //\r
925 if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
9c83c97a 926 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
10590588 927 }\r
928\r
929 PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE;\r
930 PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
931\r
932 } else {\r
933\r
934 Mask = 0xfffffff0;\r
935\r
936 PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
937\r
938 switch (Value & 0x07) {\r
939\r
940 //\r
941 //memory space; anywhere in 32 bit address space\r
942 //\r
943 case 0x00:\r
944 if (Value & 0x08) {\r
945 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
946 } else {\r
947 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
948 }\r
949\r
950 PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
951 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
952\r
953 break;\r
954\r
955 //\r
956 // memory space; anywhere in 64 bit address space\r
957 //\r
958 case 0x04:\r
959 if (Value & 0x08) {\r
960 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;\r
961 } else {\r
962 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;\r
963 }\r
964\r
965 //\r
966 // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
967 // is regarded as an extension for the first bar. As a result\r
968 // the sizing will be conducted on combined 64 bit value\r
969 // Here just store the masked first 32bit value for future size\r
970 // calculation\r
971 //\r
972 PciIoDevice->PciBar[BarIndex].Length = Value & Mask;\r
973 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
974\r
975 //\r
976 // Increment the offset to point to next DWORD\r
977 //\r
978 Offset += 4;\r
979\r
980 Status = BarExisted (\r
981 PciIoDevice,\r
982 Offset,\r
983 &Value,\r
984 &OriginalValue\r
985 );\r
986\r
987 if (EFI_ERROR (Status)) {\r
988 return Offset + 4;\r
989 }\r
990\r
991 //\r
992 // Fix the length to support some spefic 64 bit BAR\r
993 //\r
994 Data = Value;\r
995 Index = 0;\r
996 for (Data = Value; Data != 0; Data >>= 1) {\r
b29a823d 997 Index ++;\r
10590588 998 }\r
999 Value |= ((UINT32)(-1) << Index); \r
1000\r
1001 //\r
1002 // Calculate the size of 64bit bar\r
1003 //\r
1004 PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
1005\r
1006 PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
1007 PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
1008 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
1009\r
1010 break;\r
1011\r
1012 //\r
1013 // reserved\r
1014 //\r
1015 default:\r
1016 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
1017 PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
1018 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
1019\r
1020 break;\r
1021 }\r
1022 }\r
1023 \r
1024 //\r
1025 // Check the length again so as to keep compatible with some special bars\r
1026 //\r
1027 if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
1028 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
1029 PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
1030 PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
1031 }\r
1032 \r
1033 //\r
1034 // Increment number of bar\r
1035 //\r
1036 return Offset + 4;\r
1037}\r
1038\r
1039EFI_STATUS\r
1040InitializePPB (\r
1041 IN PCI_IO_DEVICE *PciIoDevice\r
1042 )\r
1043/*++\r
1044\r
1045Routine Description:\r
1046\r
1047Arguments:\r
1048\r
1049Returns:\r
1050\r
1051 None\r
1052\r
1053--*/\r
1054{\r
1055 EFI_PCI_IO_PROTOCOL *PciIo;\r
1056\r
1057 PciIo = &(PciIoDevice->PciIo);\r
1058\r
1059 //\r
1060 // Put all the resource apertures including IO16\r
1061 // Io32, pMem32, pMem64 to quiescent state\r
1062 // Resource base all ones, Resource limit all zeros\r
1063 //\r
1064 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
1065 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero);\r
1066\r
1067 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne);\r
1068 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero);\r
1069\r
1070 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne);\r
1071 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero);\r
1072\r
1073 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne);\r
1074 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero);\r
1075\r
1076 //\r
1077 // don't support use io32 as for now\r
1078 //\r
1079 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne);\r
1080 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero);\r
1081\r
1082 return EFI_SUCCESS;\r
1083}\r
1084\r
1085EFI_STATUS\r
1086InitializeP2C (\r
1087 IN PCI_IO_DEVICE *PciIoDevice\r
1088 )\r
1089/*++\r
1090\r
1091Routine Description:\r
1092\r
1093Arguments:\r
1094\r
1095Returns:\r
1096\r
1097 None\r
1098\r
1099--*/\r
1100{\r
1101 EFI_PCI_IO_PROTOCOL *PciIo;\r
1102\r
1103 PciIo = &(PciIoDevice->PciIo);\r
1104\r
1105 //\r
1106 // Put all the resource apertures including IO16\r
1107 // Io32, pMem32, pMem64 to quiescent state(\r
1108 // Resource base all ones, Resource limit all zeros\r
1109 //\r
1110 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne);\r
1111 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero);\r
1112\r
1113 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne);\r
1114 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero);\r
1115\r
1116 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne);\r
1117 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero);\r
1118\r
1119 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne);\r
1120 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero);\r
1121\r
1122 return EFI_SUCCESS;\r
1123}\r
1124\r
1125PCI_IO_DEVICE *\r
1126CreatePciIoDevice (\r
1127 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
1128 IN PCI_TYPE00 *Pci,\r
1129 UINT8 Bus,\r
1130 UINT8 Device,\r
1131 UINT8 Func\r
1132 )\r
1133/*++\r
1134\r
1135Routine Description:\r
1136\r
1137Arguments:\r
1138\r
1139Returns:\r
1140\r
1141 None\r
1142\r
1143--*/\r
1144{\r
1145\r
1146 EFI_STATUS Status;\r
1147 PCI_IO_DEVICE *PciIoDevice;\r
1148\r
1149 PciIoDevice = NULL;\r
1150\r
1151 Status = gBS->AllocatePool (\r
1152 EfiBootServicesData,\r
1153 sizeof (PCI_IO_DEVICE),\r
1154 (VOID **) &PciIoDevice\r
1155 );\r
1156\r
1157 if (EFI_ERROR (Status)) {\r
1158 return NULL;\r
1159 }\r
1160\r
1161 ZeroMem (PciIoDevice, sizeof (PCI_IO_DEVICE));\r
1162\r
1163 PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE;\r
1164 PciIoDevice->Handle = NULL;\r
1165 PciIoDevice->PciRootBridgeIo = PciRootBridgeIo;\r
1166 PciIoDevice->DevicePath = NULL;\r
1167 PciIoDevice->BusNumber = Bus;\r
1168 PciIoDevice->DeviceNumber = Device;\r
1169 PciIoDevice->FunctionNumber = Func;\r
1170 PciIoDevice->Decodes = 0;\r
1171 if (gFullEnumeration) {\r
1172 PciIoDevice->Allocated = FALSE;\r
1173 } else {\r
1174 PciIoDevice->Allocated = TRUE;\r
1175 }\r
1176\r
1177 PciIoDevice->Attributes = 0;\r
1178 PciIoDevice->Supports = 0;\r
1179 PciIoDevice->BusOverride = FALSE;\r
1180 PciIoDevice->IsPciExp = FALSE;\r
1181\r
1182 CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01));\r
1183\r
1184 //\r
1185 // Initialize the PCI I/O instance structure\r
1186 //\r
1187\r
1188 Status = InitializePciIoInstance (PciIoDevice);\r
1189 Status = InitializePciDriverOverrideInstance (PciIoDevice);\r
1190\r
1191 if (EFI_ERROR (Status)) {\r
1192 gBS->FreePool (PciIoDevice);\r
1193 return NULL;\r
1194 }\r
1195\r
1196 //\r
1197 // Initialize the reserved resource list\r
1198 //\r
1199 InitializeListHead (&PciIoDevice->ReservedResourceList);\r
1200\r
1201 //\r
1202 // Initialize the driver list\r
1203 //\r
1204 InitializeListHead (&PciIoDevice->OptionRomDriverList);\r
1205\r
1206 //\r
1207 // Initialize the child list\r
1208 //\r
1209 InitializeListHead (&PciIoDevice->ChildList);\r
1210\r
1211 return PciIoDevice;\r
1212}\r
1213\r
1214EFI_STATUS\r
1215PciEnumeratorLight (\r
1216 IN EFI_HANDLE Controller\r
1217 )\r
1218/*++\r
1219\r
1220Routine Description:\r
1221\r
1222 This routine is used to enumerate entire pci bus system \r
1223 in a given platform\r
1224\r
1225Arguments:\r
1226\r
1227Returns:\r
1228\r
1229 None\r
1230\r
1231--*/\r
1232{\r
1233\r
1234 EFI_STATUS Status;\r
1235 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
1236 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
1237 PCI_IO_DEVICE *RootBridgeDev;\r
1238 UINT16 MinBus;\r
1239 UINT16 MaxBus;\r
1240 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
1241\r
1242 MinBus = 0;\r
1243 MaxBus = PCI_MAX_BUS;\r
1244 Descriptors = NULL;\r
1245\r
1246 //\r
1247 // If this host bridge has been already enumerated, then return successfully\r
1248 //\r
1249 if (RootBridgeExisted (Controller)) {\r
1250 return EFI_SUCCESS;\r
1251 }\r
1252\r
1253 //\r
1254 // Open the IO Abstraction(s) needed to perform the supported test\r
1255 //\r
1256 Status = gBS->OpenProtocol (\r
1257 Controller , \r
1258 &gEfiDevicePathProtocolGuid, \r
1259 (VOID **)&ParentDevicePath,\r
1260 gPciBusDriverBinding.DriverBindingHandle, \r
1261 Controller, \r
1262 EFI_OPEN_PROTOCOL_BY_DRIVER\r
1263 );\r
1264 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
1265 return Status;\r
1266 }\r
1267\r
1268 //\r
1269 // Open pci root bridge io protocol\r
1270 //\r
1271 Status = gBS->OpenProtocol (\r
1272 Controller,\r
1273 &gEfiPciRootBridgeIoProtocolGuid,\r
1274 (VOID **) &PciRootBridgeIo,\r
1275 gPciBusDriverBinding.DriverBindingHandle,\r
1276 Controller,\r
1277 EFI_OPEN_PROTOCOL_BY_DRIVER\r
1278 );\r
1279 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
1280 return Status;\r
1281 }\r
1282\r
1283 //\r
1284 // Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge \r
1285 //\r
1286 Status = PciRomLoadEfiDriversFromOptionRomTable (&gPciBusDriverBinding, PciRootBridgeIo);\r
1287\r
1288 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
1289\r
1290 if (EFI_ERROR (Status)) {\r
1291 return Status;\r
1292 }\r
1293\r
a5f2a205 1294 while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {\r
10590588 1295\r
1296 //\r
1297 // Create a device node for root bridge device with a NULL host bridge controller handle\r
1298 //\r
1299 RootBridgeDev = CreateRootBridge (Controller);\r
1300\r
1301 //\r
1302 // Record the root bridge device path\r
1303 //\r
1304 RootBridgeDev->DevicePath = ParentDevicePath;\r
1305\r
1306 //\r
1307 // Record the root bridge io protocol\r
1308 //\r
1309 RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
1310\r
1311 Status = PciPciDeviceInfoCollector (\r
1312 RootBridgeDev,\r
1313 (UINT8) MinBus\r
1314 );\r
1315\r
1316 if (!EFI_ERROR (Status)) {\r
1317\r
1318 //\r
1319 // If successfully, insert the node into device pool\r
1320 //\r
1321 InsertRootBridge (RootBridgeDev);\r
1322 } else {\r
1323\r
1324 //\r
1325 // If unsuccessly, destroy the entire node\r
1326 //\r
1327 DestroyRootBridge (RootBridgeDev);\r
1328 }\r
1329\r
1330 Descriptors++;\r
1331 }\r
1332\r
1333 return EFI_SUCCESS;\r
1334}\r
1335\r
1336EFI_STATUS\r
1337PciGetBusRange (\r
a5f2a205 1338 IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors,\r
10590588 1339 OUT UINT16 *MinBus,\r
1340 OUT UINT16 *MaxBus,\r
1341 OUT UINT16 *BusRange\r
1342 )\r
1343/*++\r
1344\r
1345Routine Description:\r
1346\r
1347 Get the bus range.\r
1348\r
1349Arguments:\r
1350\r
1351 Descriptors - A pointer to the address space descriptor.\r
1352 MinBus - The min bus.\r
1353 MaxBus - The max bus.\r
1354 BusRange - The bus range.\r
1355 \r
1356Returns:\r
1357 \r
1358 Status Code.\r
1359\r
1360--*/\r
1361{\r
1362\r
a5f2a205 1363 while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
1364 if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {\r
10590588 1365 if (MinBus != NULL) {\r
a5f2a205 1366 *MinBus = (UINT16)(*Descriptors)->AddrRangeMin;\r
10590588 1367 }\r
1368\r
1369 if (MaxBus != NULL) {\r
a5f2a205 1370 *MaxBus = (UINT16)(*Descriptors)->AddrRangeMax;\r
10590588 1371 }\r
1372\r
1373 if (BusRange != NULL) {\r
a5f2a205 1374 *BusRange = (UINT16)(*Descriptors)->AddrLen;\r
10590588 1375 }\r
1376 return EFI_SUCCESS;\r
1377 }\r
1378\r
a5f2a205 1379 (*Descriptors)++;\r
10590588 1380 }\r
1381\r
1382 return EFI_NOT_FOUND;\r
1383}\r
1384\r