예제 #1
0
/**
  Entry point of this module.

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

  @return Status.

**/
EFI_STATUS
EFIAPI
PeimEntryMA (
  IN       EFI_PEI_FILE_HANDLE      FileHandle,
  IN CONST EFI_PEI_SERVICES         **PeiServices
  )
{
  EFI_STATUS                        Status;
  EFI_BOOT_MODE                     BootMode;
  TIS_TPM_HANDLE                    TpmHandle;

  if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
    return EFI_UNSUPPORTED;
  }

  Status = (**PeiServices).RegisterForShadow(FileHandle);
  if (Status == EFI_ALREADY_STARTED) {
    mImageInMemory = TRUE;
  } else if (Status == EFI_NOT_FOUND) {
    ASSERT_EFI_ERROR (Status);
  }

  if (!mImageInMemory) {
    //
    // Initialize TPM device
    //
    Status = PeiServicesGetBootMode (&BootMode);
    ASSERT_EFI_ERROR (Status);

    TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
    Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
      return Status;
    }

    Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);
    if (EFI_ERROR (Status) ) {
      return Status;
    }
    Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
    ASSERT_EFI_ERROR (Status);
  }

  if (mImageInMemory) {
    Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return Status;
}
예제 #2
0
파일: Qemu.c 프로젝트: shijunjing/edk2
/**
  Locates and extracts the QEMU SMBIOS data if present in fw_cfg

  @return                 Address of extracted QEMU SMBIOS data

**/
UINT8 *
GetQemuSmbiosTables (
  VOID
  )
{
  EFI_STATUS               Status;
  FIRMWARE_CONFIG_ITEM     Tables;
  UINTN                    TablesSize;
  UINT8                    *QemuTables;

  if (!PcdGetBool (PcdQemuSmbiosValidated)) {
    return NULL;
  }

  Status = QemuFwCfgFindFile ("etc/smbios/smbios-tables", &Tables,
             &TablesSize);
  ASSERT_EFI_ERROR (Status);
  ASSERT (TablesSize > 0);

  QemuTables = AllocatePool (TablesSize);
  if (QemuTables == NULL) {
    return NULL;
  }

  QemuFwCfgSelectItem (Tables);
  QemuFwCfgReadBytes (TablesSize, QemuTables);

  return QemuTables;
}
예제 #3
0
/**
  Get ACPI S3 enable flag.

**/
VOID
GetAcpiS3EnableFlag (
  VOID
  )
{
  mAcpiS3Enable = PcdGetBool (PcdAcpiS3Enable);
}
예제 #4
0
파일: DxeLoadFunc.c 프로젝트: lersek/edk2
/**
  The function will check if page table should be setup or not.

  @retval TRUE      Page table should be created.
  @retval FALSE     Page table should not be created.

**/
BOOLEAN
ToBuildPageTable (
  VOID
  )
{
  if (!IsIa32PaeSupport ()) {
    return FALSE;
  }

  if (IsNullDetectionEnabled ()) {
    return TRUE;
  }

  if (PcdGet8 (PcdHeapGuardPropertyMask) != 0) {
    return TRUE;
  }

  if (PcdGetBool (PcdCpuStackGuard)) {
    return TRUE;
  }

  if (IsEnableNonExecNeeded ()) {
    return TRUE;
  }

  return FALSE;
}
예제 #5
0
/**

  Support routine to get the Image read file function.

  @param ImageContext    - The context of the image being loaded

  @retval EFI_SUCCESS - If Image function location is found

**/
EFI_STATUS
GetImageReadFunction (
  IN      PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
  )
{
  PEI_CORE_INSTANCE  *Private;
  VOID*  MemoryBuffer;

  Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
  
  if (Private->PeiMemoryInstalled  && (((Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) && PcdGetBool (PcdShadowPeimOnBoot)) || 
      ((Private->HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME) && PcdGetBool (PcdShadowPeimOnS3Boot))) &&
      (EFI_IMAGE_MACHINE_TYPE_SUPPORTED(EFI_IMAGE_MACHINE_X64) || EFI_IMAGE_MACHINE_TYPE_SUPPORTED(EFI_IMAGE_MACHINE_IA32))) {
    // 
    // Shadow algorithm makes lots of non ANSI C assumptions and only works for IA32 and X64 
    //  compilers that have been tested
    //
    if (Private->ShadowedImageRead == NULL) {
      MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1);
      ASSERT (MemoryBuffer != NULL);
      CopyMem (MemoryBuffer, (CONST VOID *) (UINTN) PeiImageReadForShadow, 0x400);
      Private->ShadowedImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;
    }

    ImageContext->ImageRead = Private->ShadowedImageRead;
  } else {
    ImageContext->ImageRead = PeiImageRead;
  }

  return EFI_SUCCESS;
}
예제 #6
0
STATIC
VOID
SetSocIdStatus (
  IN VOID       *Fdt
  )
{
  UINT32        SocId;
  BOOLEAN       IsRevB1;
  BOOLEAN       DisableXgbeSmmus;

  SocId = PcdGet32 (PcdSocCpuId);
  IsRevB1 = (SocId & STYX_SOC_VERSION_MASK) >= STYX_SOC_VERSION_B1;

  SetDeviceStatus (Fdt, "sata@e0d00000",
    IsRevB1 && FixedPcdGet8 (PcdSata1PortCount) > 0);
  SetDeviceStatus (Fdt, "gpio@e0020000", IsRevB1);
  SetDeviceStatus (Fdt, "gpio@e0030000", IsRevB1);
  SetDeviceStatus (Fdt, "gwdt@e0bb0000", IsRevB1);
#if DO_KCS
  SetDeviceStatus (Fdt, "kcs@e0010000", IsRevB1);
#else
  SetDeviceStatus (Fdt, "kcs@e0010000", FALSE);
#endif

  if (!PcdGetBool (PcdEnableSmmus)) {
    DisableSmmu (Fdt, "iommu-map", "/smb/smmu@e0a00000", "/smb/pcie@f0000000");
    DisableSmmu (Fdt, "iommus", "/smb/smmu@e0200000", "/smb/sata@e0300000");
  }

  if (!PcdGetBool (PcdEnableSmmus) || !IsRevB1 || FixedPcdGet8 (PcdSata1PortCount) == 0) {
    DisableSmmu (Fdt, "iommus", "/smb/smmu@e0c00000", "/smb/sata@e0d00000");
  }

#if DO_XGBE
  DisableXgbeSmmus = !PcdGetBool (PcdEnableSmmus);
#else
  DisableXgbeSmmus = TRUE;
#endif

  if (DisableXgbeSmmus) {
    DisableSmmu (Fdt, "iommus", "/smb/smmu@e0600000", "/smb/xgmac@e0700000");
    DisableSmmu (Fdt, "iommus", "/smb/smmu@e0800000", "/smb/xgmac@e0900000");
  }
}
예제 #7
0
/**
  This interface returns whether TPM physical presence needs be locked or not.

  @param[in]  PeiServices       The pointer to the PEI Services Table.

  @retval     TRUE              The TPM physical presence should be locked.
  @retval     FALSE             The TPM physical presence cannot be locked.

**/
BOOLEAN
EFIAPI
LockTpmPhysicalPresence (
  IN CONST  EFI_PEI_SERVICES             **PeiServices
  )
{
  EFI_STATUS                         Status;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI    *Variable;
  UINTN                              DataSize;
  EFI_PHYSICAL_PRESENCE              TcgPpData;

  //
  // The CRTM has sensed the physical presence assertion of the user. For example,
  // the user has pressed the startup button or inserted a USB dongle. The details
  // of the implementation are vendor-specific. Here we read a PCD value to indicate
  // whether operator physical presence.
  //
  if (!PcdGetBool (PcdTpmPhysicalPresence)) {
    return TRUE;
  }

  //
  // Check the pending TPM requests. Lock TPM physical presence if there is no TPM
  // request.
  //
  Status = PeiServicesLocatePpi (
             &gEfiPeiReadOnlyVariable2PpiGuid,
             0,
             NULL,
             (VOID **)&Variable
             );
  if (!EFI_ERROR (Status)) {
    DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
    Status = Variable->GetVariable (
                         Variable,
                         PHYSICAL_PRESENCE_VARIABLE,
                         &gEfiPhysicalPresenceGuid,
                         NULL,
                         &DataSize,
                         &TcgPpData
                         );
    if (!EFI_ERROR (Status)) {
      if (TcgPpData.PPRequest != 0) {
        return FALSE;
      }
    }
  }

  //
  // Lock TPM physical presence by default.
  //
  return TRUE;
}
예제 #8
0
파일: VariableDxe.c 프로젝트: jeppeter/vbox
/**
  Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context.

**/
VOID
EFIAPI
OnEndOfDxe (
  EFI_EVENT                               Event,
  VOID                                    *Context
  )
{
  mEndOfDxe = TRUE;
  if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) {
    ReclaimForOS ();
  }
}
예제 #9
0
파일: BdsEntry.c 프로젝트: chinni1989/edk2
/**
  This function attempts to boot per the boot order specified by platform policy.

  If the boot via Boot#### returns with a status of EFI_SUCCESS the boot manager will stop 
  processing the BootOrder variable and present a boot manager menu to the user. If a boot via 
  Boot#### returns a status other than EFI_SUCCESS, the boot has failed and the next Boot####
  in the BootOrder variable will be tried until all possibilities are exhausted.
                                  -- Chapter 3.1.1 Boot Manager Programming, the 4th paragraph
**/
VOID
DefaultBootBehavior (
  VOID
  )
{
  UINTN                        BootOptionCount;
  EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
  EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;

  EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
  //
  // BootManagerMenu always contains the correct information even the above function returns failure.
  //

  BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);

  if (BootAllBootOptions (BootOptions, BootOptionCount)) {
    //
    // Follow generic rule, Call BdsDxeOnConnectConInCallBack to connect ConIn before enter UI
    //
    if (PcdGetBool (PcdConInConnectOnDemand)) {
      BdsDxeOnConnectConInCallBack (NULL, NULL);
    }

    //
    // Show the Boot Manager Menu after successful boot
    //
    EfiBootManagerBoot (&BootManagerMenu);
  } else {
    EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
    //
    // Re-scan all EFI boot options in case all the boot#### are deleted or failed to boot
    //
    // If no valid boot options exist, the boot manager will enumerate all removable media
    // devices followed by all fixed media devices. The order within each group is undefined.
    // These new default boot options are not saved to non volatile storage.The boot manger
    // will then attempt toboot from each boot option.
    //                            -- Chapter 3.3 Boot Manager Programming, the 2nd paragraph
    //
    EfiBootManagerConnectAll ();
    BootOptions = BdsEnumerateBootOptions (&BootOptionCount);

    if (!BootAllBootOptions (BootOptions, BootOptionCount)) {
      DEBUG ((EFI_D_ERROR, "[Bds]No bootable device!\n"));
      EfiBootManagerBoot (&BootManagerMenu);
    }
  }

  EfiBootManagerFreeLoadOption (&BootManagerMenu);
  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
}
예제 #10
0
/**
  SMM END_OF_DXE protocol notification event handler.

  @param  Protocol   Points to the protocol's unique identifier
  @param  Interface  Points to the interface instance
  @param  Handle     The handle on which the interface was installed

  @retval EFI_SUCCESS   SmmEndOfDxeCallback runs successfully

**/
EFI_STATUS
EFIAPI
SmmEndOfDxeCallback (
  IN CONST EFI_GUID                       *Protocol,
  IN VOID                                 *Interface,
  IN EFI_HANDLE                           Handle
  )
{
  DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n"));
  mEndOfDxe = TRUE;
  if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) {
    ReclaimForOS ();
  }
  return EFI_SUCCESS;
}
예제 #11
0
/**
  Determines if a user is physically present by reading the reset button state.

  @param  ImageHandle  The image handle of this driver.
  @param  SystemTable  A pointer to the EFI System Table.

  @retval EFI_SUCCESS   Install the Secure Boot Helper Protocol successfully.

**/
EFI_STATUS
EFIAPI
PlatformSecureLibInitialize (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  //
  // Read the state of the reset button when the library is initialized
  //
  mUserIsPhysicallyPresent = PcdGetBool (PcdUserIsPhysicallyPresent);
  DEBUG((EFI_D_INFO, "UserIsPhysicallyPresent - 0x%x\n", mUserIsPhysicallyPresent));

  return EFI_SUCCESS;
}
예제 #12
0
/**
   Transfers control to DxeCore.

   This function performs a CPU architecture specific operations to execute
   the entry point of DxeCore with the parameters of HobList.
   It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.

   @param DxeCoreEntryPoint         The entry point of DxeCore.
   @param HobList                   The start of HobList passed to DxeCore.

**/
VOID
HandOffToDxeCore (
  IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
  IN EFI_PEI_HOB_POINTERS   HobList
  )
{
  VOID                *BaseOfStack;
  VOID                *TopOfStack;
  EFI_STATUS          Status;

  //
  // Allocate 128KB for the Stack
  //
  BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
  ASSERT (BaseOfStack != NULL);

  if (PcdGetBool (PcdSetNxForStack)) {
    Status = ArmSetMemoryRegionNoExec ((UINTN)BaseOfStack, STACK_SIZE);
    ASSERT_EFI_ERROR (Status);
  }

  //
  // Compute the top of the stack we were allocated. Pre-allocate a UINTN
  // for safety.
  //
  TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
  TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);

  //
  // End of PEI phase singal
  //
  Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
  ASSERT_EFI_ERROR (Status);

  //
  // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
  //    
  UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE);

  SwitchStack (
    (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
    HobList.Raw,
    NULL,
    TopOfStack
    );
}
예제 #13
0
/**
  CPU Features driver entry point function.

  If PcdCpuFeaturesInitAfterSmmRelocation is TRUE, it will register one
  SMM Configuration Protocol notify function to perform CPU features
  initialization. Otherwise, it will perform CPU features initialization
  directly.

  @param ImageHandle     Image handle this driver.
  @param SystemTable     Pointer to the System Table.

  @retval EFI_SUCCESS   CPU Features is initialized successfully.
**/
EFI_STATUS
EFIAPI
CpuFeaturesDxeInitialize (
  IN EFI_HANDLE                            ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )
{
  VOID        *Registration;
  EFI_STATUS  Status;
  EFI_HANDLE  Handle;

  if (GetFirstGuidHob (&gEdkiiCpuFeaturesInitDoneGuid) != NULL) {
    //
    // Try to find HOB first. This HOB exist means CPU features have
    // been initialized by CpuFeaturesPei driver, just install
    // gEdkiiCpuFeaturesInitDoneGuid.
    //
    Handle = NULL;
    Status = gBS->InstallProtocolInterface (
                    &Handle,
                    &gEdkiiCpuFeaturesInitDoneGuid,
                    EFI_NATIVE_INTERFACE,
                    NULL
                    );
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  if (PcdGetBool (PcdCpuFeaturesInitAfterSmmRelocation)) {
    //
    // Install notification callback on SMM Configuration Protocol
    //
    EfiCreateProtocolNotifyEvent (
      &gEfiSmmConfigurationProtocolGuid,
      TPL_CALLBACK,
      SmmConfigurationEventNotify,
      NULL,
      &Registration
      );
  } else {
    CpuFeaturesInitializeWorker ();
  }

  return EFI_SUCCESS;
}
예제 #14
0
/**
  Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context.

**/
VOID
EFIAPI
OnEndOfDxe (
  EFI_EVENT                               Event,
  VOID                                    *Context
  )
{
  mEndOfDxe = TRUE;
  //
  // The initialization for variable quota.
  //
  InitializeVariableQuota ();
  if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) {
    ReclaimForOS ();
  }

  gBS->CloseEvent (Event);
}
예제 #15
0
파일: VariableDxe.c 프로젝트: baranee/edk2
/**
  Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context.

**/
VOID
EFIAPI
OnEndOfDxe (
  EFI_EVENT                               Event,
  VOID                                    *Context
  )
{
  DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n"));
  mEndOfDxe = TRUE;
  mVarCheckAddressPointer = VarCheckLibInitializeAtEndOfDxe (&mVarCheckAddressPointerCount);
  //
  // The initialization for variable quota.
  //
  InitializeVariableQuota ();
  if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) {
    ReclaimForOS ();
  }

  gBS->CloseEvent (Event);
}
예제 #16
0
/**
  SMM END_OF_DXE protocol notification event handler.

  @param  Protocol   Points to the protocol's unique identifier
  @param  Interface  Points to the interface instance
  @param  Handle     The handle on which the interface was installed

  @retval EFI_SUCCESS   SmmEndOfDxeCallback runs successfully

**/
EFI_STATUS
EFIAPI
SmmEndOfDxeCallback (
  IN CONST EFI_GUID                       *Protocol,
  IN VOID                                 *Interface,
  IN EFI_HANDLE                           Handle
  )
{
  DEBUG ((EFI_D_INFO, "[Variable]SMM_END_OF_DXE is signaled\n"));
  mEndOfDxe = TRUE;
  VarCheckLibInitializeAtEndOfDxe (NULL);
  //
  // The initialization for variable quota.
  //
  InitializeVariableQuota ();
  if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) {
    ReclaimForOS ();
  }

  return EFI_SUCCESS;
}
예제 #17
0
/**
  This function checks the HTTP(S) URI scheme.

  @param[in]    Uri              The pointer to the URI string.
  
  @retval EFI_SUCCESS            The URI scheme is valid.
  @retval EFI_INVALID_PARAMETER  The URI scheme is not HTTP or HTTPS.
  @retval EFI_ACCESS_DENIED      HTTP is disabled and the URI is HTTP.

**/
EFI_STATUS
HttpBootCheckUriScheme (
  IN      CHAR8                  *Uri
  )
{
  UINTN                Index;
  EFI_STATUS           Status;

  Status = EFI_SUCCESS;

  //
  // Convert the scheme to all lower case.
  //
  for (Index = 0; Index < AsciiStrLen (Uri); Index++) {
    if (Uri[Index] == ':') {
      break;
    }
    if (Uri[Index] >= 'A' && Uri[Index] <= 'Z') {
      Uri[Index] -= (CHAR8)('A' - 'a');
    }
  }

  //
  // Return EFI_INVALID_PARAMETER if the URI is not HTTP or HTTPS.
  //
  if ((AsciiStrnCmp (Uri, "http://", 7) != 0) && (AsciiStrnCmp (Uri, "https://", 8) != 0)) {
    DEBUG ((EFI_D_ERROR, "HttpBootCheckUriScheme: Invalid Uri.\n"));
    return EFI_INVALID_PARAMETER;
  }
  
  //
  // HTTP is disabled, return EFI_ACCESS_DENIED if the URI is HTTP.
  //
  if (!PcdGetBool (PcdAllowHttpConnections) && (AsciiStrnCmp (Uri, "http://", 7) == 0)) {
    DEBUG ((EFI_D_ERROR, "HttpBootCheckUriScheme: HTTP is disabled.\n"));
    return EFI_ACCESS_DENIED;
  }

  return Status;
}
EFI_STATUS
EFIAPI
AcpiPlatformEntryPoint (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS Status;
  EFI_EVENT  RootBridgesConnected;

  //
  // If the platform doesn't support PCI, or PCI enumeration has been disabled,
  // install the tables at once, and let the entry point's return code reflect
  // the full functionality.
  //
  if (PcdGetBool (PcdPciDisableBusEnumeration)) {
    DEBUG ((EFI_D_INFO, "%a: PCI or its enumeration disabled, installing "
      "ACPI tables\n", __FUNCTION__));
    return InstallAcpiTables (FindAcpiTableProtocol ());
  }

  //
  // Otherwise, delay installing the ACPI tables until root bridges are
  // connected. The entry point's return status will only reflect the callback
  // setup. (Note that we're a DXE_DRIVER; our entry point function is invoked
  // strictly before BDS is entered and can connect the root bridges.)
  //
  Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
                  OnRootBridgesConnected, NULL /* Context */,
                  &gRootBridgesConnectedEventGroupGuid, &RootBridgesConnected);
  if (!EFI_ERROR (Status)) {
    DEBUG ((EFI_D_INFO,
      "%a: waiting for root bridges to be connected, registered callback\n",
      __FUNCTION__));
  }

  return Status;
}
예제 #19
0
파일: BdsEntry.c 프로젝트: chinni1989/edk2
/**
  The function reads user inputs.

**/
VOID
BdsReadKeys (
  VOID
  )
{
  EFI_STATUS         Status;
  EFI_INPUT_KEY      Key;

  if (PcdGetBool (PcdConInConnectOnDemand)) {
    return;
  }

  while (gST->ConIn != NULL) {
    
    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    
    if (EFI_ERROR (Status)) {
      //
      // No more keys.
      //
      break;
    }
  }
}
예제 #20
0
  //
  // If support CPU hot plug, PcdCpuSmmEnableBspElection should be set to TRUE.
  // A constant BSP index makes no sense because it may be hot removed.
  //
  DEBUG_CODE (
    if (FeaturePcdGet (PcdCpuHotPlugSupport)) {

      ASSERT (FeaturePcdGet (PcdCpuSmmEnableBspElection));
    }
  );

  //
  // Save the PcdCpuSmmCodeAccessCheckEnable value into a global variable.
  //
  mSmmCodeAccessCheckEnable = PcdGetBool (PcdCpuSmmCodeAccessCheckEnable);
  DEBUG ((EFI_D_INFO, "PcdCpuSmmCodeAccessCheckEnable = %d\n", mSmmCodeAccessCheckEnable));

  //
  // If support CPU hot plug, we need to allocate resources for possibly hot-added processors
  //
  if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
    mMaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
  } else {
    mMaxNumberOfCpus = mNumberOfCpus;
  }
  gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus = mMaxNumberOfCpus;

  //
  // The CPU save state and code for the SMI entry point are tiled within an SMRAM
  // allocated buffer.  The minimum size of this buffer for a uniprocessor system
예제 #21
0
/**
  Perform the memory test base on the memory test intensive level,
  and update the memory resource.

  @param  Level         The memory test intensive level.

  @retval EFI_STATUS    Success test all the system memory and update
                        the memory resource

**/
EFI_STATUS
EFIAPI
BdsMemoryTest (
  IN EXTENDMEM_COVERAGE_LEVEL Level
  )
{
  EFI_STATUS                        Status;
  EFI_STATUS                        KeyStatus;
  EFI_STATUS                        InitStatus;
  EFI_STATUS                        ReturnStatus;
  BOOLEAN                           RequireSoftECCInit;
  EFI_GENERIC_MEMORY_TEST_PROTOCOL  *GenMemoryTest;
  UINT64                            TestedMemorySize;
  UINT64                            TotalMemorySize;
  UINTN                             TestPercent;
  UINT64                            PreviousValue;
  BOOLEAN                           ErrorOut;
  BOOLEAN                           TestAbort;
  EFI_INPUT_KEY                     Key;
  CHAR16                            StrPercent[80];
  CHAR16                            *StrTotalMemory;
  CHAR16                            *Pos;
  CHAR16                            *TmpStr;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Foreground;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Background;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL     Color;
  BOOLEAN                           IsFirstBoot;
  UINT32                            TempData;
  UINTN                             StrTotalMemorySize;

  ReturnStatus = EFI_SUCCESS;
  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));

  StrTotalMemorySize = 128;
  Pos = AllocateZeroPool (StrTotalMemorySize);

  if (Pos == NULL) {
    return ReturnStatus;
  }

  StrTotalMemory    = Pos;

  TestedMemorySize  = 0;
  TotalMemorySize   = 0;
  PreviousValue     = 0;
  ErrorOut          = FALSE;
  TestAbort         = FALSE;

  SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
  SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
  SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);

  RequireSoftECCInit = FALSE;

  Status = gBS->LocateProtocol (
                  &gEfiGenericMemTestProtocolGuid,
                  NULL,
                  (VOID **) &GenMemoryTest
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Pos);
    return EFI_SUCCESS;
  }

  InitStatus = GenMemoryTest->MemoryTestInit (
                                GenMemoryTest,
                                Level,
                                &RequireSoftECCInit
                                );
  if (InitStatus == EFI_NO_MEDIA) {
    //
    // The PEI codes also have the relevant memory test code to check the memory,
    // it can select to test some range of the memory or all of them. If PEI code
    // checks all the memory, this BDS memory test will has no not-test memory to
    // do the test, and then the status of EFI_NO_MEDIA will be returned by
    // "MemoryTestInit". So it does not need to test memory again, just return.
    //
    FreePool (Pos);
    return EFI_SUCCESS;
  }
  
  if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
    TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST));

    if (TmpStr != NULL) {
      PrintXY (10, 10, NULL, NULL, TmpStr);
      FreePool (TmpStr);
    }
  } else {
    DEBUG ((EFI_D_INFO, "Enter memory test.\n"));
  }
  do {
    Status = GenMemoryTest->PerformMemoryTest (
                              GenMemoryTest,
                              &TestedMemorySize,
                              &TotalMemorySize,
                              &ErrorOut,
                              TestAbort
                              );
    if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {
      TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR));
      if (TmpStr != NULL) {
        PrintXY (10, 10, NULL, NULL, TmpStr);
        FreePool (TmpStr);
      }

      ASSERT (0);
    }
    
    if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
      TempData = (UINT32) DivU64x32 (TotalMemorySize, 16);
      TestPercent = (UINTN) DivU64x32 (
                              DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),
                              TempData
                              );
      if (TestPercent != PreviousValue) {
        UnicodeValueToString (StrPercent, 0, TestPercent, 0);
        TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT));
        if (TmpStr != NULL) {
          //
          // TmpStr size is 64, StrPercent is reserved to 16.
          //
          StrCatS (StrPercent, sizeof (StrPercent) / sizeof (CHAR16), TmpStr);
          PrintXY (10, 10, NULL, NULL, StrPercent);
          FreePool (TmpStr);
        }

        TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));
        if (TmpStr != NULL) {
          PlatformBdsShowProgress (
            Foreground,
            Background,
            TmpStr,
            Color,
            TestPercent,
            (UINTN) PreviousValue
            );
          FreePool (TmpStr);
        }
      }

      PreviousValue = TestPercent;
    } else {
      DEBUG ((EFI_D_INFO, "Perform memory test (ESC to skip).\n"));
    }

    if (!PcdGetBool (PcdConInConnectOnDemand)) {
      KeyStatus     = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
      if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) {
        if (!RequireSoftECCInit) {
          if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
            TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));
            if (TmpStr != NULL) {
              PlatformBdsShowProgress (
                Foreground,
                Background,
                TmpStr,
                Color,
                100,
                (UINTN) PreviousValue
                );
              FreePool (TmpStr);
            }

            PrintXY (10, 10, NULL, NULL, L"100");
          }
          Status = GenMemoryTest->Finished (GenMemoryTest);
          goto Done;
        }

        TestAbort = TRUE;
      }
    }
  } while (Status != EFI_NOT_FOUND);

  Status = GenMemoryTest->Finished (GenMemoryTest);

Done:
  if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
    UnicodeValueToString (StrTotalMemory, COMMA_TYPE, TotalMemorySize, 0);
    if (StrTotalMemory[0] == L',') {
      StrTotalMemory++;
      StrTotalMemorySize -= sizeof (CHAR16);
    }

    TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED));
    if (TmpStr != NULL) {
      StrCatS (StrTotalMemory, StrTotalMemorySize / sizeof (CHAR16), TmpStr);
      FreePool (TmpStr);
    }

    PrintXY (10, 10, NULL, NULL, StrTotalMemory);
    PlatformBdsShowProgress (
      Foreground,
      Background,
      StrTotalMemory,
      Color,
      100,
      (UINTN) PreviousValue
      );
    
  } else {
    DEBUG ((EFI_D_INFO, "%d bytes of system memory tested OK\r\n", TotalMemorySize));
  }
  
  FreePool (Pos);


  //
  // Use a DynamicHii type pcd to save the boot status, which is used to
  // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.
  //
  IsFirstBoot = PcdGetBool(PcdBootState);
  if (IsFirstBoot) {
    PcdSetBool(PcdBootState, FALSE);
  }

  return ReturnStatus;
}
예제 #22
0
/**
  Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
  
  @param This         Pointer of EFI_DRIVER_BINDING_PROTOCOL
  @param Controller   driver controller handle
  @param RemainingDevicePath Children's device path
  
  @retval whether success to create floppy control instance.
**/
EFI_STATUS
EFIAPI
KbdControllerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                                Status;
  EFI_STATUS                                Status1;
  EFI_ISA_IO_PROTOCOL                       *IsaIo;
  KEYBOARD_CONSOLE_IN_DEV                   *ConsoleIn;
  UINT8                                     Data;
  EFI_STATUS_CODE_VALUE                     StatusCode;
  EFI_DEVICE_PATH_PROTOCOL                  *ParentDevicePath;

  StatusCode = 0;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Report that the keyboard is being enabled
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE,
    ParentDevicePath
    );

  //
  // Get the ISA I/O Protocol on Controller's handle
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiIsaIoProtocolGuid,
                  (VOID **) &IsaIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    return EFI_INVALID_PARAMETER;
  }
  //
  // Allocate private data
  //
  ConsoleIn = AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV));
  if (ConsoleIn == NULL) {
    Status      = EFI_OUT_OF_RESOURCES;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }
  //
  // Setup the device instance
  //
  ConsoleIn->Signature              = KEYBOARD_CONSOLE_IN_DEV_SIGNATURE;
  ConsoleIn->Handle                 = Controller;
  (ConsoleIn->ConIn).Reset          = KeyboardEfiReset;
  (ConsoleIn->ConIn).ReadKeyStroke  = KeyboardReadKeyStroke;
  ConsoleIn->DataRegisterAddress    = KEYBOARD_8042_DATA_REGISTER;
  ConsoleIn->StatusRegisterAddress  = KEYBOARD_8042_STATUS_REGISTER;
  ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;
  ConsoleIn->IsaIo                  = IsaIo;
  ConsoleIn->DevicePath             = ParentDevicePath;

  ConsoleIn->ConInEx.Reset               = KeyboardEfiResetEx;
  ConsoleIn->ConInEx.ReadKeyStrokeEx     = KeyboardReadKeyStrokeEx;
  ConsoleIn->ConInEx.SetState            = KeyboardSetState;
  ConsoleIn->ConInEx.RegisterKeyNotify   = KeyboardRegisterKeyNotify;
  ConsoleIn->ConInEx.UnregisterKeyNotify = KeyboardUnregisterKeyNotify;  
  
  InitializeListHead (&ConsoleIn->NotifyList);

  //
  // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.
  // When KBC decode (IO port 0x60/0x64 decode) is not enabled, 
  // KeyboardRead will read back as 0xFF and return status is EFI_SUCCESS.
  // So instead we read status register to detect after read if KBC decode is enabled.
  //
  
  //
  // Return code is ignored on purpose.
  //
  if (!PcdGetBool (PcdFastPS2Detection)) {
    KeyboardRead (ConsoleIn, &Data);
    if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {
      //
      // If nobody decodes KBC I/O port, it will read back as 0xFF.
      // Check the Time-Out and Parity bit to see if it has an active KBC in system
      //
      Status      = EFI_DEVICE_ERROR;
      StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
      goto ErrorExit;
    }
  }
  
  //
  // Setup the WaitForKey event
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_NOTIFY,
                  KeyboardWaitForKey,
                  ConsoleIn,
                  &((ConsoleIn->ConIn).WaitForKey)
                  );
  if (EFI_ERROR (Status)) {
    Status      = EFI_OUT_OF_RESOURCES;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }
  //
  // Setup the WaitForKeyEx event
  //  
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_WAIT,
                  TPL_NOTIFY,
                  KeyboardWaitForKeyEx,
                  ConsoleIn,
                  &(ConsoleIn->ConInEx.WaitForKeyEx)
                  );
  if (EFI_ERROR (Status)) {
    Status      = EFI_OUT_OF_RESOURCES;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }
  // Setup a periodic timer, used for reading keystrokes at a fixed interval
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  KeyboardTimerHandler,
                  ConsoleIn,
                  &ConsoleIn->TimerEvent
                  );
  if (EFI_ERROR (Status)) {
    Status      = EFI_OUT_OF_RESOURCES;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }

  Status = gBS->SetTimer (
                  ConsoleIn->TimerEvent,
                  TimerPeriodic,
                  KEYBOARD_TIMER_INTERVAL
                  );
  if (EFI_ERROR (Status)) {
    Status      = EFI_OUT_OF_RESOURCES;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,
    ParentDevicePath
    );

  //
  // Reset the keyboard device
  //
  Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FeaturePcdGet (PcdPs2KbdExtendedVerification));
  if (EFI_ERROR (Status)) {
    Status      = EFI_DEVICE_ERROR;
    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
    goto ErrorExit;
  }

  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DETECTED,
    ParentDevicePath
    );

  ConsoleIn->ControllerNameTable = NULL;
  AddUnicodeString2 (
    "eng",
    gPs2KeyboardComponentName.SupportedLanguages,
    &ConsoleIn->ControllerNameTable,
    L"PS/2 Keyboard Device",
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gPs2KeyboardComponentName2.SupportedLanguages,
    &ConsoleIn->ControllerNameTable,
    L"PS/2 Keyboard Device",
    FALSE
    );


  //
  // Install protocol interfaces for the keyboard device.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiSimpleTextInProtocolGuid,
                  &ConsoleIn->ConIn,
                  &gEfiSimpleTextInputExProtocolGuid,
                  &ConsoleIn->ConInEx,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
    goto ErrorExit;
  }

  return Status;

ErrorExit:
  //
  // Report error code
  //
  if (StatusCode != 0) {
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      StatusCode,
      ParentDevicePath
      );
  }

  if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) {
    gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey);
  }

  if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {
    gBS->CloseEvent (ConsoleIn->TimerEvent);
  }
  if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {
    gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
  }
  KbdFreeNotifyList (&ConsoleIn->NotifyList);
  if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {
    FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
  }
  //
  // Since there will be no timer handler for keyboard input any more,
  // exhaust input data just in case there is still keyboard data left
  //
  if (ConsoleIn != NULL) {
    Status1 = EFI_SUCCESS;
    while (!EFI_ERROR (Status1) && (Status != EFI_DEVICE_ERROR)) {
      Status1 = KeyboardRead (ConsoleIn, &Data);;
    }
  }
  
  if (ConsoleIn != NULL) {
    gBS->FreePool (ConsoleIn);
  }

  gBS->CloseProtocol (
         Controller,
         &gEfiDevicePathProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  gBS->CloseProtocol (
         Controller,
         &gEfiIsaIoProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  return Status;
}
예제 #23
0
/**
  Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.
  And lock physical presence if needed.

  @param[in] PeiServices        An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
  @param[in] NotifyDescriptor   Address of the notification descriptor data structure.
  @param[in] Ppi                Address of the PPI that was installed.

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_ABORTED           physicalPresenceCMDEnable is locked.
  @retval EFI_DEVICE_ERROR      The command was unsuccessful.

**/
EFI_STATUS
EFIAPI
PhysicalPresencePpiNotifyCallback (
  IN EFI_PEI_SERVICES               **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR      *NotifyDescriptor,
  IN VOID                           *Ppi
  )
{
  EFI_STATUS                        Status;
  TPM_PERMANENT_FLAGS               TpmPermanentFlags;
  PEI_LOCK_PHYSICAL_PRESENCE_PPI    *LockPhysicalPresencePpi;
  TPM_PHYSICAL_PRESENCE             PhysicalPresenceValue;

  Status = Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.
  //
  if (PcdGetBool (PcdPhysicalPresenceLifetimeLock) && !TpmPermanentFlags.physicalPresenceLifetimeLock) {
    //
    // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.
    //
    PhysicalPresenceValue = TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK;
    TpmPermanentFlags.physicalPresenceLifetimeLock = TRUE;

    if (PcdGetBool (PcdPhysicalPresenceCmdEnable)) {
      PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_ENABLE;
      TpmPermanentFlags.physicalPresenceCMDEnable = TRUE;
    } else {
      PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_DISABLE;
      TpmPermanentFlags.physicalPresenceCMDEnable = FALSE;
    }

    if (PcdGetBool (PcdPhysicalPresenceHwEnable)) {
      PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_ENABLE;
    } else {
      PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_DISABLE;
    }

    Status = Tpm12PhysicalPresence (
               PhysicalPresenceValue
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // 2. Lock physical presence if it is required.
  //
  LockPhysicalPresencePpi = (PEI_LOCK_PHYSICAL_PRESENCE_PPI *) Ppi;
  if (!LockPhysicalPresencePpi->LockPhysicalPresence ((CONST EFI_PEI_SERVICES**) PeiServices)) {
    return EFI_SUCCESS;
  }

  if (!TpmPermanentFlags.physicalPresenceCMDEnable) {
    if (TpmPermanentFlags.physicalPresenceLifetimeLock) {
      //
      // physicalPresenceCMDEnable is locked, can't change.
      //
      return EFI_ABORTED;
    }

    //
    // Enable physical presence command
    // It is necessary in order to lock physical presence
    //
    Status = Tpm12PhysicalPresence (
               TPM_PHYSICAL_PRESENCE_CMD_ENABLE
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Lock physical presence
  //
  Status = Tpm12PhysicalPresence (
              TPM_PHYSICAL_PRESENCE_LOCK
              );
  return Status;
}
예제 #24
0
/**
  Remove exec permissions from all regions whose type is identified by
  PcdDxeNxMemoryProtectionPolicy.
**/
STATIC
VOID
InitializeDxeNxMemoryProtectionPolicy (
  VOID
  )
{
  UINTN                             MemoryMapSize;
  UINTN                             MapKey;
  UINTN                             DescriptorSize;
  UINT32                            DescriptorVersion;
  EFI_MEMORY_DESCRIPTOR             *MemoryMap;
  EFI_MEMORY_DESCRIPTOR             *MemoryMapEntry;
  EFI_MEMORY_DESCRIPTOR             *MemoryMapEnd;
  EFI_STATUS                        Status;
  UINT64                            Attributes;
  LIST_ENTRY                        *Link;
  EFI_GCD_MAP_ENTRY                 *Entry;
  EFI_PEI_HOB_POINTERS              Hob;
  EFI_HOB_MEMORY_ALLOCATION         *MemoryHob;
  EFI_PHYSICAL_ADDRESS              StackBase;

  //
  // Get the EFI memory map.
  //
  MemoryMapSize = 0;
  MemoryMap     = NULL;

  Status = gBS->GetMemoryMap (
                  &MemoryMapSize,
                  MemoryMap,
                  &MapKey,
                  &DescriptorSize,
                  &DescriptorVersion
                  );
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
  do {
    MemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (MemoryMapSize);
    ASSERT (MemoryMap != NULL);
    Status = gBS->GetMemoryMap (
                    &MemoryMapSize,
                    MemoryMap,
                    &MapKey,
                    &DescriptorSize,
                    &DescriptorVersion
                    );
    if (EFI_ERROR (Status)) {
      FreePool (MemoryMap);
    }
  } while (Status == EFI_BUFFER_TOO_SMALL);
  ASSERT_EFI_ERROR (Status);

  StackBase = 0;
  if (PcdGetBool (PcdCpuStackGuard)) {
    //
    // Get the base of stack from Hob.
    //
    Hob.Raw = GetHobList ();
    while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
      MemoryHob = Hob.MemoryAllocation;
      if (CompareGuid(&gEfiHobMemoryAllocStackGuid, &MemoryHob->AllocDescriptor.Name)) {
        DEBUG ((
          DEBUG_INFO,
          "%a: StackBase = 0x%016lx  StackSize = 0x%016lx\n",
          __FUNCTION__,
          MemoryHob->AllocDescriptor.MemoryBaseAddress,
          MemoryHob->AllocDescriptor.MemoryLength
          ));

        StackBase = MemoryHob->AllocDescriptor.MemoryBaseAddress;
        //
        // Ensure the base of the stack is page-size aligned.
        //
        ASSERT ((StackBase & EFI_PAGE_MASK) == 0);
        break;
      }
      Hob.Raw = GET_NEXT_HOB (Hob);
    }

    //
    // Ensure the base of stack can be found from Hob when stack guard is
    // enabled.
    //
    ASSERT (StackBase != 0);
  }

  DEBUG ((
    DEBUG_INFO,
    "%a: applying strict permissions to active memory regions\n",
    __FUNCTION__
    ));

  MergeMemoryMapForProtectionPolicy (MemoryMap, &MemoryMapSize, DescriptorSize);

  MemoryMapEntry = MemoryMap;
  MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize);
  while ((UINTN) MemoryMapEntry < (UINTN) MemoryMapEnd) {

    Attributes = GetPermissionAttributeForMemoryType (MemoryMapEntry->Type);
    if (Attributes != 0) {
      SetUefiImageMemoryAttributes (
        MemoryMapEntry->PhysicalStart,
        LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT),
        Attributes);

      //
      // Add EFI_MEMORY_RP attribute for page 0 if NULL pointer detection is
      // enabled.
      //
      if (MemoryMapEntry->PhysicalStart == 0 &&
          PcdGet8 (PcdNullPointerDetectionPropertyMask) != 0) {

        ASSERT (MemoryMapEntry->NumberOfPages > 0);
        SetUefiImageMemoryAttributes (
          0,
          EFI_PAGES_TO_SIZE (1),
          EFI_MEMORY_RP | Attributes);
      }

      //
      // Add EFI_MEMORY_RP attribute for the first page of the stack if stack
      // guard is enabled.
      //
      if (StackBase != 0 &&
          (StackBase >= MemoryMapEntry->PhysicalStart &&
           StackBase <  MemoryMapEntry->PhysicalStart +
                        LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT)) &&
          PcdGetBool (PcdCpuStackGuard)) {

        SetUefiImageMemoryAttributes (
          StackBase,
          EFI_PAGES_TO_SIZE (1),
          EFI_MEMORY_RP | Attributes);
      }

    }
    MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
  }
  FreePool (MemoryMap);

  //
  // Apply the policy for RAM regions that we know are present and
  // accessible, but have not been added to the UEFI memory map (yet).
  //
  if (GetPermissionAttributeForMemoryType (EfiConventionalMemory) != 0) {
    DEBUG ((
      DEBUG_INFO,
      "%a: applying strict permissions to inactive memory regions\n",
      __FUNCTION__
      ));

    CoreAcquireGcdMemoryLock ();

    Link = mGcdMemorySpaceMap.ForwardLink;
    while (Link != &mGcdMemorySpaceMap) {

      Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

      if (Entry->GcdMemoryType == EfiGcdMemoryTypeReserved &&
          Entry->EndAddress < MAX_ADDRESS &&
          (Entry->Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
            (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) {

        Attributes = GetPermissionAttributeForMemoryType (EfiConventionalMemory) |
                     (Entry->Attributes & CACHE_ATTRIBUTE_MASK);

        DEBUG ((DEBUG_INFO,
          "Untested GCD memory space region: - 0x%016lx - 0x%016lx (0x%016lx)\n",
          Entry->BaseAddress, Entry->EndAddress - Entry->BaseAddress + 1,
          Attributes));

        ASSERT(gCpu != NULL);
        gCpu->SetMemoryAttributes (gCpu, Entry->BaseAddress,
          Entry->EndAddress - Entry->BaseAddress + 1, Attributes);
      }

      Link = Link->ForwardLink;
    }
    CoreReleaseGcdMemoryLock ();
  }
}
/**
  Entry point for this driver.

  @param[in] ImageHandle  Image handle of this driver.
  @param[in] SystemTable  Pointer to SystemTable.

  @retval EFI_SUCESS       Driver has loaded successfully.
  @retval EFI_UNSUPPORTED  PCI resource allocation has been disabled.
  @retval EFI_UNSUPPORTED  There is no 64-bit PCI MMIO aperture.
  @return                  Error codes from lower level functions.

**/
EFI_STATUS
EFIAPI
DriverInitialize (
  IN EFI_HANDLE       ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  )
{
  EFI_STATUS Status;
  EFI_EVENT  Event;
  VOID       *Registration;

  //
  // If the PCI Bus driver is not supposed to allocate resources, then it makes
  // no sense to install a protocol that influences the resource allocation.
  //
  // Similarly, if there is no 64-bit PCI MMIO aperture, then 64-bit MMIO BARs
  // have to be allocated under 4 GB unconditionally.
  //
  if (PcdGetBool (PcdPciDisableBusEnumeration) ||
      PcdGet64 (PcdPciMmio64Size) == 0) {
    return EFI_UNSUPPORTED;
  }

  //
  // Otherwise, create a protocol notify to see if a CSM is present. (With the
  // CSM absent, the PCI Bus driver won't have to worry about allocating 64-bit
  // MMIO BARs in the 32-bit MMIO aperture, for the sake of a legacy BIOS.)
  //
  // If the Legacy BIOS Protocol is present at the time of this driver starting
  // up, we can mark immediately that the PCI Bus driver should perform the
  // usual 64-bit MMIO BAR degradation.
  //
  // Otherwise, if the Legacy BIOS Protocol is absent at startup, it may be
  // installed later. However, if it doesn't show up until the first
  // EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL.CheckDevice() call from the
  // PCI Bus driver, then it never will:
  //
  // 1. The following drivers are dispatched in some unspecified order:
  //    - PCI Host Bridge DXE_DRIVER,
  //    - PCI Bus UEFI_DRIVER,
  //    - this DXE_DRIVER,
  //    - Legacy BIOS DXE_DRIVER.
  //
  // 2. The DXE_CORE enters BDS.
  //
  // 3. The platform BDS connects the PCI Root Bridge IO instances (produced by
  //    the PCI Host Bridge DXE_DRIVER).
  //
  // 4. The PCI Bus UEFI_DRIVER enumerates resources and calls into this
  //    DXE_DRIVER (CheckDevice()).
  //
  // 5. This driver remembers if EFI_LEGACY_BIOS_PROTOCOL has been installed
  //    sometime during step 1 (produced by the Legacy BIOS DXE_DRIVER).
  //
  // For breaking this order, the Legacy BIOS DXE_DRIVER would have to install
  // its protocol after the firmware enters BDS, which cannot happen.
  //
  Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
                  LegacyBiosInstalled, NULL /* Context */, &Event);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->RegisterProtocolNotify (&gEfiLegacyBiosProtocolGuid, Event,
                  &Registration);
  if (EFI_ERROR (Status)) {
    goto CloseEvent;
  }

  Status = gBS->SignalEvent (Event);
  ASSERT_EFI_ERROR (Status);

  mIncompatiblePciDeviceSupport.CheckDevice = CheckDevice;
  Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
                  &gEfiIncompatiblePciDeviceSupportProtocolGuid,
                  &mIncompatiblePciDeviceSupport, NULL);
  if (EFI_ERROR (Status)) {
    goto CloseEvent;
  }

  return EFI_SUCCESS;

CloseEvent:
  if (!mLegacyBiosInstalled) {
    EFI_STATUS CloseStatus;

    CloseStatus = gBS->CloseEvent (Event);
    ASSERT_EFI_ERROR (CloseStatus);
  }

  return Status;
}
예제 #26
0
파일: VirtualMemory.c 프로젝트: M1cha/edk2
/**
  Allocates and fills in the Page Directory and Page Table Entries to
  establish a 1:1 Virtual to Physical mapping.

  @param[in] StackBase  Stack base address.
  @param[in] StackSize  Stack size.

  @return The address of 4 level page map.

**/
UINTN
CreateIdentityMappingPageTables (
  IN EFI_PHYSICAL_ADDRESS   StackBase,
  IN UINTN                  StackSize
  )
{  
  UINT32                                        RegEax;
  UINT32                                        RegEdx;
  UINT8                                         PhysicalAddressBits;
  EFI_PHYSICAL_ADDRESS                          PageAddress;
  UINTN                                         IndexOfPml4Entries;
  UINTN                                         IndexOfPdpEntries;
  UINTN                                         IndexOfPageDirectoryEntries;
  UINT32                                        NumberOfPml4EntriesNeeded;
  UINT32                                        NumberOfPdpEntriesNeeded;
  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMapLevel4Entry;
  PAGE_MAP_AND_DIRECTORY_POINTER                *PageMap;
  PAGE_MAP_AND_DIRECTORY_POINTER                *PageDirectoryPointerEntry;
  PAGE_TABLE_ENTRY                              *PageDirectoryEntry;
  UINTN                                         TotalPagesNum;
  UINTN                                         BigPageAddress;
  VOID                                          *Hob;
  BOOLEAN                                       Page1GSupport;
  PAGE_TABLE_1G_ENTRY                           *PageDirectory1GEntry;

  Page1GSupport = FALSE;
  if (PcdGetBool(PcdUse1GPageTable)) {
    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
    if (RegEax >= 0x80000001) {
      AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
      if ((RegEdx & BIT26) != 0) {
        Page1GSupport = TRUE;
      }
    }
  }

  //
  // Get physical address bits supported.
  //
  Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
  if (Hob != NULL) {
    PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
  } else {
    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
    if (RegEax >= 0x80000008) {
      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
      PhysicalAddressBits = (UINT8) RegEax;
    } else {
      PhysicalAddressBits = 36;
    }
  }

  //
  // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
  //
  ASSERT (PhysicalAddressBits <= 52);
  if (PhysicalAddressBits > 48) {
    PhysicalAddressBits = 48;
  }

  //
  // Calculate the table entries needed.
  //
  if (PhysicalAddressBits <= 39 ) {
    NumberOfPml4EntriesNeeded = 1;
    NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
  } else {
    NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
    NumberOfPdpEntriesNeeded = 512;
  }

  //
  // Pre-allocate big pages to avoid later allocations. 
  //
  if (!Page1GSupport) {
    TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1;
  } else {
    TotalPagesNum = NumberOfPml4EntriesNeeded + 1;
  }
  BigPageAddress = (UINTN) AllocatePages (TotalPagesNum);
  ASSERT (BigPageAddress != 0);

  //
  // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
  //
  PageMap         = (VOID *) BigPageAddress;
  BigPageAddress += SIZE_4KB;

  PageMapLevel4Entry = PageMap;
  PageAddress        = 0;
  for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {
    //
    // Each PML4 entry points to a page of Page Directory Pointer entires.
    // So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
    //
    PageDirectoryPointerEntry = (VOID *) BigPageAddress;
    BigPageAddress += SIZE_4KB;

    //
    // Make a PML4 Entry
    //
    PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry;
    PageMapLevel4Entry->Bits.ReadWrite = 1;
    PageMapLevel4Entry->Bits.Present = 1;

    if (Page1GSupport) {
      PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;
    
      for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
        if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + StackSize) && ((PageAddress + SIZE_1GB) > StackBase)) {
          Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize);
        } else {
          //
          // Fill in the Page Directory entries
          //
          PageDirectory1GEntry->Uint64 = (UINT64)PageAddress;
          PageDirectory1GEntry->Bits.ReadWrite = 1;
          PageDirectory1GEntry->Bits.Present = 1;
          PageDirectory1GEntry->Bits.MustBe1 = 1;
        }
      }
    } else {
      for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
        //
        // Each Directory Pointer entries points to a page of Page Directory entires.
        // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
        //       
        PageDirectoryEntry = (VOID *) BigPageAddress;
        BigPageAddress += SIZE_4KB;

        //
        // Fill in a Page Directory Pointer Entries
        //
        PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry;
        PageDirectoryPointerEntry->Bits.ReadWrite = 1;
        PageDirectoryPointerEntry->Bits.Present = 1;

        for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
          if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + StackSize) && ((PageAddress + SIZE_2MB) > StackBase)) {
            //
            // Need to split this 2M page that covers stack range.
            //
            Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);
          } else {
            //
            // Fill in the Page Directory entries
            //
            PageDirectoryEntry->Uint64 = (UINT64)PageAddress;
            PageDirectoryEntry->Bits.ReadWrite = 1;
            PageDirectoryEntry->Bits.Present = 1;
            PageDirectoryEntry->Bits.MustBe1 = 1;
          }
        }
      }

      for (; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
        ZeroMem (
          PageDirectoryPointerEntry,
          sizeof(PAGE_MAP_AND_DIRECTORY_POINTER)
          );
      }
    }
  }

  //
  // For the PML4 entries we are not using fill in a null entry.
  //
  for (; IndexOfPml4Entries < 512; IndexOfPml4Entries++, PageMapLevel4Entry++) {
    ZeroMem (
      PageMapLevel4Entry,
      sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
      );
  }

  if (PcdGetBool (PcdSetNxForStack)) {
    EnableExecuteDisableBit ();
  }

  return (UINTN)PageMap;
}
예제 #27
0
EFI_STATUS
AcpiPlatformEntryPoint (
  IN EFI_HANDLE     ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS                   Status;
  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
  INTN                         Instance;
  EFI_ACPI_COMMON_HEADER       *CurrentTable;
  UINTN                        TableHandle;
  UINT32                       FvStatus;
  UINTN                        Size;
  EFI_ACPI_TABLE_VERSION       Version;
  QNC_DEVICE_ENABLES           QNCDeviceEnables;
  EFI_HANDLE                   Handle;
  UINTN                         Index;
  PCI_DEVICE_INFO               *PciDeviceInfo;
  EFI_ACPI_HANDLE               PciRootHandle;
  BOOLEAN                       UpdatePRT;
  BOOLEAN                       UpdatePRW;
  PCI_DEVICE_SETTING            *mConfigData;

  Instance = 0;
  TableHandle = 0;
  CurrentTable = NULL;
  mConfigData  = NULL;
  QNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables);

  //
  // Initialize the EFI Driver Library
  //

  ASSERT (sizeof (EFI_GLOBAL_NVS_AREA) == 512);

  Status = gBS->AllocatePool (
                   EfiACPIMemoryNVS,
                   sizeof (EFI_GLOBAL_NVS_AREA),
                   (VOID**)&mGlobalNvsArea.Area
                   );

  Handle = NULL;
  Status = gBS->InstallProtocolInterface (
                  &Handle,
                  &gEfiGlobalNvsAreaProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mGlobalNvsArea
                  );

  ASSERT_EFI_ERROR (Status);
  if (!EFI_ERROR (Status)) {
    SetMem (
      mGlobalNvsArea.Area,
      sizeof (EFI_GLOBAL_NVS_AREA),
      0
      );
  }

  //
  // Initialize the data.  Eventually, this will be controlled by setup options.
  //
  mGlobalNvsArea.Area->HpetEnable           =  PcdGetBool (PcdHpetEnable);  
  mGlobalNvsArea.Area->Pm1blkIoBaseAddress  =  PcdGet16(PcdPm1blkIoBaseAddress);
  mGlobalNvsArea.Area->PmbaIoBaseAddress    =  PcdGet16(PcdPmbaIoBaseAddress);   
  mGlobalNvsArea.Area->Gpe0blkIoBaseAddress =  PcdGet16(PcdGpe0blkIoBaseAddress);
  mGlobalNvsArea.Area->GbaIoBaseAddress     =  PcdGet16(PcdGbaIoBaseAddress);                        
  mGlobalNvsArea.Area->SmbaIoBaseAddress    =  PcdGet16(PcdSmbaIoBaseAddress);
  mGlobalNvsArea.Area->SpiDmaIoBaseAddress  =  PcdGet16(PcdSpiDmaIoBaseAddress);
  mGlobalNvsArea.Area->WdtbaIoBaseAddress   =  PcdGet16(PcdWdtbaIoBaseAddress);
  mGlobalNvsArea.Area->HpetBaseAddress      =  (UINT32)PcdGet64(PcdHpetBaseAddress);       
  mGlobalNvsArea.Area->HpetSize             =  (UINT32)PcdGet64(PcdHpetSize);              
  mGlobalNvsArea.Area->PciExpressBaseAddress=  (UINT32)PcdGet64(PcdPciExpressBaseAddress); 
  mGlobalNvsArea.Area->PciExpressSize       =  (UINT32)PcdGet64(PcdPciExpressSize);        
  mGlobalNvsArea.Area->RcbaMmioBaseAddress  =  (UINT32)PcdGet64(PcdRcbaMmioBaseAddress); 
  mGlobalNvsArea.Area->RcbaMmioSize         =  (UINT32)PcdGet64(PcdRcbaMmioSize);        
  mGlobalNvsArea.Area->IoApicBaseAddress    =  (UINT32)PcdGet64(PcdIoApicBaseAddress);     
  mGlobalNvsArea.Area->IoApicSize           =  (UINT32)PcdGet64(PcdIoApicSize);
  mGlobalNvsArea.Area->TpmPresent           =  (UINT32)(FALSE);

  //
  // Find the AcpiTable protocol
  //
  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  //
  // Initialize MADT table
  // 
  Status = MadtTableInitialize (&CurrentTable, &Size);
  ASSERT_EFI_ERROR (Status);
  //
  // Perform any table specific updates.
  //
  AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);

  //
  // Update the check sum 
  // It needs to be zeroed before the checksum calculation
  //
  ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;  
  ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 
    CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
    
  //
  // Add the table
  //
  TableHandle = 0;
  Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                            CurrentTable,
                            CurrentTable->Length,
                          &TableHandle
                          );
  ASSERT_EFI_ERROR (Status);
  CurrentTable = NULL;

  //
  // Init Pci Device PRT PRW information structure from PCD
  //
  mConfigData = (PCI_DEVICE_SETTING *)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING));
  ASSERT_EFI_ERROR (mConfigData);
  InitPciDeviceInfoStructure (mConfigData);
  //
  // Get the Acpi SDT protocol for manipulation on acpi table
  //
  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&mAcpiSdt);
  ASSERT_EFI_ERROR (Status);
  //
  // Locate the firmware volume protocol
  //
  Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }
  //
  // Read tables from the storage file.
  //

  while (Status == EFI_SUCCESS) {

    Status = FwVol->ReadSection (
                      FwVol,
                      (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
                      EFI_SECTION_RAW,
                      Instance,
                      (VOID**)&CurrentTable,
                      &Size,
                      &FvStatus
                      );

    if (!EFI_ERROR(Status)) {
      //
      // Perform any table specific updates.
      //
      AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);

      //
      // Update the check sum 
      // It needs to be zeroed before the checksum calculation
      //
      ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;   
      ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 
        CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);
        
      //
      // Add the table
      //
      TableHandle = 0;
      Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                              CurrentTable,
                            ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length,
                              &TableHandle
                              );
      if (EFI_ERROR(Status)) {
        return EFI_ABORTED;
      }
      //
      // If this table is the DSDT table, then update the _PRT and _PRW based on
      // the settings from pcds
      //
      if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
        //
        // Create the root handle for DSDT table
        //
        Status = mAcpiSdt->OpenSdt (TableHandle, &mDsdtHandle);
        ASSERT_EFI_ERROR (Status);

        PciRootHandle = NULL;
        PciRootHandle = SdtGetRootBridgeHandle (mAcpiSdt, mDsdtHandle);
        ASSERT (PciRootHandle != NULL);	

        PciDeviceInfo = NULL;
        for (Index = 0; Index < mConfigData->PciDeviceInfoNumber; Index++) {
          PciDeviceInfo = &(mConfigData->PciDeviceInfo[Index]);

          //
          // Check whether this is a valid item
          //
          if ((PciDeviceInfo->BridgeAddress != 0xFFFFFFFF) && (PciDeviceInfo->DeviceAddress != 0xFFFFFFFF)) {

            //DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress));

            UpdatePRT = FALSE;
            UpdatePRW = FALSE;

            SdtCheckPciDeviceInfoChanged (PciDeviceInfo, &UpdatePRT, &UpdatePRW);
            //
            // Check whether there is any valid pci routing item
            //
            if (UpdatePRT) {
              //
              // Update the pci routing information
              //
              //DEBUG ((EFI_D_ERROR, "Update _PRT\n"));
              SdtUpdatePciRouting (mAcpiSdt, PciRootHandle, PciDeviceInfo);  						
            }
            //
            // Check whether there is any valid pci routing item
            //
            if (UpdatePRW) {
              //
              // Update the pci wakeup information
              //
              //DEBUG ((EFI_D_ERROR, "Update _PRW\n"));
              SdtUpdatePowerWake (mAcpiSdt, PciRootHandle, PciDeviceInfo);				
            }
          }
        }
        Status = mAcpiSdt->Close (PciRootHandle);
        ASSERT_EFI_ERROR (Status);
        //
        // Mark the root handle as modified , let SDT protocol recaculate the checksum
        //
        ((EFI_AML_HANDLE *)mDsdtHandle)->Modified = TRUE;
        Status = mAcpiSdt->Close (mDsdtHandle);
        ASSERT_EFI_ERROR (Status);
      } 
      //
      // Increment the instance
      //
      Instance++;
      CurrentTable = NULL;
    }
  }

  gBS->FreePool (mConfigData);
  return EFI_SUCCESS;
}
예제 #28
0
/**
  Entrypoint of Boot script exector driver, this function will be executed in
  normal boot phase and invoked by DXE dispatch.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
BootScriptExecutorEntryPoint (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  UINTN                                         BufferSize;
  UINTN                                         Pages;
  BOOT_SCRIPT_EXECUTOR_VARIABLE                 *EfiBootScriptExecutorVariable;
  EFI_PHYSICAL_ADDRESS                          BootScriptExecutorBuffer;
  EFI_STATUS                                    Status;
  VOID                                          *DevicePath;
  EFI_EVENT                                     ReadyToLockEvent;
  VOID                                          *Registration;
  UINT32                                        RegEax;
  UINT32                                        RegEdx;

  if (!PcdGetBool (PcdAcpiS3Enable)) {
    return EFI_UNSUPPORTED;
  }

  //
  // Test if the gEfiCallerIdGuid of this image is already installed. if not, the entry
  // point is loaded by DXE code which is the first time loaded. or else, it is already
  // be reloaded be itself.This is a work-around
  //
  Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &DevicePath);
  if (EFI_ERROR (Status)) {
      //
      // Create ReadyToLock event to reload BootScriptExecutor image
      // to RESERVED mem and save it to LockBox.
      //
      ReadyToLockEvent = EfiCreateProtocolNotifyEvent  (
                           &gEfiDxeSmmReadyToLockProtocolGuid,
                           TPL_NOTIFY,
                           ReadyToLockEventNotify,
                           NULL,
                           &Registration
                           );
      ASSERT (ReadyToLockEvent != NULL);
    } else {
      //
      // the entry point is invoked after reloading. following code only run in RESERVED mem
      //
      if (PcdGetBool(PcdUse1GPageTable)) {
        AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
        if (RegEax >= 0x80000001) {
          AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
          if ((RegEdx & BIT26) != 0) {
            mPage1GSupport = TRUE;
          }
        }
      }

      BufferSize = sizeof (BOOT_SCRIPT_EXECUTOR_VARIABLE);

      BootScriptExecutorBuffer = 0xFFFFFFFF;
      Pages = EFI_SIZE_TO_PAGES(BufferSize);
      Status = gBS->AllocatePages (
                      AllocateMaxAddress,
                      EfiReservedMemoryType,
                      Pages,
                      &BootScriptExecutorBuffer
                      );
      ASSERT_EFI_ERROR (Status);

      EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *)(UINTN)BootScriptExecutorBuffer;
      EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = (UINTN) S3BootScriptExecutorEntryFunction ;

      Status = SaveLockBox (
                 &gEfiBootScriptExecutorVariableGuid,
                 &BootScriptExecutorBuffer,
                 sizeof(BootScriptExecutorBuffer)
                 );
      ASSERT_EFI_ERROR (Status);

      //
      // Additional step for BootScript integrity
      // Save BootScriptExecutor context
      //
      Status = SaveLockBox (
                 &gEfiBootScriptExecutorContextGuid,
                 EfiBootScriptExecutorVariable,
                 sizeof(*EfiBootScriptExecutorVariable)
                 );
      ASSERT_EFI_ERROR (Status);

      Status = SetLockBoxAttributes (&gEfiBootScriptExecutorContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
      ASSERT_EFI_ERROR (Status);
    }

    return EFI_SUCCESS;
}
예제 #29
0
파일: BdsPlatform.c 프로젝트: jeppeter/vbox
VOID
EFIAPI
PlatformBdsPolicyBehavior (
  IN OUT LIST_ENTRY                  *DriverOptionList,
  IN OUT LIST_ENTRY                  *BootOptionList,
  IN PROCESS_CAPSULES                ProcessCapsules,
  IN BASEM_MEMORY_TEST               BaseMemoryTest
  )
/*++

Routine Description:

  The function will excute with as the platform policy, current policy
  is driven by boot mode. IBV/OEM can customize this code for their specific
  policy action.

Arguments:

  DriverOptionList - The header of the driver option link list

  BootOptionList   - The header of the boot option link list

  ProcessCapsules  - A pointer to ProcessCapsules()

  BaseMemoryTest   - A pointer to BaseMemoryTest()

Returns:

  None.

--*/
{
  EFI_STATUS                         Status;
  UINT16                             Timeout;
  EFI_EVENT                          UserInputDurationTime;
  LIST_ENTRY                     *Link;
  BDS_COMMON_OPTION                  *BootOption;
  UINTN                              Index;
  EFI_INPUT_KEY                      Key;
  EFI_TPL                            OldTpl;
  EFI_BOOT_MODE                      BootMode;

  VBoxLogFlowFuncEnter();

  ConnectRootBridge ();

  if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {
    DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "
      "from disk since flash variables appear to be supported.\n"));
  } else {
    //
    // Try to restore variables from the hard disk early so
    // they can be used for the other BDS connect operations.
    //
    PlatformBdsRestoreNvVarsFromHardDisk ();
  }

  //
  // Init the time out value
  //
  Timeout = PcdGet16 (PcdPlatformBootTimeOut);

  //
  // Load the driver option as the driver option list
  //
  PlatformBdsGetDriverOption (DriverOptionList);

  //
  // Get current Boot Mode
  //
  Status = BdsLibGetBootMode (&BootMode);
  DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));

  //
  // Go the different platform policy with different boot mode
  // Notes: this part code can be change with the table policy
  //
  ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);
  //
  // Connect platform console
  //
  Status = PlatformBdsConnectConsole (gPlatformConsole);
  if (EFI_ERROR (Status)) {
    //
    // Here OEM/IBV can customize with defined action
    //
    PlatformBdsNoConsoleAction ();
  }
  //
  // Create a 300ms duration event to ensure user has enough input time to enter Setup
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER,
                  0,
                  NULL,
                  NULL,
                  &UserInputDurationTime
                  );
  ASSERT (Status == EFI_SUCCESS);
  Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000);
  ASSERT (Status == EFI_SUCCESS);
  //
  // Memory test and Logo show
  //
  PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);

  //
  // Perform some platform specific connect sequence
  //
  PlatformBdsConnectSequence ();

  //
  // Process QEMU's -kernel command line option
  //
  TryRunningQemuKernel ();

  //
  // Give one chance to enter the setup if we
  // have the time out
  //
  if (Timeout != 0) {
    //PlatformBdsEnterFrontPage (Timeout, FALSE);
  }

  DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));
  BdsLibConnectAll ();
#ifdef VBOX
    {
        UINTN cFileSystem = 0;
        EFI_HANDLE *phFileSystem = NULL;
        BDS_COMMON_OPTION *BootOption0080 = NULL;
        EFI_STATUS rc = EFI_SUCCESS;
        DEBUG ((EFI_D_INFO, "------------------ VBox Platform Specific Initialization Start -----------------------\n"));
        BootOption0080 = BdsLibVariableToOption(BootOptionList, L"Boot0080");
        if (!BootOption0080)
        {
            rc = gBS->LocateHandleBuffer (ByProtocol,
                                          &gEfiSimpleFileSystemProtocolGuid,
                                          NULL,
                                          &cFileSystem,
                                          &phFileSystem);
            VBoxLogFlowFuncMarkRC(rc);
            VBoxLogFlowFuncMarkVar(cFileSystem, "%d");
            if (   rc == EFI_SUCCESS
                && cFileSystem > 0)
            {
                EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFSVolume;
                EFI_FILE_HANDLE                  hFSRoot;
                EFI_FILE_HANDLE                  hBootEfiFile;
                UINTN iFileSystem = 0;
                /* Ok, we've found several simple file system handles
                 * 1. we should find if '\\System\\Library\\CoreServices\\boot.efi' present
                 * 2. Alter 'BootOrder' to include this file in boot sequence.
                 */
                for (iFileSystem = 0; iFileSystem < cFileSystem; ++iFileSystem)
                {
                    EFI_DEVICE_PATH_PROTOCOL *pDevicePath = NULL;
                    /* mount and look up the boot.efi */
                    rc = gBS->HandleProtocol (phFileSystem[iFileSystem],
                                              &gEfiSimpleFileSystemProtocolGuid,
                                              (VOID *) &pFSVolume);
                    VBoxLogFlowFuncMarkVar(iFileSystem, "%d");
                    VBoxLogFlowFuncMarkRC(rc);
                    if (EFI_ERROR(rc))
                        continue;

                    rc = pFSVolume->OpenVolume(pFSVolume, &hFSRoot);
                    VBoxLogFlowFuncMarkRC(rc);
                    if (EFI_ERROR(rc))
                        continue;

                    rc = hFSRoot->Open(hFSRoot, &hBootEfiFile, L"\\System\\Library\\CoreServices\\boot.efi", EFI_FILE_MODE_READ, 0);
                    VBoxLogFlowFuncMarkRC(rc);
                    if (EFI_ERROR(rc))
                        continue;
                    /* nice file is found and we have to register it */
                    pDevicePath = FileDevicePath(phFileSystem[iFileSystem], L"\\System\\Library\\CoreServices\\boot.efi");
                    VBoxLogFlowFuncMarkVar(pDevicePath,"%p");
                    if (!pDevicePath)
                        continue;
                    rc = BdsLibRegisterNewOption (BootOptionList, pDevicePath, L"Mac Boot", L"BootOrder");
                    VBoxLogFlowFuncMarkRC(rc);
                }
            }
        }
        else
        {
            VBoxLogFlowFuncMarkVar(BootOption0080->LoadOptionsSize, "%d");
            if (BootOption0080->LoadOptionsSize)
                VBoxLogFlowFuncMarkVar(BootOption0080->LoadOptions, "%s");
#if 0
            /* Boot0080 option is found */
            UINT16                    *BootOrder;
            UINTN                     BootOrderSize;
            UINTN                     Index = 0;
            CHAR16                    *BootOptionName;
            ASSERT(BootOption0080->Signature == BDS_LOAD_OPTION_SIGNATURE);
            BootOrder = BdsLibGetVariableAndSize (
                          L"BootOrder",
                          &gEfiGlobalVariableGuid,
                          &BootOrderSize);
            ASSERT(BootOrder);
            BootOptionName = AllocateRuntimePool(256 * sizeof(UINT16));
            UnicodeSPrint(BootOptionName, 256 * sizeof(UINT16), L"Boot%04x", BootOrder[Index]);
            BootOption0080->OptionName = BootOptionName;
            rc = gRT->SetVariable(BootOptionName,
                                  &gEfiGlobalVariableGuid,
                                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                                  sizeof(BDS_COMMON_OPTION),
                                  BootOption0080);
            LogFlowFuncMarkRC(rc);
#if 0
            rc = BdsLibRegisterNewOption (BootOptionList, BootOption0080->DevicePath, L"Mac Boot Temp", L"BootOrder");
#endif
            LogFlowFuncMarkRC(rc);
#endif
        }
        DEBUG ((EFI_D_INFO, "------------------ VBox Platform Specific Initialization End -----------------------\n"));
    }
#endif
  BdsLibEnumerateAllBootOption (BootOptionList);

  SetBootOrderFromQemu (BootOptionList);
  //
  // The BootOrder variable may have changed, reload the in-memory list with
  // it.
  //
  BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");

  //
  // To give the User a chance to enter Setup here, if user set TimeOut is 0.
  // BDS should still give user a chance to enter Setup
  //
  // Connect first boot option, and then check user input before exit
  //
  for (Link = BootOptionList->ForwardLink; Link != BootOptionList;Link = Link->ForwardLink) {
    BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
    if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {
      //
      // skip the header of the link list, becuase it has no boot option
      //
      continue;
    } else {
      //
      // Make sure the boot option device path connected, but ignore the BBS device path
      //
      if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {
        BdsLibConnectDevicePath (BootOption->DevicePath);
      }
      break;
    }
  }

  //
  // Check whether the user input after the duration time has expired
  //
  OldTpl = EfiGetCurrentTpl();
  gBS->RestoreTPL (TPL_APPLICATION);
  gBS->WaitForEvent (1, &UserInputDurationTime, &Index);
  gBS->CloseEvent (UserInputDurationTime);
  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
  gBS->RaiseTPL (OldTpl);

  if (!EFI_ERROR (Status)) {
    //
    // Enter Setup if user input
    //
    Timeout = 0xffff;
    PlatformBdsEnterFrontPage (Timeout, FALSE);
  }

  VBoxLogFlowFuncLeave();
  return ;
}
예제 #30
0
/**
  Allocates and fills in the Page Directory and Page Table Entries to
  establish a 1:1 Virtual to Physical mapping.
  If BootScriptExector driver will run in 64-bit mode, this function will establish the 1:1 
  virtual to physical mapping page table.
  If BootScriptExector driver will not run in 64-bit mode, this function will do nothing. 
  
  @return  the 1:1 Virtual to Physical identity mapping page table base address. 

**/
EFI_PHYSICAL_ADDRESS
S3CreateIdentityMappingPageTables (
  VOID
  )
{  
  if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
    UINT32                                        RegEax;
    UINT32                                        RegEdx;
    UINT8                                         PhysicalAddressBits;
    UINT32                                        NumberOfPml4EntriesNeeded;
    UINT32                                        NumberOfPdpEntriesNeeded;
    EFI_PHYSICAL_ADDRESS                          S3NvsPageTableAddress;
    UINTN                                         TotalPageTableSize;
    VOID                                          *Hob;
    BOOLEAN                                       Page1GSupport;

    Page1GSupport = FALSE;
    if (PcdGetBool(PcdUse1GPageTable)) {
      AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
      if (RegEax >= 0x80000001) {
        AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
        if ((RegEdx & BIT26) != 0) {
          Page1GSupport = TRUE;
        }
      }
    }

    //
    // Get physical address bits supported.
    //
    Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
    if (Hob != NULL) {
      PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
    } else {
      AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
      if (RegEax >= 0x80000008) {
        AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
        PhysicalAddressBits = (UINT8) RegEax;
      } else {
        PhysicalAddressBits = 36;
      }
    }
    
    //
    // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
    //
    ASSERT (PhysicalAddressBits <= 52);
    if (PhysicalAddressBits > 48) {
      PhysicalAddressBits = 48;
    }

    //
    // Calculate the table entries needed.
    //
    if (PhysicalAddressBits <= 39 ) {
      NumberOfPml4EntriesNeeded = 1;
      NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
    } else {
      NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
      NumberOfPdpEntriesNeeded = 512;
    }

    //
    // We need calculate whole page size then allocate once, because S3 restore page table does not know each page in Nvs.
    //
    if (!Page1GSupport) {
      TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded + NumberOfPml4EntriesNeeded * NumberOfPdpEntriesNeeded);
    } else {
      TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded);
    }
    DEBUG ((EFI_D_ERROR, "TotalPageTableSize - %x pages\n", TotalPageTableSize));

    //
    // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
    //
    S3NvsPageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGES_TO_SIZE(TotalPageTableSize));
    ASSERT (S3NvsPageTableAddress != 0);
    return S3NvsPageTableAddress;
  } else {
    //
    // If DXE is running 32-bit mode, no need to establish page table.
    //
    return  (EFI_PHYSICAL_ADDRESS) 0;  
  }
}