]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/PciBusNoEnumerationDxe/PciEnumeratorSupport.c
CryptoPkg: RuntimeCryptLib: support realloc(NULL, size)
[mirror_edk2.git] / DuetPkg / PciBusNoEnumerationDxe / PciEnumeratorSupport.c
CommitLineData
10590588 1/*++\r
2\r
5ce5ea60 3Copyright (c) 2005 - 2014, 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
260 // Deep enumerate the next level bus\r
261 //\r
262 Status = PciPciDeviceInfoCollector (\r
263 PciIoDevice,\r
264 (UINT8) (SecBus)\r
265 );\r
266\r
267 }\r
268\r
269 if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
270\r
271 //\r
272 // Skip sub functions, this is not a multi function device\r
273 //\r
274 Func = PCI_MAX_FUNC;\r
275 }\r
276 }\r
277\r
278 }\r
279 }\r
280\r
281 return EFI_SUCCESS;\r
282}\r
283\r
284EFI_STATUS\r
285PciSearchDevice (\r
286 IN PCI_IO_DEVICE *Bridge,\r
287 IN PCI_TYPE00 *Pci,\r
288 IN UINT8 Bus,\r
289 IN UINT8 Device,\r
290 IN UINT8 Func,\r
291 OUT PCI_IO_DEVICE **PciDevice\r
292 )\r
293/*++\r
294\r
295Routine Description:\r
296\r
297 Search required device.\r
298\r
299Arguments:\r
300\r
301 Bridge - A pointer to the PCI_IO_DEVICE.\r
302 Pci - A pointer to the PCI_TYPE00.\r
303 Bus - Bus number.\r
304 Device - Device number.\r
305 Func - Function number.\r
306 PciDevice - The Required pci device.\r
307\r
308Returns:\r
309\r
310 Status code.\r
311\r
312--*/\r
313{\r
314 PCI_IO_DEVICE *PciIoDevice;\r
315\r
316 PciIoDevice = NULL;\r
317\r
318 if (!IS_PCI_BRIDGE (Pci)) {\r
319\r
320 if (IS_CARDBUS_BRIDGE (Pci)) {\r
321 PciIoDevice = GatherP2CInfo (\r
322 Bridge->PciRootBridgeIo,\r
323 Pci,\r
324 Bus,\r
325 Device,\r
326 Func\r
327 );\r
328 if ((PciIoDevice != NULL) && (gFullEnumeration == TRUE)) {\r
329 InitializeP2C (PciIoDevice);\r
330 }\r
331 } else {\r
332\r
333 //\r
334 // Create private data for Pci Device\r
335 //\r
336 PciIoDevice = GatherDeviceInfo (\r
337 Bridge->PciRootBridgeIo,\r
338 Pci,\r
339 Bus,\r
340 Device,\r
341 Func\r
342 );\r
343\r
344 }\r
345\r
346 } else {\r
347\r
348 //\r
349 // Create private data for PPB\r
350 //\r
351 PciIoDevice = GatherPPBInfo (\r
352 Bridge->PciRootBridgeIo,\r
353 Pci,\r
354 Bus,\r
355 Device,\r
356 Func\r
357 );\r
358\r
359 //\r
360 // Special initialization for PPB including making the PPB quiet\r
361 //\r
362 if ((PciIoDevice != NULL) && (gFullEnumeration == TRUE)) {\r
363 InitializePPB (PciIoDevice);\r
364 }\r
365 }\r
366\r
367 if (!PciIoDevice) {\r
368 return EFI_OUT_OF_RESOURCES;\r
369 }\r
370 \r
371 //\r
372 // Create a device path for this PCI device and store it into its private data\r
373 //\r
374 CreatePciDevicePath(\r
375 Bridge->DevicePath,\r
376 PciIoDevice \r
377 );\r
378 \r
379 //\r
380 // Detect this function has option rom\r
381 //\r
382 if (gFullEnumeration) {\r
383\r
384 if (!IS_CARDBUS_BRIDGE (Pci)) {\r
385\r
386 GetOpRomInfo (PciIoDevice);\r
387\r
388 }\r
389\r
390 ResetPowerManagementFeature (PciIoDevice);\r
391 \r
392 } \r
393 else {\r
394 PciRomGetRomResourceFromPciOptionRomTable (\r
395 &gPciBusDriverBinding,\r
396 PciIoDevice->PciRootBridgeIo,\r
397 PciIoDevice\r
398 );\r
399 }\r
400\r
401 \r
402 //\r
403 // Insert it into a global tree for future reference\r
404 //\r
405 InsertPciDevice (Bridge, PciIoDevice);\r
406\r
407 //\r
408 // Determine PCI device attributes\r
409 //\r
410 DetermineDeviceAttribute (PciIoDevice);\r
411\r
412 if (PciDevice != NULL) {\r
413 *PciDevice = PciIoDevice;\r
414 }\r
415\r
416 return EFI_SUCCESS;\r
417}\r
418\r
419PCI_IO_DEVICE *\r
420GatherDeviceInfo (\r
421 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
422 IN PCI_TYPE00 *Pci,\r
423 UINT8 Bus,\r
424 UINT8 Device,\r
425 UINT8 Func\r
426 )\r
427/*++\r
428\r
429Routine Description:\r
430\r
431Arguments:\r
432\r
433Returns:\r
434\r
435 None\r
436\r
437--*/\r
438{\r
439 UINTN Offset;\r
440 UINTN BarIndex;\r
441 PCI_IO_DEVICE *PciIoDevice;\r
442\r
443 PciIoDevice = CreatePciIoDevice (\r
444 PciRootBridgeIo,\r
445 Pci,\r
446 Bus,\r
447 Device,\r
448 Func\r
449 );\r
450\r
451 if (!PciIoDevice) {\r
452 return NULL;\r
453 }\r
454\r
455 //\r
456 // If it is a full enumeration, disconnect the device in advance\r
457 //\r
458 if (gFullEnumeration) {\r
459\r
460 PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
461\r
462 }\r
463\r
464 //\r
465 // Start to parse the bars\r
466 //\r
467 for (Offset = 0x10, BarIndex = 0; Offset <= 0x24; BarIndex++) {\r
468 Offset = PciParseBar (PciIoDevice, Offset, BarIndex);\r
469 }\r
470\r
471 return PciIoDevice;\r
472}\r
473\r
474PCI_IO_DEVICE *\r
475GatherPPBInfo (\r
476 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
477 IN PCI_TYPE00 *Pci,\r
478 UINT8 Bus,\r
479 UINT8 Device,\r
480 UINT8 Func\r
481 )\r
482/*++\r
483\r
484Routine Description:\r
485\r
486Arguments:\r
487\r
488Returns:\r
489\r
490 None\r
491\r
492--*/\r
493{\r
494 PCI_IO_DEVICE *PciIoDevice;\r
495 EFI_STATUS Status;\r
7e7e7fec 496 UINT8 Value;\r
10590588 497 EFI_PCI_IO_PROTOCOL *PciIo;\r
498 UINT8 Temp;\r
499\r
500 PciIoDevice = CreatePciIoDevice (\r
501 PciRootBridgeIo,\r
502 Pci,\r
503 Bus,\r
504 Device,\r
505 Func\r
506 );\r
507\r
508 if (!PciIoDevice) {\r
509 return NULL;\r
510 }\r
511 \r
512 if (gFullEnumeration) {\r
513 PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
514\r
515 //\r
516 // Initalize the bridge control register\r
517 //\r
518 PciDisableBridgeControlRegister (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED);\r
519 }\r
520\r
521 PciIo = &PciIoDevice->PciIo;\r
522\r
523 //\r
524 // Test whether it support 32 decode or not\r
525 //\r
526 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
527 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne);\r
528 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value);\r
529 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp);\r
530\r
531 if (Value) {\r
532 if (Value & 0x01) {\r
533 PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
534 } else {\r
535 PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED;\r
536 }\r
537 }\r
538\r
539 Status = BarExisted (\r
540 PciIoDevice,\r
541 0x24,\r
542 NULL,\r
543 NULL\r
544 );\r
545\r
546 //\r
547 // test if it supports 64 memory or not\r
548 //\r
549 if (!EFI_ERROR (Status)) {\r
550\r
551 Status = BarExisted (\r
552 PciIoDevice,\r
553 0x28,\r
554 NULL,\r
555 NULL\r
556 );\r
557\r
558 if (!EFI_ERROR (Status)) {\r
559 PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
560 PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;\r
561 } else {\r
562 PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
563 }\r
564 }\r
565\r
566 //\r
567 // Memory 32 code is required for ppb\r
568 //\r
569 PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED;\r
570\r
571 return PciIoDevice;\r
572}\r
573\r
574PCI_IO_DEVICE *\r
575GatherP2CInfo (\r
576 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
577 IN PCI_TYPE00 *Pci,\r
578 UINT8 Bus,\r
579 UINT8 Device,\r
580 UINT8 Func\r
581 )\r
582/*++\r
583\r
584Routine Description:\r
585\r
586Arguments:\r
587\r
588Returns:\r
589\r
590 None\r
591\r
592--*/\r
593{\r
594 PCI_IO_DEVICE *PciIoDevice;\r
595 \r
596 PciIoDevice = CreatePciIoDevice (\r
597 PciRootBridgeIo,\r
598 Pci,\r
599 Bus,\r
600 Device,\r
601 Func\r
602 );\r
603\r
604 if (!PciIoDevice) {\r
605 return NULL;\r
606 }\r
607\r
608 if (gFullEnumeration) {\r
609 PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
610\r
611 //\r
612 // Initalize the bridge control register\r
613 //\r
614 PciDisableBridgeControlRegister (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED);\r
615\r
616 }\r
617 //\r
618 // P2C only has one bar that is in 0x10\r
619 //\r
620 PciParseBar(PciIoDevice, 0x10, 0);\r
621 \r
622 PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED |\r
623 EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |\r
624 EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
625\r
626 return PciIoDevice;\r
627}\r
628\r
629EFI_DEVICE_PATH_PROTOCOL *\r
630CreatePciDevicePath (\r
631 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
632 IN PCI_IO_DEVICE *PciIoDevice\r
633 )\r
634/*++\r
635\r
636Routine Description:\r
637\r
638Arguments:\r
639\r
640Returns:\r
641\r
642 None\r
643\r
644--*/\r
645{\r
646\r
647 PCI_DEVICE_PATH PciNode;\r
648\r
649 //\r
650 // Create PCI device path\r
651 //\r
652 PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
653 PciNode.Header.SubType = HW_PCI_DP;\r
654 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
655\r
656 PciNode.Device = PciIoDevice->DeviceNumber;\r
657 PciNode.Function = PciIoDevice->FunctionNumber;\r
658 PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header);\r
659\r
660 return PciIoDevice->DevicePath;\r
661}\r
662\r
663EFI_STATUS\r
664BarExisted (\r
665 IN PCI_IO_DEVICE *PciIoDevice,\r
666 IN UINTN Offset,\r
667 OUT UINT32 *BarLengthValue,\r
668 OUT UINT32 *OriginalBarValue\r
669 )\r
670/*++\r
671\r
672Routine Description:\r
673\r
674 Check the bar is existed or not.\r
675\r
676Arguments:\r
677\r
678 PciIoDevice - A pointer to the PCI_IO_DEVICE.\r
679 Offset - The offset.\r
680 BarLengthValue - The bar length value.\r
681 OriginalBarValue - The original bar value.\r
682\r
683Returns:\r
684\r
685 EFI_NOT_FOUND - The bar don't exist.\r
686 EFI_SUCCESS - The bar exist.\r
687\r
688--*/\r
689{\r
690 EFI_PCI_IO_PROTOCOL *PciIo;\r
691 UINT32 OriginalValue;\r
692 UINT32 Value;\r
693 EFI_TPL OldTpl;\r
694\r
695 PciIo = &PciIoDevice->PciIo;\r
696\r
697 //\r
698 // Preserve the original value\r
699 //\r
700\r
701 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
702\r
703 //\r
704 // Raise TPL to high level to disable timer interrupt while the BAR is probed\r
705 //\r
706 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
707\r
708 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);\r
709 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);\r
710\r
711 //\r
712 // Write back the original value\r
713 //\r
714 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
715\r
716 //\r
717 // Restore TPL to its original level\r
718 //\r
719 gBS->RestoreTPL (OldTpl);\r
720\r
721 if (BarLengthValue != NULL) {\r
722 *BarLengthValue = Value;\r
723 }\r
724\r
725 if (OriginalBarValue != NULL) {\r
726 *OriginalBarValue = OriginalValue;\r
727 }\r
728\r
729 if (Value == 0) {\r
730 return EFI_NOT_FOUND;\r
731 } else {\r
732 return EFI_SUCCESS;\r
733 }\r
734}\r
735\r
736\r
737EFI_STATUS\r
738DetermineDeviceAttribute (\r
739 IN PCI_IO_DEVICE *PciIoDevice\r
740 )\r
741/*++\r
742\r
743Routine Description:\r
744 \r
745 Determine the related attributes of all devices under a Root Bridge\r
746\r
747Arguments:\r
748\r
749Returns:\r
750\r
751 None\r
752\r
753--*/\r
754{\r
755 UINT16 Command;\r
756 UINT16 BridgeControl;\r
757\r
758 Command = 0;\r
759\r
760 PciIoDevice->Supports |= EFI_PCI_DEVICE_ENABLE;\r
761 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
762\r
763 if (IS_PCI_VGA (&(PciIoDevice->Pci))){\r
764\r
765 //\r
766 // If the device is VGA, VGA related Attributes are supported\r
767 //\r
768 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO ;\r
769 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY ;\r
770 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_IO ;\r
771 }\r
772\r
773 if(IS_ISA_BRIDGE(&(PciIoDevice->Pci)) || IS_INTEL_ISA_BRIDGE(&(PciIoDevice->Pci))) {\r
774 //\r
775 // If the devie is a ISA Bridge, set the two attributes\r
776 //\r
777 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
778 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
779 }\r
780\r
781 if (IS_PCI_GFX (&(PciIoDevice->Pci))) {\r
782\r
783 //\r
784 // If the device is GFX, then only set the EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO\r
785 // attribute\r
786 //\r
787 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO ;\r
788 }\r
789\r
790\r
791 //\r
792 // If the device is IDE, IDE related attributes are supported\r
793 //\r
794 if (IS_PCI_IDE (&(PciIoDevice->Pci))) {\r
795 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO ;\r
796 PciIoDevice->Supports |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO ;\r
797 }\r
798\r
799 PciReadCommandRegister(PciIoDevice, &Command);\r
800\r
801 \r
802 if (Command & EFI_PCI_COMMAND_IO_SPACE) {\r
803 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;\r
804 }\r
805\r
806 if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {\r
807 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY;\r
808 }\r
809\r
810 if (Command & EFI_PCI_COMMAND_BUS_MASTER) {\r
811 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;\r
812 }\r
813\r
814 if (IS_PCI_BRIDGE (&(PciIoDevice->Pci)) || \r
815 IS_CARDBUS_BRIDGE (&(PciIoDevice->Pci))){\r
816\r
817 //\r
818 // If it is a PPB, read the Bridge Control Register to determine\r
819 // the relevant attributes\r
820 //\r
821 BridgeControl = 0;\r
822 PciReadBridgeControlRegister(PciIoDevice, &BridgeControl);\r
823\r
824 //\r
825 // Determine whether the ISA bit is set\r
826 // If ISA Enable on Bridge is set, the PPB\r
827 // will block forwarding 0x100-0x3ff for each 1KB in the \r
828 // first 64KB I/O range.\r
829 //\r
1c8bea11 830 if ((BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) != 0) {\r
10590588 831 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;\r
832 } \r
833\r
834 //\r
835 // Determine whether the VGA bit is set\r
836 // If it is set, the bridge is set to decode VGA memory range\r
837 // and palette register range\r
838 //\r
839 if (IS_PCI_VGA (&(PciIoDevice->Pci)) &&BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) {\r
840 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;\r
841 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
842 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
843 }\r
844\r
845 //\r
846 // if the palette snoop bit is set, then the brige is set to \r
847 // decode palette IO write\r
848 //\r
849 if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {\r
850 PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;\r
851 }\r
852 } \r
853\r
854 return EFI_SUCCESS;\r
855}\r
856\r
857UINTN\r
858PciParseBar (\r
859 IN PCI_IO_DEVICE *PciIoDevice,\r
860 IN UINTN Offset,\r
861 IN UINTN BarIndex\r
862 )\r
863/*++\r
864\r
865Routine Description:\r
866\r
867Arguments:\r
868\r
869Returns:\r
870\r
871 None\r
872\r
873--*/\r
874{\r
875 UINT32 Value;\r
10590588 876 UINT32 OriginalValue;\r
877 UINT32 Mask;\r
10590588 878 EFI_STATUS Status;\r
879\r
880 OriginalValue = 0;\r
881 Value = 0;\r
10590588 882\r
883 Status = BarExisted (\r
884 PciIoDevice,\r
885 Offset,\r
886 &Value,\r
887 &OriginalValue\r
888 );\r
889\r
890 if (EFI_ERROR (Status)) {\r
891 PciIoDevice->PciBar[BarIndex].BaseAddress = 0;\r
892 PciIoDevice->PciBar[BarIndex].Length = 0;\r
893 PciIoDevice->PciBar[BarIndex].Alignment = 0;\r
894\r
895 //\r
896 // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway\r
897 //\r
898 PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
899 return Offset + 4;\r
900 }\r
901\r
902 PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
903 if (Value & 0x01) {\r
904 //\r
905 // Device I/Os\r
906 //\r
907 Mask = 0xfffffffc;\r
908\r
909 if (Value & 0xFFFF0000) {\r
910 //\r
911 // It is a IO32 bar\r
912 //\r
913 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32;\r
914 PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1);\r
915 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
916\r
917 } else {\r
918 //\r
919 // It is a IO16 bar\r
920 //\r
921 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16;\r
922 PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1);\r
923 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
924\r
925 }\r
926 //\r
927 // Workaround. Some platforms inplement IO bar with 0 length\r
928 // Need to treat it as no-bar\r
929 //\r
930 if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
9c83c97a 931 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
10590588 932 }\r
933\r
934 PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE;\r
935 PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
936\r
937 } else {\r
938\r
939 Mask = 0xfffffff0;\r
940\r
941 PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
942\r
943 switch (Value & 0x07) {\r
944\r
945 //\r
946 //memory space; anywhere in 32 bit address space\r
947 //\r
948 case 0x00:\r
949 if (Value & 0x08) {\r
950 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
951 } else {\r
952 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
953 }\r
954\r
955 PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
956 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
957\r
958 break;\r
959\r
960 //\r
961 // memory space; anywhere in 64 bit address space\r
962 //\r
963 case 0x04:\r
964 if (Value & 0x08) {\r
965 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;\r
966 } else {\r
967 PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;\r
968 }\r
969\r
970 //\r
971 // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
972 // is regarded as an extension for the first bar. As a result\r
973 // the sizing will be conducted on combined 64 bit value\r
974 // Here just store the masked first 32bit value for future size\r
975 // calculation\r
976 //\r
977 PciIoDevice->PciBar[BarIndex].Length = Value & Mask;\r
978 PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
979\r
980 //\r
981 // Increment the offset to point to next DWORD\r
982 //\r
983 Offset += 4;\r
984\r
985 Status = BarExisted (\r
986 PciIoDevice,\r
987 Offset,\r
988 &Value,\r
989 &OriginalValue\r
990 );\r
991\r
992 if (EFI_ERROR (Status)) {\r
993 return Offset + 4;\r
994 }\r
995\r
996 //\r
997 // Fix the length to support some spefic 64 bit BAR\r
998 //\r
ae837d36 999 Value |= ((UINT32)(-1) << HighBitSet32 (Value)); \r
10590588 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