summaryrefslogtreecommitdiffstats
path: root/DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c
diff options
context:
space:
mode:
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2008-04-17 05:48:13 +0000
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2008-04-17 05:48:13 +0000
commitc69dd9dfad3eb97d5e21f520f3ba35d102ec4cfa (patch)
treee6065a748931519b3cf11d9811c0beef9c80d58e /DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c
parentfcf03596d10de53e45292bd9eb4767a8ddc344ed (diff)
downloadedk2-c69dd9dfad3eb97d5e21f520f3ba35d102ec4cfa.tar.gz
edk2-c69dd9dfad3eb97d5e21f520f3ba35d102ec4cfa.tar.bz2
edk2-c69dd9dfad3eb97d5e21f520f3ba35d102ec4cfa.zip
Porting Duet module from EDKI to EDKII
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5076 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c')
-rw-r--r--DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c845
1 files changed, 845 insertions, 0 deletions
diff --git a/DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c b/DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c
new file mode 100644
index 0000000000..286c03ef4c
--- /dev/null
+++ b/DuetPkg/PciRootBridgeNoEnumerationDxe/DeviceIo.c
@@ -0,0 +1,845 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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 = Width - MMIO_COPY_UINT8;
+ Status = Private->PciRootBridgeIo->CopyMem (
+ Private->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ (UINT64) 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 = Width - MMIO_COPY_UINT8;
+ Status = Private->PciRootBridgeIo->CopyMem (
+ Private->PciRootBridgeIo,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Address,
+ (UINT64) 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 (Width < 0 || 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 (Width < 0 || 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 (Operation < 0 || 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 ((Type >= MaxAllocateType) || (Type < AllocateAnyPages)) {
+ 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);
+}