deviceio.c

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

C
915
字号

  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:

  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 < 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:

  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 < 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:

  Arguments:

  Returns:

--*/
// TODO:    Private - add argument and description to function comment
// TODO:    Bus - add argument and description to function comment
// TODO:    Device - add argument and description to function comment
// TODO:    Function - add argument and description to function comment
// TODO:    DevicePath - add argument and description to function comment
// TODO:    BridgePrimaryBus - add argument and description to function comment
// TODO:    BridgeSubordinateBus - add argument and description to function comment
{
  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);
        EfiZeroMem (PciPtr, sizeof (PCI_TYPE01));
        Private->DeviceIo.Pci.Read (
                                &Private->DeviceIo,
                                IO_UINT32,
                                Address,
                                1,
                                &(PciPtr->Hdr.VendorId)
                                );
        if (PciPtr->Hdr.VendorId == 0xffff) {
          break;
        } else {
          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      = EfiAppendDevicePathNode (DevicePath, &PciNode.Header);

              *BridgePrimaryBus     = PciPtr->Bridge.SecondaryBus;
              *BridgeSubordinateBus = PciPtr->Bridge.SubordinateBus;
              return ReturnDevicePath;
            }
          }

          if (ThisFunc == 0 && !(PciPtr->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION)) {
            //
            // Skip sub functions, this is not a multi function device
            //
            ThisFunc = 8;
          }
        }
      }
    }
  }

  EfiZeroMem (&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      = EfiAppendDevicePathNode (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:

  Arguments:

  Returns:

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Address - add argument and description to function comment
// TODO:    PciDevicePath - add argument and description to function comment
// TODO:    EFI_UNSUPPORTED - add return value to function comment
// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  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:

  Arguments:

  Returns:

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Operation - add argument and description to function comment
// TODO:    HostAddress - add argument and description to function comment
// TODO:    NumberOfBytes - add argument and description to function comment
// TODO:    DeviceAddress - add argument and description to function comment
// TODO:    Mapping - add argument and description to function comment
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
// TODO:    EFI_UNSUPPORTED - add return value to function comment
{
  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:

  Arguments:

  Returns:

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Mapping - add argument and description to function comment
{
  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:

  Arguments:

  Returns:

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Type - add argument and description to function comment
// TODO:    MemoryType - add argument and description to function comment
// TODO:    Pages - add argument and description to function comment
// TODO:    PhysicalAddress - add argument and description to function comment
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
// TODO:    EFI_UNSUPPORTED - add return value to function comment
// TODO:    EFI_UNSUPPORTED - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  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_UNSUPPORTED;
  }

  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:

  Arguments:

  Returns:

--*/
// TODO:    This - add argument and description to function comment
{
  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:

  Arguments:

  Returns:

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Pages - add argument and description to function comment
// TODO:    HostAddress - add argument and description to function comment
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
{
  if (((HostAddress & EFI_PAGE_MASK) != 0) || (Pages <= 0)) {
    return EFI_INVALID_PARAMETER;
  }

  return gBS->FreePages (HostAddress, Pages);
}

⌨️ 快捷键说明

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