コード例 #1
0
ファイル: cpuF10PowerCheck.c プロジェクト: Godkey/coreboot
/**
 * Core-level error handler called if any p-states were determined to be out
 * of range for the mother board.
 *
 * This function implements steps 2a-c and 3a-c on each core.
 *
 * @param[in]  ErrorData            Details about the error condition.
 * @param[in]  StdHeader            Config handle for library and services.
 *
 */
VOID
STATIC
F10PmPwrCheckCore (
  IN       VOID *ErrorData,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT8  i;
  UINT8  PsMaxVal;
  UINT8  DisPsNum;
  UINT8  CurrentPs;
  UINT8  EnBsNum;
  UINT64 LocalMsrRegister;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
  PsMaxVal = (((PWRCHK_ERROR_DATA *) ErrorData)->HwPstateNumber - 1);
  DisPsNum = (((PWRCHK_ERROR_DATA *) ErrorData)->HwPstateNumber -
             ((PWRCHK_ERROR_DATA *) ErrorData)->AllowablePstateNumber);
  EnBsNum = ((PWRCHK_ERROR_DATA *) ErrorData)->NumberofBoostStates;

  LibAmdMsrRead (MSR_PSTATE_STS, &LocalMsrRegister, StdHeader);
  CurrentPs = (UINT8) (((PSTATE_STS_MSR *) &LocalMsrRegister)->CurPstate);

  if (((PWRCHK_ERROR_DATA *) ErrorData)->AllowablePstateNumber == 0) {

    // Step 1
    // Transition to Pstate Max if not there already

    if ((CurrentPs + EnBsNum) != PsMaxVal) {
      FamilySpecificServices->TransitionPstate (FamilySpecificServices, (PsMaxVal - EnBsNum), (BOOLEAN) TRUE, StdHeader);
    }


    // Step 2
    // If Pstate Max is not 000b, copy Pstate max contents to P0 and switch
    // to P0. This step uses software P-state numbering

    if (PsMaxVal != 0) {
      F10PmPwrChkCopyPstate (EnBsNum, PsMaxVal, StdHeader);
      FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) TRUE, StdHeader);
    }
  } else {

    // move remaining P-state register(s) up
    // Step 1
    // Transition to a valid Pstate if current Pstate has been disabled

    if ((CurrentPs + EnBsNum) < DisPsNum) {
      FamilySpecificServices->TransitionPstate (FamilySpecificServices, (DisPsNum - EnBsNum), (BOOLEAN) TRUE, StdHeader);
      CurrentPs = DisPsNum - EnBsNum;
    }

    // Step 2
    // Move enabled Pstates up and disable the remainder. This step uses software P-state numbering.
    if (DisPsNum > EnBsNum) {
      for (i = 0; (i + DisPsNum) <= PsMaxVal; ++i) {
        F10PmPwrChkCopyPstate ((i + EnBsNum), (i + DisPsNum), StdHeader);
      }
    }
    // Step 3
    // Transition to current COF/VID at shifted location

    CurrentPs = ((CurrentPs + EnBsNum) - DisPsNum);
    FamilySpecificServices->TransitionPstate (FamilySpecificServices, CurrentPs, (BOOLEAN) TRUE, StdHeader);
  }
  i = ((PWRCHK_ERROR_DATA *) ErrorData)->AllowablePstateNumber;
  if (i == 0) {
    ++i;
  }
  while (i <= PsMaxVal) {
    FamilySpecificServices->DisablePstate (FamilySpecificServices, i, StdHeader);
    ++i;
  }
}
コード例 #2
0
ファイル: cpuF15PowerCheck.c プロジェクト: fishbaoz/KaveriPI
/**
 * Core-level error handler called if any p-states were determined to be out
 * of range for the mother board.
 *
 * This function implements steps 2a-c and 3a-c on each core.
 *
 * @param[in]  ErrorData            Details about the error condition.
 * @param[in]  StdHeader            Config handle for library and services.
 *
 */
VOID
STATIC
F15PmPwrCheckCore (
  IN       VOID *ErrorData,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT8  i;
  UINT8  HwPsMaxVal;
  UINT8  SwPsMaxVal;
  UINT8  HwDisPsNum;
  UINT8  CurrentSwPs;
  UINT8  PsDisableCount;
  UINT64 LocalMsrRegister;
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  if (IsCoreComputeUnitPrimary (FirstCoreIsComputeUnitPrimary, StdHeader)) {
    // P-state MSRs are shared, so only 1 core per compute unit needs to perform this
    GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader);
    HwPsMaxVal = (((PWRCHK_ERROR_DATA *) ErrorData)->HwPstateNumber - 1);
    HwDisPsNum = (((PWRCHK_ERROR_DATA *) ErrorData)->HwPstateNumber -
                  ((PWRCHK_ERROR_DATA *) ErrorData)->AllowablePstateNumber);

    LibAmdMsrRead (MSR_PSTATE_STS, &LocalMsrRegister, StdHeader);
    CurrentSwPs = (UINT8) (((PSTATE_STS_MSR *) &LocalMsrRegister)->CurPstate);
    LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &LocalMsrRegister, StdHeader);
    SwPsMaxVal = (UINT8) (((PSTATE_CURLIM_MSR *) &LocalMsrRegister)->PstateMaxVal);
    PsDisableCount = 0;

    if (((PWRCHK_ERROR_DATA *) ErrorData)->AllowablePstateNumber == 0) {
      // All P-States are over the limit.

      // Step 1
      // Transition to Pstate Max if not there already
      if (CurrentSwPs != SwPsMaxVal) {
        FamilySpecificServices->TransitionPstate (FamilySpecificServices, SwPsMaxVal, (BOOLEAN) TRUE, StdHeader);
      }

      // Step 2
      // If Pstate Max is not P0, copy Pstate max contents to P0 and switch
      // to P0.
      if (SwPsMaxVal != 0) {
        F15PmPwrChkCopyPstate (((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfBoostStates, HwPsMaxVal, StdHeader);
        FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) TRUE, StdHeader);
      }

      // Disable all SW P-states except P0
      PsDisableCount = ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled - 1;
    } else {
      // At least one P-State is under the limit & at least one P-State is
      // over the limit.
      if (((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfBoostStates > HwDisPsNum) {
        // A subset of boosted P-states are disabled.  Copy the contents of the
        // highest performance boosted P-state still enabled to the boosted
        // P-states that have been disabled.
        for (i = 0; i < HwDisPsNum; i++) {
          F15PmPwrChkCopyPstate (i, HwDisPsNum, StdHeader);
        }
      } else if (((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled != 0) {
        // Move remaining P-state register(s) up
        // Step 1
        // Transition to a valid Pstate if current Pstate has been disabled
        if (CurrentSwPs < ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled) {
          FamilySpecificServices->TransitionPstate (FamilySpecificServices, ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled, (BOOLEAN) TRUE, StdHeader);
          CurrentSwPs = ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled;
        }

        // Step 2
        // Move enabled Pstates up and disable the remainder
        for (i = ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfBoostStates; (i + ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled) <= HwPsMaxVal; i++) {
          F15PmPwrChkCopyPstate (i, (i + ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled), StdHeader);
        }

        // Step 3
        // Transition to current COF/VID at shifted location
        CurrentSwPs = (CurrentSwPs - ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled);
        FamilySpecificServices->TransitionPstate (FamilySpecificServices, CurrentSwPs, (BOOLEAN) TRUE, StdHeader);

        // Disable the appropriate number of P-states
        PsDisableCount = ((PWRCHK_ERROR_DATA *) ErrorData)->NumberOfSwPstatesDisabled;
      }
    }
    // Disable the appropriate P-states if any, starting from HW Pmin
    for (i = 0; i < PsDisableCount; i++) {
      FamilySpecificServices->DisablePstate (FamilySpecificServices, (HwPsMaxVal - i), StdHeader);
    }
  }
}