2 Scan the entire PCI bus for root bridges to support OVMF on Bhyve and Xen.
4 Copyright (C) 2021, Red Hat, Inc.
5 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <IndustryStandard/Pci.h> // EFI_PCI_COMMAND_IO_SPACE
12 #include <Library/BaseLib.h> // DisableInterrupts()
13 #include <Library/BaseMemoryLib.h> // ZeroMem()
14 #include <Library/DebugLib.h> // ASSERT()
15 #include <Library/MemoryAllocationLib.h> // ReallocatePool()
16 #include <Library/PciHostBridgeLib.h> // PCI_ROOT_BRIDGE_APERTURE
17 #include <Library/PciHostBridgeUtilityLib.h> // PciHostBridgeUtilityInitRoot...
18 #include <Library/PciLib.h> // PciRead32()
19 #include <Protocol/PciRootBridgeIo.h> // EFI_PCI_ATTRIBUTE_ISA_IO
21 #include "PciHostBridge.h"
25 PcatPciRootBridgeBarExisted (
27 OUT UINT32
*OriginalValue
,
32 // Preserve the original value
34 *OriginalValue
= PciRead32 (Address
);
37 // Disable timer interrupt while the BAR is probed
41 PciWrite32 (Address
, 0xFFFFFFFF);
42 *Value
= PciRead32 (Address
);
43 PciWrite32 (Address
, *OriginalValue
);
51 #define PCI_COMMAND_DECODE ((UINT16)(EFI_PCI_COMMAND_IO_SPACE |\
52 EFI_PCI_COMMAND_MEMORY_SPACE))
55 PcatPciRootBridgeDecodingDisable (
61 Value
= PciRead16 (Address
);
62 if (Value
& PCI_COMMAND_DECODE
) {
63 PciWrite16 (Address
, Value
& ~(UINT32
)PCI_COMMAND_DECODE
);
69 PcatPciRootBridgeParseBars (
74 IN UINTN BarOffsetBase
,
75 IN UINTN BarOffsetEnd
,
76 IN PCI_ROOT_BRIDGE_APERTURE
*Io
,
77 IN PCI_ROOT_BRIDGE_APERTURE
*Mem
,
78 IN PCI_ROOT_BRIDGE_APERTURE
*MemAbove4G
84 UINT32 OriginalUpperValue
;
91 PCI_ROOT_BRIDGE_APERTURE
*MemAperture
;
93 // Disable address decoding for every device before OVMF starts sizing it
94 PcatPciRootBridgeDecodingDisable (
95 PCI_LIB_ADDRESS (Bus
, Device
, Function
, PCI_COMMAND_OFFSET
)
98 for (Offset
= BarOffsetBase
; Offset
< BarOffsetEnd
; Offset
+= sizeof (UINT32
)) {
99 PcatPciRootBridgeBarExisted (
100 PCI_LIB_ADDRESS (Bus
, Device
, Function
, Offset
),
108 if ((Value
& BIT0
) == BIT0
) {
112 if (Command
& EFI_PCI_COMMAND_IO_SPACE
) {
114 Base
= OriginalValue
& Mask
;
115 Length
= ((~(Value
& Mask
)) & Mask
) + 0x04;
116 if (!(Value
& 0xFFFF0000)) {
117 Length
&= 0x0000FFFF;
120 Limit
= Base
+ Length
- 1;
123 if (Io
->Base
> Base
) {
127 if (Io
->Limit
< Limit
) {
136 if (Command
& EFI_PCI_COMMAND_MEMORY_SPACE
) {
138 Base
= OriginalValue
& Mask
;
139 Length
= Value
& Mask
;
141 if ((Value
& (BIT1
| BIT2
)) == 0) {
145 Length
= ((~Length
) + 1) & 0xffffffff;
153 PcatPciRootBridgeBarExisted (
154 PCI_LIB_ADDRESS (Bus
, Device
, Function
, Offset
),
159 Base
= Base
| LShiftU64 ((UINT64
)OriginalUpperValue
, 32);
160 Length
= Length
| LShiftU64 ((UINT64
)UpperValue
, 32);
161 Length
= (~Length
) + 1;
163 if (Base
< BASE_4GB
) {
166 MemAperture
= MemAbove4G
;
170 Limit
= Base
+ Length
- 1;
172 if (MemAperture
->Base
> Base
) {
173 MemAperture
->Base
= Base
;
176 if (MemAperture
->Limit
< Limit
) {
177 MemAperture
->Limit
= Limit
;
185 STATIC PCI_ROOT_BRIDGE_APERTURE mNonExistAperture
= { MAX_UINT64
, 0 };
189 UINTN
*NumberOfRootBridges
196 UINTN NumberOfDevices
;
203 PCI_ROOT_BRIDGE_APERTURE Io
, Mem
, MemAbove4G
, *MemAperture
;
204 PCI_ROOT_BRIDGE
*RootBridges
;
207 *NumberOfRootBridges
= 0;
211 // After scanning all the PCI devices on the PCI root bridge's primary bus,
212 // update the Primary Bus Number for the next PCI root bridge to be this PCI
213 // root bridge's subordinate bus number + 1.
215 for (PrimaryBus
= 0; PrimaryBus
<= PCI_MAX_BUS
; PrimaryBus
= SubBus
+ 1) {
219 ZeroMem (&Io
, sizeof (Io
));
220 ZeroMem (&Mem
, sizeof (Mem
));
221 ZeroMem (&MemAbove4G
, sizeof (MemAbove4G
));
222 Io
.Base
= Mem
.Base
= MemAbove4G
.Base
= MAX_UINT64
;
224 // Scan all the PCI devices on the primary bus of the PCI root bridge
226 for (Device
= 0, NumberOfDevices
= 0; Device
<= PCI_MAX_DEVICE
; Device
++) {
227 for (Function
= 0; Function
<= PCI_MAX_FUNC
; Function
++) {
229 // Compute the PCI configuration address of the PCI device to probe
231 Address
= PCI_LIB_ADDRESS (PrimaryBus
, Device
, Function
, 0);
234 // Read the Vendor ID from the PCI Configuration Header
236 if (PciRead16 (Address
) == MAX_UINT16
) {
239 // If the PCI Configuration Read fails, or a PCI device does not
240 // exist, then skip this entire PCI device
245 // If PCI function != 0, VendorId == 0xFFFF, we continue to search
253 // Read the entire PCI Configuration Header
255 PciReadBuffer (Address
, sizeof (Pci
), &Pci
);
258 // Increment the number of PCI device found on the primary bus of the
264 // Look for devices with the VGA Palette Snoop enabled in the COMMAND
265 // register of the PCI Config Header
267 if ((Pci
.Hdr
.Command
& EFI_PCI_COMMAND_VGA_PALETTE_SNOOP
) != 0) {
268 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO
;
269 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16
;
277 if (IS_PCI_BRIDGE (&Pci
)) {
279 // Get the Bus range that the PPB is decoding
281 if (Pci
.Bridge
.SubordinateBus
> SubBus
) {
283 // If the subordinate bus number of the PCI-PCI bridge is greater
284 // than the PCI root bridge's current subordinate bus number,
285 // then update the PCI root bridge's subordinate bus number
287 SubBus
= Pci
.Bridge
.SubordinateBus
;
291 // Get the I/O range that the PPB is decoding
293 Value
= Pci
.Bridge
.IoBase
& 0x0f;
294 Base
= ((UINT32
)Pci
.Bridge
.IoBase
& 0xf0) << 8;
295 Limit
= (((UINT32
)Pci
.Bridge
.IoLimit
& 0xf0) << 8) | 0x0fff;
297 Base
|= ((UINT32
)Pci
.Bridge
.IoBaseUpper16
<< 16);
298 Limit
|= ((UINT32
)Pci
.Bridge
.IoLimitUpper16
<< 16);
302 if (Io
.Base
> Base
) {
306 if (Io
.Limit
< Limit
) {
312 // Get the Memory range that the PPB is decoding
314 Base
= ((UINT32
)Pci
.Bridge
.MemoryBase
& 0xfff0) << 16;
315 Limit
= (((UINT32
)Pci
.Bridge
.MemoryLimit
& 0xfff0) << 16) | 0xfffff;
317 if (Mem
.Base
> Base
) {
321 if (Mem
.Limit
< Limit
) {
327 // Get the Prefetchable Memory range that the PPB is decoding
328 // and merge it into Memory range
330 Value
= Pci
.Bridge
.PrefetchableMemoryBase
& 0x0f;
331 Base
= ((UINT32
)Pci
.Bridge
.PrefetchableMemoryBase
& 0xfff0) << 16;
332 Limit
= (((UINT32
)Pci
.Bridge
.PrefetchableMemoryLimit
& 0xfff0)
336 Base
|= LShiftU64 (Pci
.Bridge
.PrefetchableBaseUpper32
, 32);
337 Limit
|= LShiftU64 (Pci
.Bridge
.PrefetchableLimitUpper32
, 32);
338 MemAperture
= &MemAbove4G
;
342 if (MemAperture
->Base
> Base
) {
343 MemAperture
->Base
= Base
;
346 if (MemAperture
->Limit
< Limit
) {
347 MemAperture
->Limit
= Limit
;
352 // Look at the PPB Configuration for legacy decoding attributes
354 if ((Pci
.Bridge
.BridgeControl
& EFI_PCI_BRIDGE_CONTROL_ISA
)
355 == EFI_PCI_BRIDGE_CONTROL_ISA
)
357 Attributes
|= EFI_PCI_ATTRIBUTE_ISA_IO
;
358 Attributes
|= EFI_PCI_ATTRIBUTE_ISA_IO_16
;
359 Attributes
|= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO
;
362 if ((Pci
.Bridge
.BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA
)
363 == EFI_PCI_BRIDGE_CONTROL_VGA
)
365 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO
;
366 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_MEMORY
;
367 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_IO
;
368 if ((Pci
.Bridge
.BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA_16
)
371 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16
;
372 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_IO_16
;
376 BarOffsetEnd
= OFFSET_OF (PCI_TYPE01
, Bridge
.Bar
[2]);
379 // Parse the BARs of the PCI device to get what I/O Ranges, Memory
380 // Ranges, and Prefetchable Memory Ranges the device is decoding
382 if ((Pci
.Hdr
.HeaderType
& HEADER_LAYOUT_CODE
) == HEADER_TYPE_DEVICE
) {
383 BarOffsetEnd
= OFFSET_OF (PCI_TYPE00
, Device
.Bar
[6]);
387 PcatPciRootBridgeParseBars (
392 OFFSET_OF (PCI_TYPE00
, Device
.Bar
),
400 // See if the PCI device is an IDE controller
404 PCI_CLASS_MASS_STORAGE
,
405 PCI_CLASS_MASS_STORAGE_IDE
408 if (Pci
.Hdr
.ClassCode
[0] & 0x80) {
409 Attributes
|= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO
;
410 Attributes
|= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO
;
413 if (Pci
.Hdr
.ClassCode
[0] & 0x01) {
414 Attributes
|= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO
;
417 if (Pci
.Hdr
.ClassCode
[0] & 0x04) {
418 Attributes
|= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO
;
423 // See if the PCI device is a legacy VGA controller or
424 // a standard VGA controller
426 if (IS_CLASS2 (&Pci
, PCI_CLASS_OLD
, PCI_CLASS_OLD_VGA
) ||
427 IS_CLASS2 (&Pci
, PCI_CLASS_DISPLAY
, PCI_CLASS_DISPLAY_VGA
)
430 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO
;
431 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16
;
432 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_MEMORY
;
433 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_IO
;
434 Attributes
|= EFI_PCI_ATTRIBUTE_VGA_IO_16
;
438 // See if the PCI Device is a PCI - ISA or PCI - EISA
439 // or ISA_POSITIVE_DECODE Bridge device
441 if (Pci
.Hdr
.ClassCode
[2] == PCI_CLASS_BRIDGE
) {
442 if ((Pci
.Hdr
.ClassCode
[1] == PCI_CLASS_BRIDGE_ISA
) ||
443 (Pci
.Hdr
.ClassCode
[1] == PCI_CLASS_BRIDGE_EISA
) ||
444 (Pci
.Hdr
.ClassCode
[1] == PCI_CLASS_BRIDGE_ISA_PDECODE
))
446 Attributes
|= EFI_PCI_ATTRIBUTE_ISA_IO
;
447 Attributes
|= EFI_PCI_ATTRIBUTE_ISA_IO_16
;
448 Attributes
|= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO
;
453 // If this device is not a multi function device, then skip the rest
454 // of this PCI device
456 if ((Function
== 0) && !IS_PCI_MULTI_FUNC (&Pci
)) {
463 // If at least one PCI device was found on the primary bus of this PCI
464 // root bridge, then the PCI root bridge exists.
466 if (NumberOfDevices
> 0) {
467 RootBridges
= ReallocatePool (
468 (*NumberOfRootBridges
) * sizeof (PCI_ROOT_BRIDGE
),
469 (*NumberOfRootBridges
+ 1) * sizeof (PCI_ROOT_BRIDGE
),
472 ASSERT (RootBridges
!= NULL
);
473 PciHostBridgeUtilityInitRootBridge (
478 TRUE
/* NoExtendedConfigSpace */,
486 &RootBridges
[*NumberOfRootBridges
]
488 RootBridges
[*NumberOfRootBridges
].ResourceAssigned
= TRUE
;
490 // Increment the index for the next PCI Root Bridge
492 (*NumberOfRootBridges
)++;