35 IN EFI_PCI_IO_PROTOCOL *PciIo,
42 UINT32 CapabilityEntry;
45 CapabilityPtr = EFI_PCIE_CAPABILITY_BASE_OFFSET;
47 while (CapabilityPtr != 0) {
51 CapabilityPtr &= 0xFFC;
52 Status = PciIo->Pci.Read (
59 if (EFI_ERROR (Status)) {
60 DEBUG ((DEBUG_INFO,
"OCDM: Capability I/O error - %r\n", Status));
61 return EFI_DEVICE_ERROR;
64 if (CapabilityEntry == MAX_UINT32) {
65 DEBUG ((DEBUG_INFO,
"OCDM: Read from disabled device\n"));
66 return EFI_INVALID_PARAMETER;
69 CapabilityID = (UINT16)CapabilityEntry;
71 if (CapabilityID == CapId) {
72 DEBUG ((DEBUG_VERBOSE,
"OCDM: Found CAP 0x%X at 0x%X\n", CapabilityID, CapabilityPtr));
73 *Offset = CapabilityPtr;
77 CapabilityPtr = (CapabilityEntry >> 20) & 0xFFF;
104 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
105 IN UINT64 PciAddress,
111 UINT32 CapabilityPtr;
112 UINT32 CapabilityEntry;
115 CapabilityPtr = EFI_PCIE_CAPABILITY_BASE_OFFSET;
117 while (CapabilityPtr != 0) {
121 CapabilityPtr &= 0xFFC;
122 Status = PciRootBridgeIo->Pci.Read (
129 if (EFI_ERROR (Status)) {
130 DEBUG ((DEBUG_INFO,
"OCDM: Capability I/O error - %r\n", Status));
131 return EFI_DEVICE_ERROR;
134 if (CapabilityEntry == MAX_UINT32) {
135 DEBUG ((DEBUG_INFO,
"OCDM: Read from disabled device\n"));
136 return EFI_INVALID_PARAMETER;
139 CapabilityID = (UINT16)CapabilityEntry;
141 if (CapabilityID == CapId) {
142 DEBUG ((DEBUG_VERBOSE,
"OCDM: Found CAP 0x%X at 0x%X\n", CapabilityID, CapabilityPtr));
143 *Offset = CapabilityPtr;
147 CapabilityPtr = (CapabilityEntry >> 20) & 0xFFF;
150 return EFI_NOT_FOUND;
156 IN EFI_PCI_IO_PROTOCOL *PciIo,
162 UINT32 ResizableBarOffset;
163 PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY Entries[PCI_MAX_BAR];
164 PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL ResizableBarControl;
167 UINT32 ResizableBarNumber;
169 UINT64 NewCapabilities;
170 UINT32 OldBar[PCI_MAX_BAR];
171 UINT32 NewBar[PCI_MAX_BAR];
179 PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID,
182 if (EFI_ERROR (Status)) {
183 DEBUG ((DEBUG_INFO,
"OCDM: RBAR is unsupported by device - %r\n", Status));
184 return EFI_UNSUPPORTED;
187 ResizableBarControl.Uint32 = 0;
188 Offset = ResizableBarOffset +
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER)
189 +
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CAPABILITY);
190 Status = PciIo->Pci.Read (
194 sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL),
200 "OCDM: RBAR control is %X, total %u - %r\n",
201 ResizableBarControl.Uint32,
202 MIN (ResizableBarControl.Bits.ResizableBarNumber, PCI_MAX_BAR),
206 if (EFI_ERROR (Status)) {
207 return EFI_UNSUPPORTED;
210 ResizableBarNumber =
MIN (ResizableBarControl.Bits.ResizableBarNumber, PCI_MAX_BAR);
212 Status = PciIo->Pci.Read (
215 ResizableBarOffset +
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER),
216 sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY) * ResizableBarNumber,
219 if (EFI_ERROR (Status)) {
220 DEBUG ((DEBUG_INFO,
"OCDM: RBAR caps cannot be read - %r\n", Status));
221 return EFI_UNSUPPORTED;
224 Status = PciIo->Pci.Read (
227 OFFSET_OF (PCI_TYPE00, Device.Bar),
231 if (EFI_ERROR (Status)) {
232 ZeroMem (OldBar,
sizeof (OldBar));
237 "OCDM: Old BAR %08X %08X %08X %08X %08X %08X - %r\n",
247 for (Index = 0; Index < ResizableBarNumber; Index++) {
272 NewCapabilities = Capabilities =
LShiftU64 (Entries[Index].ResizableBarControl.Bits.BarSizeCapability, 28)
273 | Entries[Index].ResizableBarCapability.Bits.BarSizeCapability;
285 NewCapabilities &=
PCI_BAR_CAP_LIMIT (Entries[Index].ResizableBarControl.Bits.BarSize);
291 if ( (NewCapabilities == 0)
292 && (Entries[Index].ResizableBarControl.Bits.BarSize > (UINT32)
Size))
294 Bit = LowBitSet64 (Capabilities);
296 Bit = HighBitSet64 (NewCapabilities);
301 "OCDM: RBAR %u/%u supports 0x%Lx, sizing %u inc %d results setting from %u to %d\n",
307 Entries[Index].ResizableBarControl.Bits.BarSize,
314 if ((Bit < 0) || (Entries[Index].ResizableBarControl.Bits.BarSize == (UINT32)Bit)) {
318 Offset = ResizableBarOffset +
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER)
319 + Index *
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY)
320 + OFFSET_OF (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY, ResizableBarControl);
322 Entries[Index].ResizableBarControl.Bits.BarSize = (UINT32)Bit;
328 &Entries[Index].ResizableBarControl.Uint32
337 Status = PciIo->Pci.Read (
340 OFFSET_OF (PCI_TYPE00, Device.Bar),
344 if (EFI_ERROR (Status)) {
345 ZeroMem (NewBar,
sizeof (NewBar));
350 "OCDM: New BAR %08X %08X %08X %08X %08X %08X - %r\n",
370 Status = PciIo->Pci.Write (
373 OFFSET_OF (PCI_TYPE00, Device.Bar),
377 DEBUG ((DEBUG_INFO,
"OCDM: Reprogrammed BARs to original - %r\n", Status));
387 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
388 IN UINT64 PciAddress,
394 UINT32 ResizableBarOffset;
395 PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY Entries[PCI_MAX_BAR];
396 PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL ResizableBarControl;
399 UINT32 ResizableBarNumber;
401 UINT64 NewCapabilities;
402 UINT32 OldBar[PCI_MAX_BAR];
403 UINT32 NewBar[PCI_MAX_BAR];
409 PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID,
412 if (EFI_ERROR (Status)) {
413 DEBUG ((DEBUG_INFO,
"OCDM: RBAR is unsupported by device - %r\n", Status));
414 return EFI_UNSUPPORTED;
417 ResizableBarControl.Uint32 = 0;
418 Offset = ResizableBarOffset +
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER)
419 +
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CAPABILITY);
420 Status = PciRootBridgeIo->Pci.Read (
424 sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL),
430 "OCDM: RBAR control is %X, total %u - %r\n",
431 ResizableBarControl.Uint32,
432 MIN (ResizableBarControl.Bits.ResizableBarNumber, PCI_MAX_BAR),
436 if (EFI_ERROR (Status)) {
437 return EFI_UNSUPPORTED;
440 ResizableBarNumber =
MIN (ResizableBarControl.Bits.ResizableBarNumber, PCI_MAX_BAR);
442 Status = PciRootBridgeIo->Pci.Read (
445 PciAddrOffset (PciAddress, ResizableBarOffset +
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER)),
446 sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY) * ResizableBarNumber,
449 if (EFI_ERROR (Status)) {
450 DEBUG ((DEBUG_INFO,
"OCDM: RBAR caps cannot be read - %r\n", Status));
451 return EFI_UNSUPPORTED;
454 Status = PciRootBridgeIo->Pci.Read (
457 PciAddrOffset (PciAddress, OFFSET_OF (PCI_TYPE00, Device.Bar)),
461 if (EFI_ERROR (Status)) {
462 ZeroMem (OldBar,
sizeof (OldBar));
467 "OCDM: Old BAR %08X %08X %08X %08X %08X %08X - %r\n",
477 for (Index = 0; Index < ResizableBarNumber; Index++) {
502 NewCapabilities = Capabilities =
LShiftU64 (Entries[Index].ResizableBarControl.Bits.BarSizeCapability, 28)
503 | Entries[Index].ResizableBarCapability.Bits.BarSizeCapability;
515 NewCapabilities &=
PCI_BAR_CAP_LIMIT (Entries[Index].ResizableBarControl.Bits.BarSize);
521 if ( (NewCapabilities == 0)
522 && (Entries[Index].ResizableBarControl.Bits.BarSize > (UINT32)
Size))
524 Bit = LowBitSet64 (Capabilities);
526 Bit = HighBitSet64 (NewCapabilities);
531 "OCDM: RBAR %u/%u supports 0x%Lx, sizing %u inc %d results setting from %u to %d\n",
537 Entries[Index].ResizableBarControl.Bits.BarSize,
544 if ((Bit < 0) || (Entries[Index].ResizableBarControl.Bits.BarSize == (UINT32)Bit)) {
548 Offset = ResizableBarOffset +
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER)
549 + Index *
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY)
550 + OFFSET_OF (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY, ResizableBarControl);
552 Entries[Index].ResizableBarControl.Bits.BarSize = (UINT32)Bit;
553 PciRootBridgeIo->Pci.Write (
558 &Entries[Index].ResizableBarControl.Uint32
564 Status = PciRootBridgeIo->Pci.Read (
567 PciAddrOffset (PciAddress, OFFSET_OF (PCI_TYPE00, Device.Bar)),
571 if (EFI_ERROR (Status)) {
572 ZeroMem (NewBar,
sizeof (NewBar));
577 "OCDM: New BAR %08X %08X %08X %08X %08X %08X - %r\n",
597 Status = PciRootBridgeIo->Pci.Write (
600 PciAddrOffset (PciAddress, OFFSET_OF (PCI_TYPE00, Device.Bar)),
604 DEBUG ((DEBUG_INFO,
"OCDM: Reprogrammed BARs to original - %r\n", Status));
740 EFI_HANDLE *HandleBuffer;
742 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
743 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
759 Status =
gBS->LocateHandleBuffer (
767 if (EFI_ERROR (Status)) {
768 DEBUG ((DEBUG_INFO,
"OCDM: No PCI devices for RBAR support - %r\n", Status));
772 for (Index = 0; Index < HandleCount; ++Index) {
773 Status =
gBS->HandleProtocol (
776 (VOID **)&PciRootBridgeIo
778 if (EFI_ERROR (Status)) {
782 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **)&Descriptors);
783 if (EFI_ERROR (Status)) {
793 if (IsEnd || (Descriptors == NULL)) {
797 for (Bus = 0; Bus <= MaxBus; Bus++) {
798 for (Dev = 0; Dev <= PCI_MAX_DEVICE; Dev++) {
799 for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
800 PciAddress = EFI_PCI_ADDRESS (Bus, Dev, Func, 0);
803 Status = PciRootBridgeIo->Pci.Read (
806 PciAddress + PCI_CLASSCODE_OFFSET,
810 if (EFI_ERROR (Status)) {
814 DEBUG ((DEBUG_VERBOSE,
"OCDM: PCI device %u/%u/%u has class %X\n", Bus, Dev, Func, ClassCode));
816 if (ClassCode.
BaseCode != PCI_CLASS_DISPLAY) {
822 "OCDM: Setting RBAR to %u inc %d on %u/%u/%u\n",
830 if (!EFI_ERROR (Status)) {
834 PciRootBridgeIo->Pci.Read (PciRootBridgeIo, EfiPciWidthUint8, PciAddress + PCI_HEADER_TYPE_OFFSET, 1, &HdrType);
835 if (!Func && ((HdrType & HEADER_TYPE_MULTI_FUNCTION) == 0)) {
844 FreePool (HandleBuffer);
850 return EFI_NOT_FOUND;