+++ /dev/null
-/** @file\r
-IIO PCI Root Bridge Io Protocol code. Generic enough to work for all IIOs.\r
-Does not support configuration accesses to the extended PCI Express registers yet.\r
-\r
-Copyright (c) 2013-2015 Intel Corporation.\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-\r
-**/\r
-\r
-#include "PciRootBridge.h"\r
-\r
-//\r
-// Define PCI express offse\r
-//\r
-#define PCIE_OFF(Bus, Device, Function, Register) \\r
- ((UINT64) ((UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) (Function << 12) + (UINTN) (Register)))\r
-\r
-//\r
-// Pci Root Bridge Io Module Variables\r
-//\r
-EFI_METRONOME_ARCH_PROTOCOL *mMetronome;\r
-EFI_CPU_IO2_PROTOCOL *mCpuIo;\r
-\r
-EFI_STATUS\r
-SimpleIioRootBridgeConstructor (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,\r
- IN EFI_HANDLE HostBridgeHandle,\r
- IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE *ResAperture,\r
- UINT64 AllocAttributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Construct the Pci Root Bridge Io protocol.\r
-\r
-Arguments:\r
-\r
- Protocol - Protocol to initialize.\r
- HostBridgeHandle - Handle to the HostBridge.\r
- ResAperture - Resource apperture of the root bridge.\r
- AllocAttributes - Attribute of resouce allocated.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Success.\r
- Others - Fail.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
- PCI_RESOURCE_TYPE Index;\r
- UINT32 HecBase;\r
- UINT32 HecSize;\r
-\r
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);\r
-\r
- //\r
- // Initialize the apertures with default values\r
- //\r
- CopyMem (\r
- &PrivateData->Aperture,\r
- ResAperture,\r
- sizeof (PCI_ROOT_BRIDGE_RESOURCE_APERTURE)\r
- );\r
-\r
- for (Index = TypeIo; Index < TypeMax; Index++) {\r
- PrivateData->ResAllocNode[Index].Type = Index;\r
- PrivateData->ResAllocNode[Index].Base = 0;\r
- PrivateData->ResAllocNode[Index].Length = 0;\r
- PrivateData->ResAllocNode[Index].Status = ResNone;\r
- }\r
-\r
- EfiInitializeLock (&PrivateData->PciLock, TPL_HIGH_LEVEL);\r
- PrivateData->PciAddress = 0xCF8;\r
- PrivateData->PciData = 0xCFC;\r
-\r
- PrivateData->RootBridgeAllocAttrib = AllocAttributes;\r
- PrivateData->Attributes = 0;\r
- PrivateData->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |\r
- EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |\r
- EFI_PCI_ATTRIBUTE_ISA_IO_16 |\r
- EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 |\r
- EFI_PCI_ATTRIBUTE_VGA_MEMORY |\r
- EFI_PCI_ATTRIBUTE_VGA_IO_16;\r
-\r
- //\r
- // Don't support BASE above 4GB currently\r
- // Position to bit 39:28\r
- //\r
- HecBase = (UINT32) PcdGet64 (PcdPciExpressBaseAddress);\r
- HecSize = (UINT32) PcdGet64 (PcdPciExpressSize);\r
-\r
- ASSERT ((HecBase & (HecSize - 1)) == 0);\r
- ASSERT (HecBase != 0);\r
-\r
- PrivateData->HecBase = HecBase;\r
- PrivateData->HecLen = HecSize;\r
-\r
- PrivateData->BusNumberAssigned = FALSE;\r
- PrivateData->BusScanCount = 0;\r
-\r
- Protocol->ParentHandle = HostBridgeHandle;\r
-\r
- Protocol->PollMem = RootBridgeIoPollMem;\r
- Protocol->PollIo = RootBridgeIoPollIo;\r
-\r
- Protocol->Mem.Read = RootBridgeIoMemRead;\r
- Protocol->Mem.Write = RootBridgeIoMemWrite;\r
-\r
- Protocol->Io.Read = RootBridgeIoIoRead;\r
- Protocol->Io.Write = RootBridgeIoIoWrite;\r
-\r
- Protocol->CopyMem = RootBridgeIoCopyMem;\r
-\r
- Protocol->Pci.Read = RootBridgeIoPciRead;\r
- Protocol->Pci.Write = RootBridgeIoPciWrite;\r
-\r
- Protocol->Map = RootBridgeIoMap;\r
- Protocol->Unmap = RootBridgeIoUnmap;\r
-\r
- Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;\r
- Protocol->FreeBuffer = RootBridgeIoFreeBuffer;\r
-\r
- Protocol->Flush = RootBridgeIoFlush;\r
-\r
- Protocol->GetAttributes = RootBridgeIoGetAttributes;\r
- Protocol->SetAttributes = RootBridgeIoSetAttributes;\r
-\r
- Protocol->Configuration = RootBridgeIoConfiguration;\r
-\r
- Protocol->SegmentNumber = 0;\r
-\r
- Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **) &mMetronome);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = gBS->LocateProtocol (\r
- &gEfiCpuIo2ProtocolGuid,\r
- NULL,\r
- (VOID **) &mCpuIo\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoPollMem (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINT64 Mask,\r
- IN UINT64 Value,\r
- IN UINT64 Delay,\r
- OUT UINT64 *Result\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Poll an address in memory mapped space until an exit condition is met\r
- or a timeout occurs.\r
-\r
-Arguments:\r
-\r
- This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
- Width - Width of the memory operation.\r
- Address - The base address of the memory operation.\r
- Mask - Mask used for polling criteria.\r
- Value - Comparison value used for polling exit criteria.\r
- Delay - Number of 100ns units to poll.\r
- Result - Pointer to the last value read from memory location.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Success.\r
- EFI_INVALID_PARAMETER - Invalid parameter found.\r
- EFI_TIMEOUT - Delay expired before a match occurred.\r
- EFI_OUT_OF_RESOURCES - Fail due to lack of resources.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINT64 NumberOfTicks;\r
- UINT32 Remainder;\r
-\r
- if (Result == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Width < 0 || Width > EfiPciWidthUint64) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // No matter what, always do a single poll.\r
- //\r
- Status = This->Mem.Read (\r
- This,\r
- Width,\r
- Address,\r
- 1,\r
- Result\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if ((*Result & Mask) == Value) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (Delay != 0) {\r
- //\r
- // Determine the proper # of metronome ticks to wait for polling the\r
- // location. The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1\r
- // The "+1" to account for the possibility of the first tick being short\r
- // because we started in the middle of a tick.\r
- //\r
- // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome\r
- // protocol definition is updated.\r
- //\r
- NumberOfTicks = DivU64x32Remainder (\r
- Delay,\r
- (UINT32) mMetronome->TickPeriod,\r
- &Remainder\r
- );\r
- if (Remainder != 0) {\r
- NumberOfTicks += 1;\r
- }\r
-\r
- NumberOfTicks += 1;\r
-\r
- while (NumberOfTicks) {\r
-\r
- mMetronome->WaitForTick (mMetronome, 1);\r
-\r
- Status = This->Mem.Read (\r
- This,\r
- Width,\r
- Address,\r
- 1,\r
- Result\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if ((*Result & Mask) == Value) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- NumberOfTicks -= 1;\r
- }\r
- }\r
-\r
- return EFI_TIMEOUT;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoPollIo (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINT64 Mask,\r
- IN UINT64 Value,\r
- IN UINT64 Delay,\r
- OUT UINT64 *Result\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Poll an address in I/O space until an exit condition is met\r
- or a timeout occurs.\r
-\r
-Arguments:\r
-\r
- This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
- Width - Width of I/O operation.\r
- Address - The base address of the I/O operation.\r
- Mask - Mask used for polling criteria.\r
- Value - Comparison value used for polling exit criteria.\r
- Delay - Number of 100ns units to poll.\r
- Result - Pointer to the last value read from memory location.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Success.\r
- EFI_INVALID_PARAMETER - Invalid parameter found.\r
- EFI_TIMEOUT - Delay expired before a match occurred.\r
- EFI_OUT_OF_RESOURCES - Fail due to lack of resources.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINT64 NumberOfTicks;\r
- UINT32 Remainder;\r
-\r
- //\r
- // No matter what, always do a single poll.\r
- //\r
- if (Result == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Width < 0 || Width > EfiPciWidthUint64) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = This->Io.Read (\r
- This,\r
- Width,\r
- Address,\r
- 1,\r
- Result\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if ((*Result & Mask) == Value) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (Delay != 0) {\r
- //\r
- // Determine the proper # of metronome ticks to wait for polling the\r
- // location. The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1\r
- // The "+1" to account for the possibility of the first tick being short\r
- // because we started in the middle of a tick.\r
- //\r
- NumberOfTicks = DivU64x32Remainder (\r
- Delay,\r
- (UINT32) mMetronome->TickPeriod,\r
- &Remainder\r
- );\r
- if (Remainder != 0) {\r
- NumberOfTicks += 1;\r
- }\r
-\r
- NumberOfTicks += 1;\r
-\r
- while (NumberOfTicks) {\r
-\r
- mMetronome->WaitForTick (mMetronome, 1);\r
-\r
- Status = This->Io.Read (\r
- This,\r
- Width,\r
- Address,\r
- 1,\r
- Result\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if ((*Result & Mask) == Value) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- NumberOfTicks -= 1;\r
- }\r
- }\r
-\r
- return EFI_TIMEOUT;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoMemRead (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Allow read from memory mapped I/O space.\r
-\r
-Arguments:\r
-\r
- This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
- Width - The width of memory operation.\r
- Address - Base address of the memory operation.\r
- Count - Number of memory opeartion to perform.\r
- Buffer - The destination buffer to store data.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Success.\r
- EFI_INVALID_PARAMETER - Invalid parameter found.\r
- EFI_OUT_OF_RESOURCES - Fail due to lack of resources.\r
-\r
---*/\r
-{\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Width < 0 ||\r
- Width == EfiPciWidthUint64 ||\r
- Width == EfiPciWidthFifoUint64 ||\r
- Width == EfiPciWidthFillUint64 ||\r
- Width >= EfiPciWidthMaximum\r
- ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
- //\r
- // Check memory access limit\r
- //\r
- if (PrivateData->Aperture.Mem64Limit > PrivateData->Aperture.Mem64Base) {\r
- if (Address > PrivateData->Aperture.Mem64Limit) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- } else {\r
- if (Address > PrivateData->Aperture.Mem32Limit) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
-\r
- return mCpuIo->Mem.Read (\r
- mCpuIo,\r
- (EFI_CPU_IO_PROTOCOL_WIDTH) Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoMemWrite (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Allow write to memory mapped I/O space.\r
-\r
-Arguments:\r
-\r
- This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
- Width - The width of memory operation.\r
- Address - Base address of the memory operation.\r
- Count - Number of memory opeartion to perform.\r
- Buffer - The source buffer to write data from.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Success.\r
- EFI_INVALID_PARAMETER - Invalid parameter found.\r
- EFI_OUT_OF_RESOURCES - Fail due to lack of resources.\r
-\r
---*/\r
-{\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
-\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Width < 0 ||\r
- Width == EfiPciWidthUint64 ||\r
- Width == EfiPciWidthFifoUint64 ||\r
- Width == EfiPciWidthFillUint64 ||\r
- Width >= EfiPciWidthMaximum\r
- ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
-\r
- //\r
- // Check memory access limit\r
- //\r
- if (PrivateData->Aperture.Mem64Limit > PrivateData->Aperture.Mem64Base) {\r
- if (Address > PrivateData->Aperture.Mem64Limit) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- } else {\r
- if (Address > PrivateData->Aperture.Mem32Limit) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
-\r
- return mCpuIo->Mem.Write (\r
- mCpuIo,\r
- (EFI_CPU_IO_PROTOCOL_WIDTH) Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoIoRead (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Enable a PCI driver to read PCI controller registers in the\r
- PCI root bridge I/O space.\r
-\r
-Arguments:\r
-\r
- This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
- Width - Signifies the width of the memory operation.\r
- Address - The base address of the I/O operation.\r
- Count - The number of I/O operations to perform.\r
- Buffer - The destination buffer to store the results.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The data was read from the PCI root bridge.\r
- EFI_INVALID_PARAMETER - Invalid parameters found.\r
- EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of\r
- resources.\r
---*/\r
-{\r
-\r
- UINTN AlignMask;\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
-\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Width < 0 ||\r
- Width == EfiPciWidthUint64 ||\r
- Width == EfiPciWidthFifoUint64 ||\r
- Width == EfiPciWidthFillUint64 ||\r
- Width >= EfiPciWidthMaximum\r
- ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
-\r
- //\r
- // AlignMask = (1 << Width) - 1;\r
- //\r
- AlignMask = (1 << (Width & 0x03)) - 1;\r
-\r
- //\r
- // check Io access limit\r
- //\r
- if (Address > PrivateData->Aperture.IoLimit) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Address & AlignMask) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- return mCpuIo->Io.Read (\r
- mCpuIo,\r
- (EFI_CPU_IO_PROTOCOL_WIDTH) Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
-\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoIoWrite (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Enable a PCI driver to write to PCI controller registers in the\r
- PCI root bridge I/O space.\r
-\r
-Arguments:\r
-\r
- This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
- Width - Signifies the width of the memory operation.\r
- Address - The base address of the I/O operation.\r
- Count - The number of I/O operations to perform.\r
- Buffer - The source buffer to write data from.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The data was written to the PCI root bridge.\r
- EFI_INVALID_PARAMETER - Invalid parameters found.\r
- EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of\r
- resources.\r
---*/\r
-{\r
- UINTN AlignMask;\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
-\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Width < 0 ||\r
- Width == EfiPciWidthUint64 ||\r
- Width == EfiPciWidthFifoUint64 ||\r
- Width == EfiPciWidthFillUint64 ||\r
- Width >= EfiPciWidthMaximum\r
- ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
-\r
- //\r
- // AlignMask = (1 << Width) - 1;\r
- //\r
- AlignMask = (1 << (Width & 0x03)) - 1;\r
-\r
- //\r
- // Check Io access limit\r
- //\r
- if (Address > PrivateData->Aperture.IoLimit) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Address & AlignMask) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- return mCpuIo->Io.Write (\r
- mCpuIo,\r
- (EFI_CPU_IO_PROTOCOL_WIDTH) Width,\r
- Address,\r
- Count,\r
- Buffer\r
- );\r
-\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoCopyMem (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 DestAddress,\r
- IN UINT64 SrcAddress,\r
- IN UINTN Count\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Copy one region of PCI root bridge memory space to be copied to\r
- another region of PCI root bridge memory space.\r
-\r
-Arguments:\r
-\r
- This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
- Width - Signifies the width of the memory operation.\r
- DestAddress - Destination address of the memory operation.\r
- SrcAddress - Source address of the memory operation.\r
- Count - Number of memory operations to perform.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The data was copied successfully.\r
- EFI_INVALID_PARAMETER - Invalid parameters found.\r
- EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of\r
- resources.\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- BOOLEAN Direction;\r
- UINTN Stride;\r
- UINTN Index;\r
- UINT64 Result;\r
-\r
- if (Width < 0 || Width > EfiPciWidthUint64) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (DestAddress == SrcAddress) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Stride = (UINTN)1 << Width;\r
-\r
- Direction = TRUE;\r
- if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {\r
- Direction = FALSE;\r
- SrcAddress = SrcAddress + (Count - 1) * Stride;\r
- DestAddress = DestAddress + (Count - 1) * Stride;\r
- }\r
-\r
- for (Index = 0; Index < Count; Index++) {\r
- Status = RootBridgeIoMemRead (\r
- This,\r
- Width,\r
- SrcAddress,\r
- 1,\r
- &Result\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = RootBridgeIoMemWrite (\r
- This,\r
- Width,\r
- DestAddress,\r
- 1,\r
- &Result\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (Direction) {\r
- SrcAddress += Stride;\r
- DestAddress += Stride;\r
- } else {\r
- SrcAddress -= Stride;\r
- DestAddress -= Stride;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-RootBridgeIoPciRW (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN BOOLEAN Write,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 UserAddress,\r
- IN UINTN Count,\r
- IN OUT VOID *UserBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-{\r
- PCI_CONFIG_ACCESS_CF8 Pci;\r
- PCI_CONFIG_ACCESS_CF8 PciAligned;\r
- UINT32 Stride;\r
- UINTN PciData;\r
- UINTN PciDataStride;\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
-\r
- if (Width >= EfiPciWidthMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
-\r
- ASSERT (((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*)&UserAddress)->ExtendedRegister == 0x00);\r
-\r
- Stride = 1 << Width;\r
-\r
- Pci.Bits.Reg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Register;\r
- Pci.Bits.Func = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Function;\r
- Pci.Bits.Dev = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Device;\r
- Pci.Bits.Bus = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Bus;\r
- Pci.Bits.Reserved = 0;\r
- Pci.Bits.Enable = 1;\r
-\r
- //\r
- // PCI Configure access are all 32-bit aligned, but by accessing the\r
- // CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types\r
- // are possible on PCI.\r
- //\r
- // To read a byte of PCI configuration space you load 0xcf8 and\r
- // read 0xcfc, 0xcfd, 0xcfe, 0xcff\r
- //\r
- PciDataStride = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Register & 0x03;\r
-\r
- while (Count) {\r
- PciAligned = Pci;\r
- PciAligned.Bits.Reg &= 0xfc;\r
- PciData = PrivateData->PciData + PciDataStride;\r
- EfiAcquireLock(&PrivateData->PciLock);\r
- This->Io.Write (This, EfiPciWidthUint32, \\r
- PrivateData->PciAddress, 1, &PciAligned);\r
- if (Write) {\r
- This->Io.Write (This, Width, PciData, 1, UserBuffer);\r
- } else {\r
- This->Io.Read (This, Width, PciData, 1, UserBuffer);\r
- }\r
- EfiReleaseLock(&PrivateData->PciLock);\r
- UserBuffer = ((UINT8 *)UserBuffer) + Stride;\r
- PciDataStride = (PciDataStride + Stride) % 4;\r
- Count -= 1;\r
-\r
- //\r
- // Only increment the PCI address if Width is not a FIFO.\r
- //\r
- if (Width >= EfiPciWidthUint8 && Width <= EfiPciWidthUint64) {\r
- Pci.Bits.Reg += Stride;\r
- }\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoPciRead (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Allows read from PCI configuration space.\r
-\r
-Arguments:\r
-\r
- This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
- Width - Signifies the width of the memory operation.\r
- Address - The address within the PCI configuration space\r
- for the PCI controller.\r
- Count - The number of PCI configuration operations\r
- to perform.\r
- Buffer - The destination buffer to store the results.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The data was read from the PCI root bridge.\r
- EFI_INVALID_PARAMETER - Invalid parameters found.\r
- EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of\r
- resources.\r
---*/\r
-{\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
- UINT32 PciBus;\r
- UINT32 PciDev;\r
- UINT32 PciFn;\r
- UINT32 PciExtReg;\r
- UINT64 ExtConfigAdd;\r
-\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Width < 0 ||\r
- Width == EfiPciWidthUint64 ||\r
- Width == EfiPciWidthFifoUint64 ||\r
- Width == EfiPciWidthFillUint64 ||\r
- Width >= EfiPciWidthMaximum\r
- ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Read Pci configuration space\r
- //\r
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
-\r
- if (PrivateData->HecBase == 0) {\r
- return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);\r
- }\r
-\r
- if (!((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister) {\r
- PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Register;\r
- } else {\r
- PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister & 0x0FFF;\r
- }\r
-\r
- PciBus = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Bus;\r
- PciDev = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Device;\r
- PciFn = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Function;\r
-\r
- ExtConfigAdd = (UINT64) PrivateData->HecBase + PCIE_OFF (PciBus, PciDev, PciFn, PciExtReg);\r
-\r
- return mCpuIo->Mem.Read (\r
- mCpuIo,\r
- (EFI_CPU_IO_PROTOCOL_WIDTH) Width,\r
- ExtConfigAdd,\r
- Count,\r
- Buffer\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoPciWrite (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Allows write to PCI configuration space.\r
-\r
-Arguments:\r
-\r
- This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
- Width - Signifies the width of the memory operation.\r
- Address - The address within the PCI configuration space\r
- for the PCI controller.\r
- Count - The number of PCI configuration operations\r
- to perform.\r
- Buffer - The source buffer to get the results.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The data was written to the PCI root bridge.\r
- EFI_INVALID_PARAMETER - Invalid parameters found.\r
- EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of\r
- resources.\r
---*/\r
-{\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
- UINT32 PciBus;\r
- UINT32 PciDev;\r
- UINT32 PciFn;\r
- UINT32 PciExtReg;\r
- UINT64 ExtConfigAdd;\r
-\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Width < 0 || Width >= EfiPciWidthMaximum) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Write Pci configuration space\r
- //\r
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
-\r
- if (PrivateData->HecBase == 0) {\r
- return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);\r
- }\r
-\r
- if (!((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister) {\r
- PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Register;\r
- } else {\r
- PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister & 0x0FFF;\r
- }\r
-\r
- PciBus = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Bus;\r
- PciDev = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Device;\r
- PciFn = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Function;\r
-\r
- ExtConfigAdd = (UINT64) PrivateData->HecBase + PCIE_OFF (PciBus, PciDev, PciFn, PciExtReg);\r
-\r
- return mCpuIo->Mem.Write (\r
- mCpuIo,\r
- (EFI_CPU_IO_PROTOCOL_WIDTH) Width,\r
- ExtConfigAdd,\r
- Count,\r
- Buffer\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoMap (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,\r
- IN VOID *HostAddress,\r
- IN OUT UINTN *NumberOfBytes,\r
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
- OUT VOID **Mapping\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Provides the PCI controller-specific address needed to access\r
- system memory for DMA.\r
-\r
-Arguments:\r
-\r
- This - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- Operation - Indicate if the bus master is going to read or write\r
- to system memory.\r
- HostAddress - The system memory address to map on the PCI controller.\r
- NumberOfBytes - On input the number of bytes to map.\r
- On output the number of bytes that were mapped.\r
- DeviceAddress - The resulting map address for the bus master PCI\r
- controller to use to access the system memory's HostAddress.\r
- Mapping - The value to pass to Unmap() when the bus master DMA\r
- operation is complete.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Success.\r
- EFI_INVALID_PARAMETER - Invalid parameters found.\r
- EFI_UNSUPPORTED - The HostAddress cannot be mapped as a common\r
- buffer.\r
- EFI_DEVICE_ERROR - The System hardware could not map the requested\r
- address.\r
- EFI_OUT_OF_RESOURCES - The request could not be completed due to\r
- lack of resources.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
- MAP_INFO *MapInfo;\r
-\r
- if (NumberOfBytes == NULL || Mapping == NULL || DeviceAddress == NULL || HostAddress == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Initialize the return values to their defaults\r
- //\r
- *Mapping = NULL;\r
-\r
- //\r
- // Make sure that Operation is valid\r
- //\r
- if ((Operation < 0) || (Operation > EfiPciOperationBusMasterCommonBuffer64)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Most PCAT like chipsets can not handle performing DMA above 4GB.\r
- // If any part of the DMA transfer being mapped is above 4GB, then\r
- // map the DMA transfer to a buffer below 4GB.\r
- //\r
- PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;\r
- if ((PhysicalAddress +*NumberOfBytes) > 0x100000000ULL) {\r
- //\r
- // Common Buffer operations can not be remapped. If the common buffer\r
- // if above 4GB, then it is not possible to generate a mapping, so return\r
- // an error.\r
- //\r
- if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
-\r
- if ((PhysicalAddress + *NumberOfBytes) > (DMA_MEMORY_TOP+1)) {\r
-\r
- //\r
- // Common Buffer operations can not be remapped.\r
- //\r
- if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {\r
- *DeviceAddress = PhysicalAddress;\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // Allocate a MAP_INFO structure to remember the mapping when Unmap() is\r
- // called later.\r
- //\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- sizeof (MAP_INFO),\r
- (VOID **) &MapInfo\r
- );\r
- if (EFI_ERROR (Status)) {\r
- *NumberOfBytes = 0;\r
- return Status;\r
- }\r
- //\r
- // Return a pointer to the MAP_INFO structure in Mapping\r
- //\r
- *Mapping = MapInfo;\r
-\r
- //\r
- // Initialize the MAP_INFO structure\r
- //\r
- MapInfo->Operation = Operation;\r
- MapInfo->NumberOfBytes = *NumberOfBytes;\r
- MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (*NumberOfBytes);\r
- MapInfo->HostAddress = PhysicalAddress;\r
- MapInfo->MappedHostAddress = DMA_MEMORY_TOP;\r
-\r
- //\r
- // Allocate a buffer below DMA_MEMORY_TOP to map the transfer to.\r
- //\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiBootServicesData,\r
- MapInfo->NumberOfPages,\r
- &MapInfo->MappedHostAddress\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (MapInfo);\r
- *NumberOfBytes = 0;\r
- return Status;\r
- }\r
- //\r
- // If this is a read operation from the Bus Master's point of view,\r
- // then copy the contents of the real buffer into the mapped buffer\r
- // so the Bus Master can read the contents of the real buffer.\r
- //\r
- if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {\r
- CopyMem (\r
- (VOID *) (UINTN) MapInfo->MappedHostAddress,\r
- (VOID *) (UINTN) MapInfo->HostAddress,\r
- MapInfo->NumberOfBytes\r
- );\r
- }\r
- //\r
- // The DeviceAddress is the address of the maped buffer below DMA_MEMORY_TOP\r
- //\r
- *DeviceAddress = MapInfo->MappedHostAddress;\r
- } else {\r
- //\r
- // The transfer is below DMA_MEMORY_TOP, so the DeviceAddress is simply the HostAddress\r
- //\r
- *DeviceAddress = PhysicalAddress;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoUnmap (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN VOID *Mapping\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Completes the Map() operation and releases any corresponding resources.\r
-\r
-Arguments:\r
-\r
- This - Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
- Mapping - The value returned from Map() operation.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The range was unmapped successfully.\r
- EFI_INVALID_PARAMETER - Mapping is not a value that was returned\r
- by Map operation.\r
- EFI_DEVICE_ERROR - The data was not committed to the target\r
- system memory.\r
-\r
---*/\r
-{\r
- MAP_INFO *MapInfo;\r
-\r
- //\r
- // See if the Map() operation associated with this Unmap() required a mapping buffer.\r
- // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.\r
- //\r
- if (Mapping != NULL) {\r
- //\r
- // Get the MAP_INFO structure from Mapping\r
- //\r
- MapInfo = (MAP_INFO *) Mapping;\r
-\r
- //\r
- // If this is a write operation from the Bus Master's point of view,\r
- // then copy the contents of the mapped buffer into the real buffer\r
- // so the processor can read the contents of the real buffer.\r
- //\r
- if ((MapInfo->Operation == EfiPciOperationBusMasterWrite) ||\r
- (MapInfo->Operation == EfiPciOperationBusMasterWrite64)\r
- ) {\r
- CopyMem (\r
- (VOID *) (UINTN) MapInfo->HostAddress,\r
- (VOID *) (UINTN) MapInfo->MappedHostAddress,\r
- MapInfo->NumberOfBytes\r
- );\r
- }\r
- //\r
- // Free the mapped buffer and the MAP_INFO structure.\r
- //\r
- gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);\r
- gBS->FreePool (Mapping);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoAllocateBuffer (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_ALLOCATE_TYPE Type,\r
- IN EFI_MEMORY_TYPE MemoryType,\r
- IN UINTN Pages,\r
- OUT VOID **HostAddress,\r
- IN UINT64 Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Allocates pages that are suitable for a common buffer mapping.\r
-\r
-Arguments:\r
-\r
- This - Pointer to EFI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
- Type - Not used and can be ignored.\r
- MemoryType - Type of memory to allocate.\r
- Pages - Number of pages to allocate.\r
- HostAddress - Pointer to store the base system memory address\r
- of the allocated range.\r
- Attributes - Requested bit mask of attributes of the allocated\r
- range.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The requested memory range were allocated.\r
- EFI_INVALID_PARAMETER - Invalid parameter found.\r
- EFI_UNSUPPORTED - Attributes is unsupported.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
-\r
- //\r
- // Validate Attributes\r
- //\r
- if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- //\r
- // Check for invalid inputs\r
- //\r
- if (HostAddress == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData\r
- //\r
- if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Limit allocations to memory below DMA_MEMORY_TOP\r
- //\r
- PhysicalAddress = DMA_MEMORY_TOP;\r
-\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- MemoryType,\r
- Pages,\r
- &PhysicalAddress\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- *HostAddress = (VOID *) (UINTN) PhysicalAddress;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoFreeBuffer (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN UINTN Pages,\r
- OUT VOID *HostAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Free memory allocated in AllocateBuffer.\r
-\r
-Arguments:\r
-\r
- This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
- instance.\r
- Pages - Number of pages to free.\r
- HostAddress - The base system memory address of the\r
- allocated range.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Requested memory pages were freed.\r
- EFI_INVALID_PARAMETER - Invalid parameter found.\r
-\r
---*/\r
-{\r
- return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoFlush (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Flushes all PCI posted write transactions from a PCI host\r
- bridge to system memory.\r
-\r
-Arguments:\r
-\r
- This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - PCI posted write transactions were flushed\r
- from PCI host bridge to system memory.\r
- EFI_DEVICE_ERROR - Fail due to hardware error.\r
-\r
---*/\r
-{\r
- //\r
- // not supported yet\r
- //\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoGetAttributes (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- OUT UINT64 *Supported,\r
- OUT UINT64 *Attributes\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Get the attributes that a PCI root bridge supports and\r
- the attributes the PCI root bridge is currently using.\r
-\r
-Arguments:\r
-\r
- This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
- instance.\r
- Supports - A pointer to the mask of attributes that\r
- this PCI root bridge supports.\r
- Attributes - A pointer to the mask of attributes that\r
- this PCI root bridge is currently using.\r
-Returns:\r
-\r
- EFI_SUCCESS - Success.\r
- EFI_INVALID_PARAMETER - Invalid parameter found.\r
-\r
---*/\r
-\r
-// GC_TODO: Supported - add argument and description to function comment\r
-//\r
-// GC_TODO: Supported - add argument and description to function comment\r
-//\r
-// GC_TODO: Supported - add argument and description to function comment\r
-//\r
-{\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
-\r
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
-\r
- if (Attributes == NULL && Supported == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Set the return value for Supported and Attributes\r
- //\r
- if (Supported) {\r
- *Supported = PrivateData->Supports;\r
- }\r
-\r
- if (Attributes) {\r
- *Attributes = PrivateData->Attributes;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoSetAttributes (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN UINT64 Attributes,\r
- IN OUT UINT64 *ResourceBase,\r
- IN OUT UINT64 *ResourceLength\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Sets the attributes for a resource range on a PCI root bridge.\r
-\r
-Arguments:\r
-\r
- This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
- Attributes - The mask of attributes to set.\r
- ResourceBase - Pointer to the base address of the resource range\r
- to be modified by the attributes specified by Attributes.\r
- ResourceLength - Pointer to the length of the resource range to be modified.\r
-\r
-Returns:\r
- EFI_SUCCESS - Success.\r
- EFI_INVALID_PARAMETER - Invalid parameter found.\r
- EFI_OUT_OF_RESOURCES - Not enough resources to set the attributes upon.\r
-\r
---*/\r
-\r
-//\r
-// GC_TODO: EFI_UNSUPPORTED - add return value to function comment\r
-//\r
-{\r
- PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
-\r
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
-\r
- if (Attributes != 0) {\r
- Attributes &= (PrivateData->Supports);\r
- if (Attributes == 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- if (Attributes == PrivateData->Attributes) {\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // It is just a trick for some attribute can only be enabled or disabled\r
- // otherwise it can impact on other devices\r
- //\r
- PrivateData->Attributes = Attributes;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-RootBridgeIoConfiguration (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- OUT VOID **Resources\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Retrieves the current resource settings of this PCI root bridge\r
- in the form of a set of ACPI 2.0 resource descriptor.\r
-\r
-Arguments:\r
-\r
- This - Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
- Resources - Pointer to the ACPI 2.0 resource descriptor that\r
- describe the current configuration of this PCI root\r
- bridge.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Success.\r
- EFI_UNSUPPORTED - Current configuration of the PCI root bridge\r
- could not be retrieved.\r
-\r
---*/\r
-\r
-//\r
-// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment\r
-//\r
-{\r
- EFI_STATUS Status;\r
- UINTN Idx;\r
-\r
- PCI_ROOT_BRIDGE_INSTANCE *RbPrivateData;\r
- PCI_RES_NODE *ResAllocNode;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Config;\r
-\r
- //\r
- // Get this instance of the Root Bridge.\r
- //\r
- RbPrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
-\r
- //\r
- // If the pointer is not NULL, it points to a buffer already allocated.\r
- //\r
- if (RbPrivateData->ConfigBuffer == NULL) {\r
- Status = gBS->AllocatePool (\r
- EfiBootServicesData,\r
- TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),\r
- &RbPrivateData->ConfigBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- Config = RbPrivateData->ConfigBuffer;\r
-\r
- ZeroMem (Config, TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));\r
-\r
- for (Idx = 0; Idx < TypeMax; Idx++) {\r
-\r
- ResAllocNode = &RbPrivateData->ResAllocNode[Idx];\r
-\r
- if (ResAllocNode->Status != ResAllocated) {\r
- continue;\r
- }\r
-\r
- switch (ResAllocNode->Type) {\r
-\r
- case TypeIo:\r
- Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- Config->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;\r
- Config->AddrRangeMin = ResAllocNode->Base;\r
- Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;\r
- Config->AddrLen = ResAllocNode->Length;\r
- break;\r
-\r
- case TypeMem32:\r
- Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- Config->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- Config->AddrSpaceGranularity = 32;\r
- Config->AddrRangeMin = ResAllocNode->Base;\r
- Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;\r
- Config->AddrLen = ResAllocNode->Length;\r
- break;\r
-\r
- case TypePMem32:\r
- Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- Config->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- Config->SpecificFlag = 6;\r
- Config->AddrSpaceGranularity = 32;\r
- Config->AddrRangeMin = ResAllocNode->Base;\r
- Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;\r
- Config->AddrLen = ResAllocNode->Length;\r
- break;\r
-\r
- case TypeMem64:\r
- Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- Config->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- Config->SpecificFlag = 6;\r
- Config->AddrSpaceGranularity = 64;\r
- Config->AddrRangeMin = ResAllocNode->Base;\r
- Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;\r
- Config->AddrLen = ResAllocNode->Length;\r
- break;\r
-\r
- case TypePMem64:\r
- Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- Config->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;\r
- Config->SpecificFlag = 6;\r
- Config->AddrSpaceGranularity = 64;\r
- Config->AddrRangeMin = ResAllocNode->Base;\r
- Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;\r
- Config->AddrLen = ResAllocNode->Length;\r
- break;\r
-\r
- case TypeBus:\r
- Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;\r
- Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;\r
- Config->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;\r
- Config->AddrRangeMin = ResAllocNode->Base;\r
- Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;\r
- Config->AddrLen = ResAllocNode->Length;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
- Config++;\r
- }\r
- //\r
- // Terminate the entries.\r
- //\r
- ((EFI_ACPI_END_TAG_DESCRIPTOR *) Config)->Desc = ACPI_END_TAG_DESCRIPTOR;\r
- ((EFI_ACPI_END_TAG_DESCRIPTOR *) Config)->Checksum = 0x0;\r
-\r
- *Resources = RbPrivateData->ConfigBuffer;\r
- return EFI_SUCCESS;\r
-}\r