Пример #1
0
/**
  The function is invoked after SMBASE relocation in S3 path to restors CPU status.

  The function is invoked after SMBASE relocation in S3 path. It restores configuration according to 
  data saved by normal boot path for both BSP and APs.

**/
VOID
InitializeCpu (
  VOID
  )
{
  CPU_REGISTER_TABLE         *RegisterTableList;
  UINT32                     InitApicId;
  UINTN                      Index;

  RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable;
  InitApicId = GetInitialApicId ();
  for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
    if (RegisterTableList[Index].InitialApicId == InitApicId) {
      SetProcessorRegister (&RegisterTableList[Index]);
      break;
    }
  } 

  mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;
  mExchangeInfo->ApFunction  = (VOID *) (UINTN) MPRendezvousProcedure;

  //
  // Send INIT IPI - SIPI to all APs
  //
  SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);

  while (mNumberToFinish > 0) {
    CpuPause ();
  }
}
Пример #2
0
/**
  AP initialization after SMBASE relocation in the S3 boot path.
**/
VOID
MPRendezvousProcedure (
  VOID
  )
{
  CPU_REGISTER_TABLE         *RegisterTableList;
  UINT32                     InitApicId;
  UINTN                      Index;

  ProgramVirtualWireMode ();
  DisableLvtInterrupts ();

  RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable;
  InitApicId = GetInitialApicId ();
  for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
    if (RegisterTableList[Index].InitialApicId == InitApicId) {
      SetProcessorRegister (&RegisterTableList[Index]);
      break;
    }
  }

  //
  // Count down the number with lock mechanism.
  //
  InterlockedDecrement (&mNumberToFinish);
} 
Пример #3
0
Файл: CpuS3.c Проект: lgao4/edk2
/**
  The function is invoked after SMBASE relocation in S3 path to restores CPU status.

  The function is invoked after SMBASE relocation in S3 path. It restores configuration according to
  data saved by normal boot path for both BSP and APs.

**/
VOID
InitializeCpu (
  VOID
  )
{
  CPU_REGISTER_TABLE         *RegisterTableList;
  UINT32                     InitApicId;
  UINTN                      Index;

  RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable;
  InitApicId = GetInitialApicId ();
  for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
    if (RegisterTableList[Index].InitialApicId == InitApicId) {
      SetProcessorRegister (&RegisterTableList[Index]);
      break;
    }
  }

  mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;
  //
  // StackStart was updated when APs were waken up in EarlyInitializeCpu.
  // Re-initialize StackAddress to original beginning address.
  //
  mExchangeInfo->StackStart  = (VOID *) (UINTN) mAcpiCpuData.StackAddress;
  mExchangeInfo->ApFunction  = (VOID *) (UINTN) MPRendezvousProcedure;

  //
  // Send INIT IPI - SIPI to all APs
  //
  SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);

  while (mNumberToFinish > 0) {
    CpuPause ();
  }
}
Пример #4
0
/**
  AP initialization before SMBASE relocation in the S3 boot path.
**/
VOID
EarlyMPRendezvousProcedure (
  VOID
  )
{
  CPU_REGISTER_TABLE         *RegisterTableList;
  UINT32                     InitApicId;
  UINTN                      Index;

  LoadMtrrData (mAcpiCpuData.MtrrTable);

  //
  // Find processor number for this CPU.
  //
  RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable;
  InitApicId = GetInitialApicId ();
  for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
    if (RegisterTableList[Index].InitialApicId == InitApicId) {
      SetProcessorRegister (&RegisterTableList[Index]);
      break;
    }
  } 

  //
  // Count down the number with lock mechanism.
  //
  InterlockedDecrement (&mNumberToFinish);
}
Пример #5
0
/**
  The function is invoked before SMBASE relocation in S3 path to restores CPU status.

  The function is invoked before SMBASE relocation in S3 path. It does first time microcode load
  and restores MTRRs for both BSP and APs.

**/
VOID
InitializeCpuBeforeRebase (
  VOID
  )
{
  LoadMtrrData (mAcpiCpuData.MtrrTable);

  SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable, mAcpiCpuData.NumberOfCpus);

  ProgramVirtualWireMode ();

  PrepareApStartupVector (mAcpiCpuData.StartupVector);

  mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;
  mExchangeInfo->ApFunction  = (VOID *) (UINTN) InitializeAp;

  //
  // Execute code for before SmmBaseReloc. Note: This flag is maintained across S3 boots.
  //
  mInitApsAfterSmmBaseReloc = FALSE;

  //
  // Send INIT IPI - SIPI to all APs
  //
  SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);

  while (mNumberToFinish > 0) {
    CpuPause ();
  }
}
Пример #6
0
/**
  AP initialization before then after SMBASE relocation in the S3 boot path.
**/
VOID
InitializeAp (
  VOID
  )
{
  UINTN                      TopOfStack;
  UINT8                      Stack[128];

  LoadMtrrData (mAcpiCpuData.MtrrTable);

  SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable, mAcpiCpuData.NumberOfCpus);

  //
  // Count down the number with lock mechanism.
  //
  InterlockedDecrement (&mNumberToFinish);

  //
  // Wait for BSP to signal SMM Base relocation done.
  //
  while (!mInitApsAfterSmmBaseReloc) {
    CpuPause ();
  }

  ProgramVirtualWireMode ();
  DisableLvtInterrupts ();

  SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable, mAcpiCpuData.NumberOfCpus);

  //
  // Place AP into the safe code, count down the number with lock mechanism in the safe code.
  //
  TopOfStack  = (UINTN) Stack + sizeof (Stack);
  TopOfStack &= ~(UINTN) (CPU_STACK_ALIGNMENT - 1);
  CopyMem ((VOID *) (UINTN) mApHltLoopCode, mApHltLoopCodeTemplate, sizeof (mApHltLoopCodeTemplate));
  TransferApToSafeState ((UINTN)mApHltLoopCode, TopOfStack, (UINTN)&mNumberToFinish);
}
Пример #7
0
/**
  The function is invoked after SMBASE relocation in S3 path to restores CPU status.

  The function is invoked after SMBASE relocation in S3 path. It restores configuration according to
  data saved by normal boot path for both BSP and APs.

**/
VOID
InitializeCpuAfterRebase (
  VOID
  )
{
  SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable, mAcpiCpuData.NumberOfCpus);

  mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;

  //
  // Signal that SMM base relocation is complete and to continue initialization.
  //
  mInitApsAfterSmmBaseReloc = TRUE;

  while (mNumberToFinish > 0) {
    CpuPause ();
  }
}
Пример #8
0
/**
  The function is invoked before SMBASE relocation in S3 path to restors CPU status.

  The function is invoked before SMBASE relocation in S3 path. It does first time microcode load 
  and restores MTRRs for both BSP and APs.

**/
VOID
EarlyInitializeCpu (
  VOID
  )
{
  CPU_REGISTER_TABLE         *RegisterTableList;
  UINT32                     InitApicId;
  UINTN                      Index;

  LoadMtrrData (mAcpiCpuData.MtrrTable);

  //
  // Find processor number for this CPU.
  //
  RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable;
  InitApicId = GetInitialApicId ();
  for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
    if (RegisterTableList[Index].InitialApicId == InitApicId) {
      SetProcessorRegister (&RegisterTableList[Index]);
      break;
    }
  } 

  ProgramVirtualWireMode ();

  PrepareAPStartupVector (mAcpiCpuData.StartupVector);

  mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;
  mExchangeInfo->ApFunction  = (VOID *) (UINTN) EarlyMPRendezvousProcedure;

  //
  // Send INIT IPI - SIPI to all APs
  //
  SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);

  while (mNumberToFinish > 0) {
    CpuPause ();
  }
}
Пример #9
0
/**
  Performs CPU features Initialization.

  This service will invoke MP service to perform CPU features
  initialization on BSP/APs per user configuration.

  @note This service could be called by BSP only.
**/
VOID
EFIAPI
CpuFeaturesInitialize (
  VOID
  )
{
  CPU_FEATURES_DATA          *CpuFeaturesData;
  UINTN                      OldBspNumber;

  CpuFeaturesData = GetCpuFeaturesData ();

  OldBspNumber = GetProcessorIndex (CpuFeaturesData);
  CpuFeaturesData->BspNumber = OldBspNumber;

  //
  // Known limitation: In PEI phase, CpuFeatures driver not
  // support async mode execute tasks. So semaphore type
  // register can't been used for this instance, must use
  // DXE type instance.
  //

  //
  // Wakeup all APs for programming.
  //
  StartupAPsWorker (SetProcessorRegister, NULL);
  //
  // Programming BSP
  //
  SetProcessorRegister (CpuFeaturesData);

  //
  // Switch to new BSP if required
  //
  if (CpuFeaturesData->BspNumber != OldBspNumber) {
    SwitchNewBsp (CpuFeaturesData->BspNumber);
  }
}
Пример #10
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;
}