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