deviceio.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 846 行 · 第 1/2 页

C
846
字号
/*++

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 "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 = EfiLibAllocateZeroPool (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,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?