deviceio.c

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

C
915
字号
/*++

Copyright (c) 2004 - 2005, 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:

--*/

#include "PciHostBridge.h"
#include "DeviceIo.h"
#include "pci22.h"

typedef struct {
  EFI_DEVICE_PATH_PROTOCOL  DeviceIoRootPath;
  EFI_DEVICE_PATH_PROTOCOL  EndDevicePath;
} EFI_DEV_IO_DEFAULT_DEVICE_PATH;

static EFI_DEV_IO_DEFAULT_DEVICE_PATH mEndDevicePath = {
  END_DEVICE_PATH_TYPE,
  END_ENTIRE_DEVICE_PATH_SUBTYPE,
  END_DEVICE_PATH_LENGTH,
  0
};

//
// Prototypes
//

//
// Device I/O Protocol Interface
//

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
  );

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
  );

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
  );

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
  );

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
  );

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
  );

EFI_STATUS
EFIAPI
DeviceIoPciDevicePath (
  IN EFI_DEVICE_IO_PROTOCOL        *This,
  IN UINT64                        Address,
  IN OUT EFI_DEVICE_PATH_PROTOCOL  **PciDevicePath
  );

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
  );

EFI_STATUS
EFIAPI
DeviceIoUnmap (
  IN EFI_DEVICE_IO_PROTOCOL   *This,
  IN VOID                     *Mapping
  );

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  *HostAddress
  );

EFI_STATUS
EFIAPI
DeviceIoFlush (
  IN EFI_DEVICE_IO_PROTOCOL  *This
  );

EFI_STATUS
EFIAPI
DeviceIoFreeBuffer (
  IN EFI_DEVICE_IO_PROTOCOL   *This,
  IN UINTN                    Pages,
  IN EFI_PHYSICAL_ADDRESS     HostAddress
  );

EFI_STATUS
DeviceIoConstructor (
  VOID
  )
/*++

  Routine Description:
    Initialize and install a Device IO protocol on a empty device path handle.

  Arguments:

  Returns:
    EFI_SUCCESS         - This driver is added to ControllerHandle.
    EFI_ALREADY_STARTED - This driver is already running on ControllerHandle.
    other               - This driver does not support this device.

--*/
// TODO:    EFI_NOT_FOUND - add return value to function comment
{
  EFI_STATUS                      Status;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
  DEVICE_IO_PRIVATE_DATA          *Private;
  EFI_HANDLE                      Handle;
  EFI_HANDLE                      *HandleBuffer;
  UINTN                           HandleCount;

  Handle  = NULL;
  Private = NULL;

  //
  // Locate PciRootBridge IO protocol.
  //
  Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, &PciRootBridgeIo);
  ASSERT_EFI_ERROR (Status);

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiPciRootBridgeIoProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status) || HandleCount == 0) {
    return EFI_NOT_FOUND;
  }

  Status = gBS->HandleProtocol (
                  HandleBuffer[0],
                  &gEfiDevicePathProtocolGuid,
                  (VOID *) (&DevicePath)
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Initialize the Device IO device instance.
  //
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof (DEVICE_IO_PRIVATE_DATA),
                  (VOID **) &Private
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  EfiZeroMem (Private, sizeof (DEVICE_IO_PRIVATE_DATA));

  Private->Signature                = DEVICE_IO_PRIVATE_DATA_SIGNATURE;
  Private->PciRootBridgeIo          = PciRootBridgeIo;
  Private->DevicePath               = DevicePath;
  Private->PrimaryBus               = 0;
  Private->SubordinateBus           = 255;

  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 (
                  &Handle,
                  &gEfiDeviceIoProtocolGuid,
                  &Private->DeviceIo,
                  &gEfiDevicePathProtocolGuid,
                  &mEndDevicePath,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    gBS->FreePool (Private);
    return 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:

  Arguments:

  Returns:

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Width - add argument and description to function comment
// TODO:    Address - add argument and description to function comment
// TODO:    Count - add argument and description to function comment
// TODO:    Buffer - add argument and description to function comment
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
{
  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:

  Arguments:

  Returns:

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Width - add argument and description to function comment
// TODO:    Address - add argument and description to function comment
// TODO:    Count - add argument and description to function comment
// TODO:    Buffer - add argument and description to function comment
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
{
  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:

  Arguments:

  Returns:

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Width - add argument and description to function comment
// TODO:    Address - add argument and description to function comment
// TODO:    Count - add argument and description to function comment
// TODO:    Buffer - add argument and description to function comment
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
{
  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:

  Arguments:

  Returns:

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Width - add argument and description to function comment
// TODO:    Address - add argument and description to function comment
// TODO:    Count - add argument and description to function comment
// TODO:    Buffer - add argument and description to function comment
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
{
  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
                                          );

⌨️ 快捷键说明

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