コード例 #1
0
ファイル: AcpiSmmPlatform.c プロジェクト: OznOg/edk2
EFI_STATUS
GetAllQncPmBase (
  IN EFI_SMM_SYSTEM_TABLE2       *Smst
  )
/*++

Routine Description:

  Get QNC chipset LPC Power Management I/O Base at runtime.

Arguments:

  Smst  -  The standard SMM system table.

Returns:

  EFI_SUCCESS  -  Successfully init the device.
  Other        -  Error occured whening calling Dxe lib functions.

--*/
{
  mAcpiSmm.QncPmBase    = PciRead16 (PCI_LIB_ADDRESS(PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, R_QNC_LPC_PM1BLK)) & B_QNC_LPC_PM1BLK_MASK;
  mAcpiSmm.QncGpe0Base  = PciRead16 (PCI_LIB_ADDRESS(PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, R_QNC_LPC_GPE0BLK)) & B_QNC_LPC_GPE0BLK_MASK;

  //
  // Quark does not support Changing Primary SoC IOBARs from what was
  // setup in SEC/PEI UEFI stages.
  //
  ASSERT (mAcpiSmm.QncPmBase == (UINT32) PcdGet16 (PcdPm1blkIoBaseAddress));
  ASSERT (mAcpiSmm.QncGpe0Base == (UINT32) PcdGet16 (PcdGpe0blkIoBaseAddress));
  return EFI_SUCCESS;
}
コード例 #2
0
ファイル: PlatformInitDxe.c プロジェクト: OznOg/edk2
VOID
GetQncName (
  VOID
  )
{
  DEBUG  ((EFI_D_INFO, "QNC Name: "));
  switch (PciRead16 (PCI_LIB_ADDRESS (MC_BUS, MC_DEV, MC_FUN, PCI_DEVICE_ID_OFFSET))) {
  case QUARK_MC_DEVICE_ID:
    DEBUG  ((EFI_D_INFO, "Quark"));
    break;
  case QUARK2_MC_DEVICE_ID:
    DEBUG  ((EFI_D_INFO, "Quark2"));
    break;
  default:
    DEBUG  ((EFI_D_INFO, "Unknown"));
  }

  //
  // Revision
  //
  switch (PciRead8 (PCI_LIB_ADDRESS (MC_BUS, MC_DEV, MC_FUN, PCI_REVISION_ID_OFFSET))) {
  case QNC_MC_REV_ID_A0:
    DEBUG  ((EFI_D_INFO, " - A0 stepping\n"));
    break;
  default:
    DEBUG  ((EFI_D_INFO, " - xx\n"));
  }

  return;
}
コード例 #3
0
ファイル: AcpiTimerLib.c プロジェクト: FishYu1222/edk2
/**
  The constructor function enables ACPI IO space.

  If ACPI I/O space not enabled, this function will enable it.
  It will always return RETURN_SUCCESS.

  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.

**/
RETURN_STATUS
EFIAPI
AcpiTimerLibConstructor (
  VOID
  )
{
  UINTN   Bus;
  UINTN   Device;
  UINTN   Function;
  UINTN   EnableRegister;
  UINT8   EnableMask;

  //
  // ASSERT for the invalid PCD values. They must be configured to the real value. 
  //
  ASSERT (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0xFFFF);
  ASSERT (PcdGet16 (PcdAcpiIoPortBaseAddress)      != 0xFFFF);

  //
  // If the register offset to the BAR for the ACPI I/O Port Base Address is 0x0000, then 
  // no PCI register programming is required to enable access to the the ACPI registers
  // specified by PcdAcpiIoPortBaseAddress
  //
  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) == 0x0000) {
    return RETURN_SUCCESS;
  }

  //
  // ASSERT for the invalid PCD values. They must be configured to the real value. 
  //
  ASSERT (PcdGet8  (PcdAcpiIoPciDeviceNumber)   != 0xFF);
  ASSERT (PcdGet8  (PcdAcpiIoPciFunctionNumber) != 0xFF);
  ASSERT (PcdGet16 (PcdAcpiIoPciEnableRegisterOffset) != 0xFFFF);

  //
  // Retrieve the PCD values for the PCI configuration space required to program the ACPI I/O Port Base Address
  //
  Bus            = PcdGet8  (PcdAcpiIoPciBusNumber);
  Device         = PcdGet8  (PcdAcpiIoPciDeviceNumber);
  Function       = PcdGet8  (PcdAcpiIoPciFunctionNumber);
  EnableRegister = PcdGet16 (PcdAcpiIoPciEnableRegisterOffset);
  EnableMask     = PcdGet8  (PcdAcpiIoBarEnableMask);

  //
  // If ACPI I/O space is not enabled yet, program ACPI I/O base address and enable it.
  //
  if ((PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister) & EnableMask) != EnableMask)) {
    PciWrite16 (
      PCI_LIB_ADDRESS (Bus, Device, Function, PcdGet16 (PcdAcpiIoPciBarRegisterOffset)),
      PcdGet16 (PcdAcpiIoPortBaseAddress)
      );
    PciOr8 (
      PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister),
      EnableMask
      );
  }
  
  return RETURN_SUCCESS;
}
コード例 #4
0
ファイル: VlvPlatformInit.c プロジェクト: FishYu1222/edk2
EFI_STATUS
EFIAPI    
PostPmInitCallBack (
  IN EFI_EVENT Event,
  IN VOID      *Context
  )
{
  UINT64      OriginalGTTMMADR;
  UINT32      LoGTBaseAddress;
  UINT32      HiGTBaseAddress;

  //
  // Enable Bus Master, I/O and Memory access on 0:2:0
  //
  PciOr8 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_CMD), (BIT2 | BIT1));

  //
  // only 32bit read/write is legal for device 0:2:0
  //
  OriginalGTTMMADR  = (UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR));
  OriginalGTTMMADR  = LShiftU64 ((UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR + 4)), 32) | (OriginalGTTMMADR);

  //
  // 64bit GTTMADR does not work for S3 save script table since it is executed in PEIM phase
  // Program temporarily 32bits GTTMMADR for POST and S3 resume
  //
  LoGTBaseAddress                   = (UINT32) (GTTMMADR & 0xFFFFFFFF);
  HiGTBaseAddress                   = (UINT32) RShiftU64 ((GTTMMADR & 0xFFFFFFFF00000000), 32);
  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR), LoGTBaseAddress);
  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4), HiGTBaseAddress);



  //
  // Restore original GTTMMADR
  //
  LoGTBaseAddress                   = (UINT32) (OriginalGTTMMADR & 0xFFFFFFFF);
  HiGTBaseAddress                   = (UINT32) RShiftU64 ((OriginalGTTMMADR & 0xFFFFFFFF00000000), 32);

  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR), LoGTBaseAddress);
  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4), HiGTBaseAddress);


  //
  // Lock the following registers, GGC, BDSM, BGSM
  //
  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_MGGC_OFFSET), LockBit);
  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_BSM_OFFSET), LockBit);
  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_BGSM), LockBit);

  gBS->CloseEvent (Event);

  //
  // Return final status
  //
  return EFI_SUCCESS;
}
コード例 #5
0
ファイル: PciCfg2.c プロジェクト: bhanug/virtualbox
/**
   Convert EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS to PCI_LIB_ADDRESS.

   @param Address   PCI address with EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS format.

   @return PCI address with PCI_LIB_ADDRESS format.

**/
UINTN
PciCfgAddressConvert (
  EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS *Address
  )
{
  if (Address->ExtendedRegister == 0) {
    return PCI_LIB_ADDRESS (Address->Bus, Address->Device, Address->Function, Address->Register);
  }

  return PCI_LIB_ADDRESS (Address->Bus, Address->Device, Address->Function, Address->ExtendedRegister);
}
コード例 #6
0
/**
  The constructor function enables ACPI IO space.

  If ACPI I/O space not enabled, this function will enable it.
  It will always return RETURN_SUCCESS.

  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.

**/
RETURN_STATUS
   EFIAPI
   IntelQNCAcpiTimerLibConstructor (
   VOID
   )
{  
   if ((PciRead32 (PCI_LIB_ADDRESS (LPC_PCI_BUS, LPC_PCI_DEV, LPC_PCI_FUNC, R_LPC_PM1BLK)) & BIT31) == 0) {
     //
     // If ACPI I/O space is not enabled, program ACPI I/O base address and enable it.
     //
     PciWrite32 (PCI_LIB_ADDRESS (LPC_PCI_BUS, LPC_PCI_DEV, LPC_PCI_FUNC, R_LPC_PM1BLK), BIT31 | PcdGet16 (PcdPm1blkIoBaseAddress));
   }
   return RETURN_SUCCESS;
}
コード例 #7
0
ファイル: AcpiTimerLib.c プロジェクト: FishYu1222/edk2
/**
  Internal function to retrieve the ACPI I/O Port Base Address.

  Internal function to retrieve the ACPI I/O Port Base Address.

  @return The 16-bit ACPI I/O Port Base Address.

**/
UINT16
InternalAcpiGetAcpiTimerIoPort (
  VOID
  )
{
  UINT16  Port;
  
  Port = PcdGet16 (PcdAcpiIoPortBaseAddress);
  
  //
  // If the register offset to the BAR for the ACPI I/O Port Base Address is not 0x0000, then 
  // read the PCI register for the ACPI BAR value in case the BAR has been programmed to a 
  // value other than PcdAcpiIoPortBaseAddress
  //
  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0x0000) {
    Port = PciRead16 (PCI_LIB_ADDRESS (
                        PcdGet8  (PcdAcpiIoPciBusNumber), 
                        PcdGet8  (PcdAcpiIoPciDeviceNumber), 
                        PcdGet8  (PcdAcpiIoPciFunctionNumber), 
                        PcdGet16 (PcdAcpiIoPciBarRegisterOffset)
                        ));
  }
  
  return (Port & PcdGet16 (PcdAcpiIoPortBaseAddressMask)) + PcdGet16 (PcdAcpiPm1TmrOffset);
}
コード例 #8
0
/**
  The constructor function enables ACPI IO space.

  If ACPI I/O space not enabled, this function will enable it.
  It will always return RETURN_SUCCESS.

  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.

**/
RETURN_STATUS
EFIAPI
AcpiTimerLibConstructor (
  VOID
  )
{
  UINT8     u8Device = 7;
  UINT16    u16VendorID = 0;
  UINT16    u16DeviceID = 0;
  u16VendorID = PciRead16(PCI_LIB_ADDRESS(0, u8Device, 0, 0));
  u16DeviceID = PciRead16(PCI_LIB_ADDRESS(0, u8Device, 0, 2));
  if (   u16VendorID != 0x8086
      || u16DeviceID != 0x7113)
    return RETURN_ABORTED;

  if (PciRead8 (PCI_LIB_ADDRESS (0,u8Device,0,0x80)) & 1) {
    mPmba = PciRead32 (PCI_LIB_ADDRESS (0, u8Device, 0, 0x40));
    ASSERT (mPmba & PCI_BAR_IO);
    DEBUG((DEBUG_INFO, "%a:%d mPmba:%x\n", __FUNCTION__, __LINE__, mPmba));
    mPmba &= ~PCI_BAR_IO;
    DEBUG((DEBUG_INFO, "%a:%d mPmba:%x\n", __FUNCTION__, __LINE__, mPmba));
  } else {
    PciAndThenOr32 (PCI_LIB_ADDRESS (0,u8Device,0,0x40),
                    (UINT32) ~0xfc0, mPmba);
    PciOr8         (PCI_LIB_ADDRESS (0,u8Device,0,0x04), 0x01);
    DEBUG((DEBUG_INFO, "%a:%d mPmba:%x\n", __FUNCTION__, __LINE__, mPmba));
  }

  //
  // ACPI Timer enable is in Bus 0, Device ?, Function 3
  //
  PciOr8         (PCI_LIB_ADDRESS (0,u8Device,0,0x80), 0x01);
  return RETURN_SUCCESS;
}
コード例 #9
0
ファイル: Platform.c プロジェクト: ChenFanFnst/edk2
VOID
MiscInitialization (
  VOID
  )
{
  //
  // Disable A20 Mask
  //
  IoOr8 (0x92, BIT1);

  //
  // Build the CPU hob with 36-bit addressing and 16-bits of IO space.
  //
  BuildCpuHob (36, 16);

  //
  // If PMREGMISC/PMIOSE is set, assume the ACPI PMBA has been configured (for
  // example by Xen) and skip the setup here. This matches the logic in
  // AcpiTimerLibConstructor ().
  //
  if ((PciRead8 (PCI_LIB_ADDRESS (0, 1, 3, 0x80)) & 0x01) == 0) {
    //
    // The PEI phase should be exited with fully accessibe PIIX4 IO space:
    // 1. set PMBA
    //
    PciAndThenOr32 (
      PCI_LIB_ADDRESS (0, 1, 3, 0x40),
      (UINT32) ~0xFFC0,
      PcdGet16 (PcdAcpiPmBaseAddress)
      );

    //
    // 2. set PCICMD/IOSE
    //
    PciOr8 (
      PCI_LIB_ADDRESS (0, 1, 3, PCI_COMMAND_OFFSET),
      EFI_PCI_COMMAND_IO_SPACE
      );

    //
    // 3. set PMREGMISC/PMIOSE
    //
    PciOr8 (PCI_LIB_ADDRESS (0, 1, 3, 0x80), 0x01);
  }
}
コード例 #10
0
ファイル: BdsPlatform.c プロジェクト: jeppeter/vbox
VOID
AcpiInitialization (
  VOID
  )
{
  //
  // Set ACPI SCI_EN bit in PMCNTRL
  //
  IoOr16 ((PciRead32 (PCI_LIB_ADDRESS (0, 1, 3, 0x40)) & ~BIT0) + 4, BIT0);
}
コード例 #11
0
VOID
MiscInitialization ()
{
  //
  // Disable A20 Mask
  //
  IoOr8 (0x92, BIT1);

  //
  // Build the CPU hob with 36-bit addressing and 16-bits of IO space.
  //
  BuildCpuHob (36, 16);

  //
  // Set the PM I/O base address to 0x400
  //
  PciAndThenOr32 (PCI_LIB_ADDRESS (0, 1, 3, 0x40), (UINT32) ~0xfc0, 0x400);
}
コード例 #12
0
ファイル: PciInfo.c プロジェクト: 0xDEC0DE8/STM
/**

  This function scan PCI bus.

  @param VtdIndex      VTd engine index
  @param Bus           Pci bus

  @retval EFI_SUCCESS  scan PCI bus successfully.

**/
EFI_STATUS
ScanPciBus (
  IN UINTN          VtdIndex,
  IN UINT8          Bus
  )
{
  UINT8                   Device;
  UINT8                   Function;
  UINT8                   SecondaryBusNumber;
  UINT8                   HeaderType;
  UINT8                   BaseClass;
  UINT8                   SubClass;
  UINT32                  MaxFunction;
  UINT16                  VendorID;
  UINT16                  DeviceID;
  EFI_STATUS              Status;

  // Scan the PCI bus for devices
  for (Device = 0; Device < PCI_MAX_DEVICE + 1; Device++) {
    HeaderType = PciRead8 (PCI_LIB_ADDRESS(Bus, Device, 0, PCI_HEADER_TYPE_OFFSET));
    MaxFunction = PCI_MAX_FUNC + 1;
    if ((HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00) {
      MaxFunction = 1;
    }
    for (Function = 0; Function < MaxFunction; Function++) {
      VendorID  = PciRead16 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_VENDOR_ID_OFFSET));
      DeviceID  = PciRead16 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_DEVICE_ID_OFFSET));
      if (VendorID == 0xFFFF && DeviceID == 0xFFFF) {
        continue;
      }

      Status = RegisterPciDevice (VtdIndex, Bus, Device, Function, FALSE);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      BaseClass = PciRead8 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_CLASSCODE_OFFSET + 2));
      if (BaseClass == PCI_CLASS_BRIDGE) {
        SubClass = PciRead8 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_CLASSCODE_OFFSET + 1));
        if (SubClass == PCI_CLASS_BRIDGE_P2P) {
          SecondaryBusNumber = PciRead8 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
          DEBUG ((EFI_D_INFO,"  ScanPciBus: PCI bridge B%02x D%02x F%02x (SecondBus:%02x)\n", Bus, Device, Function, SecondaryBusNumber));
          if (SecondaryBusNumber != 0) {
            ScanPciBus (VtdIndex, SecondaryBusNumber);
          }
        }
      }
    }
  }

  return EFI_SUCCESS;
}
コード例 #13
0
ファイル: OpalPasswordSmm.c プロジェクト: iderzh/edk2
/**
  Save/Restore RootPort configuration space.

  @param[in] DeviceNode             - The device node.
  @param[in] SaveAction             - TRUE: Save, FALSE: Restore
  @param[in,out] PcieConfBufferList     - Configuration space data buffer for save/restore

  @retval - PCIE base address of this RootPort
**/
UINTN
SaveRestoreRootportConfSpace (
  IN     OPAL_SMM_DEVICE                *DeviceNode,
  IN     BOOLEAN                        SaveAction,
  IN OUT UINT8                          **PcieConfBufferList
  )
{
  UINTN      RpBase;
  UINTN      Length;
  PCI_DEVICE *DevNode;
  UINT8      *StorePcieConfData;
  UINTN      Index;

  Length = 0;
  Index  = 0;
  RpBase = 0;

  while (Length < DeviceNode->Length) {
    DevNode = (PCI_DEVICE *)((UINT8*)DeviceNode->PciBridgeNode + Length);
    RpBase = PCI_LIB_ADDRESS (DevNode->BusNum, DevNode->DevNum, DevNode->FuncNum, 0x0);

    if (PcieConfBufferList != NULL) {
      if (SaveAction) {
        StorePcieConfData = (UINT8 *) AllocateZeroPool (OPAL_PCIE_ROOTPORT_SAVESIZE);
        ASSERT (StorePcieConfData != NULL);
        OpalPciRead (StorePcieConfData, RpBase, OPAL_PCIE_ROOTPORT_SAVESIZE);
        PcieConfBufferList[Index] = StorePcieConfData;
      } else {
        // Skip PCIe Command & Status registers
        StorePcieConfData = PcieConfBufferList[Index];
        OpalPciWrite (RpBase, StorePcieConfData, 4);
        OpalPciWrite (RpBase + 8, StorePcieConfData + 8, OPAL_PCIE_ROOTPORT_SAVESIZE - 8);

        FreePool (StorePcieConfData);
      }
    }

    Length += sizeof (PCI_DEVICE);
    Index ++;
  }

  return RpBase;
}
コード例 #14
0
ファイル: BdsPlatform.c プロジェクト: jeppeter/vbox
/**
  This notification function is invoked when an instance of the
  EFI_DEVICE_PATH_PROTOCOL is produced.

  @param  Event                 The event that occured
  @param  Context               For EFI compatiblity.  Not used.

**/
VOID
EFIAPI
NotifyDevPath (
  IN  EFI_EVENT Event,
  IN  VOID      *Context
  )
{
  EFI_HANDLE                            Handle;
  EFI_STATUS                            Status;
  UINTN                                 BufferSize;
  EFI_DEVICE_PATH_PROTOCOL             *DevPathNode;
  ATAPI_DEVICE_PATH                    *Atapi;

  //
  // Examine all new handles
  //
  for (;;) {
    //
    // Get the next handle
    //
    BufferSize = sizeof (Handle);
    Status = gBS->LocateHandle (
              ByRegisterNotify,
              NULL,
              mEfiDevPathNotifyReg,
              &BufferSize,
              &Handle
              );

    //
    // If not found, we're done
    //
    if (EFI_NOT_FOUND == Status) {
      break;
    }

    if (EFI_ERROR (Status)) {
      continue;
    }

    //
    // Get the DevicePath protocol on that handle
    //
    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);
    ASSERT_EFI_ERROR (Status);

    while (!IsDevicePathEnd (DevPathNode)) {
      //
      // Find the handler to dump this device path node
      //
      if (
           (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&
           (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)
         ) {
        Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;
        PciOr16 (
          PCI_LIB_ADDRESS (
            0,
            1,
            1,
            (Atapi->PrimarySecondary == 1) ? 0x42: 0x40
            ),
          BIT15
          );
      }

      //
      // Next device path node
      //
      DevPathNode = NextDevicePathNode (DevPathNode);
    }
  }

  return;
}
コード例 #15
0
ファイル: VbeShim.c プロジェクト: ChenFanFnst/edk2
/**
  Install the VBE Info and VBE Mode Info structures, and the VBE service
  handler routine in the C segment. Point the real-mode Int10h interrupt vector
  to the handler. The only advertised mode is 1024x768x32.

  @param[in] CardName         Name of the video card to be exposed in the
                              Product Name field of the VBE Info structure. The
                              parameter must originate from a
                              QEMU_VIDEO_CARD.Name field.
  @param[in] FrameBufferBase  Guest-physical base address of the video card's
                              frame buffer.
**/
VOID
InstallVbeShim (
  IN CONST CHAR16         *CardName,
  IN EFI_PHYSICAL_ADDRESS FrameBufferBase
  )
{
  EFI_PHYSICAL_ADDRESS Segment0, SegmentC, SegmentF;
  UINTN                Segment0Pages;
  IVT_ENTRY            *Int0x10;
  EFI_STATUS           Status;
  UINTN                Pam1Address;
  UINT8                Pam1;
  UINTN                SegmentCPages;
  VBE_INFO             *VbeInfoFull;
  VBE_INFO_BASE        *VbeInfo;
  UINT8                *Ptr;
  UINTN                Printed;
  VBE_MODE_INFO        *VbeModeInfo;

  Segment0 = 0x00000;
  SegmentC = 0xC0000;
  SegmentF = 0xF0000;

  //
  // Attempt to cover the real mode IVT with an allocation. This is a UEFI
  // driver, hence the arch protocols have been installed previously. Among
  // those, the CPU arch protocol has configured the IDT, so we can overwrite
  // the IVT used in real mode.
  //
  // The allocation request may fail, eg. if LegacyBiosDxe has already run.
  //
  Segment0Pages = 1;
  Int0x10       = (IVT_ENTRY *)(UINTN)Segment0 + 0x10;
  Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode,
                  Segment0Pages, &Segment0);

  if (EFI_ERROR (Status)) {
    EFI_PHYSICAL_ADDRESS Handler;

    //
    // Check if a video BIOS handler has been installed previously -- we
    // shouldn't override a real video BIOS with our shim, nor our own shim if
    // it's already present.
    //
    Handler = (Int0x10->Segment << 4) + Int0x10->Offset;
    if (Handler >= SegmentC && Handler < SegmentF) {
      DEBUG ((EFI_D_VERBOSE, "%a: Video BIOS handler found at %04x:%04x\n",
        __FUNCTION__, Int0x10->Segment, Int0x10->Offset));
      return;
    }

    //
    // Otherwise we'll overwrite the Int10h vector, even though we may not own
    // the page at zero.
    //
    DEBUG ((EFI_D_VERBOSE, "%a: failed to allocate page at zero: %r\n",
      __FUNCTION__, Status));
  } else {
    //
    // We managed to allocate the page at zero. SVN r14218 guarantees that it
    // is NUL-filled.
    //
    ASSERT (Int0x10->Segment == 0x0000);
    ASSERT (Int0x10->Offset  == 0x0000);
  }

  //
  // Put the shim in place first.
  //
  Pam1Address = PCI_LIB_ADDRESS (0, 0, 0, 0x5A);
  //
  // low nibble covers 0xC0000 to 0xC3FFF
  // high nibble covers 0xC4000 to 0xC7FFF
  // bit1 in each nibble is Write Enable
  // bit0 in each nibble is Read Enable
  //
  Pam1 = PciRead8 (Pam1Address);
  PciWrite8 (Pam1Address, Pam1 | (BIT1 | BIT0));

  //
  // We never added memory space durig PEI or DXE for the C segment, so we
  // don't need to (and can't) allocate from there. Also, guest operating
  // systems will see a hole in the UEFI memory map there.
  //
  SegmentCPages = 4;

  ASSERT (sizeof mVbeShim <= EFI_PAGES_TO_SIZE (SegmentCPages));
  CopyMem ((VOID *)(UINTN)SegmentC, mVbeShim, sizeof mVbeShim);

  //
  // Fill in the VBE INFO structure.
  //
  VbeInfoFull = (VBE_INFO *)(UINTN)SegmentC;
  VbeInfo     = &VbeInfoFull->Base;
  Ptr         = VbeInfoFull->Buffer;

  CopyMem (VbeInfo->Signature, "VESA", 4);
  VbeInfo->VesaVersion = 0x0300;

  VbeInfo->OemNameAddress = (UINT32)(SegmentC << 12 | (UINT16)(UINTN)Ptr);
  CopyMem (Ptr, "QEMU", 5);
  Ptr += 5;

  VbeInfo->Capabilities = BIT0; // DAC can be switched into 8-bit mode

  VbeInfo->ModeListAddress = (UINT32)(SegmentC << 12 | (UINT16)(UINTN)Ptr);
  *(UINT16*)Ptr = 0x00f1; // mode number
  Ptr += 2;
  *(UINT16*)Ptr = 0xFFFF; // mode list terminator
  Ptr += 2;

  VbeInfo->VideoMem64K = (UINT16)((1024 * 768 * 4 + 65535) / 65536);
  VbeInfo->OemSoftwareVersion = 0x0000;

  VbeInfo->VendorNameAddress = (UINT32)(SegmentC << 12 | (UINT16)(UINTN)Ptr);
  CopyMem (Ptr, "OVMF", 5);
  Ptr += 5;

  VbeInfo->ProductNameAddress = (UINT32)(SegmentC << 12 | (UINT16)(UINTN)Ptr);
  Printed = AsciiSPrint ((CHAR8 *)Ptr,
              sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer), "%s",
              CardName);
  Ptr += Printed + 1;

  VbeInfo->ProductRevAddress = (UINT32)(SegmentC << 12 | (UINT16)(UINTN)Ptr);
  CopyMem (Ptr, mProductRevision, sizeof mProductRevision);
  Ptr += sizeof mProductRevision;

  ASSERT (sizeof VbeInfoFull->Buffer >= Ptr - VbeInfoFull->Buffer);
  ZeroMem (Ptr, sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer));

  //
  // Fil in the VBE MODE INFO structure.
  //
  VbeModeInfo = (VBE_MODE_INFO *)(VbeInfoFull + 1);

  //
  // bit0: mode supported by present hardware configuration
  // bit1: optional information available (must be =1 for VBE v1.2+)
  // bit3: set if color, clear if monochrome
  // bit4: set if graphics mode, clear if text mode
  // bit5: mode is not VGA-compatible
  // bit7: linear framebuffer mode supported
  //
  VbeModeInfo->ModeAttr = BIT7 | BIT5 | BIT4 | BIT3 | BIT1 | BIT0;

  //
  // bit0: exists
  // bit1: bit1: readable
  // bit2: writeable
  //
  VbeModeInfo->WindowAAttr              = BIT2 | BIT1 | BIT0;

  VbeModeInfo->WindowBAttr              = 0x00;
  VbeModeInfo->WindowGranularityKB      = 0x0040;
  VbeModeInfo->WindowSizeKB             = 0x0040;
  VbeModeInfo->WindowAStartSegment      = 0xA000;
  VbeModeInfo->WindowBStartSegment      = 0x0000;
  VbeModeInfo->WindowPositioningAddress = 0x0000;
  VbeModeInfo->BytesPerScanLine         = 1024 * 4;

  VbeModeInfo->Width                = 1024;
  VbeModeInfo->Height               = 768;
  VbeModeInfo->CharCellWidth        = 8;
  VbeModeInfo->CharCellHeight       = 16;
  VbeModeInfo->NumPlanes            = 1;
  VbeModeInfo->BitsPerPixel         = 32;
  VbeModeInfo->NumBanks             = 1;
  VbeModeInfo->MemoryModel          = 6; // direct color
  VbeModeInfo->BankSizeKB           = 0;
  VbeModeInfo->NumImagePagesLessOne = 0;
  VbeModeInfo->Vbe3                 = 0x01;

  VbeModeInfo->RedMaskSize      = 8;
  VbeModeInfo->RedMaskPos       = 16;
  VbeModeInfo->GreenMaskSize    = 8;
  VbeModeInfo->GreenMaskPos     = 8;
  VbeModeInfo->BlueMaskSize     = 8;
  VbeModeInfo->BlueMaskPos      = 0;
  VbeModeInfo->ReservedMaskSize = 8;
  VbeModeInfo->ReservedMaskPos  = 24;

  //
  // bit1: Bytes in reserved field may be used by application
  //
  VbeModeInfo->DirectColorModeInfo = BIT1;

  VbeModeInfo->LfbAddress       = (UINT32)FrameBufferBase;
  VbeModeInfo->OffScreenAddress = 0;
  VbeModeInfo->OffScreenSizeKB  = 0;

  VbeModeInfo->BytesPerScanLineLinear = 1024 * 4;
  VbeModeInfo->NumImagesLessOneBanked = 0;
  VbeModeInfo->NumImagesLessOneLinear = 0;
  VbeModeInfo->RedMaskSizeLinear      = 8;
  VbeModeInfo->RedMaskPosLinear       = 16;
  VbeModeInfo->GreenMaskSizeLinear    = 8;
  VbeModeInfo->GreenMaskPosLinear     = 8;
  VbeModeInfo->BlueMaskSizeLinear     = 8;
  VbeModeInfo->BlueMaskPosLinear      = 0;
  VbeModeInfo->ReservedMaskSizeLinear = 8;
  VbeModeInfo->ReservedMaskPosLinear  = 24;
  VbeModeInfo->MaxPixelClockHz        = 0;

  ZeroMem (VbeModeInfo->Reserved, sizeof VbeModeInfo->Reserved);

  //
  // Clear Write Enable (bit1), keep Read Enable (bit0) set
  //
  PciWrite8 (Pam1Address, (Pam1 & ~BIT1) | BIT0);

  //
  // Second, point the Int10h vector at the shim.
  //
  Int0x10->Segment = SegmentC >> 4;
  Int0x10->Offset  = (EFI_PHYSICAL_ADDRESS)(UINTN)(VbeModeInfo + 1) - SegmentC;

  DEBUG ((EFI_D_INFO, "%a: VBE shim installed\n", __FUNCTION__));
}
コード例 #16
0
ファイル: AcpiSmmPlatform.c プロジェクト: OznOg/edk2
EFI_STATUS
SaveRuntimeScriptTable (
  IN EFI_SMM_SYSTEM_TABLE2       *Smst
  )
{
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  PciAddress;
  UINT32                Data32;
  UINT16                Data16;
  UINT8                 Mask;
  UINTN                 Index;
  UINTN                 Offset;
  UINT16                DeviceId;

  //
  // Check what Soc we are running on (read Host bridge DeviceId)
  //
  DeviceId = QncGetSocDeviceId();

  //
  // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
  // and vital to S3 resume. That's why we put save code here
  //
  Index = 0;
  while (mPciCfgRegTable[Index] != PCI_DEVICE_END) {

    PciAddress.Bus              = mPciCfgRegTable[Index++];
    PciAddress.Device           = mPciCfgRegTable[Index++];
    PciAddress.Function         = mPciCfgRegTable[Index++];
    PciAddress.Register         = 0;
    PciAddress.ExtendedRegister = 0;

    Data16 = PciRead16 (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));
    if (Data16 == 0xFFFF) {
      Index += 8;
      continue;
    }

    for (Offset = 0, Mask = 0x01; Offset < 256; Offset += 4, Mask <<= 1) {

      if (Mask == 0x00) {
        Mask = 0x01;
      }

      if (mPciCfgRegTable[Index + Offset / 32] & Mask) {

        PciAddress.Register = (UINT8) Offset;
        Data32 = PciRead32 (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));


        //
        // Save latest settings to runtime script table
        //
        S3BootScriptSavePciCfgWrite (
             S3BootScriptWidthUint32,
             PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register)),
             1,
             &Data32
             );
      }
    }

    Index += 8;

  }

  //
  // Save message bus registers
  //
  Index = 0;
  while (QNCS3SaveExtReg[Index] != 0xFF) {
    Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);

    //
    // Save IMR settings with IMR protection disabled initially
    // HMBOUND and IMRs will be locked just before jumping to the OS waking vector
    //
    if (QNCS3SaveExtReg[Index] == QUARK_NC_MEMORY_MANAGER_SB_PORT_ID) {
      if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) == QUARK_NC_MEMORY_MANAGER_IMRXL)) {
        Data32 &= ~IMR_LOCK;
        if (DeviceId == QUARK2_MC_DEVICE_ID) {
          Data32 &= ~IMR_EN;
        }
      }
      if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXRM)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) >= QUARK_NC_MEMORY_MANAGER_IMRXRM)) {
        Data32 = (UINT32)IMRX_ALL_ACCESS;
      }
    }

    //
    // Save latest settings to runtime script table
    //
    S3BootScriptSavePciCfgWrite (
      S3BootScriptWidthUint32,
      PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)),
      1,
      &Data32
     );

    Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);

    S3BootScriptSavePciCfgWrite (
      S3BootScriptWidthUint32,
      PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
      1,
      &Data32
     );
    Index += 2;
  }

  Index = 0;
  while (QNCS3SaveExtReg[Index] != 0xFF) {
    //
    // Save IMR settings with IMR protection enabled (above script was to handle restoring all settings first - now we want to enable)
    //
    if (QNCS3SaveExtReg[Index] == QUARK_NC_MEMORY_MANAGER_SB_PORT_ID) {
      if (DeviceId == QUARK2_MC_DEVICE_ID) {
        if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) == QUARK_NC_MEMORY_MANAGER_IMRXL)) {
          Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);
          Data32 &= ~IMR_LOCK;

          //
          // Save latest settings to runtime script table
          //
          S3BootScriptSavePciCfgWrite (
            S3BootScriptWidthUint32,
            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)),
            1,
            &Data32
          );

          Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);

          S3BootScriptSavePciCfgWrite (
            S3BootScriptWidthUint32,
            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
            1,
            &Data32
          );
        }
      } else {
        if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXRM)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) >= QUARK_NC_MEMORY_MANAGER_IMRXRM)) {
          Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);

          //
          // Save latest settings to runtime script table
          //
          S3BootScriptSavePciCfgWrite (
            S3BootScriptWidthUint32,
            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)),
            1,
            &Data32
          );

          Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);

          S3BootScriptSavePciCfgWrite (
            S3BootScriptWidthUint32,
            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
            1,
            &Data32
          );
        }
      }
    }
    Index += 2;
  }

  // Check if ECC scrub enabled and need re-enabling on resume
  // All scrub related configuration registers are saved on suspend
  // as part of QNCS3SaveExtReg configuration table script.
  // The code below extends the S3 resume script with scrub reactivation
  // message (if needed only)
  Data32 = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_CONFIG_REG);
  if( 0 != (Data32 & SCRUB_CFG_ACTIVE)) {

      Data32 = SCRUB_RESUME_MSG();

      S3BootScriptSavePciCfgWrite (
        S3BootScriptWidthUint32,
        PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
        1,
        &Data32
       );
  }

  //
  // Save I/O ports to S3 script table
  //

  //
  // Important to trap Sx for SMM
  //
  Data32 = IoRead32 (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE);
  S3BootScriptSaveIoWrite(S3BootScriptWidthUint32, (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE), 1, &Data32);

  return EFI_SUCCESS;
}
コード例 #17
0
ファイル: QNCRegTable.c プロジェクト: Laurie0131/OpenPlatform
VOID
PlatformInitQNCRegs (
  VOID
  )
{
  //
  // All devices on bus 0.
  // Device 0:
  //    FNC 0: Host Bridge
  // Device 20:
  //    FNC 0: IOSF2AHB Bridge
  // Device 21:
  //    FNC 0: IOSF2AHB Bridge
  // Device 23:
  //    FNC 0: PCIe Port 0
  // Device 24:
  //    FNC 0: PCIe Port 1

  // Device 31:
  //    FNC 0: PCI-LPC Bridge
  //
  S3PciWrite32 (PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_QNC_LPC_FWH_BIOS_DEC),
                B_QNC_LPC_FWH_BIOS_DEC_F0 | B_QNC_LPC_FWH_BIOS_DEC_F8 |
                B_QNC_LPC_FWH_BIOS_DEC_E0 | B_QNC_LPC_FWH_BIOS_DEC_E8 |
                B_QNC_LPC_FWH_BIOS_DEC_D0 | B_QNC_LPC_FWH_BIOS_DEC_D8 |
                B_QNC_LPC_FWH_BIOS_DEC_C0 | B_QNC_LPC_FWH_BIOS_DEC_C8
                );

  //
  // Program SCI Interrupt for IRQ9
  //
  S3PciWrite8 (PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_QNC_LPC_ACTL),
               V_QNC_LPC_ACTL_SCIS_IRQ9
               );

  //
  // Program Quark Interrupt Route Registers
  //
  S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT0IR,
             PcdGet16(PcdQuarkAgent0IR)
             );
  S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT1IR,
             PcdGet16(PcdQuarkAgent1IR)
             );
  S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT2IR,
             PcdGet16(PcdQuarkAgent2IR)
             );
  S3MmioWrite16 ((UINTN)PcdGet64(PcdRcbaMmioBaseAddress) + R_QNC_RCRB_AGENT3IR,
             PcdGet16(PcdQuarkAgent3IR)
             );

  //
  // Program SVID and SID for QNC PCI devices. In order to boost performance, we
  // combine two 16 bit PCI_WRITE into one 32 bit PCI_WRITE. The programmed LPC SVID
  // will reflect on all internal devices's SVID registers
  //
  S3PciWrite32 (PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_EFI_PCI_SVID),
                (UINT32)(V_INTEL_VENDOR_ID + (QUARK_V_LPC_DEVICE_ID_0 << 16))
                );

  //
  // Write once on Element Self Description Register before OS boot
  //
  QNCMmio32And (PcdGet64(PcdRcbaMmioBaseAddress), 0x04, 0xFF00FFFF);

  return;
}
コード例 #18
0
ファイル: LegacyPlatform.c プロジェクト: etiago/vbox
/**
  Finds the device path that should be used as the primary display adapter.

  @param  VgaHandle - The handle of the video device

**/
VOID
GetSelectedVgaDeviceInfo (
  OUT EFI_HANDLE                *VgaHandle
  )
{
  EFI_STATUS                Status;
  UINTN                     HandleCount;
  EFI_HANDLE                *HandleBuffer;
  UINTN                     Index;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  PCI_TYPE00                Pci;
  UINT8                     MinBus;
  UINT8                     MaxBus;
  UINTN                     Segment;
  UINTN                     Bus;
  UINTN                     Device;
  UINTN                     Function;
  UINTN                     SelectedAddress;
  UINTN                     CurrentAddress;

  //
  // Initialize return to 'not found' state
  //
  *VgaHandle = NULL;

  //
  // Initialize variable states.  Ths is important for selecting the VGA device
  // if multiple devices exist behind a single bridge.
  //
  HandleCount = 0;
  HandleBuffer = NULL;
  SelectedAddress = PCI_LIB_ADDRESS(0xff, 0x1f, 0x7, 0);

  //
  // The bus range to search for a VGA device in.
  //
  MinBus = MaxBus = 0;

  //
  // Start to check all the pci io to find all possible VGA device
  //
  HandleCount = 0;
  HandleBuffer = NULL;
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiPciIoProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return;
  }

  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID**)&PciIo);
    if (!EFI_ERROR (Status)) {
      //
      // Detemine if this is in the correct bus range.
      //
      Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
      if (EFI_ERROR(Status) || (Bus < MinBus || Bus > MaxBus)) {
        continue;
      }

      //
      // Read device information.
      //
      Status = PciIo->Pci.Read (
                        PciIo,
                        EfiPciIoWidthUint32,
                        0,
                        sizeof (Pci) / sizeof (UINT32),
                        &Pci
                        );
      if (EFI_ERROR (Status)) {
        continue;
      }

      //
      // Make sure the device is a VGA device.
      //
      if (!IS_PCI_VGA (&Pci)) {
        continue;
      }
      DEBUG ((EFI_D_INFO,
        "PCI VGA: 0x%04x:0x%04x\n",
        Pci.Hdr.VendorId,
        Pci.Hdr.DeviceId
        ));

      //
      // Currently we use the lowest numbered bus/device/function if multiple
      // devices are found in the target bus range.
      //
      CurrentAddress = PCI_LIB_ADDRESS(Bus, Device, Function, 0);
      if (CurrentAddress < SelectedAddress) {
        SelectedAddress = CurrentAddress;
        *VgaHandle = HandleBuffer[Index];
      }
    }
  }

  FreePool (HandleBuffer);
}
コード例 #19
0
/**
  Performs any early platform specific GPIO Controller manipulation.

**/
VOID
EFIAPI
EarlyPlatformGpioCtrlerManipulation (
  VOID
  )
{
  UINT32                            IohGpioBase;
  UINT32                            Data32;
  UINT32                            Addr;
  UINT32                            DevPcieAddr;
  UINT16                            SaveCmdReg;
  UINT32                            SaveBarReg;
  UINT16                            PciVid;
  UINT16                            PciDid;

  IohGpioBase = (UINT32) PcdGet64 (PcdIohGpioMmioBase);

  DevPcieAddr = PCI_LIB_ADDRESS (
                  PcdGet8 (PcdIohGpioBusNumber),
                  PcdGet8 (PcdIohGpioDevNumber),
                  PcdGet8 (PcdIohGpioFunctionNumber),
                  0
                  );

  //
  // Do nothing if not a supported device.
  //
  PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET);
  PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET);
  if((PciVid != V_IOH_I2C_GPIO_VENDOR_ID) || (PciDid != V_IOH_I2C_GPIO_DEVICE_ID)) {
    return;
  }

  //
  // Save current settings for PCI CMD/BAR registers.
  //
  SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET);
  SaveBarReg = PciRead32 (DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister));

  //
  // Use predefined tempory memory resource.
  //
  PciWrite32 ( DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister), IohGpioBase);
  PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);

  //
  // Gpio Controller Manipulation Tasks.
  //

    //
    // Reset Cypress Expander on Galileo Platform
    //
    Addr = IohGpioBase + GPIO_SWPORTA_DR;
    Data32 = *((volatile UINT32 *) (UINTN)(Addr));
    Data32 |= BIT4;                                 // Cypress Reset line controlled by GPIO<4>
    *((volatile UINT32 *) (UINTN)(Addr)) = Data32;

    Data32 = *((volatile UINT32 *) (UINTN)(Addr));
    Data32 &= ~BIT4;                                // Cypress Reset line controlled by GPIO<4>
    *((volatile UINT32 *) (UINTN)(Addr)) = Data32;

  //
  // Restore settings for PCI CMD/BAR registers
  //
  PciWrite32 ((DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister)), SaveBarReg);
  PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);
}
コード例 #20
0
ファイル: SpiCommon.c プロジェクト: RafaelRMachado/edk2
EFI_STATUS
EFIAPI
SpiProtocolExecute (
  IN     EFI_SPI_PROTOCOL   *This,
  IN     UINT8              OpcodeIndex,
  IN     UINT8              PrefixOpcodeIndex,
  IN     BOOLEAN            DataCycle,
  IN     BOOLEAN            Atomic,
  IN     BOOLEAN            ShiftOut,
  IN     UINTN              Address,
  IN     UINT32             DataByteCount,
  IN OUT UINT8              *Buffer,
  IN     SPI_REGION_TYPE    SpiRegionType
  )
/*++

Routine Description:

  Execute SPI commands from the host controller.
  This function would be called by runtime driver, please do not use any MMIO marco here

Arguments:

  This              Pointer to the EFI_SPI_PROTOCOL instance.
  OpcodeIndex       Index of the command in the OpCode Menu.
  PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence.
  DataCycle         TRUE if the SPI cycle contains data
  Atomic            TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
  ShiftOut          If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
  Address           In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
                    Region, this value specifies the offset from the Region Base; for BIOS Region,
                    this value specifies the offset from the start of the BIOS Image. In Non
                    Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
                    Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
                    Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
                    supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
                    the flash (in Non Descriptor Mode)
  DataByteCount     Number of bytes in the data portion of the SPI cycle. This function may break the
                    data transfer into multiple operations. This function ensures each operation does
                    not cross 256 byte flash address boundary.
                    *NOTE: if there is some SPI chip that has a stricter address boundary requirement
                    (e.g., its write page size is < 256 byte), then the caller cannot rely on this
                    function to cut the data transfer at proper address boundaries, and it's the
                    caller's reponsibility to pass in a properly cut DataByteCount parameter.
  Buffer            Pointer to caller-allocated buffer containing the dada received or sent during the
                    SPI cycle.
  SpiRegionType     SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
                    EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
                    Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
                    and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
                    to base of the 1st flash device (i.e., it is a Flash Linear Address).

Returns:

  EFI_SUCCESS             Command succeed.
  EFI_INVALID_PARAMETER   The parameters specified are not valid.
  EFI_UNSUPPORTED         Command not supported.
  EFI_DEVICE_ERROR        Device error, command aborts abnormally.

--*/
{
  EFI_STATUS  Status;
  UINT16      BiosCtlSave;
  UINT32      SmiEnSave;

  BiosCtlSave = 0;
  SmiEnSave   = 0;

  //
  // Check if the parameters are valid.
  //
  if ((OpcodeIndex >= SPI_NUM_OPCODE) || (PrefixOpcodeIndex >= SPI_NUM_PREFIX_OPCODE)) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Make sure it's safe to program the command.
  //
  if (!WaitForSpiCycleComplete (This, FALSE)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Acquire access to the SPI interface is not required any more.
  //
  //
  // Disable SMIs to make sure normal mode flash access is not interrupted by an SMI
  // whose SMI handler accesses flash (e.g. for error logging)
  //
  SmiEnSave = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, (SmiEnSave & ~SMI_EN));

  //
  // Save BIOS Ctrl register
  //
  BiosCtlSave = PciRead16 (
                  PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC,
                  PCI_DEVICE_NUMBER_QNC_LPC,
                  PCI_FUNCTION_NUMBER_QNC_LPC,
                  R_QNC_LPC_BIOS_CNTL)
                  ) & (B_QNC_LPC_BIOS_CNTL_BCD | B_QNC_LPC_BIOS_CNTL_PFE | B_QNC_LPC_BIOS_CNTL_BIOSWE | B_QNC_LPC_BIOS_CNTL_SMM_BWP);

  //
  // Enable flash writing
  //
  PciOr16 (
    PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC,
    PCI_DEVICE_NUMBER_QNC_LPC,
    PCI_FUNCTION_NUMBER_QNC_LPC,
    R_QNC_LPC_BIOS_CNTL),
    (UINT16) (B_QNC_LPC_BIOS_CNTL_BIOSWE | B_QNC_LPC_BIOS_CNTL_SMM_BWP)
    );

  //
  // If shifts the data out, disable Prefetching and Caching.
  //
  if (ShiftOut) {
    PciAndThenOr16 (
      PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC,
      PCI_DEVICE_NUMBER_QNC_LPC,
      PCI_FUNCTION_NUMBER_QNC_LPC,
      R_QNC_LPC_BIOS_CNTL),
      (UINT16) (~(B_QNC_LPC_BIOS_CNTL_BCD | B_QNC_LPC_BIOS_CNTL_PFE)),
      (UINT16) ((B_QNC_LPC_BIOS_CNTL_BCD))
      );
  }
  //
  // Sends the command to the SPI interface to execute.
  //
  Status = SendSpiCmd (
            This,
            OpcodeIndex,
            PrefixOpcodeIndex,
            DataCycle,
            Atomic,
            ShiftOut,
            Address,
            DataByteCount,
            Buffer,
            SpiRegionType
            );

  //
  // Restore BIOS Ctrl register
  //
  PciAndThenOr16 (
    PCI_LIB_ADDRESS (PCI_BUS_NUMBER_QNC,
    PCI_DEVICE_NUMBER_QNC_LPC,
    PCI_FUNCTION_NUMBER_QNC_LPC,
    R_QNC_LPC_BIOS_CNTL),
    (UINT16) (~(B_QNC_LPC_BIOS_CNTL_BCD | B_QNC_LPC_BIOS_CNTL_PFE | B_QNC_LPC_BIOS_CNTL_BIOSWE | B_QNC_LPC_BIOS_CNTL_SMM_BWP)),
    (UINT16) (BiosCtlSave)
      );
  //
  // Restore SMIs.
  //
  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, SmiEnSave);

  return Status;
}
コード例 #21
0
ファイル: OpalPasswordSmm.c プロジェクト: iderzh/edk2
/**
  Extract device info from the input device path.

  @param[in]       DevicePath        Device path info for the device.
  @param[in,out]   Dev               The device which new inputed.

**/
VOID
ExtractDeviceInfoFromDevicePath (
  IN     EFI_DEVICE_PATH_PROTOCOL    *DevicePath,
  IN OUT OPAL_SMM_DEVICE             *Dev
  )
{
  EFI_DEVICE_PATH_PROTOCOL      *TmpDevPath;
  EFI_DEVICE_PATH_PROTOCOL      *TmpDevPath2;
  PCI_DEVICE_PATH               *PciDevPath;
  SATA_DEVICE_PATH              *SataDevPath;
  NVME_NAMESPACE_DEVICE_PATH    *NvmeDevPath;
  UINTN                         BusNum;

  TmpDevPath = DevicePath;
  Dev->DeviceType = OPAL_DEVICE_TYPE_UNKNOWN;

  while (!IsDevicePathEnd(TmpDevPath)) {
    if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath->SubType == MSG_SATA_DP) {
      //
      // SATA
      //
      SataDevPath = ( SATA_DEVICE_PATH* )TmpDevPath;
      Dev->SataPort = SataDevPath->HBAPortNumber;
      Dev->SataPortMultiplierPort = SataDevPath->PortMultiplierPortNumber;
      Dev->DeviceType = OPAL_DEVICE_TYPE_SATA;
      break;
    } else if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP) {
      //
      // NVMe
      //
      NvmeDevPath = ( NVME_NAMESPACE_DEVICE_PATH* )TmpDevPath;
      Dev->NvmeNamespaceId = NvmeDevPath->NamespaceId;
      Dev->DeviceType = OPAL_DEVICE_TYPE_NVME;
      break;
    }
    TmpDevPath = NextDevicePathNode (TmpDevPath);
  }

  //
  // Get bridge node info for the nvme device.
  //
  BusNum = 0;
  TmpDevPath = DevicePath;
  TmpDevPath2 = NextDevicePathNode (DevicePath);
  while (!IsDevicePathEnd(TmpDevPath2)) {
    if (TmpDevPath->Type == HARDWARE_DEVICE_PATH && TmpDevPath->SubType == HW_PCI_DP) {
      PciDevPath = (PCI_DEVICE_PATH *) TmpDevPath;
      if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH && TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)||
          (TmpDevPath2->Type == MESSAGING_DEVICE_PATH && TmpDevPath2->SubType == MSG_SATA_DP)) {
        Dev->BusNum = (UINT32)BusNum;
        Dev->DevNum = PciDevPath->Device;
        Dev->FuncNum = PciDevPath->Function;
      } else {
        AddPciDeviceNode((UINT32)BusNum, PciDevPath->Device, PciDevPath->Function, Dev);
        if (TmpDevPath2->Type == HARDWARE_DEVICE_PATH && TmpDevPath2->SubType == HW_PCI_DP) {
          BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath->Device, PciDevPath->Function, NVME_PCIE_SEC_BNUM));
        }
      }
    }

    TmpDevPath  = NextDevicePathNode (TmpDevPath);
    TmpDevPath2 = NextDevicePathNode (TmpDevPath2);
  }
}
コード例 #22
0
ファイル: PciHostBridgeLib.c プロジェクト: ErikBjorge/edk2
EFIAPI
PciHostBridgeGetRootBridges (
  UINTN *Count
  )
{
  EFI_STATUS           Status;
  FIRMWARE_CONFIG_ITEM FwCfgItem;
  UINTN                FwCfgSize;
  UINT64               ExtraRootBridges;
  PCI_ROOT_BRIDGE      *Bridges;
  UINTN                Initialized;
  UINTN                LastRootBridgeNumber;
  UINTN                RootBridgeNumber;

  *Count = 0;

  //
  // QEMU provides the number of extra root buses, shortening the exhaustive
  // search below. If there is no hint, the feature is missing.
  //
  Status = QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCfgSize);
  if (EFI_ERROR (Status) || FwCfgSize != sizeof ExtraRootBridges) {
    ExtraRootBridges = 0;
  } else {
    QemuFwCfgSelectItem (FwCfgItem);
    QemuFwCfgReadBytes (FwCfgSize, &ExtraRootBridges);

    if (ExtraRootBridges > PCI_MAX_BUS) {
      DEBUG ((EFI_D_ERROR, "%a: invalid count of extra root buses (%Lu) "
        "reported by QEMU\n", __FUNCTION__, ExtraRootBridges));
      return NULL;
    }
    DEBUG ((EFI_D_INFO, "%a: %Lu extra root buses reported by QEMU\n",
      __FUNCTION__, ExtraRootBridges));
  }

  //
  // Allocate the "main" root bridge, and any extra root bridges.
  //
  Bridges = AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Bridges);
  if (Bridges == NULL) {
    DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));
    return NULL;
  }
  Initialized = 0;

  //
  // The "main" root bus is always there.
  //
  LastRootBridgeNumber = 0;

  //
  // Scan all other root buses. If function 0 of any device on a bus returns a
  // VendorId register value different from all-bits-one, then that bus is
  // alive.
  //
  for (RootBridgeNumber = 1;
       RootBridgeNumber <= PCI_MAX_BUS && Initialized < ExtraRootBridges;
       ++RootBridgeNumber) {
    UINTN Device;

    for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) {
      if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0,
                       PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) {
        break;
      }
    }
    if (Device <= PCI_MAX_DEVICE) {
      //
      // Found the next root bus. We can now install the *previous* one,
      // because now we know how big a bus number range *that* one has, for any
      // subordinate buses that might exist behind PCI bridges hanging off it.
      //
      Status = InitRootBridge ((UINT8)LastRootBridgeNumber,
                 (UINT8)(RootBridgeNumber - 1), &Bridges[Initialized]);
      if (EFI_ERROR (Status)) {
        goto FreeBridges;
      }
      ++Initialized;
      LastRootBridgeNumber = RootBridgeNumber;
    }
  }

  //
  // Install the last root bus (which might be the only, ie. main, root bus, if
  // we've found no extra root buses).
  //
  Status = InitRootBridge ((UINT8)LastRootBridgeNumber, PCI_MAX_BUS,
             &Bridges[Initialized]);
  if (EFI_ERROR (Status)) {
    goto FreeBridges;
  }
  ++Initialized;

  *Count = Initialized;
  return Bridges;

FreeBridges:
  while (Initialized > 0) {
    --Initialized;
    UninitRootBridge (&Bridges[Initialized]);
  }

  FreePool (Bridges);
  return NULL;
}
コード例 #23
0
ファイル: VlvPlatformInit.c プロジェクト: FishYu1222/edk2
EFI_STATUS
IgdPmHook (
  IN EFI_HANDLE                      ImageHandle,
  IN DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformSaPolicy
  )
{

  EFI_EVENT             mConOutEvent;
  VOID                  *gConOutNotifyReg;

  EFI_STATUS            Status;

  EFI_PHYSICAL_ADDRESS  MemBaseAddress;
  UINT32                LoGTBaseAddress;
  UINT32                HiGTBaseAddress;

  GTTMMADR    = 0;
  Status      = EFI_SUCCESS;

  //
  // If device 0:2:0 (Internal Graphics Device, or GT) is enabled, then Program GTTMMADR,
  //
  if (PciRead16(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_VID))  != 0xFFFF) {

    ASSERT (gDS!=NULL);

    //
    // Enable Bus Master, I/O and Memory access on 0:2:0
    //
    PciOr8(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_CMD), (BIT2 | BIT1 | BIT0));

    //
    // Means Allocate 4MB for GTTMADDR
    //
    MemBaseAddress = 0x0ffffffff;

    Status = gDS->AllocateMemorySpace (
                    EfiGcdAllocateMaxAddressSearchBottomUp,
                    EfiGcdMemoryTypeMemoryMappedIo,
                    GTT_MEM_ALIGN,
                    GTTMMADR_SIZE_4MB,
                    &MemBaseAddress,
                    ImageHandle,
                    NULL
                    );
    ASSERT_EFI_ERROR (Status);

    //
    // Program GT PM Settings if GTTMMADR allocation is Successful
    //
    GTTMMADR                          = (UINTN) MemBaseAddress;

    LoGTBaseAddress                   = (UINT32) (MemBaseAddress & 0xFFFFFFFF);
    HiGTBaseAddress                   = (UINT32) RShiftU64 ((MemBaseAddress & 0xFFFFFFFF00000000), 32);

    PciWrite32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR), LoGTBaseAddress);
    PciWrite32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR+4), HiGTBaseAddress);


    S3PciRead32(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_GTTMMADR));


    S3MmioRead32(IGD_R_GTTMMADR + 4);


    S3PciRead8(PCI_LIB_ADDRESS(0, IGD_DEV, 0, IGD_R_CMD));

    //
    // Do POST GT PM Init Steps after VBIOS Initialization in DoPostPmInitCallBack
    //
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_CALLBACK,
                    (EFI_EVENT_NOTIFY)PostPmInitCallBack,
                    NULL,
                    &mConOutEvent
                    );

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


    Status = gBS->RegisterProtocolNotify (
                    &gEfiGraphicsOutputProtocolGuid,
                    mConOutEvent,
                    &gConOutNotifyReg
                    );



    MmioWrite64 (IGD_R_GTTMMADR, 0);

    //
    // Free allocated resources
    //
    gDS->FreeMemorySpace (
           MemBaseAddress,
           GTTMMADR_SIZE_4MB
           );

  }

  return EFI_SUCCESS;
}
コード例 #24
0
ファイル: PciHostBridgeSupport.c プロジェクト: hwu25/edk2
/**
  Parse PCI bar and collect the assigned PCI resouce information.

  @param[in]  Command          Supported attributes.

  @param[in]  Bus              PCI bus number.

  @param[in]  Device           PCI device number.

  @param[in]  Function         PCI function number.

  @param[in]  BarOffsetBase    PCI bar start offset.

  @param[in]  BarOffsetEnd     PCI bar end offset.

  @param[in]  Io               IO aperture.

  @param[in]  Mem              MMIO aperture.

  @param[in]  MemAbove4G       MMIO aperture above 4G.

  @param[in]  PMem             Prefetchable MMIO aperture.

  @param[in]  PMemAbove4G      Prefetchable MMIO aperture above 4G.
**/
STATIC
VOID
PcatPciRootBridgeParseBars (
  IN UINT16                         Command,
  IN UINTN                          Bus,
  IN UINTN                          Device,
  IN UINTN                          Function,
  IN UINTN                          BarOffsetBase,
  IN UINTN                          BarOffsetEnd,
  IN PCI_ROOT_BRIDGE_APERTURE       *Io,
  IN PCI_ROOT_BRIDGE_APERTURE       *Mem,
  IN PCI_ROOT_BRIDGE_APERTURE       *MemAbove4G,
  IN PCI_ROOT_BRIDGE_APERTURE       *PMem,
  IN PCI_ROOT_BRIDGE_APERTURE       *PMemAbove4G

)
{
  UINT32                            OriginalValue;
  UINT32                            Value;
  UINT32                            OriginalUpperValue;
  UINT32                            UpperValue;
  UINT64                            Mask;
  UINTN                             Offset;
  UINTN                             LowBit;
  UINT64                            Base;
  UINT64                            Length;
  UINT64                            Limit;
  PCI_ROOT_BRIDGE_APERTURE          *MemAperture;

  for (Offset = BarOffsetBase; Offset < BarOffsetEnd; Offset += sizeof (UINT32)) {
    PcatPciRootBridgeBarExisted (
      PCI_LIB_ADDRESS (Bus, Device, Function, Offset),
      &OriginalValue, &Value
    );
    if (Value == 0) {
      continue;
    }
    if ((Value & BIT0) == BIT0) {
      //
      // IO Bar
      //
      if (Command & EFI_PCI_COMMAND_IO_SPACE) {
        Mask = 0xfffffffc;
        Base = OriginalValue & Mask;
        Length = ((~(Value & Mask)) & Mask) + 0x04;
        if (!(Value & 0xFFFF0000)) {
          Length &= 0x0000FFFF;
        }
        Limit = Base + Length - 1;

        if ((Base > 0) && (Base < Limit)) {
          if (Io->Base > Base) {
            Io->Base = Base;
          }
          if (Io->Limit < Limit) {
            Io->Limit = Limit;
          }
        }
      }
    } else {
      //
      // Mem Bar
      //
      if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {

        Mask = 0xfffffff0;
        Base = OriginalValue & Mask;
        Length = Value & Mask;

        if ((Value & (BIT1 | BIT2)) == 0) {
          //
          // 32bit
          //
          Length = ((~Length) + 1) & 0xffffffff;

          if ((Value & BIT3) == BIT3) {
            MemAperture = PMem;
          } else {
            MemAperture = Mem;
          }
        } else {
          //
          // 64bit
          //
          Offset += 4;
          PcatPciRootBridgeBarExisted (
            PCI_LIB_ADDRESS (Bus, Device, Function, Offset),
            &OriginalUpperValue,
            &UpperValue
          );

          Base = Base | LShiftU64 ((UINT64) OriginalUpperValue, 32);
          Length = Length | LShiftU64 ((UINT64) UpperValue, 32);
          if (Length != 0) {
            LowBit = LowBitSet64 (Length);
            Length = LShiftU64 (1ULL, LowBit);
          }

          if ((Value & BIT3) == BIT3) {
            MemAperture = PMemAbove4G;
          } else {
            MemAperture = MemAbove4G;
          }
        }

        Limit = Base + Length - 1;
        if ((Base > 0) && (Base < Limit)) {
          if (MemAperture->Base > Base) {
            MemAperture->Base = Base;
          }
          if (MemAperture->Limit < Limit) {
            MemAperture->Limit = Limit;
          }
        }
      }
    }
  }
}
コード例 #25
0
ファイル: PciHostBridgeSupport.c プロジェクト: hwu25/edk2
/**
  Scan for all root bridges in platform.

  @param[out] NumberOfRootBridges  Number of root bridges detected

  @retval     Pointer to the allocated PCI_ROOT_BRIDGE structure array.
**/
PCI_ROOT_BRIDGE *
ScanForRootBridges (
  OUT UINTN      *NumberOfRootBridges
)
{
  UINTN      PrimaryBus;
  UINTN      SubBus;
  UINT8      Device;
  UINT8      Function;
  UINTN      NumberOfDevices;
  UINTN      Address;
  PCI_TYPE01 Pci;
  UINT64     Attributes;
  UINT64     Base;
  UINT64     Limit;
  UINT64     Value;
  PCI_ROOT_BRIDGE_APERTURE Io, Mem, MemAbove4G, PMem, PMemAbove4G, *MemAperture;
  PCI_ROOT_BRIDGE *RootBridges;
  UINTN      BarOffsetEnd;


  *NumberOfRootBridges = 0;
  RootBridges = NULL;

  //
  // After scanning all the PCI devices on the PCI root bridge's primary bus,
  // update the Primary Bus Number for the next PCI root bridge to be this PCI
  // root bridge's subordinate bus number + 1.
  //
  for (PrimaryBus = 0; PrimaryBus <= PCI_MAX_BUS; PrimaryBus = SubBus + 1) {
    SubBus = PrimaryBus;
    Attributes = 0;
    Io.Base = Mem.Base = MemAbove4G.Base = PMem.Base = PMemAbove4G.Base = MAX_UINT64;
    Io.Limit = Mem.Limit = MemAbove4G.Limit = PMem.Limit = PMemAbove4G.Limit = 0;
    //
    // Scan all the PCI devices on the primary bus of the PCI root bridge
    //
    for (Device = 0, NumberOfDevices = 0; Device <= PCI_MAX_DEVICE; Device++) {

      for (Function = 0; Function <= PCI_MAX_FUNC; Function++) {

        //
        // Compute the PCI configuration address of the PCI device to probe
        //
        Address = PCI_LIB_ADDRESS (PrimaryBus, Device, Function, 0);

        //
        // Read the Vendor ID from the PCI Configuration Header
        //
        if (PciRead16 (Address) == MAX_UINT16) {
          if (Function == 0) {
            //
            // If the PCI Configuration Read fails, or a PCI device does not
            // exist, then skip this entire PCI device
            //
            break;
          } else {
            //
            // If PCI function != 0, VendorId == 0xFFFF, we continue to search
            // PCI function.
            //
            continue;
          }
        }

        //
        // Read the entire PCI Configuration Header
        //
        PciReadBuffer (Address, sizeof (Pci), &Pci);

        //
        // Increment the number of PCI device found on the primary bus of the
        // PCI root bridge
        //
        NumberOfDevices++;

        //
        // Look for devices with the VGA Palette Snoop enabled in the COMMAND
        // register of the PCI Config Header
        //
        if ((Pci.Hdr.Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) != 0) {
          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
        }

        BarOffsetEnd = 0;

        //
        // PCI-PCI Bridge
        //
        if (IS_PCI_BRIDGE (&Pci)) {
          //
          // Get the Bus range that the PPB is decoding
          //
          if (Pci.Bridge.SubordinateBus > SubBus) {
            //
            // If the suborinate bus number of the PCI-PCI bridge is greater
            // than the PCI root bridge's current subordinate bus number,
            // then update the PCI root bridge's subordinate bus number
            //
            SubBus = Pci.Bridge.SubordinateBus;
          }

          //
          // Get the I/O range that the PPB is decoding
          //
          Value = Pci.Bridge.IoBase & 0x0f;
          Base = ((UINT32) Pci.Bridge.IoBase & 0xf0) << 8;
          Limit = (((UINT32) Pci.Bridge.IoLimit & 0xf0) << 8) | 0x0fff;
          if (Value == BIT0) {
            Base |= ((UINT32) Pci.Bridge.IoBaseUpper16 << 16);
            Limit |= ((UINT32) Pci.Bridge.IoLimitUpper16 << 16);
          }
          if ((Base > 0) && (Base < Limit)) {
            if (Io.Base > Base) {
              Io.Base = Base;
            }
            if (Io.Limit < Limit) {
              Io.Limit = Limit;
            }
          }

          //
          // Get the Memory range that the PPB is decoding
          //
          Base = ((UINT32) Pci.Bridge.MemoryBase & 0xfff0) << 16;
          Limit = (((UINT32) Pci.Bridge.MemoryLimit & 0xfff0) << 16) | 0xfffff;
          if ((Base > 0) && (Base < Limit)) {
            if (Mem.Base > Base) {
              Mem.Base = Base;
            }
            if (Mem.Limit < Limit) {
              Mem.Limit = Limit;
            }
          }

          //
          // Get the Prefetchable Memory range that the PPB is decoding
          //
          Value = Pci.Bridge.PrefetchableMemoryBase & 0x0f;
          Base = ((UINT32) Pci.Bridge.PrefetchableMemoryBase & 0xfff0) << 16;
          Limit = (((UINT32) Pci.Bridge.PrefetchableMemoryLimit & 0xfff0)
                   << 16) | 0xfffff;
          MemAperture = &PMem;
          if (Value == BIT0) {
            Base |= LShiftU64 (Pci.Bridge.PrefetchableBaseUpper32, 32);
            Limit |= LShiftU64 (Pci.Bridge.PrefetchableLimitUpper32, 32);
            MemAperture = &PMemAbove4G;
          }
          if ((Base > 0) && (Base < Limit)) {
            if (MemAperture->Base > Base) {
              MemAperture->Base = Base;
            }
            if (MemAperture->Limit < Limit) {
              MemAperture->Limit = Limit;
            }
          }

          //
          // Look at the PPB Configuration for legacy decoding attributes
          //
          if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA)
              == EFI_PCI_BRIDGE_CONTROL_ISA) {
            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO_16;
            Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
          }
          if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA)
              == EFI_PCI_BRIDGE_CONTROL_VGA) {
            Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
            Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
            Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
            if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16)
                != 0) {
              Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
              Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO_16;
            }
          }

          BarOffsetEnd = OFFSET_OF (PCI_TYPE01, Bridge.Bar[2]);
        } else {
          //
          // Parse the BARs of the PCI device to get what I/O Ranges, Memory
          // Ranges, and Prefetchable Memory Ranges the device is decoding
          //
          if ((Pci.Hdr.HeaderType & HEADER_LAYOUT_CODE) == HEADER_TYPE_DEVICE) {
            BarOffsetEnd = OFFSET_OF (PCI_TYPE00, Device.Bar[6]);
          }
        }

        PcatPciRootBridgeParseBars (
          Pci.Hdr.Command,
          PrimaryBus,
          Device,
          Function,
          OFFSET_OF (PCI_TYPE00, Device.Bar),
          BarOffsetEnd,
          &Io,
          &Mem, &MemAbove4G,
          &PMem, &PMemAbove4G
        );

        //
        // See if the PCI device is an IDE controller
        //
        if (IS_CLASS2 (&Pci, PCI_CLASS_MASS_STORAGE,
                       PCI_CLASS_MASS_STORAGE_IDE)) {
          if (Pci.Hdr.ClassCode[0] & 0x80) {
            Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
            Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
          }
          if (Pci.Hdr.ClassCode[0] & 0x01) {
            Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
          }
          if (Pci.Hdr.ClassCode[0] & 0x04) {
            Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
          }
        }

        //
        // See if the PCI device is a legacy VGA controller or
        // a standard VGA controller
        //
        if (IS_CLASS2 (&Pci, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA) ||
            IS_CLASS2 (&Pci, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA)
           ) {
          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
          Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
          Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
          Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO_16;
        }

        //
        // See if the PCI Device is a PCI - ISA or PCI - EISA
        // or ISA_POSITIVIE_DECODE Bridge device
        //
        if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
          if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA ||
              Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_EISA ||
              Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE) {
            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO_16;
            Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
          }
        }

        //
        // If this device is not a multi function device, then skip the rest
        // of this PCI device
        //
        if (Function == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
          break;
        }
      }
    }

    //
    // If at least one PCI device was found on the primary bus of this PCI
    // root bridge, then the PCI root bridge exists.
    //
    if (NumberOfDevices > 0) {
      RootBridges = ReallocatePool (
                      (*NumberOfRootBridges) * sizeof (PCI_ROOT_BRIDGE),
                      (*NumberOfRootBridges + 1) * sizeof (PCI_ROOT_BRIDGE),
                      RootBridges
                    );
      ASSERT (RootBridges != NULL);

      AdjustRootBridgeResource (&Io, &Mem, &MemAbove4G, &PMem, &PMemAbove4G);

      InitRootBridge (
        Attributes, Attributes, 0,
        (UINT8) PrimaryBus, (UINT8) SubBus,
        &Io, &Mem, &MemAbove4G, &PMem, &PMemAbove4G,
        &RootBridges[*NumberOfRootBridges]
      );
      RootBridges[*NumberOfRootBridges].ResourceAssigned = TRUE;
      //
      // Increment the index for the next PCI Root Bridge
      //
      (*NumberOfRootBridges)++;
    }
  }

  return RootBridges;
}
コード例 #26
0
ファイル: BdsPlatform.c プロジェクト: jeppeter/vbox
VOID
PciInitialization (
  )
{
  //
  // Bus 0, Device 0, Function 0 - Host to PCI Bridge
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);

  //
  // Bus 0, Device 1, Function 0 - PCI to ISA Bridge
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // LNKA routing target
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // LNKB routing target
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // LNKC routing target
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // LNKD routing target

  //
  // Bus 0, Device 1, Function 1 - IDE Controller
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);

  //
  // Bus 0, Device 1, Function 3 - Power Managment Controller
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x09);
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01); // INTA

  //
  // Bus 0, Device 2, Function 0 - Video Controller
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);

  //
  // Bus 0, Device 3, Function 0 - Network Controller
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0a);
  PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01); // INTA (-> LNKC)

  //
  // Bus 0, Device 5, Function 0 - RAM Memory
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3c), 0x0b);
  PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3d), 0x01); // INTA (-> LNKA)
}
コード例 #27
0
ファイル: OpalPasswordSmm.c プロジェクト: iderzh/edk2
/**
  Dispatch function for a Software SMI handler.

  @param[in]     DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().
  @param[in]     RegisterContext Points to an optional handler context which was specified when the
                                 handler was registered.
  @param[in, out] CommBuffer     A pointer to a collection of Data in memory that will
                                 be conveyed from a non-SMM environment into an SMM environment.
  @param[in, out] CommBufferSize The Size of the CommBuffer.

  @retval EFI_SUCCESS            The interrupt was handled and quiesced. No other handlers
                                 should still be called.
  @retval Others                 Other execution results.
**/
EFI_STATUS
EFIAPI
SmmUnlockOpalPassword (
  IN     EFI_HANDLE              DispatchHandle,
  IN     CONST VOID              *RegisterContext,
  IN OUT VOID                    *CommBuffer,
  IN OUT UINTN                   *CommBufferSize
  )
{
  EFI_STATUS                     Status;
  OPAL_SMM_DEVICE                *OpalDev;
  LIST_ENTRY                     *Entry;
  UINT8                          BaseClassCode;
  UINT8                          SubClassCode;
  UINT8                          ProgInt;
  TCG_RESULT                     Result;
  UINT8                          SataCmdSt;
  UINT8                          *StorePcieConfDataList[16];
  UINTN                          RpBase;
  UINTN                          MemoryBase;
  UINTN                          MemoryLength;
  OPAL_SESSION                   Session;
  BOOLEAN                        BlockSidSupport;

  ZeroMem (StorePcieConfDataList, sizeof (StorePcieConfDataList));
  Status = EFI_DEVICE_ERROR;

  //
  // try to unlock all locked hdd disks.
  //
  for (Entry = mSmmDeviceList.ForwardLink; Entry != &mSmmDeviceList; Entry = Entry->ForwardLink) {
    OpalDev = BASE_CR(Entry, OPAL_SMM_DEVICE, Link);

    RpBase    = 0;
    SataCmdSt = 0;

    ///
    /// Configure RootPort for PCIe AHCI/NVME devices.
    ///
    if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {
      ///
      /// Save original RootPort configuration space to heap
      ///
      RpBase = SaveRestoreRootportConfSpace (
                  OpalDev,
                  TRUE,
                  StorePcieConfDataList
                  );
      MemoryBase = mNvmeContext.Nbar;
      MemoryLength = 0;
      ConfigureRootPortForPcieNand (RpBase, OpalDev->BusNum, (UINT32) MemoryBase, (UINT32) MemoryLength);

      ///
      /// Enable PCIE decode for RootPort
      ///
      SataCmdSt = PciRead8 (RpBase + NVME_PCIE_PCICMD);
      PciWrite8  (RpBase + NVME_PCIE_PCICMD,  0x6);
    } else {
      SataCmdSt = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, NVME_PCIE_PCICMD));
      PciWrite8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, NVME_PCIE_PCICMD), 0x6);
    }

    BaseClassCode = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x0B));
    SubClassCode  = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x0A));
    ProgInt       = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x09));
    if (BaseClassCode != PCI_CLASS_MASS_STORAGE) {
      Status = EFI_INVALID_PARAMETER;
      break;
    }

    Status = EFI_DEVICE_ERROR;
    if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_SATA) {
      if ((SubClassCode == PCI_CLASS_MASS_STORAGE_AHCI) || (SubClassCode == PCI_CLASS_MASS_STORAGE_RAID)) {
        Status = GetAhciBaseAddress (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum);
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "GetAhciBaseAddress error, Status: %r\n", Status));
          goto done;
        }
        Status = AhciModeInitialize ((UINT8)OpalDev->SataPort);
        ASSERT_EFI_ERROR (Status);
        if (EFI_ERROR (Status)) {
          DEBUG ((DEBUG_ERROR, "AhciModeInitialize error, Status: %r\n", Status));
          goto done;
        }
      } else {
        DEBUG ((DEBUG_ERROR, "SubClassCode not support for SATA device\n"));
      }
    } else if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {
      if (SubClassCode == PCI_CLASS_MASS_STORAGE_NVM) {
        if (ProgInt != PCI_IF_NVMHCI) {
          DEBUG ((DEBUG_ERROR, "PI not support, skipped\n"));
          Status = EFI_NOT_FOUND;
          goto done;
        }

        mNvmeContext.PciBase = PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x0);
        mNvmeContext.NvmeInitWaitTime = 0;
        mNvmeContext.Nsid = OpalDev->NvmeNamespaceId;
        Status = NvmeControllerInit (&mNvmeContext);
      } else {
        DEBUG ((DEBUG_ERROR, "SubClassCode not support for NVME device\n"));
      }
    } else {
      DEBUG ((DEBUG_ERROR, "Invalid Devicetype\n"));
      goto done;
    }

    Status = EFI_DEVICE_ERROR;
    BlockSidSupport = FALSE;
    if (IsOpalDeviceLocked (OpalDev, &BlockSidSupport)) {
      ZeroMem(&Session, sizeof(Session));
      Session.Sscp = &OpalDev->Sscp;
      Session.MediaId = 0;
      Session.OpalBaseComId = OpalDev->OpalBaseComId;

      Result = OpalSupportUnlock (&Session, OpalDev->Password, OpalDev->PasswordLength, NULL);
      if (Result == TcgResultSuccess) {
        Status = EFI_SUCCESS;
      }
    }

    if (mSendBlockSID && BlockSidSupport) {
      Result = OpalBlockSid (&Session, TRUE);
      if (Result != TcgResultSuccess) {
        break;
      }
    }

    if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {
      if (SubClassCode == PCI_CLASS_MASS_STORAGE_NVM) {
        Status = NvmeControllerExit (&mNvmeContext);
      }
    }

done:
    if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {
      ASSERT (RpBase != 0);
      PciWrite8  (RpBase + NVME_PCIE_PCICMD, 0);
      RpBase = SaveRestoreRootportConfSpace (
                  OpalDev,
                  FALSE,  // restore
                  StorePcieConfDataList
                  );
      PciWrite8  (RpBase + NVME_PCIE_PCICMD, SataCmdSt);
    } else {
      PciWrite8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, NVME_PCIE_PCICMD), SataCmdSt);
    }

    if (EFI_ERROR (Status)) {
      break;
    }
  }

  return Status;
}
コード例 #28
0
ファイル: BdsPlatform.c プロジェクト: jeppeter/vbox
VOID
PciInitialization (
  )
{
  //
  // Bus 0, Device 0, Function 0 - Host to PCI Bridge
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);

  //
  // Bus 0, Device 1, Function 0 - PCI to ISA Bridge
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b);
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x09);
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0b);
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x09);

  //
  // Bus 0, Device 1, Function 1 - IDE Controller
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);

  //
  // Bus 0, Device 1, Function 3 - Power Managment Controller
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x0b);
  PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01);

  //
  // Bus 0, Device 2, Function 0 - Video Controller
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);

  //
  // Bus 0, Device 3, Function 0 - Network Controller
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0b);
  PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01);

  //
  // Bus 0, Device 4, Function 0 - RAM Memory
  //
  PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3c), 0x09);
  PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3d), 0x01);
}
コード例 #29
0
ファイル: PlatformErratas.c プロジェクト: feizwang/quarkfsp
//
#define EHCI_OUT_THRESHOLD_VALUE              (0x7f)
#define EHCI_IN_THRESHOLD_VALUE               (0x7f)

//
// Platform init USB device interrupt masks.
//
#define V_IOH_USBDEVICE_D_INTR_MSK_UDC_REG    (0x0000007f)
#define V_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG   (B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_OUT_EP_MASK | B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_IN_EP_MASK)

//
// Global variables defined within this source module.
//

UINTN IohEhciPciReg[IOH_MAX_EHCI_USB_CONTROLLERS] = {
  PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, 0),
};

UINTN IohUsbDevicePciReg[IOH_MAX_USBDEVICE_USB_CONTROLLERS] = {
  PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USBDEVICE_DEVICE_NUMBER, IOH_USBDEVICE_FUNCTION_NUMBER, 0),
};

//
// Routines local to this source module.
//

/** Perform USB erratas after MRC init.

**/
VOID
PlatformUsbErratasPostMrc (
コード例 #30
0
ファイル: SdMmcPciHcPei.c プロジェクト: EvanLloyd/tianocore
/**
  The user code starts with this function.

  @param  FileHandle             Handle of the file being invoked.
  @param  PeiServices            Describes the list of possible PEI Services.

  @retval EFI_SUCCESS            The driver is successfully initialized.
  @retval Others                 Can't initialize the driver.

**/
EFI_STATUS
EFIAPI
InitializeSdMmcHcPeim (
  IN EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES    **PeiServices
  )
{
  EFI_BOOT_MODE                BootMode;
  EFI_STATUS                   Status;
  UINT16                       Bus;
  UINT16                       Device;
  UINT16                       Function;
  UINT32                       Size;
  UINT64                       MmioSize;
  UINT8                        SubClass;
  UINT8                        BaseClass;
  UINT8                        SlotInfo;
  UINT8                        SlotNum;
  UINT8                        FirstBar;
  UINT8                        Index;
  UINT8                        Slot;
  UINT32                       BarAddr;
  SD_MMC_HC_PEI_PRIVATE_DATA   *Private;

  //
  // Shadow this PEIM to run from memory
  //
  if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
    return EFI_SUCCESS;
  }

  Status = PeiServicesGetBootMode (&BootMode);
  ///
  /// We do not expose this in S3 boot path, because it is only for recovery.
  ///
  if (BootMode == BOOT_ON_S3_RESUME) {
    return EFI_SUCCESS;
  }

  Private = (SD_MMC_HC_PEI_PRIVATE_DATA *) AllocateZeroPool (sizeof (SD_MMC_HC_PEI_PRIVATE_DATA));
  if (Private == NULL) {
    DEBUG ((EFI_D_ERROR, "Failed to allocate memory for SD_MMC_HC_PEI_PRIVATE_DATA! \n"));
    return EFI_OUT_OF_RESOURCES;
  }

  Private->Signature              = SD_MMC_HC_PEI_SIGNATURE;
  Private->SdMmcHostControllerPpi = mSdMmcHostControllerPpi;
  Private->PpiList                = mPpiList;
  Private->PpiList.Ppi            = &Private->SdMmcHostControllerPpi;

  BarAddr = PcdGet32 (PcdSdMmcPciHostControllerMmioBase);
  for (Bus = 0; Bus < 256; Bus++) {
    for (Device = 0; Device < 32; Device++) {
      for (Function = 0; Function < 8; Function++) {
        SubClass  = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0A));
        BaseClass = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0B));

        if ((SubClass == PCI_SUBCLASS_SD_HOST_CONTROLLER) && (BaseClass == PCI_CLASS_SYSTEM_PERIPHERAL)) {
          //
          // Get the SD/MMC Pci host controller's Slot Info.
          //
          SlotInfo = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, SD_MMC_HC_PEI_SLOT_OFFSET));
          FirstBar = (*(SD_MMC_HC_PEI_SLOT_INFO*)&SlotInfo).FirstBar;
          SlotNum  = (*(SD_MMC_HC_PEI_SLOT_INFO*)&SlotInfo).SlotNum + 1;
          ASSERT ((FirstBar + SlotNum) < MAX_SD_MMC_SLOTS);

          for (Index = 0, Slot = FirstBar; Slot < (FirstBar + SlotNum); Index++, Slot++) {
            //
            // Get the SD/MMC Pci host controller's MMIO region size.
            //
            PciAnd16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (UINT16)~(EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
            PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot), 0xFFFFFFFF);
            Size = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot));

            switch (Size & 0x07) {
              case 0x0:
                //
                // Memory space: anywhere in 32 bit address space
                //
                MmioSize = (~(Size & 0xFFFFFFF0)) + 1;
                break;
              case 0x4:
                //
                // Memory space: anywhere in 64 bit address space
                //
                MmioSize = Size & 0xFFFFFFF0;
                PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4), 0xFFFFFFFF);
                Size = PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4));      
                //
                // Fix the length to support some spefic 64 bit BAR
                //
                Size |= ((UINT32)(-1) << HighBitSet32 (Size));
                //
                // Calculate the size of 64bit bar
                //
                MmioSize  |= LShiftU64 ((UINT64) Size, 32);
                MmioSize  = (~(MmioSize)) + 1;
                //
                // Clean the high 32bits of this 64bit BAR to 0 as we only allow a 32bit BAR.
                //
                PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot + 4), 0);
                break;
              default:
                //
                // Unknown BAR type
                //
                ASSERT (FALSE);
                continue;
            };
            //
            // Assign resource to the SdMmc Pci host controller's MMIO BAR.
            // Enable the SdMmc Pci host controller by setting BME and MSE bits of PCI_CMD register.
            //
            PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot), BarAddr);
            PciOr16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
            //
            // Record the allocated Mmio base address.
            //
            Private->MmioBar[Private->TotalSdMmcHcs].SlotNum++;
            Private->MmioBar[Private->TotalSdMmcHcs].MmioBarAddr[Index] = BarAddr;
            BarAddr += (UINT32)MmioSize;
          }
          Private->TotalSdMmcHcs++;
          ASSERT (Private->TotalSdMmcHcs < MAX_SD_MMC_HCS);
        }
      }
    }
  }

  ///
  /// Install SdMmc Host Controller PPI
  ///
  Status = PeiServicesInstallPpi (&Private->PpiList);

  ASSERT_EFI_ERROR (Status);
  return Status;
}