]> git.proxmox.com Git - mirror_edk2.git/blob - UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c
bf2d10f4bfcf7b2560fb1d4d32ff8dc63ccdc621
[mirror_edk2.git] / UefiPayloadPkg / Library / PciHostBridgeLib / PciHostBridgeSupport.c
1 /** @file
2 Scan the entire PCI bus for root bridges to support coreboot UEFI payload.
3
4 Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <PiDxe.h>
11 #include <IndustryStandard/Pci.h>
12 #include <Protocol/PciHostBridgeResourceAllocation.h>
13 #include <Protocol/PciRootBridgeIo.h>
14 #include <Library/BaseMemoryLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/MemoryAllocationLib.h>
17 #include <Library/PciHostBridgeLib.h>
18 #include <Library/PciLib.h>
19 #include "PciHostBridge.h"
20
21 /**
22 Adjust the collected PCI resource.
23
24 @param[in] Io IO aperture.
25
26 @param[in] Mem MMIO aperture.
27
28 @param[in] MemAbove4G MMIO aperture above 4G.
29
30 @param[in] PMem Prefetchable MMIO aperture.
31
32 @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
33 **/
34 VOID
35 AdjustRootBridgeResource (
36 IN PCI_ROOT_BRIDGE_APERTURE *Io,
37 IN PCI_ROOT_BRIDGE_APERTURE *Mem,
38 IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
39 IN PCI_ROOT_BRIDGE_APERTURE *PMem,
40 IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G
41 )
42 {
43 UINT64 Mask;
44
45 //
46 // For now try to downgrade everything into MEM32 since
47 // - coreboot does not assign resource above 4GB
48 // - coreboot might allocate interleaved MEM32 and PMEM32 resource
49 // in some cases
50 //
51 if (PMem->Base < Mem->Base) {
52 Mem->Base = PMem->Base;
53 }
54
55 if (PMem->Limit > Mem->Limit) {
56 Mem->Limit = PMem->Limit;
57 }
58
59 PMem->Base = MAX_UINT64;
60 PMem->Limit = 0;
61
62 if (MemAbove4G->Base < 0x100000000ULL) {
63 if (MemAbove4G->Base < Mem->Base) {
64 Mem->Base = MemAbove4G->Base;
65 }
66
67 if (MemAbove4G->Limit > Mem->Limit) {
68 Mem->Limit = MemAbove4G->Limit;
69 }
70
71 MemAbove4G->Base = MAX_UINT64;
72 MemAbove4G->Limit = 0;
73 }
74
75 if (PMemAbove4G->Base < 0x100000000ULL) {
76 if (PMemAbove4G->Base < Mem->Base) {
77 Mem->Base = PMemAbove4G->Base;
78 }
79
80 if (PMemAbove4G->Limit > Mem->Limit) {
81 Mem->Limit = PMemAbove4G->Limit;
82 }
83
84 PMemAbove4G->Base = MAX_UINT64;
85 PMemAbove4G->Limit = 0;
86 }
87
88 //
89 // Align IO resource at 4K boundary
90 //
91 Mask = 0xFFFULL;
92 Io->Limit = ((Io->Limit + Mask) & ~Mask) - 1;
93 if (Io->Base != MAX_UINT64) {
94 Io->Base &= ~Mask;
95 }
96
97 //
98 // Align MEM resource at 1MB boundary
99 //
100 Mask = 0xFFFFFULL;
101 Mem->Limit = ((Mem->Limit + Mask) & ~Mask) - 1;
102 if (Mem->Base != MAX_UINT64) {
103 Mem->Base &= ~Mask;
104 }
105 }
106
107 /**
108 Probe a bar is existed or not.
109
110 @param[in] Address PCI address for the BAR.
111 @param[out] OriginalValue The original bar value returned.
112 @param[out] Value The probed bar value returned.
113 **/
114 STATIC
115 VOID
116 PcatPciRootBridgeBarExisted (
117 IN UINT64 Address,
118 OUT UINT32 *OriginalValue,
119 OUT UINT32 *Value
120 )
121 {
122 UINTN PciAddress;
123
124 PciAddress = (UINTN)Address;
125
126 //
127 // Preserve the original value
128 //
129 *OriginalValue = PciRead32 (PciAddress);
130
131 //
132 // Disable timer interrupt while the BAR is probed
133 //
134 DisableInterrupts ();
135
136 PciWrite32 (PciAddress, 0xFFFFFFFF);
137 *Value = PciRead32 (PciAddress);
138 PciWrite32 (PciAddress, *OriginalValue);
139
140 //
141 // Enable interrupt
142 //
143 EnableInterrupts ();
144 }
145
146 /**
147 Parse PCI bar and collect the assigned PCI resource information.
148
149 @param[in] Command Supported attributes.
150
151 @param[in] Bus PCI bus number.
152
153 @param[in] Device PCI device number.
154
155 @param[in] Function PCI function number.
156
157 @param[in] BarOffsetBase PCI bar start offset.
158
159 @param[in] BarOffsetEnd PCI bar end offset.
160
161 @param[in] Io IO aperture.
162
163 @param[in] Mem MMIO aperture.
164
165 @param[in] MemAbove4G MMIO aperture above 4G.
166
167 @param[in] PMem Prefetchable MMIO aperture.
168
169 @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
170 **/
171 STATIC
172 VOID
173 PcatPciRootBridgeParseBars (
174 IN UINT16 Command,
175 IN UINTN Bus,
176 IN UINTN Device,
177 IN UINTN Function,
178 IN UINTN BarOffsetBase,
179 IN UINTN BarOffsetEnd,
180 IN PCI_ROOT_BRIDGE_APERTURE *Io,
181 IN PCI_ROOT_BRIDGE_APERTURE *Mem,
182 IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
183 IN PCI_ROOT_BRIDGE_APERTURE *PMem,
184 IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G
185
186 )
187 {
188 UINT32 OriginalValue;
189 UINT32 Value;
190 UINT32 OriginalUpperValue;
191 UINT32 UpperValue;
192 UINT64 Mask;
193 UINTN Offset;
194 UINTN LowBit;
195 UINT64 Base;
196 UINT64 Length;
197 UINT64 Limit;
198 PCI_ROOT_BRIDGE_APERTURE *MemAperture;
199
200 for (Offset = BarOffsetBase; Offset < BarOffsetEnd; Offset += sizeof (UINT32)) {
201 PcatPciRootBridgeBarExisted (
202 PCI_LIB_ADDRESS (Bus, Device, Function, Offset),
203 &OriginalValue,
204 &Value
205 );
206 if (Value == 0) {
207 continue;
208 }
209
210 if ((Value & BIT0) == BIT0) {
211 //
212 // IO Bar
213 //
214 if ((Command & EFI_PCI_COMMAND_IO_SPACE) != 0) {
215 Mask = 0xfffffffc;
216 Base = OriginalValue & Mask;
217 Length = ((~(Value & Mask)) & Mask) + 0x04;
218 if (!(Value & 0xFFFF0000)) {
219 Length &= 0x0000FFFF;
220 }
221
222 Limit = Base + Length - 1;
223
224 if ((Base > 0) && (Base < Limit)) {
225 if (Io->Base > Base) {
226 Io->Base = Base;
227 }
228
229 if (Io->Limit < Limit) {
230 Io->Limit = Limit;
231 }
232 }
233 }
234 } else {
235 //
236 // Mem Bar
237 //
238 if ((Command & EFI_PCI_COMMAND_MEMORY_SPACE) != 0) {
239 Mask = 0xfffffff0;
240 Base = OriginalValue & Mask;
241 Length = Value & Mask;
242
243 if ((Value & (BIT1 | BIT2)) == 0) {
244 //
245 // 32bit
246 //
247 Length = ((~Length) + 1) & 0xffffffff;
248
249 if ((Value & BIT3) == BIT3) {
250 MemAperture = PMem;
251 } else {
252 MemAperture = Mem;
253 }
254 } else {
255 //
256 // 64bit
257 //
258 Offset += 4;
259 PcatPciRootBridgeBarExisted (
260 PCI_LIB_ADDRESS (Bus, Device, Function, Offset),
261 &OriginalUpperValue,
262 &UpperValue
263 );
264
265 Base = Base | LShiftU64 ((UINT64)OriginalUpperValue, 32);
266 Length = Length | LShiftU64 ((UINT64)UpperValue, 32);
267 if (Length != 0) {
268 LowBit = LowBitSet64 (Length);
269 Length = LShiftU64 (1ULL, LowBit);
270 }
271
272 if ((Value & BIT3) == BIT3) {
273 MemAperture = PMemAbove4G;
274 } else {
275 MemAperture = MemAbove4G;
276 }
277 }
278
279 Limit = Base + Length - 1;
280 if ((Base > 0) && (Base < Limit)) {
281 if (MemAperture->Base > Base) {
282 MemAperture->Base = Base;
283 }
284
285 if (MemAperture->Limit < Limit) {
286 MemAperture->Limit = Limit;
287 }
288 }
289 }
290 }
291 }
292 }
293
294 /**
295 Scan for all root bridges in platform.
296
297 @param[out] NumberOfRootBridges Number of root bridges detected
298
299 @retval Pointer to the allocated PCI_ROOT_BRIDGE structure array.
300 **/
301 PCI_ROOT_BRIDGE *
302 ScanForRootBridges (
303 OUT UINTN *NumberOfRootBridges
304 )
305 {
306 UINTN PrimaryBus;
307 UINTN SubBus;
308 UINT8 Device;
309 UINT8 Function;
310 UINTN NumberOfDevices;
311 UINTN Address;
312 PCI_TYPE01 Pci;
313 UINT64 Attributes;
314 UINT64 Base;
315 UINT64 Limit;
316 UINT64 Value;
317 PCI_ROOT_BRIDGE_APERTURE Io;
318 PCI_ROOT_BRIDGE_APERTURE Mem;
319 PCI_ROOT_BRIDGE_APERTURE MemAbove4G;
320 PCI_ROOT_BRIDGE_APERTURE PMem;
321 PCI_ROOT_BRIDGE_APERTURE PMemAbove4G;
322 PCI_ROOT_BRIDGE_APERTURE *MemAperture;
323 PCI_ROOT_BRIDGE *RootBridges;
324 UINTN BarOffsetEnd;
325
326 *NumberOfRootBridges = 0;
327 RootBridges = NULL;
328
329 //
330 // After scanning all the PCI devices on the PCI root bridge's primary bus,
331 // update the Primary Bus Number for the next PCI root bridge to be this PCI
332 // root bridge's subordinate bus number + 1.
333 //
334 for (PrimaryBus = 0; PrimaryBus <= PCI_MAX_BUS; PrimaryBus = SubBus + 1) {
335 SubBus = PrimaryBus;
336 Attributes = 0;
337
338 ZeroMem (&Io, sizeof (Io));
339 ZeroMem (&Mem, sizeof (Mem));
340 ZeroMem (&MemAbove4G, sizeof (MemAbove4G));
341 ZeroMem (&PMem, sizeof (PMem));
342 ZeroMem (&PMemAbove4G, sizeof (PMemAbove4G));
343 Io.Base = Mem.Base = MemAbove4G.Base = PMem.Base = PMemAbove4G.Base = MAX_UINT64;
344 //
345 // Scan all the PCI devices on the primary bus of the PCI root bridge
346 //
347 for (Device = 0, NumberOfDevices = 0; Device <= PCI_MAX_DEVICE; Device++) {
348 for (Function = 0; Function <= PCI_MAX_FUNC; Function++) {
349 //
350 // Compute the PCI configuration address of the PCI device to probe
351 //
352 Address = PCI_LIB_ADDRESS (PrimaryBus, Device, Function, 0);
353
354 //
355 // Read the Vendor ID from the PCI Configuration Header
356 //
357 if (PciRead16 (Address) == MAX_UINT16) {
358 if (Function == 0) {
359 //
360 // If the PCI Configuration Read fails, or a PCI device does not
361 // exist, then skip this entire PCI device
362 //
363 break;
364 } else {
365 //
366 // If PCI function != 0, VendorId == 0xFFFF, we continue to search
367 // PCI function.
368 //
369 continue;
370 }
371 }
372
373 //
374 // Read the entire PCI Configuration Header
375 //
376 PciReadBuffer (Address, sizeof (Pci), &Pci);
377
378 //
379 // Increment the number of PCI device found on the primary bus of the
380 // PCI root bridge
381 //
382 NumberOfDevices++;
383
384 //
385 // Look for devices with the VGA Palette Snoop enabled in the COMMAND
386 // register of the PCI Config Header
387 //
388 if ((Pci.Hdr.Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) != 0) {
389 Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
390 Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
391 }
392
393 BarOffsetEnd = 0;
394
395 //
396 // PCI-PCI Bridge
397 //
398 if (IS_PCI_BRIDGE (&Pci)) {
399 //
400 // Get the Bus range that the PPB is decoding
401 //
402 if (Pci.Bridge.SubordinateBus > SubBus) {
403 //
404 // If the subordinate bus number of the PCI-PCI bridge is greater
405 // than the PCI root bridge's current subordinate bus number,
406 // then update the PCI root bridge's subordinate bus number
407 //
408 SubBus = Pci.Bridge.SubordinateBus;
409 }
410
411 //
412 // Get the I/O range that the PPB is decoding
413 //
414 Value = Pci.Bridge.IoBase & 0x0f;
415 Base = ((UINT32)Pci.Bridge.IoBase & 0xf0) << 8;
416 Limit = (((UINT32)Pci.Bridge.IoLimit & 0xf0) << 8) | 0x0fff;
417 if (Value == BIT0) {
418 Base |= ((UINT32)Pci.Bridge.IoBaseUpper16 << 16);
419 Limit |= ((UINT32)Pci.Bridge.IoLimitUpper16 << 16);
420 }
421
422 if ((Base > 0) && (Base < Limit)) {
423 if (Io.Base > Base) {
424 Io.Base = Base;
425 }
426
427 if (Io.Limit < Limit) {
428 Io.Limit = Limit;
429 }
430 }
431
432 //
433 // Get the Memory range that the PPB is decoding
434 //
435 Base = ((UINT32)Pci.Bridge.MemoryBase & 0xfff0) << 16;
436 Limit = (((UINT32)Pci.Bridge.MemoryLimit & 0xfff0) << 16) | 0xfffff;
437 if ((Base > 0) && (Base < Limit)) {
438 if (Mem.Base > Base) {
439 Mem.Base = Base;
440 }
441
442 if (Mem.Limit < Limit) {
443 Mem.Limit = Limit;
444 }
445 }
446
447 //
448 // Get the Prefetchable Memory range that the PPB is decoding
449 //
450 Value = Pci.Bridge.PrefetchableMemoryBase & 0x0f;
451 Base = ((UINT32)Pci.Bridge.PrefetchableMemoryBase & 0xfff0) << 16;
452 Limit = (((UINT32)Pci.Bridge.PrefetchableMemoryLimit & 0xfff0)
453 << 16) | 0xfffff;
454 MemAperture = &PMem;
455 if (Value == BIT0) {
456 Base |= LShiftU64 (Pci.Bridge.PrefetchableBaseUpper32, 32);
457 Limit |= LShiftU64 (Pci.Bridge.PrefetchableLimitUpper32, 32);
458 MemAperture = &PMemAbove4G;
459 }
460
461 if ((Base > 0) && (Base < Limit)) {
462 if (MemAperture->Base > Base) {
463 MemAperture->Base = Base;
464 }
465
466 if (MemAperture->Limit < Limit) {
467 MemAperture->Limit = Limit;
468 }
469 }
470
471 //
472 // Look at the PPB Configuration for legacy decoding attributes
473 //
474 if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA)
475 == EFI_PCI_BRIDGE_CONTROL_ISA)
476 {
477 Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
478 Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO_16;
479 Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
480 }
481
482 if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA)
483 == EFI_PCI_BRIDGE_CONTROL_VGA)
484 {
485 Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
486 Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
487 Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
488 if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16)
489 != 0)
490 {
491 Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
492 Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO_16;
493 }
494 }
495
496 BarOffsetEnd = OFFSET_OF (PCI_TYPE01, Bridge.Bar[2]);
497 } else {
498 //
499 // Parse the BARs of the PCI device to get what I/O Ranges, Memory
500 // Ranges, and Prefetchable Memory Ranges the device is decoding
501 //
502 if ((Pci.Hdr.HeaderType & HEADER_LAYOUT_CODE) == HEADER_TYPE_DEVICE) {
503 BarOffsetEnd = OFFSET_OF (PCI_TYPE00, Device.Bar[6]);
504 }
505 }
506
507 PcatPciRootBridgeParseBars (
508 Pci.Hdr.Command,
509 PrimaryBus,
510 Device,
511 Function,
512 OFFSET_OF (PCI_TYPE00, Device.Bar),
513 BarOffsetEnd,
514 &Io,
515 &Mem,
516 &MemAbove4G,
517 &PMem,
518 &PMemAbove4G
519 );
520
521 //
522 // See if the PCI device is an IDE controller
523 //
524 if (IS_CLASS2 (
525 &Pci,
526 PCI_CLASS_MASS_STORAGE,
527 PCI_CLASS_MASS_STORAGE_IDE
528 ))
529 {
530 if (Pci.Hdr.ClassCode[0] & 0x80) {
531 Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
532 Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
533 }
534
535 if (Pci.Hdr.ClassCode[0] & 0x01) {
536 Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
537 }
538
539 if (Pci.Hdr.ClassCode[0] & 0x04) {
540 Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
541 }
542 }
543
544 //
545 // See if the PCI device is a legacy VGA controller or
546 // a standard VGA controller
547 //
548 if (IS_CLASS2 (&Pci, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA) ||
549 IS_CLASS2 (&Pci, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA)
550 )
551 {
552 Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
553 Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
554 Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
555 Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
556 Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO_16;
557 }
558
559 //
560 // See if the PCI Device is a PCI - ISA or PCI - EISA
561 // or ISA_POSITIVE_DECODE Bridge device
562 //
563 if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
564 if ((Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) ||
565 (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_EISA) ||
566 (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE))
567 {
568 Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
569 Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO_16;
570 Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
571 }
572 }
573
574 //
575 // If this device is not a multi function device, then skip the rest
576 // of this PCI device
577 //
578 if ((Function == 0) && !IS_PCI_MULTI_FUNC (&Pci)) {
579 break;
580 }
581 }
582 }
583
584 //
585 // If at least one PCI device was found on the primary bus of this PCI
586 // root bridge, then the PCI root bridge exists.
587 //
588 if (NumberOfDevices > 0) {
589 RootBridges = ReallocatePool (
590 (*NumberOfRootBridges) * sizeof (PCI_ROOT_BRIDGE),
591 (*NumberOfRootBridges + 1) * sizeof (PCI_ROOT_BRIDGE),
592 RootBridges
593 );
594 ASSERT (RootBridges != NULL);
595
596 AdjustRootBridgeResource (&Io, &Mem, &MemAbove4G, &PMem, &PMemAbove4G);
597
598 InitRootBridge (
599 Attributes,
600 Attributes,
601 0,
602 (UINT8)PrimaryBus,
603 (UINT8)SubBus,
604 &Io,
605 &Mem,
606 &MemAbove4G,
607 &PMem,
608 &PMemAbove4G,
609 &RootBridges[*NumberOfRootBridges]
610 );
611 RootBridges[*NumberOfRootBridges].ResourceAssigned = TRUE;
612 //
613 // Increment the index for the next PCI Root Bridge
614 //
615 (*NumberOfRootBridges)++;
616 }
617 }
618
619 return RootBridges;
620 }
621
622 /**
623 Scan for all root bridges from Universal Payload PciRootBridgeInfoHob
624
625 @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob
626 @param[out] NumberOfRootBridges Number of root bridges detected
627
628 @retval Pointer to the allocated PCI_ROOT_BRIDGE structure array.
629
630 **/
631 PCI_ROOT_BRIDGE *
632 RetrieveRootBridgeInfoFromHob (
633 IN UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo,
634 OUT UINTN *NumberOfRootBridges
635 )
636 {
637 PCI_ROOT_BRIDGE *PciRootBridges;
638 UINTN Size;
639 UINT8 Index;
640
641 ASSERT (PciRootBridgeInfo != NULL);
642 ASSERT (NumberOfRootBridges != NULL);
643 if (PciRootBridgeInfo == NULL) {
644 return NULL;
645 }
646
647 if (PciRootBridgeInfo->Count == 0) {
648 return NULL;
649 }
650
651 Size = PciRootBridgeInfo->Count * sizeof (PCI_ROOT_BRIDGE);
652 PciRootBridges = (PCI_ROOT_BRIDGE *)AllocatePool (Size);
653 ASSERT (PciRootBridges != NULL);
654 if (PciRootBridges == NULL) {
655 return NULL;
656 }
657
658 ZeroMem (PciRootBridges, PciRootBridgeInfo->Count * sizeof (PCI_ROOT_BRIDGE));
659
660 //
661 // Create all root bridges with PciRootBridgeInfoHob
662 //
663 for (Index = 0; Index < PciRootBridgeInfo->Count; Index++) {
664 PciRootBridges[Index].Segment = PciRootBridgeInfo->RootBridge[Index].Segment;
665 PciRootBridges[Index].Supports = PciRootBridgeInfo->RootBridge[Index].Supports;
666 PciRootBridges[Index].Attributes = PciRootBridgeInfo->RootBridge[Index].Attributes;
667 PciRootBridges[Index].DmaAbove4G = PciRootBridgeInfo->RootBridge[Index].DmaAbove4G;
668 PciRootBridges[Index].NoExtendedConfigSpace = PciRootBridgeInfo->RootBridge[Index].NoExtendedConfigSpace;
669 PciRootBridges[Index].ResourceAssigned = PciRootBridgeInfo->ResourceAssigned;
670 PciRootBridges[Index].AllocationAttributes = PciRootBridgeInfo->RootBridge[Index].AllocationAttributes;
671 PciRootBridges[Index].DevicePath = CreateRootBridgeDevicePath (PciRootBridgeInfo->RootBridge[Index].HID, PciRootBridgeInfo->RootBridge[Index].UID);
672 CopyMem (&PciRootBridges[Index].Bus, &PciRootBridgeInfo->RootBridge[Index].Bus, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE));
673 CopyMem (&PciRootBridges[Index].Io, &PciRootBridgeInfo->RootBridge[Index].Io, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE));
674 CopyMem (&PciRootBridges[Index].Mem, &PciRootBridgeInfo->RootBridge[Index].Mem, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE));
675 CopyMem (&PciRootBridges[Index].MemAbove4G, &PciRootBridgeInfo->RootBridge[Index].MemAbove4G, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE));
676 CopyMem (&PciRootBridges[Index].PMem, &PciRootBridgeInfo->RootBridge[Index].PMem, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE));
677 CopyMem (&PciRootBridges[Index].PMemAbove4G, &PciRootBridgeInfo->RootBridge[Index].PMemAbove4G, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE));
678 }
679
680 *NumberOfRootBridges = PciRootBridgeInfo->Count;
681
682 //
683 // Now, this library only supports RootBridge that ResourceAssigned is True
684 //
685 if (PciRootBridgeInfo->ResourceAssigned) {
686 PcdSetBoolS (PcdPciDisableBusEnumeration, TRUE);
687 } else {
688 DEBUG ((DEBUG_ERROR, "There is root bridge whose ResourceAssigned is FALSE\n"));
689 PcdSetBoolS (PcdPciDisableBusEnumeration, FALSE);
690 return NULL;
691 }
692
693 return PciRootBridges;
694 }