BOOLEAN MemS3ResumeConstructNBBlockC32 ( IN OUT VOID *S3NBPtr, IN OUT MEM_DATA_STRUCT *MemPtr, IN UINT8 NodeID ) { INT32 i; MEM_NB_BLOCK *NBPtr; NBPtr = ((S3_MEM_NB_BLOCK *)S3NBPtr)->NBPtr; // // Determine if this is the expected NB Type // GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); if (!MemNIsIdSupportedC32 (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { return FALSE; } NBPtr->MemPtr = MemPtr; NBPtr->MCTPtr = &(MemPtr->DiesPerSystem[NodeID]); NBPtr->PciAddr.AddressValue = MemPtr->DiesPerSystem[NodeID].PciAddr.AddressValue; InitNBRegTableC32 (NBPtr, NBPtr->NBRegTable); NBPtr->Node = ((UINT8) NBPtr->PciAddr.Address.Device) - 24; NBPtr->Dct = 0; NBPtr->Channel = 0; NBPtr->Ganged = FALSE; NBPtr->NodeCount = MAX_NODES_SUPPORTED_C32; NBPtr->DctCount = MAX_DCTS_PER_NODE_C32; for (i = 0; i < EnumSize; i++) { NBPtr->IsSupported[i] = FALSE; } for (i = 0; i < NumberOfHooks; i++) { NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) memDefTrue; } LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &MemPtr->StdHeader); NBPtr->IsSupported[CheckDllSpeedUp] = TRUE; NBPtr->SwitchDCT = MemNSwitchDCTNb; NBPtr->SwitchChannel = MemNSwitchChannelNb; NBPtr->GetBitField = MemNGetBitFieldNb; NBPtr->SetBitField = MemNSetBitFieldNb; NBPtr->MemNCmnGetSetFieldNb = MemNCmnGetSetFieldC32; NBPtr->MemNIsIdSupportedNb = MemNIsIdSupportedC32; ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3ExitSelfRefReg = MemNS3ExitSelfRefRegC32; ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetConPCIMask = MemNS3GetConPCIMaskNb; ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetConMSRMask = (VOID (*) (MEM_NB_BLOCK *, DESCRIPTOR_GROUP *)) memDefRet; ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3Resume = MemNS3ResumeNb; ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3RestoreScrub = MemNS3RestoreScrubNb; ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetRegLstPtr = MemNS3GetRegLstPtrC32; ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3GetDeviceRegLst = MemNS3GetDeviceRegLstC32; ((S3_MEM_NB_BLOCK *)S3NBPtr)->MemS3SpecialCaseHeapSize = (sizeof (SpecialCasePCIRegC32) / sizeof (UINT16)) * sizeof (UINT32); MemNSwitchDCTNb (NBPtr, 0); return TRUE; }
BOOLEAN MemNIdentifyDimmConstructorLN ( IN OUT MEM_NB_BLOCK *NBPtr, IN OUT MEM_DATA_STRUCT *MemPtr, IN UINT8 NodeID ) { // // Determine if this is the expected NB Type // GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); if (!MemNIsIdSupportedLN (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { return FALSE; } NBPtr->NodeCount = MAX_NODES_SUPPORTED_LN; NBPtr->DctCount = MAX_DCTS_PER_NODE_LN; NBPtr->CsRegMsk = 0x1FF83FE0; NBPtr->MemPtr = MemPtr; NBPtr->MCTPtr = &(MemPtr->DiesPerSystem[NodeID]); NBPtr->PciAddr.AddressValue = MemPtr->DiesPerSystem[NodeID].PciAddr.AddressValue; NBPtr->Node = ((UINT8) NBPtr->PciAddr.Address.Device) - 24; NBPtr->Ganged = FALSE; MemNInitNBRegTableLN (NBPtr, NBPtr->NBRegTable); NBPtr->MemNCmnGetSetFieldNb = MemNCmnGetSetFieldLN; NBPtr->SetBitField = MemNSetBitFieldNb; NBPtr->GetBitField = MemNGetBitFieldNb; NBPtr->GetSocketRelativeChannel = MemNGetSocketRelativeChannelNb; return TRUE; }
/** * Should message-based C1e be enabled * * @param[in] MsgBasedC1eServices Pointer to this CPU's HW C1e family services. * @param[in] Socket Processor socket to check. * @param[in] StdHeader Config Handle for library, services. * * @retval TRUE HW C1e is supported. * */ BOOLEAN STATIC F10IsMsgBasedC1eSupported ( IN MSG_BASED_C1E_FAMILY_SERVICES *MsgBasedC1eServices, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader ) { CPU_LOGICAL_ID LogicalId; GetLogicalIdOfSocket (Socket, &LogicalId, StdHeader); return ((BOOLEAN) ((LogicalId.Revision & AMD_F10_GT_D0) != 0)); }
/** * Hook before the probe filter initialization sequence. * * @param[in] HtAssistServices HT Assist family services. * @param[in] Socket Processor socket to check. * @param[in] StdHeader Config Handle for library, services. * */ VOID STATIC F10HookBeforeInit ( IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Module; UINT32 PciRegister; UINT32 PfCtrlRegister; PCI_ADDR PciAddress; CPU_LOGICAL_ID LogicalId; AGESA_STATUS IgnoredStatus; UINT32 PackageType; GetLogicalIdOfSocket (Socket, &LogicalId, StdHeader); PackageType = LibAmdGetPackageType (StdHeader); PciRegister = 0; ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFWayNum = 2; ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFSubCacheEn = 15; ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFLoIndexHashEn = 1; for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) { PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = PROBE_FILTER_CTRL_REG; LibAmdPciRead (AccessWidth32, PciAddress, &PfCtrlRegister, StdHeader); ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFPreferredSORepl = ((PROBE_FILTER_CTRL_REGISTER *) &PfCtrlRegister)->PFPreferredSORepl; LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); // Assumption: all socket use the same CPU package. if (((LogicalId.Revision & AMD_F10_D0) != 0) && (PackageType == PACKAGE_TYPE_C32)) { // Apply erratum #384 // Set F2x11C[13:12] = 11b PciAddress.Address.Function = FUNC_2; PciAddress.Address.Register = 0x11C; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); PciRegister |= 0x3000; LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); } } } }
/** * * * This function defines the memory initialization flow for * systems that only support DDR3 and KV processor. * * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK * * @return AGESA_STATUS * - AGESA_FATAL * - AGESA_CRITICAL * - AGESA_SUCCESS */ AGESA_STATUS MemMFlowD3KV ( IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr ) { MEM_NB_BLOCK *NBPtr; MEM_TECH_BLOCK *TechPtr; MEM_DATA_STRUCT *MemPtr; NBPtr = MemMainPtr->NBPtr; TechPtr = MemMainPtr->TechPtr; MemPtr = MemMainPtr->MemPtr; GetLogicalIdOfSocket (MemPtr->DiesPerSystem[BSP_DIE].SocketId, &(MemPtr->DiesPerSystem[BSP_DIE].LogicalCpuid), &(MemPtr->StdHeader)); if (!MemNIsIdSupportedKV (&(MemPtr->DiesPerSystem[BSP_DIE].LogicalCpuid))) { MemPtr->IsFlowControlSupported = FALSE; return AGESA_FATAL; } else { MemPtr->IsFlowControlSupported = TRUE; } MemFInitTableDrive (&NBPtr[BSP_DIE], MTBeforeInitializeMCT); // Clear DisDllShutdownSR prior any P-State changes. MemNConfigureDisDllShutdownSrKV (NBPtr); //---------------------------------------------------------------- // Force NB-Pstate to NBP0 //---------------------------------------------------------------- MemNChangeNbFrequencyWrapUnb (NBPtr, 0); NBPtr->IsSupported[G5DimmInD3Socket] = FALSE; if (MemTDIMMPresence3 (NBPtr[BSP_DIE].TechPtr) && (NBPtr[BSP_DIE].MCTPtr->DimmPresent != 0)) { return MemMD3FlowKV (MemMainPtr); } else { PutEventLog (AGESA_FATAL, MEM_ERROR_NO_DIMM_FOUND_ON_SYSTEM, 0, 0, 0, 0, &(MemMainPtr->MemPtr->StdHeader)); return AGESA_FATAL; // No DIMMs found } }
BOOLEAN MemConstructNBBlockDA ( IN OUT MEM_NB_BLOCK *NBPtr, IN OUT MEM_DATA_STRUCT *MemPtr, IN MEM_FEAT_BLOCK_NB *FeatPtr, IN MEM_SHARED_DATA *SharedPtr, IN UINT8 NodeID ) { UINT8 Dct; UINT8 Channel; UINT8 SpdSocketIndex; UINT8 SpdChannelIndex; DIE_STRUCT *MCTPtr; ALLOCATE_HEAP_PARAMS AllocHeapParams; // // Determine if this is the expected NB Type // GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); if (!MemNIsIdSupportedDA (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { return FALSE; } NBPtr->MemPtr = MemPtr; NBPtr->RefPtr = MemPtr->ParameterListPtr; NBPtr->SharedPtr = SharedPtr; MCTPtr = &(MemPtr->DiesPerSystem[NodeID]); NBPtr->MCTPtr = MCTPtr; NBPtr->MCTPtr->NodeId = NodeID; NBPtr->PciAddr.AddressValue = MCTPtr->PciAddr.AddressValue; NBPtr->VarMtrrHiMsk = GetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); // // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs // AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DA * ( sizeof (DCT_STRUCT) + ( MAX_CHANNELS_PER_DCT_DA * (sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK)) ) ); AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0); AllocHeapParams.Persist = HEAP_LOCAL_CACHE; if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) { PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_DCT_STRUCT_AND_CH_DEF_STRUCTs, NBPtr->Node, 0, 0, 0, &MemPtr->StdHeader); SetMemError (AGESA_FATAL, MCTPtr); return FALSE; } MCTPtr->DctCount = MAX_DCTS_PER_NODE_DA; MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DA * sizeof (DCT_STRUCT); for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) { MCTPtr->DctData[Dct].Dct = Dct; MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DA; MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr; AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DA * sizeof (CH_DEF_STRUCT); } NBPtr->PSBlock = (MEM_PS_BLOCK *) AllocHeapParams.BufferPtr; // // Initialize Socket List // for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) { MemPtr->SocketList[MCTPtr->SocketId].ChannelPtr[Dct] = &(MCTPtr->DctData[Dct].ChData[0]); MemPtr->SocketList[MCTPtr->SocketId].TimingsPtr[Dct] = &(MCTPtr->DctData[Dct].Timings); MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct; } MemNInitNBDataDA (NBPtr); FeatPtr->InitCPG (NBPtr); NBPtr->FeatPtr = FeatPtr; FeatPtr->InitHwRxEn (NBPtr); // // Calculate SPD Offsets per channel and assign pointers to the data. At this point, we calculate the Node-Dct-Channel // centric offsets and store the pointers to the first DIMM of each channel in the Channel Definition struct for that // channel. This pointer is then used later to calculate the offsets to be used for each logical dimm once the // dimm types(QR or not) are known. This is done in the Technology block constructor. // // Calculate the SpdSocketIndex separately from the SpdChannelIndex. // This will facilitate modifications due to some processors that might // map the DCT-CHANNEL differently. // SpdSocketIndex = GetSpdSocketIndex (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, &MemPtr->StdHeader); // // Traverse the Dct/Channel structures // for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) { for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DA; Channel++) { // // Calculate the number of Dimms on this channel using the // die/dct/channel to Socket/channel conversion. // SpdChannelIndex = GetSpdChannelIndex (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, MemNGetSocketRelativeChannelNb (NBPtr, Dct, Channel), &MemPtr->StdHeader); NBPtr->MCTPtr->DctData[Dct].ChData[Channel].SpdPtr = &(MemPtr->SpdDataStructure[SpdSocketIndex + SpdChannelIndex]); } } MemNSwitchDCTNb (NBPtr, 0); return TRUE; }
/** * Set Dll Cap based on fuses * * * * @param[in] Wrapper Pointer to Wrapper configuration data area * @param[in] Pcie Pointer to PCIe configuration data area */ VOID PcieSetDllCapTN ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { D18F3x1FC_STRUCT D18F3x1FC; D0F0xE4_PHY_500F_STRUCT D0F0xE4_PHY_500F; D0F0xE4_PHY_4010_STRUCT D0F0xE4_PHY_4010; D0F0xE4_PHY_4011_STRUCT D0F0xE4_PHY_4011; UINT32 Gen1Index; UINT32 Gen2Index; CPU_LOGICAL_ID LogicalId; GNB_HANDLE *GnbHandle; IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetDllCapTN Enter\n"); D0F0xE4_PHY_500F.Value = 0; GnbHandle = GnbGetHandle (GnbLibGetHeader (Pcie)); ASSERT (GnbHandle != NULL); GetLogicalIdOfSocket (GnbGetSocketId (GnbHandle), &LogicalId, GnbLibGetHeader (Pcie)); //Read SWDllCapTableEn GnbRegisterReadTN (D18F3x1FC_TYPE, D18F3x1FC_ADDRESS, &D18F3x1FC, 0, GnbLibGetHeader (Pcie)); IDS_HDT_CONSOLE (GNB_TRACE, "Read D18F3x1FC value %x\n", D18F3x1FC.Value); if ((D18F3x1FC.Field.SWDllCapTableEn != 0) || ((LogicalId.Revision & AMD_F15_TN_A0) != AMD_F15_TN_A0 )) { IDS_HDT_CONSOLE (GNB_TRACE, "Executing DLL configuration\n"); // Read D0F0xE4_x0[2:1]2[1:0]_[5:4][7:6,3:0][9,1]0 Phy Receiver Functional Fuse Control (FuseFuncDllProcessCompCtl[1:0]) IDS_HDT_CONSOLE (GNB_TRACE, "Reading 0x4010 from PHY_SPACE %x\n", PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_4010_ADDRESS)); D0F0xE4_PHY_4010.Value = PcieRegisterRead (Wrapper, PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_4010_ADDRESS), Pcie); IDS_HDT_CONSOLE (GNB_TRACE, "Read 4010 value = %x\n", D0F0xE4_PHY_4010.Value); // Read D0F0xE4_x0[2:1]2[1:0]_[5:4][7:6,3:0][9,1]1 Phy Receiver Process Fuse Control (FuseProcDllProcessComp[2:0]) IDS_HDT_CONSOLE (GNB_TRACE, "Reading 0x4011 from PHY_SPACE %x\n", PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_4011_ADDRESS)); D0F0xE4_PHY_4011.Value = PcieRegisterRead (Wrapper, PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_4011_ADDRESS), Pcie); IDS_HDT_CONSOLE (GNB_TRACE, "Read 4011 value = %x\n", D0F0xE4_PHY_4011.Value); // If FuseProcDllProcessCompCtl[1:0] == 2'b11 Then Gen1Index[3:0] = FuseProcDllProcessComp[2:0], 0 // Else... // If FuseProcDllProcessComp[2:0] == 3'b000 Then Gen1Index[3:0] =4'b1101 //Typical // If FuseProcDllProcessComp[2:0] == 3'b001 Then Gen1Index[3:0] =4'b1111 //Fast // If FuseProcDllProcessComp[2:0] == 3'b010 Then Gen1Index[3:0] =4'b1010 //Slow IDS_HDT_CONSOLE (GNB_TRACE, "FuseFuncDllProcessCompCtl %x\n", D0F0xE4_PHY_4010.Field.FuseFuncDllProcessCompCtl); if (D0F0xE4_PHY_4010.Field.FuseFuncDllProcessCompCtl == 3) { IDS_HDT_CONSOLE (GNB_TRACE, "Setting Gen1Index from FuseFuncDllProcessComp %x\n", D0F0xE4_PHY_4011.Field.FuseProcDllProcessComp); Gen1Index = D0F0xE4_PHY_4011.Field.FuseProcDllProcessComp << 1; } else { IDS_HDT_CONSOLE (GNB_TRACE, "Setting Gen1Index from switch case..."); switch (D0F0xE4_PHY_4011.Field.FuseProcDllProcessComp) { case 0: IDS_HDT_CONSOLE (GNB_TRACE, "case 0 - using 0xd\n"); Gen1Index = 0xd; break; case 1: IDS_HDT_CONSOLE (GNB_TRACE, "case 1 - using 0xf\n"); Gen1Index = 0xf; break; case 2: IDS_HDT_CONSOLE (GNB_TRACE, "case 2 - using 0xa\n"); Gen1Index = 0xa; break; default: IDS_HDT_CONSOLE (GNB_TRACE, "default - using 0xd\n"); Gen1Index = 0xd; //Use typical for default case break; } } D0F0xE4_PHY_500F.Field.DllProcessFreqCtlIndex1 = Gen1Index; IDS_HDT_CONSOLE (GNB_TRACE, "Set Gen1Index to %x\n", Gen1Index); // Bits 3:0 = Gen1Index[3:0] // Bits 10:7 = DllProcessFreqCtlIndex2Rate50[3:0] if (D18F3x1FC.Field.SWDllCapTableEn != 0) { IDS_HDT_CONSOLE (GNB_TRACE, "Gen2Index - using DllProcFreqCtlIndex2Rate50 = %x\n", D18F3x1FC.Field.DllProcFreqCtlIndex2Rate50); Gen2Index = D18F3x1FC.Field.DllProcFreqCtlIndex2Rate50; } else { Gen2Index = 0x03; // Hard coded default } D0F0xE4_PHY_500F.Field.DllProcessFreqCtlIndex2 = Gen2Index; IDS_HDT_CONSOLE (GNB_TRACE, "Set Gen2Index to %x\n", Gen2Index); PcieRegisterWrite ( Wrapper, PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_500F_ADDRESS), D0F0xE4_PHY_500F.Value, FALSE, Pcie ); // Set DllProcessFreqCtlOverride on second write D0F0xE4_PHY_500F.Field.DllProcessFreqCtlOverride = 1; PcieRegisterWrite ( Wrapper, PHY_SPACE (Wrapper->WrapId, 0, D0F0xE4_PHY_500F_ADDRESS), D0F0xE4_PHY_500F.Value, FALSE, Pcie ); if (Wrapper->WrapId == 1) { // For Wrapper 1, configure PHY0 and PHY1 D0F0xE4_PHY_500F.Field.DllProcessFreqCtlOverride = 0; PcieRegisterWrite ( Wrapper, PHY_SPACE (Wrapper->WrapId, 1, D0F0xE4_PHY_500F_ADDRESS), D0F0xE4_PHY_500F.Value, FALSE, Pcie ); // Set DllProcessFreqCtlOverride on second write D0F0xE4_PHY_500F.Field.DllProcessFreqCtlOverride = 1; PcieRegisterWrite ( Wrapper, PHY_SPACE (Wrapper->WrapId, 1, D0F0xE4_PHY_500F_ADDRESS), D0F0xE4_PHY_500F.Value, FALSE, Pcie ); } } IDS_HDT_CONSOLE (GNB_TRACE, "PcieSetDllCapTN Exit\n"); }
BOOLEAN MemRecConstructNBBlockON ( IN OUT MEM_NB_BLOCK *NBPtr, IN OUT MEM_DATA_STRUCT *MemPtr, IN UINT8 NodeID ) { UINT8 i; DIE_STRUCT *MCTPtr; ALLOCATE_HEAP_PARAMS AllocHeapParams; // // Determine if this is the expected NB Type // GetLogicalIdOfSocket (MemPtr->DiesPerSystem->SocketId, &(MemPtr->DiesPerSystem->LogicalCpuid), &(MemPtr->StdHeader)); if (!MemRecNIsIdSupportedON (NBPtr, &(MemPtr->DiesPerSystem->LogicalCpuid))) { return FALSE; } NBPtr->MemPtr = MemPtr; NBPtr->RefPtr = MemPtr->ParameterListPtr; MCTPtr = MemPtr->DiesPerSystem; NBPtr->MCTPtr = MCTPtr; NBPtr->MCTPtr->NodeId = 0; NBPtr->PciAddr.AddressValue = MCTPtr->PciAddr.AddressValue; // // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs // AllocHeapParams.RequestedBufferSize = (sizeof (DCT_STRUCT) + sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK)) + (MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES); AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0); AllocHeapParams.Persist = HEAP_LOCAL_CACHE; if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) { ASSERT(FALSE); // Could not allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs return FALSE; } NBPtr->SPDPtr = MemPtr->SpdDataStructure; NBPtr->AllNodeSPDPtr = MemPtr->SpdDataStructure; MemPtr->DieCount = 1; MCTPtr->Dct = 0; MCTPtr->DctCount = 1; MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; AllocHeapParams.BufferPtr += sizeof (DCT_STRUCT); MCTPtr->DctData->ChannelCount = 1; MCTPtr->DctData->ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr; AllocHeapParams.BufferPtr += sizeof (CH_DEF_STRUCT); NBPtr->PSBlock = (MEM_PS_BLOCK *) AllocHeapParams.BufferPtr; AllocHeapParams.BufferPtr += sizeof (MEM_PS_BLOCK); MCTPtr->DctData->ChData->RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr; AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2; MCTPtr->DctData->ChData->WrDqsDlys = AllocHeapParams.BufferPtr; // // Initialize NB block's variables // NBPtr->DCTPtr = NBPtr->MCTPtr->DctData; NBPtr->DctCachePtr = NBPtr->DctCache; NBPtr->PsPtr = NBPtr->PSBlock; NBPtr->ChannelPtr = NBPtr->DCTPtr->ChData; NBPtr->DctCachePtr = NBPtr->DctCache; MemRecNInitNBRegTableON (NBPtr->NBRegTable); NBPtr->Dct = 0; NBPtr->Channel = 0; NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); NBPtr->FreqChangeParam = (MEM_FREQ_CHANGE_PARAM *) &RecFreqChangeParamON; LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader); LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader); for (i = 0; i < NumberOfHooks; i++) { NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK *, VOID *)) MemRecDefTrue; } NBPtr->InitRecovery = MemRecNMemInitON; NBPtr->RecModeDefRegArray = RecModeDefRegArrayON; NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet; NBPtr->SwitchDCT = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet; NBPtr->SwitchChannel = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet; NBPtr->SetMaxLatency = MemRecNSetMaxLatencyON; NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb; NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb; NBPtr->sendZQCmd = MemRecNSendZQCmdNb; NBPtr->SetDramOdtRec = MemRecNSetDramOdtON; NBPtr->GetBitField = MemRecNGetBitFieldNb; NBPtr->SetBitField = MemRecNSetBitFieldNb; NBPtr->GetTrainDly = MemRecNGetTrainDlyNb; NBPtr->SetTrainDly = MemRecNSetTrainDlyNb; NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldON; NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyClientNb; NBPtr->MemRecNSwitchDctNb = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet; NBPtr->TrainingFlow = MemNRecTrainingFlowClientNb; NBPtr->ReadPattern = MemRecNContReadPatternClientNb; NBPtr->IsSupported[DramModeAfterDimmPres] = TRUE; NBPtr->FamilySpecificHook[OverrideRcvEnSeed] = MemRecNOverrideRcvEnSeedON; return TRUE; }
BOOLEAN MemConstructNBBlockLN ( IN OUT MEM_NB_BLOCK *NBPtr, IN OUT MEM_DATA_STRUCT *MemPtr, IN MEM_FEAT_BLOCK_NB *FeatPtr, IN MEM_SHARED_DATA *SharedPtr, IN UINT8 NodeID ) { UINT8 Dct; UINT8 Channel; UINT8 SpdSocketIndex; UINT8 SpdChannelIndex; DIE_STRUCT *MCTPtr; ALLOCATE_HEAP_PARAMS AllocHeapParams; // // Determine if this is the expected NB Type // GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); if (!MemNIsIdSupportedLN (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { return FALSE; } NBPtr->MemPtr = MemPtr; NBPtr->RefPtr = MemPtr->ParameterListPtr; NBPtr->SharedPtr = SharedPtr; MCTPtr = &(MemPtr->DiesPerSystem[NodeID]); NBPtr->MCTPtr = MCTPtr; NBPtr->MCTPtr->NodeId = NodeID; NBPtr->PciAddr.AddressValue = MCTPtr->PciAddr.AddressValue; NBPtr->VarMtrrHiMsk = GetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); // // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs // AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_LN * ( sizeof (DCT_STRUCT) + ( MAX_CHANNELS_PER_DCT_LN * (sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK)) ) ); AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0); AllocHeapParams.Persist = HEAP_LOCAL_CACHE; if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) { PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_DCT_STRUCT_AND_CH_DEF_STRUCTs, NBPtr->Node, 0, 0, 0, &MemPtr->StdHeader); SetMemError (AGESA_FATAL, MCTPtr); ASSERT(FALSE); // Could not allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs return FALSE; } MCTPtr->DctCount = MAX_DCTS_PER_NODE_LN; MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_LN * sizeof (DCT_STRUCT); for (Dct = 0; Dct < MAX_DCTS_PER_NODE_LN; Dct++) { MCTPtr->DctData[Dct].Dct = Dct; MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_LN; MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr; MCTPtr->DctData[Dct].ChData[0].Dct = Dct; AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_LN * sizeof (CH_DEF_STRUCT); } NBPtr->PSBlock = (MEM_PS_BLOCK *) AllocHeapParams.BufferPtr; // // Initialize Socket List // for (Dct = 0; Dct < MAX_DCTS_PER_NODE_LN; Dct++) { MemPtr->SocketList[MCTPtr->SocketId].ChannelPtr[Dct] = &(MCTPtr->DctData[Dct].ChData[0]); MemPtr->SocketList[MCTPtr->SocketId].TimingsPtr[Dct] = &(MCTPtr->DctData[Dct].Timings); MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct; } // // Initialize NB block member variables // NBPtr->DctCachePtr = NBPtr->DctCache; NBPtr->PsPtr = NBPtr->PSBlock; MemNInitNBRegTableLN (NBPtr, NBPtr->NBRegTable); NBPtr->Node = 0; NBPtr->Dct = 0; NBPtr->Channel = 0; NBPtr->DctCount = MAX_DCTS_PER_NODE_LN; NBPtr->ChannelCount = MAX_CHANNELS_PER_DCT_LN; NBPtr->NodeCount = MAX_NODES_SUPPORTED_LN; NBPtr->Ganged = FALSE; NBPtr->PosTrnPattern = POS_PATTERN_256B; NBPtr->MemCleared = FALSE; NBPtr->StartupSpeed = DDR800_FREQUENCY; NBPtr->RcvrEnDlyLimit = 0x1FF; NBPtr->NbFreqChgState = 0; NBPtr->DefDctSelIntLvAddr = 5; NBPtr->FreqChangeParam = (MEM_FREQ_CHANGE_PARAM *) &FreqChangeParamLN; NBPtr->CsRegMsk = 0x1FF83FE0; NBPtr->MaxRxEnSeedTotal = 0x33F; NBPtr->MinRxEnSeedGross = 0; LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader); NBPtr->SetMaxLatency = MemNSetMaxLatencyLN; NBPtr->getMaxLatParams = MemNGetMaxLatParamsClientLN; NBPtr->InitializeMCT = (BOOLEAN (*) (MEM_NB_BLOCK *)) memDefTrue; NBPtr->FinalizeMCT = MemNFinalizeMctLN; NBPtr->SendMrsCmd = MemNSendMrsCmdLN; NBPtr->sendZQCmd = MemNSendZQCmdNb; NBPtr->WritePattern = MemNWritePatternLN; NBPtr->ReadPattern = MemNReadPatternLN; NBPtr->GenHwRcvEnReads = (VOID (*) (MEM_NB_BLOCK *, UINT32)) memDefRet; NBPtr->CompareTestPattern = MemNCompareTestPatternNb; NBPtr->InsDlyCompareTestPattern = MemNInsDlyCompareTestPatternNb; NBPtr->InitMCT = MemNInitMCTNb; NBPtr->StitchMemory = MemNStitchMemoryNb; NBPtr->AutoConfig = MemNAutoConfigLN; NBPtr->PlatformSpec = MemNPlatformSpecUnb; NBPtr->DisableDCT = MemNDisableDCTClientNb; NBPtr->StartupDCT = MemNStartupDCTUnb; NBPtr->SyncTargetSpeed = MemNSyncTargetSpeedNb; NBPtr->MemNCapSpeedBatteryLife = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; NBPtr->ChangeFrequency = MemNChangeFrequencyClientNb; NBPtr->RampUpFrequency = MemNRampUpFrequencyNb; NBPtr->ChangeNbFrequency = MemNChangeNbFrequencyNb; NBPtr->ProgramNbPsDependentRegs = MemNProgramNbPstateDependentRegistersClientNb; NBPtr->ProgramCycTimings = MemNProgramCycTimingsClientNb; NBPtr->SyncDctsReady = (BOOLEAN (*) (MEM_NB_BLOCK *)) memDefTrue; NBPtr->HtMemMapInit = MemNHtMemMapInitLN; NBPtr->SyncAddrMapToAllNodes = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; NBPtr->CpuMemTyping = MemNCPUMemTypingNb; NBPtr->UMAMemTyping = MemNUMAMemTypingNb; NBPtr->BeforeDqsTraining = MemNBeforeDQSTrainingLN; NBPtr->AfterDqsTraining = MemNAfterDQSTrainingLN; NBPtr->OtherTiming = MemNOtherTimingLN; NBPtr->GetSocketRelativeChannel = MemNGetSocketRelativeChannelNb; NBPtr->TechBlockSwitch = MemNTechBlockSwitchLN; NBPtr->SetEccSymbolSize = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; NBPtr->TrainingFlow = (VOID (*) (MEM_NB_BLOCK *))(memNTrainFlowControl[DDR3_TRAIN_FLOW]); NBPtr->MinDataEyeWidth = MemNMinDataEyeWidthNb; NBPtr->ChangeNbFrequencyWrap = MemNChangeNbFrequencyWrapLN; NBPtr->AllocateC6Storage = MemNAllocateC6StorageClientNb; MemNInitNBDataNb (NBPtr); FeatPtr->InitHwRxEn (NBPtr); NBPtr->PollBitField = MemNPollBitFieldNb; NBPtr->BrdcstCheck = MemNBrdcstCheckNb; NBPtr->BrdcstSet = MemNBrdcstSetNb; NBPtr->GetTrainDly = MemNGetTrainDlyNb; NBPtr->SetTrainDly = MemNSetTrainDlyNb; NBPtr->PhyFenceTraining = MemNPhyFenceTrainingUnb; NBPtr->GetSysAddr = MemNGetMCTSysAddrNb; NBPtr->RankEnabled = MemNRankEnabledNb; NBPtr->MemNCmnGetSetFieldNb = MemNCmnGetSetFieldLN; NBPtr->MemNBeforeDramInitNb = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; NBPtr->MemNBeforePlatformSpecNb = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; NBPtr->MemNInitPhyComp = MemNInitPhyCompClientNb; NBPtr->MemNcmnGetSetTrainDly = MemNcmnGetSetTrainDlyClientNb; NBPtr->MemPPhyFenceTrainingNb = (VOID (*) (MEM_NB_BLOCK *)) memDefRet; NBPtr->MemNPlatformSpecificFormFactorInitNb = MemNPlatformSpecificFormFactorInitLN; NBPtr->MemNPFenceAdjustNb = MemNPFenceAdjustUnb; NBPtr->GetTrainDlyParms = MemNGetTrainDlyParmsClientNb; NBPtr->TrainingPatternInit = MemNTrainingPatternInitNb; NBPtr->TrainingPatternFinalize = MemNTrainingPatternFinalizeNb; NBPtr->GetApproximateWriteDatDelay = MemNGetApproximateWriteDatDelayNb; NBPtr->CSPerChannel = MemNCSPerChannelLN; NBPtr->CSPerDelay = MemNCSPerDelayNb; NBPtr->FlushPattern = MemNFlushPatternNb; NBPtr->GetUmaSize = MemNGetUmaSizeLN; NBPtr->GetMemClkFreqId = MemNGetMemClkFreqIdClientNb; NBPtr->EnableSwapIntlvRgn = MemNEnableSwapIntlvRgnLN; NBPtr->WaitXMemClks = MemNWaitXMemClksNb; NBPtr->MemNGetDramTerm = MemNGetDramTermNb; NBPtr->MemNGetDynDramTerm = MemNGetDynDramTermNb; NBPtr->MemNGetMR0CL = MemNGetMR0CLNb; NBPtr->MemNGetMR0WR = MemNGetMR0WRLN; NBPtr->MemNSaveMR0 = (VOID (*) (MEM_NB_BLOCK *, UINT32)) memDefRet; NBPtr->MemNGetMR2CWL = MemNGetMR2CWLNb; NBPtr->IsSupported[SetDllShutDown] = TRUE; NBPtr->IsSupported[CheckPhyFenceTraining] = TRUE; NBPtr->IsSupported[CheckSendAllMRCmds] = TRUE; NBPtr->IsSupported[CheckFindPSDct] = TRUE; NBPtr->IsSupported[FenceTrnBeforeDramInit] = TRUE; NBPtr->IsSupported[WLSeedAdjust] = TRUE; NBPtr->IsSupported[UnifiedNbFence] = TRUE; NBPtr->IsSupported[CheckODTControls] = TRUE; NBPtr->IsSupported[ReverseMaxRdLatTrain] = TRUE; NBPtr->IsSupported[SkipErrTrain] = TRUE; NBPtr->IsSupported[DramSrHys] = TRUE; NBPtr->IsSupported[CheckMaxDramRate] = TRUE; NBPtr->IsSupported[SchedDlySlot1Extra] = TRUE; NBPtr->IsSupported[CsrPhyPllPdEn] = TRUE; NBPtr->IsSupported[AdjustTrc] = TRUE; NBPtr->IsSupported[ProgramCsrComparator] = TRUE; NBPtr->IsSupported[CheckDrvImpCtrl] = TRUE; NBPtr->IsSupported[EnProcOdtAdvForUDIMM] = TRUE; NBPtr->FamilySpecificHook[AddlMaxRdLatTrain] = MemNSlot1MaxRdLatTrainClientNb; NBPtr->FamilySpecificHook[BeforePhyFenceTraining] = MemNBeforePhyFenceTrainingClientNb; NBPtr->FamilySpecificHook[ReEnablePhyComp] = MemNReEnablePhyCompNb; NBPtr->FamilySpecificHook[AdjustTxpdll] = MemNAdjustTxpdllClientNb; NBPtr->FamilySpecificHook[DisLowPwrDrvStr] = MemNDisLowPwrDrvStrLN; NBPtr->FamilySpecificHook[CalcWrDqDqsEarly] = MemNCalcWrDqDqsEarlyClientNb; NBPtr->FamilySpecificHook[InitializeRxEnSeedlessTraining] = MemNInitializeRxEnSeedlessTrainingUnb; NBPtr->FamilySpecificHook[TrackRxEnSeedlessRdWrNoWindBLError] = MemNTrackRxEnSeedlessRdWrNoWindBLErrorUnb; NBPtr->FamilySpecificHook[TrackRxEnSeedlessRdWrSmallWindBLError] = MemNTrackRxEnSeedlessRdWrSmallWindBLErrorUnb; NBPtr->FamilySpecificHook[InitialzeRxEnSeedlessByteLaneError] = MemNInitialzeRxEnSeedlessByteLaneErrorUnb; NBPtr->FamilySpecificHook[OverridePrevPassRcvEnDly] = MemNOverridePrevPassRcvEnDlyLN; NBPtr->FamilySpecificHook[ResetRxFifoPtr] = MemNResetRxFifoPtrClientNb; NBPtr->FamilySpecificHook[BfAfExcludeDimm] = MemNBfAfExcludeDimmClientNb; FeatPtr->InitCPG (NBPtr); FeatPtr->InitEarlySampleSupport (NBPtr); NBPtr->FeatPtr = FeatPtr; // // Calculate SPD Offsets per channel and assign pointers // to the data. // SpdSocketIndex = GetSpdSocketIndex (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, &MemPtr->StdHeader); // // Traverse the Dct/Channel structures // for (Dct = 0; Dct < MAX_DCTS_PER_NODE_LN; Dct++) { for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_LN; Channel++) { // // Calculate the number of Dimms on this channel using the // die/dct/channel to Socket/channel conversion. // SpdChannelIndex = GetSpdChannelIndex (NBPtr->RefPtr->PlatformMemoryConfiguration, NBPtr->MCTPtr->SocketId, MemNGetSocketRelativeChannelNb (NBPtr, Dct, Channel), &MemPtr->StdHeader); NBPtr->MCTPtr->DctData[Dct].ChData[Channel].SpdPtr = &(MemPtr->SpdDataStructure[SpdSocketIndex + SpdChannelIndex]); } } MemNSwitchDCTNb (NBPtr, 0); NBPtr->Channel = 0; return TRUE; }