示例#1
0
文件: CpuIo.c 项目: Kohrara/edk
STATIC
EFI_STATUS
CpuIoMemRW (
  IN  EFI_CPU_IO_PROTOCOL_WIDTH  Width,
  IN  UINTN                      Count,
  IN  BOOLEAN                    DestinationStrideFlag,
  OUT PTR                        Destination,
  IN  BOOLEAN                    SourceStrideFlag,
  IN  PTR                        Source
  )
/*++

Routine Description:

  Private service to perform memory mapped I/O read/write

Arguments:

  Width                 - Width of the memory mapped I/O operation
  Count                 - Count of the number of accesses to perform
  DestinationStrideFlag - Boolean flag indicates if the destination is to be incremented
  Destination           - Destination of the memory mapped I/O operation
  SourceStrideFlag      - Boolean flag indicates if the source is to be incremented
  Source                - Source of the memory mapped I/O operation

Returns:

  EFI_SUCCESS           - Successful operation
  EFI_INVALID_PARAMETER - Width is invalid

--*/
{
  UINTN Stride;
  UINTN DestinationStride;
  UINTN SourceStride;

  Width             = Width & 0x03;
  Stride            = (UINTN)1 << Width;
  DestinationStride = DestinationStrideFlag ? Stride : 0;
  SourceStride      = SourceStrideFlag ? Stride : 0;

  //
  // Loop for each iteration and move the data
  //
  switch (Width) {
  case EfiCpuIoWidthUint8:
    for (; Count > 0; Count--, Destination.buf += DestinationStride, Source.buf += SourceStride) {
      MEMORY_FENCE ();
      *Destination.ui8 = *Source.ui8;
      MEMORY_FENCE ();
    }
    break;

  case EfiCpuIoWidthUint16:
    for (; Count > 0; Count--, Destination.buf += DestinationStride, Source.buf += SourceStride) {
      MEMORY_FENCE ();
      *Destination.ui16 = *Source.ui16;
      MEMORY_FENCE ();
    }
    break;

  case EfiCpuIoWidthUint32:
    for (; Count > 0; Count--, Destination.buf += DestinationStride, Source.buf += SourceStride) {
      MEMORY_FENCE ();
      *Destination.ui32 = *Source.ui32;
      MEMORY_FENCE ();
    }
    break;

  case EfiCpuIoWidthUint64:
    for (; Count > 0; Count--, Destination.buf += DestinationStride, Source.buf += SourceStride) {
      MEMORY_FENCE ();
      *Destination.ui64 = *Source.ui64;
      MEMORY_FENCE ();
    }
    break;

  default:
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}
示例#2
0
EFI_STATUS
PcatRootBridgeIoIoRead (
  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL        *This,
  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,
  IN     UINT64                                 UserAddress,
  IN     UINTN                                  Count,
  IN OUT VOID                                   *UserBuffer
  )
{
  PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
  UINTN                         InStride;
  UINTN                         OutStride;
  UINTN                         AlignMask;
  UINTN                         Address;
  PTR                           Buffer;
  UINT16                        Data16;
  UINT32                        Data32;
  
 
  if ( UserBuffer == NULL ) {
    return EFI_INVALID_PARAMETER;
  }
  
  PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);

  Address    = (UINTN)  UserAddress;
  Buffer.buf = (UINT8 *)UserBuffer;

  if ( Address < PrivateData->IoBase || Address > PrivateData->IoLimit ) {
    return EFI_INVALID_PARAMETER;
  }
    
  if ((UINT32)Width >= EfiPciWidthMaximum) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Width & 0x03) == EfiPciWidthUint64) {
    return EFI_INVALID_PARAMETER;
  }

  AlignMask = (1 << (Width & 0x03)) - 1;
  if ( Address & AlignMask ) {
    return EFI_INVALID_PARAMETER;
  }

  InStride  = 1 << (Width & 0x03);
  OutStride = InStride;
  if (Width >=EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
    InStride = 0;
  }
  if (Width >=EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
    OutStride = 0;
  }
  Width = Width & 0x03;

  Address += PrivateData->PhysicalIoBase;

  //
  // Loop for each iteration and move the data
  //

  switch (Width) {
  case EfiPciWidthUint8:
    for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
      MEMORY_FENCE();
      *Buffer.ui8 = PORT_TO_MEM8(Address);
      MEMORY_FENCE();
    }
    break;

  case EfiPciWidthUint16:
    for (; Count > 0; Count--, Buffer.buf += OutStride, Address += InStride) {
      MEMORY_FENCE();
      if (Buffer.ui & 0x1) {
        Data16 = PORT_TO_MEM16(Address);
        *Buffer.ui8     = (UINT8)(Data16 & 0xff);
        *(Buffer.ui8+1) = (UINT8)((Data16 >> 8) & 0xff);
      } else {
        *Buffer.ui16 = PORT_TO_MEM16(Address);
      }
      MEMORY_FENCE();
    }
示例#3
0
文件: CpuIo.c 项目: Kohrara/edk
EFI_STATUS
CpuIoMemRW (
    IN EFI_CPU_IO_PROTOCOL_WIDTH     Width,
    IN UINTN                         Count,
    IN BOOLEAN                       InStrideFlag,
    IN PTR                           In,
    IN BOOLEAN                       OutStrideFlag,
    OUT PTR                          Out
)
/*++

Routine Description:

  Private service to provide the memory read/write

Arguments:

  Width of the Memory Access
  Count of the number of accesses to perform

Returns:

  Status

  EFI_SUCCESS           - Successful transaction
  EFI_INVALID_PARAMETER - Unsupported width and address combination

--*/
// TODO:    InStrideFlag - add argument and description to function comment
// TODO:    In - add argument and description to function comment
// TODO:    OutStrideFlag - add argument and description to function comment
// TODO:    Out - add argument and description to function comment
{
    UINTN Stride;
    UINTN InStride;
    UINTN OutStride;
    LONG  ReturnedLength;

    Width     = Width & 0x03;
    Stride    = 1 << Width;
    InStride  = InStrideFlag ? Stride : 0;
    OutStride = OutStrideFlag ? Stride : 0;

    //
    // Loop for each iteration and move the data
    //
    switch (Width) {
    case EfiCpuIoWidthUint8:
        for (; Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
            MEMORY_FENCE ();
            gWinNtThunk->DeviceIoControl (
                gDeviceHandle,    // Handle to device
                IOCTL_MEM_COPY,   // IO Control code to use
                Out.ui8,          // Out Buffer to communicate to driver
                Count,            // Length of buffer in bytes.
                In.ui8,           // In Buffer to fill in by kernel driver.
                Count,            // Length of buffer in bytes.
                &ReturnedLength,  // Bytes placed in In buffer.
                NULL              // NULL means wait till op. completes.
            );
            MEMORY_FENCE ();
        }
        break;

    case EfiCpuIoWidthUint16:
        for (; Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
            MEMORY_FENCE ();
            gWinNtThunk->DeviceIoControl (
                gDeviceHandle,    // Handle to device
                IOCTL_MEM_COPY,   // IO Control code to use
                Out.ui16,         // Out Buffer to communicate to driver
                Count * 2,        // Length of buffer in bytes.
                In.ui16,          // In Buffer to fill in by kernel driver.
                Count * 2,        // Length of buffer in bytes.
                &ReturnedLength,  // Bytes placed in In buffer.
                NULL              // NULL means wait till op. completes.
            );
            MEMORY_FENCE ();
        }
        break;

    case EfiCpuIoWidthUint32:
        for (; Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
            MEMORY_FENCE ();
            gWinNtThunk->DeviceIoControl (
                gDeviceHandle,    // Handle to device
                IOCTL_MEM_COPY,   // IO Control code to use
                Out.ui32,         // Out Buffer to communicate to driver
                Count * 4,        // Length of buffer in bytes.
                In.ui32,          // In Buffer to fill in by kernel driver.
                Count * 4,        // Length of buffer in bytes.
                &ReturnedLength,  // Bytes placed in In buffer.
                NULL              // NULL means wait till op. completes.
            );
            MEMORY_FENCE ();
        }
        break;

    default:
        return EFI_INVALID_PARAMETER;
    }

    return EFI_SUCCESS;
}