Ejemplo n.º 1
0
UINT8
PciRead8 (
  UINT8   Segment,
  UINT8   Bus,
  UINT8   DevFunc,
  UINT8   Register
  )
/*++

Routine Description:
  Perform an one byte PCI config cycle read
    
Arguments:
  Segment   - PCI Segment ACPI _SEG
  Bus       - PCI Bus
  DevFunc   - PCI Device(7:3) and Func(2:0)
  Register  - PCI config space register

Returns:
  Data read from PCI config space

--*/
{
  EFI_STATUS  Status;
  UINT32      PciAddress;
  UINT32      PciAddress1;
  UINT8       Data;

  PciAddress = GetPciAddress (Segment, Bus, DevFunc, Register);
  //
  // Set bit 31 for PCI config access
  //
  PciAddress1 = PciAddress;
  PciAddress  = ((PciAddress & 0xFFFFFFFC) | (0x80000000));

  Status      = EfiIoWrite (EfiCpuIoWidthUint32, PCI_CONFIG_INDEX_PORT, 1, &PciAddress);

  if (EFI_ERROR (Status)) {
    return 0;
  }

  EfiIoRead (EfiCpuIoWidthUint8, (PCI_CONFIG_DATA_PORT + (PciAddress1 & 0x3)), 1, &Data);

  return Data;
}
Ejemplo n.º 2
0
UINT32
IoRead32 (
  IN  UINT64    Address
  )
/*++

Routine Description:
  Do a four byte IO read

Arguments:
  Address - IO address to read

Returns: 
  Data read

--*/
{
  UINT32  Buffer;

  Buffer = 0;
  EfiIoRead (EfiCpuIoWidthUint32, Address, 1, &Buffer);
  return Buffer;
}
Ejemplo n.º 3
0
UINT16
IoRead16 (
  IN  UINT64    Address
  )
/*++

Routine Description:
  Do a two byte IO read

Arguments:
  Address - IO address to read

Returns: 
  Data read

--*/
{
  UINT16  Buffer;

  Buffer = 0;
  EfiIoRead (EfiCpuIoWidthUint16, Address, 1, &Buffer);
  return Buffer;
}
Ejemplo n.º 4
0
//
// Delay Primative
//
VOID
EfiStall (
  IN  UINTN   Microseconds
  )
/*++

Routine Description:
 Delay for at least the request number of microseconds
    
Arguments:
  Microseconds - Number of microseconds to delay.

Returns:
  NONE

--*/
{
  UINT8 Data;
  UINT8 InitialState;
  UINTN CycleIterations;

  CycleIterations = 0;
  Data            = 0;
  InitialState    = 0;

  if (EfiAtRuntime ()) {
    //
    // The time-source is 30 us granular, so calibrate the timing loop
    // based on this baseline
    // Error is possible 30us.
    //
    CycleIterations = (Microseconds - 1) / 30 + 1;

    //
    // Use the DMA Refresh timer in port 0x61.  Cheap but effective.
    // The only issue is that the granularity is 30us, and we want to
    // guarantee "at least" one full transition to avoid races.
    //
    //
    //   _____________/----------\__________/--------
    //
    //                |<--15us-->|<--15us-->|
    //
    // --------------------------------------------------> Time (us)
    //
    while (CycleIterations--) {
      EfiIoRead (EfiCpuIoWidthUint8, 0x61, 1, &Data);
      Data &= REFRESH_CYCLE_TOGGLE_BIT;
      InitialState = Data;

      //
      // Capture first transition (strictly less than one period)
      //
      while (InitialState == Data) {
        EfiIoRead (EfiCpuIoWidthUint8, 0x61, 1, &Data);
        Data &= REFRESH_CYCLE_TOGGLE_BIT;
      }

      InitialState = Data;
      //
      // Capture next transition (guarantee at least one full pulse)
      //
      while (InitialState == Data) {
        EfiIoRead (EfiCpuIoWidthUint8, 0x61, 1, &Data);
        Data &= REFRESH_CYCLE_TOGGLE_BIT;
      }
    }
  } else {
    gBS->Stall (Microseconds);
  }
}