diff options
Diffstat (limited to 'CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c')
-rw-r--r-- | CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c | 845 |
1 files changed, 845 insertions, 0 deletions
diff --git a/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c b/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c new file mode 100644 index 0000000000..e924b44dcd --- /dev/null +++ b/CorebootModulePkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c @@ -0,0 +1,845 @@ +/*++ + +Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + DeviceIo.c + +Abstract: + + EFI PC-AT PCI Device IO driver + +--*/ +#include "PcatPciRootBridge.h" +#include "DeviceIo.h" + +EFI_STATUS +DeviceIoConstructor ( + IN EFI_HANDLE Handle, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN UINT16 PrimaryBus, + IN UINT16 SubordinateBus + ) +/*++ + +Routine Description: + + Initialize and install a Device IO protocol on a empty device path handle. + +Arguments: + + Handle - Handle of PCI RootBridge IO instance + PciRootBridgeIo - PCI RootBridge IO instance + DevicePath - Device Path of PCI RootBridge IO instance + PrimaryBus - Primary Bus + SubordinateBus - Subordinate Bus + +Returns: + + EFI_SUCCESS - This driver is added to ControllerHandle. + EFI_ALREADY_STARTED - This driver is already running on ControllerHandle. + Others - This driver does not support this device. + +--*/ +{ + EFI_STATUS Status; + DEVICE_IO_PRIVATE_DATA *Private; + + // + // Initialize the Device IO device instance. + // + Private = AllocateZeroPool (sizeof (DEVICE_IO_PRIVATE_DATA)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Private->Signature = DEVICE_IO_PRIVATE_DATA_SIGNATURE; + Private->Handle = Handle; + Private->PciRootBridgeIo = PciRootBridgeIo; + Private->DevicePath = DevicePath; + Private->PrimaryBus = PrimaryBus; + Private->SubordinateBus = SubordinateBus; + + Private->DeviceIo.Mem.Read = DeviceIoMemRead; + Private->DeviceIo.Mem.Write = DeviceIoMemWrite; + Private->DeviceIo.Io.Read = DeviceIoIoRead; + Private->DeviceIo.Io.Write = DeviceIoIoWrite; + Private->DeviceIo.Pci.Read = DeviceIoPciRead; + Private->DeviceIo.Pci.Write = DeviceIoPciWrite; + Private->DeviceIo.PciDevicePath = DeviceIoPciDevicePath; + Private->DeviceIo.Map = DeviceIoMap; + Private->DeviceIo.Unmap = DeviceIoUnmap; + Private->DeviceIo.AllocateBuffer = DeviceIoAllocateBuffer; + Private->DeviceIo.Flush = DeviceIoFlush; + Private->DeviceIo.FreeBuffer = DeviceIoFreeBuffer; + + // + // Install protocol interfaces for the Device IO device. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiDeviceIoProtocolGuid, + &Private->DeviceIo, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +EFI_STATUS +EFIAPI +DeviceIoMemRead ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Perform reading memory mapped I/O space of device. + +Arguments: + + This - A pointer to EFI_DEVICE_IO protocol instance. + Width - Width of I/O operations. + Address - The base address of I/O operations. + Count - The number of I/O operations to perform. + Bytes moves is Width size * Count, starting at Address. + Buffer - The destination buffer to store results. + +Returns: + + EFI_SUCCESS - The data was read from the device. + EFI_INVALID_PARAMETER - Width is invalid. + EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. + +--*/ +{ + EFI_STATUS Status; + DEVICE_IO_PRIVATE_DATA *Private; + + Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); + + if (Width > MMIO_COPY_UINT64) { + return EFI_INVALID_PARAMETER; + } + if (Width >= MMIO_COPY_UINT8) { + Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8); + Status = Private->PciRootBridgeIo->CopyMem ( + Private->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + (UINT64)(UINTN) Buffer, + Address, + Count + ); + } else { + Status = Private->PciRootBridgeIo->Mem.Read ( + Private->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + Count, + Buffer + ); + } + + return Status; +} + + + +EFI_STATUS +EFIAPI +DeviceIoMemWrite ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Perform writing memory mapped I/O space of device. + +Arguments: + + This - A pointer to EFI_DEVICE_IO protocol instance. + Width - Width of I/O operations. + Address - The base address of I/O operations. + Count - The number of I/O operations to perform. + Bytes moves is Width size * Count, starting at Address. + Buffer - The source buffer of data to be written. + +Returns: + + EFI_SUCCESS - The data was written to the device. + EFI_INVALID_PARAMETER - Width is invalid. + EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. + +--*/ +{ + EFI_STATUS Status; + DEVICE_IO_PRIVATE_DATA *Private; + + Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); + + if (Width > MMIO_COPY_UINT64) { + return EFI_INVALID_PARAMETER; + } + if (Width >= MMIO_COPY_UINT8) { + Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8); + Status = Private->PciRootBridgeIo->CopyMem ( + Private->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + (UINT64)(UINTN) Buffer, + Count + ); + } else { + Status = Private->PciRootBridgeIo->Mem.Write ( + Private->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + Count, + Buffer + ); + } + + return Status; +} + +EFI_STATUS +EFIAPI +DeviceIoIoRead ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Perform reading I/O space of device. + +Arguments: + + This - A pointer to EFI_DEVICE_IO protocol instance. + Width - Width of I/O operations. + Address - The base address of I/O operations. + Count - The number of I/O operations to perform. + Bytes moves is Width size * Count, starting at Address. + Buffer - The destination buffer to store results. + +Returns: + + EFI_SUCCESS - The data was read from the device. + EFI_INVALID_PARAMETER - Width is invalid. + EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. + +--*/ +{ + EFI_STATUS Status; + DEVICE_IO_PRIVATE_DATA *Private; + + Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); + + if (Width >= MMIO_COPY_UINT8) { + return EFI_INVALID_PARAMETER; + } + + Status = Private->PciRootBridgeIo->Io.Read ( + Private->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + Count, + Buffer + ); + + return Status; +} + +EFI_STATUS +EFIAPI +DeviceIoIoWrite ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Perform writing I/O space of device. + +Arguments: + + This - A pointer to EFI_DEVICE_IO protocol instance. + Width - Width of I/O operations. + Address - The base address of I/O operations. + Count - The number of I/O operations to perform. + Bytes moves is Width size * Count, starting at Address. + Buffer - The source buffer of data to be written. + +Returns: + + EFI_SUCCESS - The data was written to the device. + EFI_INVALID_PARAMETER - Width is invalid. + EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. + +--*/ +{ + EFI_STATUS Status; + DEVICE_IO_PRIVATE_DATA *Private; + + Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); + + if (Width >= MMIO_COPY_UINT8) { + return EFI_INVALID_PARAMETER; + } + + Status = Private->PciRootBridgeIo->Io.Write ( + Private->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + Count, + Buffer + ); + + return Status; +} + +EFI_STATUS +EFIAPI +DeviceIoPciRead ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Perform reading PCI configuration space of device + +Arguments: + + This - A pointer to EFI_DEVICE_IO protocol instance. + Width - Width of I/O operations. + Address - The base address of I/O operations. + Count - The number of I/O operations to perform. + Bytes moves is Width size * Count, starting at Address. + Buffer - The destination buffer to store results. + +Returns: + + EFI_SUCCESS - The data was read from the device. + EFI_INVALID_PARAMETER - Width is invalid. + EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. + +--*/ +{ + EFI_STATUS Status; + DEVICE_IO_PRIVATE_DATA *Private; + + Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); + + if ((UINT32)Width >= MMIO_COPY_UINT8) { + return EFI_INVALID_PARAMETER; + } + + Status = Private->PciRootBridgeIo->Pci.Read ( + Private->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + Count, + Buffer + ); + + return Status; +} + +EFI_STATUS +EFIAPI +DeviceIoPciWrite ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Perform writing PCI configuration space of device. + +Arguments: + + This - A pointer to EFI_DEVICE_IO protocol instance. + Width - Width of I/O operations. + Address - The base address of I/O operations. + Count - The number of I/O operations to perform. + Bytes moves is Width size * Count, starting at Address. + Buffer - The source buffer of data to be written. + +Returns: + + EFI_SUCCESS - The data was written to the device. + EFI_INVALID_PARAMETER - Width is invalid. + EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. + +--*/ +{ + EFI_STATUS Status; + DEVICE_IO_PRIVATE_DATA *Private; + + Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); + + if ((UINT32)Width >= MMIO_COPY_UINT8) { + return EFI_INVALID_PARAMETER; + } + + Status = Private->PciRootBridgeIo->Pci.Write ( + Private->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, + Address, + Count, + Buffer + ); + + return Status; +} + +EFI_DEVICE_PATH_PROTOCOL * +AppendPciDevicePath ( + IN DEVICE_IO_PRIVATE_DATA *Private, + IN UINT8 Bus, + IN UINT8 Device, + IN UINT8 Function, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN OUT UINT16 *BridgePrimaryBus, + IN OUT UINT16 *BridgeSubordinateBus + ) +/*++ + +Routine Description: + + Append a PCI device path node to another device path. + +Arguments: + + Private - A pointer to DEVICE_IO_PRIVATE_DATA instance. + Bus - PCI bus number of the device. + Device - PCI device number of the device. + Function - PCI function number of the device. + DevicePath - Original device path which will be appended a PCI device path node. + BridgePrimaryBus - Primary bus number of the bridge. + BridgeSubordinateBus - Subordinate bus number of the bridge. + +Returns: + + Pointer to the appended PCI device path. + +--*/ +{ + UINT16 ThisBus; + UINT8 ThisDevice; + UINT8 ThisFunc; + UINT64 Address; + PCI_TYPE01 PciBridge; + PCI_TYPE01 *PciPtr; + EFI_DEVICE_PATH_PROTOCOL *ReturnDevicePath; + PCI_DEVICE_PATH PciNode; + + PciPtr = &PciBridge; + for (ThisBus = *BridgePrimaryBus; ThisBus <= *BridgeSubordinateBus; ThisBus++) { + for (ThisDevice = 0; ThisDevice <= PCI_MAX_DEVICE; ThisDevice++) { + for (ThisFunc = 0; ThisFunc <= PCI_MAX_FUNC; ThisFunc++) { + Address = EFI_PCI_ADDRESS (ThisBus, ThisDevice, ThisFunc, 0); + ZeroMem (PciPtr, sizeof (PCI_TYPE01)); + Private->DeviceIo.Pci.Read ( + &Private->DeviceIo, + IO_UINT32, + Address, + 1, + &(PciPtr->Hdr.VendorId) + ); + if ((PciPtr->Hdr.VendorId == 0xffff) && (ThisFunc == 0)) { + break; + } + if (PciPtr->Hdr.VendorId == 0xffff) { + continue; + } + + Private->DeviceIo.Pci.Read ( + &Private->DeviceIo, + IO_UINT32, + Address, + sizeof (PCI_TYPE01) / sizeof (UINT32), + PciPtr + ); + if (IS_PCI_BRIDGE (PciPtr)) { + if (Bus >= PciPtr->Bridge.SecondaryBus && Bus <= PciPtr->Bridge.SubordinateBus) { + + PciNode.Header.Type = HARDWARE_DEVICE_PATH; + PciNode.Header.SubType = HW_PCI_DP; + SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode)); + + PciNode.Device = ThisDevice; + PciNode.Function = ThisFunc; + ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header); + + *BridgePrimaryBus = PciPtr->Bridge.SecondaryBus; + *BridgeSubordinateBus = PciPtr->Bridge.SubordinateBus; + return ReturnDevicePath; + } + } + + if ((ThisFunc == 0) && ((PciPtr->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x0)) { + // + // Skip sub functions, this is not a multi function device + // + break; + } + } + } + } + + ZeroMem (&PciNode, sizeof (PciNode)); + PciNode.Header.Type = HARDWARE_DEVICE_PATH; + PciNode.Header.SubType = HW_PCI_DP; + SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode)); + PciNode.Device = Device; + PciNode.Function = Function; + + ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header); + + *BridgePrimaryBus = 0xffff; + *BridgeSubordinateBus = 0xffff; + return ReturnDevicePath; +} + +EFI_STATUS +EFIAPI +DeviceIoPciDevicePath ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN UINT64 Address, + IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath + ) +/*++ + +Routine Description: + + Provides an EFI Device Path for a PCI device with the given PCI configuration space address. + +Arguments: + + This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. + Address - The PCI configuration space address of the device whose Device Path + is going to be returned. + PciDevicePath - A pointer to the pointer for the EFI Device Path for PciAddress. + Memory for the Device Path is allocated from the pool. + +Returns: + + EFI_SUCCESS - The PciDevicePath returns a pointer to a valid EFI Device Path. + EFI_UNSUPPORTED - The PciAddress does not map to a valid EFI Device Path. + EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources. + +--*/ +{ + DEVICE_IO_PRIVATE_DATA *Private; + UINT16 PrimaryBus; + UINT16 SubordinateBus; + UINT8 Bus; + UINT8 Device; + UINT8 Func; + + Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); + + Bus = (UINT8) (((UINT32) Address >> 24) & 0xff); + Device = (UINT8) (((UINT32) Address >> 16) & 0xff); + Func = (UINT8) (((UINT32) Address >> 8) & 0xff); + + if (Bus < Private->PrimaryBus || Bus > Private->SubordinateBus) { + return EFI_UNSUPPORTED; + } + + *PciDevicePath = Private->DevicePath; + PrimaryBus = Private->PrimaryBus; + SubordinateBus = Private->SubordinateBus; + do { + *PciDevicePath = AppendPciDevicePath ( + Private, + Bus, + Device, + Func, + *PciDevicePath, + &PrimaryBus, + &SubordinateBus + ); + if (*PciDevicePath == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } while (PrimaryBus != 0xffff); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +DeviceIoMap ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_OPERATION_TYPE Operation, + IN EFI_PHYSICAL_ADDRESS *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +/*++ + +Routine Description: + + Provides the device-specific addresses needed to access system memory. + +Arguments: + + This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. + Operation - Indicates if the bus master is going to read or write to system memory. + HostAddress - The system memory address to map to the device. + NumberOfBytes - On input the number of bytes to map. On output the number of bytes + that were mapped. + DeviceAddress - The resulting map address for the bus master device to use to access the + hosts HostAddress. + Mapping - A resulting value to pass to Unmap(). + +Returns: + + EFI_SUCCESS - The range was mapped for the returned NumberOfBytes. + EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined. + EFI_UNSUPPORTED - The HostAddress cannot be mapped as a common buffer. + EFI_DEVICE_ERROR - The system hardware could not map the requested address. + EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources. + +--*/ +{ + EFI_STATUS Status; + DEVICE_IO_PRIVATE_DATA *Private; + + Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); + + if ((UINT32)Operation > EfiBusMasterCommonBuffer) { + return EFI_INVALID_PARAMETER; + } + + if (((UINTN) (*HostAddress) != (*HostAddress)) && Operation == EfiBusMasterCommonBuffer) { + return EFI_UNSUPPORTED; + } + + Status = Private->PciRootBridgeIo->Map ( + Private->PciRootBridgeIo, + (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation, + (VOID *) (UINTN) (*HostAddress), + NumberOfBytes, + DeviceAddress, + Mapping + ); + + return Status; +} + +EFI_STATUS +EFIAPI +DeviceIoUnmap ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN VOID *Mapping + ) +/*++ + +Routine Description: + + Completes the Map() operation and releases any corresponding resources. + +Arguments: + + This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. + Mapping - The mapping value returned from Map(). + +Returns: + + EFI_SUCCESS - The range was unmapped. + EFI_DEVICE_ERROR - The data was not committed to the target system memory. + +--*/ +{ + EFI_STATUS Status; + DEVICE_IO_PRIVATE_DATA *Private; + + Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); + + Status = Private->PciRootBridgeIo->Unmap ( + Private->PciRootBridgeIo, + Mapping + ); + + return Status; +} + +EFI_STATUS +EFIAPI +DeviceIoAllocateBuffer ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress + ) +/*++ + +Routine Description: + + Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping. + +Arguments: + + This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. + Type - The type allocation to perform. + MemoryType - The type of memory to allocate, EfiBootServicesData or + EfiRuntimeServicesData. + Pages - The number of pages to allocate. + PhysicalAddress - A pointer to store the base address of the allocated range. + +Returns: + + EFI_SUCCESS - The requested memory pages were allocated. + EFI_OUT_OF_RESOURCES - The memory pages could not be allocated. + EFI_INVALID_PARAMETER - The requested memory type is invalid. + EFI_UNSUPPORTED - The requested PhysicalAddress is not supported on + this platform. + +--*/ +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS HostAddress; + + HostAddress = *PhysicalAddress; + + if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) { + return EFI_INVALID_PARAMETER; + } + + if ((UINT32)Type >= MaxAllocateType) { + return EFI_INVALID_PARAMETER; + } + + if ((Type == AllocateAddress) && (HostAddress + EFI_PAGES_TO_SIZE (Pages) - 1 > MAX_COMMON_BUFFER)) { + return EFI_UNSUPPORTED; + } + + if ((AllocateAnyPages == Type) || (AllocateMaxAddress == Type && HostAddress > MAX_COMMON_BUFFER)) { + Type = AllocateMaxAddress; + HostAddress = MAX_COMMON_BUFFER; + } + + Status = gBS->AllocatePages ( + Type, + MemoryType, + Pages, + &HostAddress + ); + if (EFI_ERROR (Status)) { + return Status; + } + + + *PhysicalAddress = HostAddress; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +DeviceIoFlush ( + IN EFI_DEVICE_IO_PROTOCOL *This + ) +/*++ + +Routine Description: + + Flushes any posted write data to the device. + +Arguments: + + This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. + +Returns: + + EFI_SUCCESS - The buffers were flushed. + EFI_DEVICE_ERROR - The buffers were not flushed due to a hardware error. + +--*/ +{ + EFI_STATUS Status; + DEVICE_IO_PRIVATE_DATA *Private; + + Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); + + Status = Private->PciRootBridgeIo->Flush (Private->PciRootBridgeIo); + + return Status; +} + +EFI_STATUS +EFIAPI +DeviceIoFreeBuffer ( + IN EFI_DEVICE_IO_PROTOCOL *This, + IN UINTN Pages, + IN EFI_PHYSICAL_ADDRESS HostAddress + ) +/*++ + +Routine Description: + + Frees pages that were allocated with AllocateBuffer(). + +Arguments: + + This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. + Pages - The number of pages to free. + HostAddress - The base address of the range to free. + +Returns: + + EFI_SUCCESS - The requested memory pages were freed. + EFI_NOT_FOUND - The requested memory pages were not allocated with + AllocateBuffer(). + EFI_INVALID_PARAMETER - HostAddress is not page aligned or Pages is invalid. + +--*/ +{ + if (((HostAddress & EFI_PAGE_MASK) != 0) || (Pages <= 0)) { + return EFI_INVALID_PARAMETER; + } + + return gBS->FreePages (HostAddress, Pages); +} |