Exemple #1
0
/**
 *
 *
 *
 *
 *     @param[in,out]   *mmPtr   - Pointer to the MEM_MAIN_DATA_BLOCK
 *
 *     @return          TRUE -  No fatal error occurs.
 *     @return          FALSE - Fatal error occurs.
 */
BOOLEAN
MemMParallelTraining (
  IN OUT   MEM_MAIN_DATA_BLOCK *mmPtr
  )
{
  AMD_CONFIG_PARAMS *StdHeader;
  MEM_DATA_STRUCT *MemPtr;
  MEM_NB_BLOCK *NBPtr;
  DIE_INFO TrainInfo[MAX_NODES_SUPPORTED];
  AP_DATA_TRANSFER ReturnData;
  AGESA_STATUS Status;
  UINT8 ApSts;
  UINT8 Die;
  UINT8 Socket;
  UINT32 Module;
  UINT32 LowCore;
  UINT32 HighCore;
  UINT32 Time;
  UINT32 TimeOut;
  UINT32 TargetApicId;
  BOOLEAN StillTraining;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  UINT8 *BufferPtr;
  BOOLEAN TimeoutEn;

  NBPtr = mmPtr->NBPtr;
  MemPtr = mmPtr->MemPtr;
  StdHeader = &(mmPtr->MemPtr->StdHeader);
  Time = 0;
  TimeOut = PARALLEL_TRAINING_TIMEOUT;
  TimeoutEn = TRUE;
  IDS_TIMEOUT_CTL (&TimeoutEn);

  IDS_HDT_CONSOLE (MEM_STATUS, "\nStart parallel training\n");
  AGESA_TESTPOINT (TpProcMemBeforeAnyTraining, StdHeader);
  //
  // Initialize Training Info Array
  //
  for (Die = 0; Die < mmPtr->DieCount; Die ++) {
    Socket = TrainInfo[Die].Socket = NBPtr[Die].MCTPtr->SocketId;
    Module = NBPtr[Die].MCTPtr->DieId;
    GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader);
    TrainInfo[Die].Core = (UINT8) (LowCore & 0x000000FF);
    IDS_HDT_CONSOLE (MEM_FLOW, "\tLaunch core %d of socket %d\n", LowCore, Socket);
    TrainInfo[Die].Training = FALSE;
  }
  //
  // Start Training on Each remote die.
  //
  for (Die = 0; Die < mmPtr->DieCount; Die ++ ) {
    if (Die != BSP_DIE) {
      NBPtr[Die].BeforeDqsTraining (&(mmPtr->NBPtr[Die]));
      if (NBPtr[Die].MCTPtr->NodeMemSize != 0) {
        if (!NBPtr[Die].FeatPtr->Training (&(mmPtr->NBPtr[Die]))) {
          // Fail to launch code on AP
          PutEventLog (AGESA_ERROR, MEM_ERROR_PARALLEL_TRAINING_LAUNCH_FAIL, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &NBPtr->MemPtr->StdHeader);
          SetMemError (AGESA_ERROR, NBPtr[Die].MCTPtr);
          MemPtr->ErrorHandling (NBPtr[Die].MCTPtr, EXCLUDE_ALL_DCT, EXCLUDE_ALL_CHIPSEL, &MemPtr->StdHeader);
        } else {
          TrainInfo[Die].Training = TRUE;
        }
      }
    }
  }
  //
  // Call training on BSP
  //
  IDS_HDT_CONSOLE (MEM_STATUS, "Node %d\n", NBPtr[BSP_DIE].Node);
  NBPtr[BSP_DIE].BeforeDqsTraining (&(mmPtr->NBPtr[BSP_DIE]));
  NBPtr[BSP_DIE].TrainingFlow (&(mmPtr->NBPtr[BSP_DIE]));
  NBPtr[BSP_DIE].AfterDqsTraining (&(mmPtr->NBPtr[BSP_DIE]));

  //
  // Get Results from remote processors training
  //
  do {
    StillTraining = FALSE;
    for (Die = 0; Die < mmPtr->DieCount; Die ++ ) {
      //
      // For each Die that is training, read the status
      //
      if (TrainInfo[Die].Training == TRUE) {
        GetLocalApicIdForCore (TrainInfo[Die].Socket, TrainInfo[Die].Core, &TargetApicId, StdHeader);
        ApSts = ApUtilReadRemoteControlByte (TargetApicId, StdHeader);
        if ((ApSts & 0x80) == 0) {
          //
          // Allocate buffer for received data
          //
          AllocHeapParams.RequestedBufferSize = (
            sizeof (DIE_STRUCT) +
            NBPtr[Die].DctCount * (
              sizeof (DCT_STRUCT) + (
                NBPtr[Die].ChannelCount * (
                  sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK) + (
                   (NBPtr[Die].MCTPtr->DctData[0].ChData[0].RowCount *
                    NBPtr[Die].MCTPtr->DctData[0].ChData[0].ColumnCount *
                    NUMBER_OF_DELAY_TABLES) +
                    (MAX_BYTELANES_PER_CHANNEL * MAX_CS_PER_CHANNEL * NUMBER_OF_FAILURE_MASK_TABLES)
                  )
                )
              )
            )
          ) + 3;
          AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_PAR_TRN_HANDLE, Die, 0, 0);
          AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
          if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) {
            //
            // Receive Training Results
            //

            ReturnData.DataPtr = AllocHeapParams.BufferPtr;
            ReturnData.DataSizeInDwords = (UINT16) AllocHeapParams.RequestedBufferSize / 4;
            ReturnData.DataTransferFlags = 0;
            Status = ApUtilReceiveBuffer (TrainInfo[Die].Socket, TrainInfo[Die].Core, &ReturnData, StdHeader);
            if (Status != AGESA_SUCCESS) {
              SetMemError (Status, NBPtr[Die].MCTPtr);
            }

            BufferPtr = AllocHeapParams.BufferPtr;
            LibAmdMemCopy (NBPtr[Die].MCTPtr, BufferPtr, sizeof (DIE_STRUCT), StdHeader);
            BufferPtr += sizeof (DIE_STRUCT);
            LibAmdMemCopy ( NBPtr[Die].MCTPtr->DctData,
                            BufferPtr,
                            NBPtr[Die].DctCount * (sizeof (DCT_STRUCT) + NBPtr[Die].ChannelCount * sizeof (CH_DEF_STRUCT)),
                            StdHeader);
            BufferPtr += NBPtr[Die].DctCount * (sizeof (DCT_STRUCT) + NBPtr[Die].ChannelCount * sizeof (CH_DEF_STRUCT));
            LibAmdMemCopy ( NBPtr[Die].PSBlock,
                            BufferPtr,
                            NBPtr[Die].DctCount * NBPtr[Die].ChannelCount * sizeof (MEM_PS_BLOCK),
                            StdHeader);
            BufferPtr += NBPtr[Die].DctCount * NBPtr[Die].ChannelCount * sizeof (MEM_PS_BLOCK);
            LibAmdMemCopy ( NBPtr[Die].MCTPtr->DctData[0].ChData[0].RcvEnDlys,
                            BufferPtr,
                            (NBPtr[Die].DctCount * NBPtr[Die].ChannelCount) *
                            ((NBPtr[Die].MCTPtr->DctData[0].ChData[0].RowCount *
                              NBPtr[Die].MCTPtr->DctData[0].ChData[0].ColumnCount *
                              NUMBER_OF_DELAY_TABLES) +
                              (MAX_BYTELANES_PER_CHANNEL * MAX_CS_PER_CHANNEL * NUMBER_OF_FAILURE_MASK_TABLES)
                            ),
                            StdHeader);

            HeapDeallocateBuffer (AllocHeapParams.BufferHandle, StdHeader);

            NBPtr[Die].AfterDqsTraining (&(mmPtr->NBPtr[Die]));
            TrainInfo[Die].Training = FALSE;
          } else {
            PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_RECEIVED_DATA, NBPtr[Die].Node, 0, 0, 0, StdHeader);
            SetMemError (AGESA_FATAL, NBPtr[Die].MCTPtr);
            ASSERT(FALSE); // Insufficient Heap Space allocation for parallel training buffer
          }
        } else if (ApSts == CORE_IDLE) {
          // AP does not have buffer to transmit to BSP
          // AP fails to locate a buffer for data transfer
          TrainInfo[Die].Training = FALSE;
        } else {
          // Signal to loop through again
          StillTraining = TRUE;
        }
      }
    }
    // Wait for 1 us
    MemUWait10ns (100, NBPtr->MemPtr);
    Time ++;
  } while ((StillTraining) && ((Time < TimeOut) || !TimeoutEn)); // Continue until all Dies are finished
                                                // if cannot finish in 1 s, do fatal exit

  if (StillTraining && TimeoutEn) {
    // Parallel training time out, do fatal exit, as there is at least one AP hangs.
    PutEventLog (AGESA_FATAL, MEM_ERROR_PARALLEL_TRAINING_TIME_OUT, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader);
    SetMemError (AGESA_FATAL, NBPtr[BSP_DIE].MCTPtr);
    ASSERT(FALSE); // Timeout occurred while still training
  }

  for (Die = 0; Die < mmPtr->DieCount; Die ++ ) {
    if (NBPtr[Die].MCTPtr->ErrCode == AGESA_FATAL) {
      return FALSE;
    }
  }
  return TRUE;
}
Exemple #2
0
/**
 *
 *  Poll a bitfield. If the bitfield does not get set to the target value within
 *  specified microseconds, it times out.
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *     @param[in]   FieldName - Bit Field name
 *     @param[in]   Field - Value to be set
 *     @param[in]   MicroSecond - Number of microsecond to wait
 *     @param[in]   IfBroadCast - Need to broadcast to both DCT or not
 *
 * ----------------------------------------------------------------------------
 */
VOID
MemNPollBitFieldNb (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       BIT_FIELD_NAME FieldName,
  IN       UINT32 Field,
  IN       UINT32 MicroSecond,
  IN       BOOLEAN IfBroadCast
  )
{
  UINT8 ExcludeDCT;
  UINT16 ExcludeChipSelMask;
  UINT32 EventInfo;
  UINT64 InitTSC;
  UINT64 CurrentTSC;
  UINT64 TimeOut;
  AGESA_STATUS EventClass;
  MEM_DATA_STRUCT *MemPtr;
  DIE_STRUCT *MCTPtr;
  BOOLEAN TimeoutEn;

  MemPtr = NBPtr->MemPtr;
  MCTPtr = NBPtr->MCTPtr;
  ExcludeDCT = EXCLUDE_ALL_DCT;
  ExcludeChipSelMask = EXCLUDE_ALL_CHIPSEL;
  TimeoutEn = TRUE;
  IDS_TIMEOUT_CTL (&TimeoutEn);

  CurrentTSC = 0;
  LibAmdMsrRead (TSC, &InitTSC, &MemPtr->StdHeader);
  TimeOut = InitTSC + ((UINT64) MicroSecond * 1600);

  while ((CurrentTSC < TimeOut) || !TimeoutEn) {
    if (IfBroadCast) {
      if (NBPtr->BrdcstCheck (NBPtr, FieldName, Field)) {
        break;
      }
    } else {
      if (MemNGetBitFieldNb (NBPtr, FieldName) == Field) {
        break;
      }
    }
    LibAmdMsrRead (TSC, &CurrentTSC, &MemPtr->StdHeader);
  }

  if ((CurrentTSC >= TimeOut) && TimeoutEn) {
    // Default event class
    // If different event class is needed in one entry, override it.
    EventClass = AGESA_ERROR;
    switch (FieldName) {
    case BFDramEnabled:
      EventInfo = MEM_ERROR_DRAM_ENABLED_TIME_OUT;
      break;
    case BFDctAccessDone:
      EventInfo = MEM_ERROR_DCT_ACCESS_DONE_TIME_OUT;
      ExcludeDCT = NBPtr->Dct;
      break;
    case BFSendCtrlWord:
      EventInfo = MEM_ERROR_SEND_CTRL_WORD_TIME_OUT;
      ExcludeDCT = NBPtr->Dct;
      break;
    case BFPrefDramTrainMode:
      EventInfo = MEM_ERROR_PREF_DRAM_TRAIN_MODE_TIME_OUT;
      ExcludeDCT = NBPtr->Dct;
      break;
    case BFEnterSelfRef:
      EventInfo = MEM_ERROR_ENTER_SELF_REF_TIME_OUT;
      break;
    case BFFreqChgInProg:
      EventInfo = MEM_ERROR_FREQ_CHG_IN_PROG_TIME_OUT;
      ExcludeDCT = NBPtr->Dct;
      break;
    case BFExitSelfRef:
      EventInfo = MEM_ERROR_EXIT_SELF_REF_TIME_OUT;
      break;
    case BFSendMrsCmd:
      EventInfo = MEM_ERROR_SEND_MRS_CMD_TIME_OUT;
      ExcludeDCT = NBPtr->Dct;
      break;
    case BFSendZQCmd:
      EventInfo = MEM_ERROR_SEND_ZQ_CMD_TIME_OUT;
      ExcludeDCT = NBPtr->Dct;
      break;
    case BFDctExtraAccessDone:
      EventInfo = MEM_ERROR_DCT_EXTRA_ACCESS_DONE_TIME_OUT;
      ExcludeDCT = NBPtr->Dct;
      break;
    case BFMemClrBusy:
      EventInfo = MEM_ERROR_MEM_CLR_BUSY_TIME_OUT;
      break;
    case BFMemCleared:
      EventInfo = MEM_ERROR_MEM_CLEARED_TIME_OUT;
      break;
    case BFFlushWr:
      EventInfo = MEM_ERROR_FLUSH_WR_TIME_OUT;
      ExcludeDCT = NBPtr->Dct;
      break;
    default:
      EventClass = 0;
      EventInfo = 0;
      IDS_ERROR_TRAP;
    }

    PutEventLog (EventClass, EventInfo, NBPtr->Node, NBPtr->Dct, NBPtr->Channel, 0, &MemPtr->StdHeader);
    SetMemError (EventClass, MCTPtr);
    MemPtr->ErrorHandling (MCTPtr, ExcludeDCT, ExcludeChipSelMask, &MemPtr->StdHeader);
  }
}