/* $NoKeywords:$ */
/**
 * @file
 *
 * mnParTrainc32.c
 *
 * Feature which performs Memory DQS training on each node with each node training
 * its own memory through code running on a core in the associated processor.
 * This way memory can be trained in parallel by more than one processor.
 *
 * This file contains the C32 specific parallel training function.
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project: AGESA
 * @e sub-project: (Mem/NB/C32)
 * @e \$Revision: 54775 $ @e \$Date: 2011-06-12 21:05:26 -0600 (Sun, 12 Jun 2011) $
 *
 **/
/*****************************************************************************
  *
 * Copyright (C) 2012 Advanced Micro Devices, Inc.
 * All rights reserved.
  *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
 *       its contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * ***************************************************************************
  *
 */




#include "AGESA.h"
#include "AdvancedApi.h"
#include "amdlib.h"
#include "OptionMemory.h"
#include "mm.h"
#include "mn.h"
#include "mnc32.h"
#include "Ids.h"
#include "cpuRegisters.h"
#include "cpuServices.h"
#include "GeneralServices.h"
#include "cpuFamilyTranslation.h"
#include "cpuApicUtilities.h"
#include "mfParallelTraining.h"
#include "heapManager.h"
#include "Filecode.h"
CODE_GROUP (G2_PEI)
RDATA_GROUP (G2_PEI)

#define FILECODE PROC_MEM_NB_C32_MNPARTRAINC32_FILECODE
/*-----------------------------------------------------------------------------
*                                EXPORTED FUNCTIONS
*
*-----------------------------------------------------------------------------
*/
BOOLEAN
MemFParallelTrainingC32 (
  IN OUT   MEM_NB_BLOCK *NBPtr
  );

BOOLEAN
STATIC
MemConstructRemoteNBBlockC32 (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       DIE_STRUCT *MCTPtr,
  IN       MEM_FEAT_BLOCK_NB *FeatPtr
);
/* -----------------------------------------------------------------------------*/
/**
 *
 *
 *       This is the training function which set up the environment for remote
 * training on the ap and launches the remote routine.
 *
 *     @param[in,out]   *NBPtr   - Pointer to the MEM_NB_BLOCK
 *
 *     @return          TRUE -  Launch training on AP successfully.
 *     @return          FALSE - Fail to launch training on AP.
 */
BOOLEAN
MemFParallelTrainingC32 (
  IN OUT   MEM_NB_BLOCK *NBPtr
  )
{
  AMD_CONFIG_PARAMS *StdHeader;
  DIE_STRUCT *MCTPtr;
  REMOTE_TRAINING_ENV *EnvPtr;
  AP_TASK TrainingTask;
  UINT8 Socket;
  UINT8 Module;
  UINT8 APCore;
  UINT8 p;
  UINT32 LowCore;
  UINT32 HighCore;
  UINT32 BspSocket;
  UINT32 BspModule;
  UINT32 BspCore;
  AGESA_STATUS Status;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;
  UINT16 MctDataSize;
  StdHeader = &(NBPtr->MemPtr->StdHeader);
  MCTPtr = NBPtr->MCTPtr;
  Socket = MCTPtr->SocketId;
  Module = MCTPtr->DieId;

  //
  // Allocate buffer for REMOTE_TRAINING_ENV
  //
  MctDataSize = MAX_DCTS_PER_NODE_C32 * (
                  sizeof (DCT_STRUCT) + (
                    MAX_CHANNELS_PER_DCT_C32 * (sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK))
                  )
                );
  AllocHeapParams.RequestedBufferSize = MctDataSize + sizeof (REMOTE_TRAINING_ENV);
  AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_PAR_TRN_HANDLE, Socket, Module, 0);
  AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
  if (HeapAllocateBuffer (&AllocHeapParams, StdHeader) == AGESA_SUCCESS) {
    EnvPtr = (REMOTE_TRAINING_ENV *) AllocHeapParams.BufferPtr;
    AllocHeapParams.BufferPtr += sizeof (REMOTE_TRAINING_ENV);

    //
    // Setup Remote training environment
    //
    LibAmdMemCopy (&(EnvPtr->StdHeader), StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader);
    LibAmdMemCopy (&(EnvPtr->DieStruct), MCTPtr, sizeof (DIE_STRUCT), StdHeader);
    for (p = 0; p < MAX_PLATFORM_TYPES; p++) {
      EnvPtr->GetPlatformCfg[p] = NBPtr->MemPtr->GetPlatformCfg[p];
    }
    EnvPtr->ErrorHandling = NBPtr->MemPtr->ErrorHandling;
    EnvPtr->NBBlockCtor = MemConstructRemoteNBBlockC32;
    EnvPtr->FeatPtr = NBPtr->FeatPtr;
    EnvPtr->HoleBase = NBPtr->RefPtr->HoleBase;
    EnvPtr->BottomIo = NBPtr->RefPtr->BottomIo;
    EnvPtr->UmaSize = NBPtr->RefPtr->UmaSize;
    EnvPtr->SysLimit = NBPtr->RefPtr->SysLimit;
    EnvPtr->TableBasedAlterations = NBPtr->RefPtr->TableBasedAlterations;
    EnvPtr->PlatformMemoryConfiguration = NBPtr->RefPtr->PlatformMemoryConfiguration;

    LibAmdMemCopy (AllocHeapParams.BufferPtr, MCTPtr->DctData, MctDataSize, StdHeader);

    //
    // Get Socket, Core of the BSP
    //
    IdentifyCore (StdHeader, &BspSocket, &BspModule, &BspCore, &Status);
    EnvPtr->BspSocket = ((UINT8)BspSocket & 0x000000FF);
    EnvPtr->BspCore = ((UINT8)BspCore & 0x000000FF);

    //
    // Set up the remote task structure
    //
    TrainingTask.DataTransfer.DataPtr = EnvPtr;
    TrainingTask.DataTransfer.DataSizeInDwords = (UINT16) (AllocHeapParams.RequestedBufferSize + 3) / 4;
    TrainingTask.DataTransfer.DataTransferFlags = 0;
    TrainingTask.ExeFlags = 0;
    TrainingTask.FuncAddress.PfApTaskI = (PF_AP_TASK_I)MemFParallelTraining;

    //
    // Get Target AP Core
    //
    GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader);
    APCore = (UINT8) (LowCore & 0x000000FF);

    //
    // Launch Remote Training
    //
    ApUtilRunCodeOnSocketCore (Socket, APCore, &TrainingTask, StdHeader);

    HeapDeallocateBuffer (AllocHeapParams.BufferHandle, StdHeader);

    return TRUE;
  } else {
    PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_REMOTE_TRAINING_ENV, NBPtr->Node, 0, 0, 0, StdHeader);
    SetMemError (AGESA_FATAL, MCTPtr);
    ASSERT(FALSE); // Could not allocated heap space for "REMOTE_TRAINING_ENV"
    return FALSE;
  }
}

BOOLEAN
STATIC
MemConstructRemoteNBBlockC32 (
  IN OUT   MEM_NB_BLOCK *NBPtr,
  IN       DIE_STRUCT *MCTPtr,
  IN       MEM_FEAT_BLOCK_NB *FeatPtr
  )
{
  CPU_SPECIFIC_SERVICES *FamilySpecificServices;

  NBPtr->MCTPtr = MCTPtr;
  NBPtr->PciAddr.AddressValue = MCTPtr->PciAddr.AddressValue;

  MemNInitNBDataC32 (NBPtr);

  FeatPtr->InitCPG (NBPtr);
  NBPtr->FeatPtr = FeatPtr;
  FeatPtr->InitHwRxEn (NBPtr);
  MemNSwitchDCTNb (NBPtr, 0);

  //----------------------------------------------------------------------------
  // Get TSC rate of the this AP
  //----------------------------------------------------------------------------
  GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &NBPtr->MemPtr->StdHeader);
  FamilySpecificServices->GetTscRate (FamilySpecificServices, &NBPtr->MemPtr->TscRate, &NBPtr->MemPtr->StdHeader);

  return TRUE;
}
