Example #1
0
EFI_STATUS
EFIAPI
CpuIoServiceRead (
  IN EFI_CPU_IO2_PROTOCOL               *This,
  IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,
  IN  UINT64                            UserAddress,
  IN  UINTN                             Count,
  IN  OUT VOID                          *UserBuffer
  )
/*++

Routine Description:
  
  This is the service that implements the I/O read

Arguments:

  Pointer to an instance of the CPU I/O Protocol
  Width of the Memory Access
  Address of the I/O access
  Count of the number of accesses to perform
  Pointer to the buffer to read or write from I/O space

Returns:

  Status
  EFI_SUCCESS             - The data was read from or written to the EFI System.
  EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.
  EFI_INVALID_PARAMETER   - Buffer is NULL.
  EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.
  EFI_UNSUPPORTED         - The address range specified by Address, Width, and 
                            Count is not valid for this EFI System.
--*/
// TODO:    This - add argument and description to function comment
// TODO:    UserAddress - add argument and description to function comment
// TODO:    UserBuffer - add argument and description to function comment
{
  UINTN       Address;
  EFI_STATUS  Status;

  if (!UserBuffer) {
    return EFI_INVALID_PARAMETER;
  }

  Address = (UINTN) UserAddress;

  if ((Width < 0) || (Width >= EfiCpuIoWidthMaximum)) {
    return EFI_INVALID_PARAMETER;
  }

  Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Do nothing for Nt32 version
  //
  return EFI_UNSUPPORTED;
}
Example #2
0
File: CpuIo.c Project: Kohrara/edk
EFI_STATUS
EFIAPI
CpuIoServiceWrite (
    IN EFI_CPU_IO_PROTOCOL                *This,
    IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,
    IN  UINT64                            UserAddress,
    IN  UINTN                             Count,
    IN  OUT VOID                          *UserBuffer
)
/*++

Routine Description:


  This is the service that implements the I/O Write

Arguments:

  Pointer to an instance of the CPU I/O Protocol
  Width of the Memory Access
  Address of the I/O access
  Count of the number of accesses to perform
  Pointer to the buffer to read or write from I/O space

Returns:

  Status

  Status
  EFI_SUCCESS             - The data was read from or written to the EFI System.
  EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.
  EFI_INVALID_PARAMETER   - Buffer is NULL.
  EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.
  EFI_UNSUPPORTED         - The address range specified by Address, Width, and
                            Count is not valid for this EFI System.

--*/
// TODO:    This - add argument and description to function comment
// TODO:    UserAddress - add argument and description to function comment
// TODO:    UserBuffer - add argument and description to function comment
{
    UINTN       Address;
    EFI_STATUS  Status;
    UINTN       InStride;
    UINTN       OutStride;
    PTR         Buffer;
    LONG        ReturnedLength;
    UINT32      Result;

    if (!UserBuffer) {
        return EFI_INVALID_PARAMETER;
    }

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

    if (Width >= EfiCpuIoWidthMaximum) {
        return EFI_INVALID_PARAMETER;
    }

    Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);
    if (EFI_ERROR (Status)) {
        return Status;
    }

    InStride  = 1 << (Width & 0x03);
    OutStride = InStride;
    if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
        InStride = 0;
    }

    if (Width >= EfiCpuIoWidthFillUint8 && Width <= EfiCpuIoWidthFillUint64) {
        OutStride = 0;
    }

    Width         = Width & 0x03;

    gReadPending  = FALSE;
    //
    // NT32PASSTHRU: Thunk into our I/O routine to talk to the kernel driver IOCTL
    //               I/O such as write CF8->80000000, Read CFC etc......  Bit 31    = Enable PCI Config Access
    //                                                                    Bit 24-30 = Reserved must be zero (segment?)
    //                                                                    Bit 16-23 = Bus (0-255)
    //                                                                    Bit 11-15 = Device (0-31)
    //                                                                    Bit 8-10  = Function (0-7)
    //                                                                    Bit 2-7   = Target dword (0-63) (yields 256 bytes of access)
    //                                                                    Bit 0-1   = Zero's)
    //
    switch (Width) {
    case EfiCpuIoWidthUint8:
        //
        // If the NT32 Passthrough has forced a HostBridgeInit and if the request is from a device
        // on a given Bus/Device location.  Mask off the remaining functions
        //
        if (gHostBridgeInit) {
            if ((*(UINT32 *) Buffer.ui32 & 0xFFFFFF00) == *((UINT32 *) &gConfigData)) {
                Result = *Buffer.ui8;

                //
                // We found an access to our device
                //
                EFI_BREAKPOINT ();
                gWinNtThunk->DeviceIoControl (
                    gDeviceHandle,    // Handle to device
                    IOCTL_IO_WRITE,   // IO Control code to use
                    &Address,         // Address to communicate to driver
                    sizeof (UINT32),  // Length of buffer in bytes.
                    &Result,          // In Buffer to fill in by kernel driver.
                    sizeof (UINT8),   // Length of buffer in bytes.
                    &ReturnedLength,  // Bytes placed in In buffer.
                    NULL              // NULL means wait till op. completes.
                );
                gReadPending = TRUE;
                return EFI_SUCCESS;
            }
        }
        break;

    case EfiCpuIoWidthUint16:
        //
        // If the NT32 Passthrough has forced a HostBridgeInit and if the request is from a device
        // on a given Bus/Device location.  Mask off the remaining functions
        //
        if (gHostBridgeInit) {
            if ((*(UINT32 *) Buffer.ui32 & 0xFFFFFF00) == *((UINT32 *) &gConfigData)) {
                Result = *Buffer.ui16;

                //
                // We found an access to our device
                //
                EFI_BREAKPOINT ();
                gWinNtThunk->DeviceIoControl (
                    gDeviceHandle,    // Handle to device
                    IOCTL_IO_WRITE,   // IO Control code to use
                    &Address,         // Address to communicate to driver
                    sizeof (UINT32),  // Length of buffer in bytes.
                    &Result,          // In Buffer to fill in by kernel driver.
                    sizeof (UINT16),  // Length of buffer in bytes.
                    &ReturnedLength,  // Bytes placed in In buffer.
                    NULL              // NULL means wait till op. completes.
                );
                gReadPending = TRUE;
                return EFI_SUCCESS;
            }
        }
        break;

    case EfiCpuIoWidthUint32:
        //
        // If the NT32 Passthrough has forced a HostBridgeInit and if the request is from a device
        // on a given Bus/Device location.  Mask off the remaining functions
        //
        if (gHostBridgeInit) {
            if ((*(UINT32 *) Buffer.ui32 & 0xFFFFFF00) == *((UINT32 *) &gConfigData)) {
                Result = *Buffer.ui32;

                //
                // We found an access to our device
                //
                EFI_BREAKPOINT ();
                gWinNtThunk->DeviceIoControl (
                    gDeviceHandle,    // Handle to device
                    IOCTL_IO_WRITE,   // IO Control code to use
                    &Address,         // Address to communicate to driver
                    sizeof (UINT32),  // Length of buffer in bytes.
                    &Result,          // In Buffer to fill in by kernel driver.
                    sizeof (UINT32),  // Length of buffer in bytes.
                    &ReturnedLength,  // Bytes placed in In buffer.
                    NULL              // NULL means wait till op. completes.
                );
                gReadPending = TRUE;
                return EFI_SUCCESS;
            }
        }
        break;

    default:
        return EFI_INVALID_PARAMETER;
    }

    return EFI_SUCCESS;
}
Example #3
0
File: CpuIo.c Project: Kohrara/edk
EFI_STATUS
EFIAPI
CpuMemoryServiceWrite (
    IN EFI_CPU_IO_PROTOCOL                *This,
    IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,
    IN  UINT64                            Address,
    IN  UINTN                             Count,
    IN  OUT VOID                          *Buffer
)
/*++

Routine Description:

  Perform the Memory Access Read service for the CPU I/O Protocol

Arguments:

  Pointer to an instance of the CPU I/O Protocol
  Width of the Memory Access
  Address of the Memory access
  Count of the number of accesses to perform
  Pointer to the buffer to read or write from memory

Returns:

  Status

  EFI_SUCCESS             - The data was read from or written to the EFI System.
  EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.
  EFI_INVALID_PARAMETER   - Buffer is NULL.
  EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.
  EFI_UNSUPPORTED         - The address range specified by Address, Width, and
                            Count is not valid for this EFI System.

--*/
// TODO:    This - add argument and description to function comment
{
    EFI_STATUS  Status;
    PTR         In;
    PTR         Out;

    if (!Buffer) {
        return EFI_INVALID_PARAMETER;
    }

    Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);
    if (EFI_ERROR (Status)) {
        return Status;
    }

    In.buf  = (VOID *) (UINTN) Address;
    Out.buf = Buffer;
    if (Width >= EfiCpuIoWidthUint8 && Width <= EfiCpuIoWidthUint64) {
        return CpuIoMemRW (Width, Count, TRUE, In, TRUE, Out);
    }

    if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
        return CpuIoMemRW (Width, Count, FALSE, In, TRUE, Out);
    }

    if (Width >= EfiCpuIoWidthFillUint8 && Width <= EfiCpuIoWidthFillUint64) {
        return CpuIoMemRW (Width, Count, TRUE, In, FALSE, Out);
    }

    return EFI_INVALID_PARAMETER;
}