Exemple #1
0
/**

  This function initialize basic context for FRM.

**/
VOID
InitBasicContext (
  VOID
  )
{
  UINT32  RegEax;

  mHostContextCommon.CpuNum = GetCpuNumFromAcpi ();

  GetPciExpressInfoFromAcpi (&mHostContextCommon.PciExpressBaseAddress, &mHostContextCommon.PciExpressLength);
  PcdSet64 (PcdPciExpressBaseAddress, mHostContextCommon.PciExpressBaseAddress);
  if (mHostContextCommon.PciExpressBaseAddress == 0) {
    CpuDeadLoop ();
  }

  mHostContextCommon.AcpiTimerIoPortBaseAddress = GetAcpiTimerPort (&mHostContextCommon.AcpiTimerWidth);
  PcdSet16 (PcdAcpiTimerIoPortBaseAddress, mHostContextCommon.AcpiTimerIoPortBaseAddress);
  PcdSet8 (PcdAcpiTimerWidth, mHostContextCommon.AcpiTimerWidth);
  if (mHostContextCommon.AcpiTimerIoPortBaseAddress == 0) {
    CpuDeadLoop ();
  }

  mHostContextCommon.ResetIoPortBaseAddress = GetAcpiResetPort ();

  mHostContextCommon.AcpiPmControlIoPortBaseAddress = GetAcpiPmControlPort ();
  if (mHostContextCommon.AcpiPmControlIoPortBaseAddress == 0) {
    CpuDeadLoop ();
  }

  mHostContextCommon.HostContextPerCpu = AllocatePages (FRM_SIZE_TO_PAGES(sizeof(FRM_HOST_CONTEXT_PER_CPU)) * mHostContextCommon.CpuNum);
  mGuestContextCommon.GuestContextPerCpu = AllocatePages (FRM_SIZE_TO_PAGES(sizeof(FRM_GUEST_CONTEXT_PER_CPU)) * mHostContextCommon.CpuNum);

  mHostContextCommon.LowMemoryBase = mCommunicationData.LowMemoryBase;
  mHostContextCommon.LowMemorySize = mCommunicationData.LowMemorySize;
  mHostContextCommon.LowMemoryBackupBase = (UINT64)(UINTN)AllocatePages (FRM_SIZE_TO_PAGES ((UINTN)mCommunicationData.LowMemorySize));

  //
  // Save current context
  //
  mBspIndex = ApicToIndex (ReadLocalApicId ());
  mGuestContextCommon.GuestContextPerCpu[mBspIndex].Cr0 = AsmReadCr0 ();
  mGuestContextCommon.GuestContextPerCpu[mBspIndex].Cr3 = AsmReadCr3 ();
  mGuestContextCommon.GuestContextPerCpu[mBspIndex].Cr4 = AsmReadCr4 ();
  AsmReadGdtr (&mGuestContextCommon.GuestContextPerCpu[mBspIndex].Gdtr);
  AsmReadIdtr (&mGuestContextCommon.GuestContextPerCpu[mBspIndex].Idtr);

  AsmCpuid (CPUID_EXTENDED_INFORMATION, &RegEax, NULL, NULL, NULL);
  if (RegEax >= CPUID_EXTENDED_ADDRESS_SIZE) {
    AsmCpuid (CPUID_EXTENDED_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);
    mHostContextCommon.PhysicalAddressBits = (UINT8)RegEax;
  } else {
    mHostContextCommon.PhysicalAddressBits = 36;
  }
}
Exemple #2
0
/**
  Programs processor registers according to register tables.

  This function programs processor registers according to register tables.

**/
VOID
SettingPhase (
  VOID
  )
{
  UINT8                     CallbackSignalValue;
  UINTN                     Index;
  UINTN                     ProcessorNumber;
  CPU_REGISTER_TABLE        *RegisterTable;
  BOOLEAN                   NeedCpuOnlyReset;

  //
  // Set PcdCpuCallbackSignal to trigger callback function, and reads the value back.
  //
  CallbackSignalValue = SetAndReadCpuCallbackSignal (CPU_PROCESSOR_SETTING_SIGNAL);
  //
  // Checks whether the callback function requests to bypass Setting phase.
  //
  if (CallbackSignalValue == CPU_BYPASS_SIGNAL) {
    return;
  }

  //
  // Check if CPU-only reset is needed
  //
  NeedCpuOnlyReset = FALSE;
  for (Index = 0; Index < mCpuConfigConextBuffer.NumberOfProcessors; Index++) {
    RegisterTable = &mCpuConfigConextBuffer.RegisterTable[Index];
    if (RegisterTable->NumberBeforeReset > 0) {
      NeedCpuOnlyReset = TRUE;
      break;
    }
  }

  //
  // if CPU-only reset is needed, then program corresponding registers, and
  // trigger CPU-only reset.
  //
  if (NeedCpuOnlyReset) {
    mSetBeforeCpuOnlyReset = TRUE;
    DispatchAPAndWait (
      TRUE,
      0,
      SetProcessorRegister
      );

    SetProcessorRegister (mCpuConfigConextBuffer.BspNumber);

    CpuOnlyResetAndRestore ();
  }

  //
  // Program processors' registers in sequential mode.
  //
  mSetBeforeCpuOnlyReset = FALSE;
  for (Index = 0; Index < mCpuConfigConextBuffer.NumberOfProcessors; Index++) {
    
    ProcessorNumber = mCpuConfigConextBuffer.SettingSequence[Index];

    if (ProcessorNumber == mCpuConfigConextBuffer.BspNumber) {
      SetProcessorRegister (ProcessorNumber);
    } else {

      DispatchAPAndWait (
        FALSE,
        GET_CPU_MISC_DATA (ProcessorNumber, ApicID),
        SetProcessorRegister
        );
    }

    RegisterTable = &mCpuConfigConextBuffer.RegisterTable[ProcessorNumber];
    RegisterTable->InitialApicId = GetInitialLocalApicId (ProcessorNumber);
  }
  //
  // Set PcdCpuCallbackSignal to trigger callback function
  //
  PcdSet8 (PcdCpuCallbackSignal, CPU_PROCESSOR_SETTING_END_SIGNAL);

  //
  // From now on, SetProcessorRegister() will be called only by SimpleApProcWrapper()
  // and ApProcWrapper to restore register settings after INIT signal, so switch
  // this flag from FALSE to TRUE.
  //
  mRestoreSettingAfterInit = TRUE;
}
Exemple #3
0
/**
  This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration.

  @param  SetupTpmDevice  TpmDevice configuration in setup driver

  @return TpmDevice configuration
**/
UINT8
DetectTpmDevice (
    IN UINT8 SetupTpmDevice
)
{
    EFI_STATUS                        Status;
    EFI_BOOT_MODE                     BootMode;
    TREE_DEVICE_DETECTION             TrEEDeviceDetection;
    EFI_PEI_READ_ONLY_VARIABLE2_PPI   *VariablePpi;
    UINTN                             Size;

    Status = PeiServicesGetBootMode (&BootMode);
    ASSERT_EFI_ERROR (Status);

    //
    // In S3, we rely on normal boot Detection, because we save to ReadOnly Variable in normal boot.
    //
    if (BootMode == BOOT_ON_S3_RESUME) {
        DEBUG ((EFI_D_ERROR, "DetectTpmDevice: S3 mode\n"));

        Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);
        ASSERT_EFI_ERROR (Status);

        Size = sizeof(TREE_DEVICE_DETECTION);
        ZeroMem (&TrEEDeviceDetection, sizeof(TrEEDeviceDetection));
        Status = VariablePpi->GetVariable (
                     VariablePpi,
                     TREE_DEVICE_DETECTION_NAME,
                     &gTrEEConfigFormSetGuid,
                     NULL,
                     &Size,
                     &TrEEDeviceDetection
                 );
        if (!EFI_ERROR (Status) &&
                (TrEEDeviceDetection.TpmDeviceDetected >= TPM_DEVICE_MIN) &&
                (TrEEDeviceDetection.TpmDeviceDetected <= TPM_DEVICE_MAX)) {
            DEBUG ((EFI_D_ERROR, "TpmDevice from DeviceDetection: %x\n", TrEEDeviceDetection.TpmDeviceDetected));
            return TrEEDeviceDetection.TpmDeviceDetected;
        }
    }

    DEBUG ((EFI_D_ERROR, "DetectTpmDevice:\n"));
    if (!IsDtpmPresent ()) {
        // dTPM not available
        return TPM_DEVICE_NULL;
    }

    // dTPM available and not disabled by setup
    // We need check if it is TPM1.2 or TPM2.0
    // So try TPM1.2 command at first

    Status = Tpm12RequestUseTpm ();
    if (EFI_ERROR (Status)) {
        return TPM_DEVICE_2_0_DTPM;
    }

    if (BootMode == BOOT_ON_S3_RESUME) {
        Status = Tpm12Startup (TPM_ST_STATE);
    } else {
        Status = Tpm12Startup (TPM_ST_CLEAR);
    }
    if (EFI_ERROR (Status)) {
        return TPM_DEVICE_2_0_DTPM;
    }

    // NO initialization needed again.
    PcdSet8 (PcdTpmInitializationPolicy, 0);
    return TPM_DEVICE_1_2;
}