/** * * This function calculates RcvEn seed value for each rank * * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK * */ VOID MemNPrepareRcvrEnDlySeedNb ( IN OUT MEM_NB_BLOCK *NBPtr ) { MEM_TECH_BLOCK *TechPtr; CH_DEF_STRUCT *ChannelPtr; DIE_STRUCT *MCTPtr; UINT16 SeedTotal; UINT16 SeedFine; UINT16 SeedGross; UINT16 SeedPreGross; UINT16 SeedTotalPreScaling; UINT8 ByteLane; UINT16 Speed; UINT16 PlatEst; UINT8 ChipSel; UINT8 Pass; UINT16 *PlatEstSeed; UINT16 SeedValue[9]; UINT16 SeedTtl[9]; UINT16 SeedPre[9]; TechPtr = NBPtr->TechPtr; MCTPtr = NBPtr->MCTPtr; ChannelPtr = TechPtr->NBPtr->ChannelPtr; Speed = NBPtr->DCTPtr->Timings.Speed; SeedTotalPreScaling = 0; ChipSel = TechPtr->ChipSel; Pass = TechPtr->Pass; for (ByteLane = 0; ByteLane < (MCTPtr->Status[SbEccDimms] ? 9 : 8); ByteLane++) { TechPtr->Bytelane = ByteLane; if (Pass == 1) { // Get platform override seed PlatEstSeed = (UINT16 *) FindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_RXEN_SEED, MCTPtr->SocketId, ChannelPtr->ChannelID, ChipSel >> 1, &(NBPtr->MCTPtr->LogicalCpuid), &(NBPtr->MemPtr->StdHeader)); // For Pass1, BIOS starts with the delay value obtained from the first pass of write // levelization training that was done in DDR3 Training and add a delay value of 3Bh. PlatEst = 0x3B; NBPtr->FamilySpecificHook[OverrideRcvEnSeed] (NBPtr, &PlatEst); PlatEst = ((PlatEstSeed != NULL) ? PlatEstSeed[ByteLane] : PlatEst); SeedTotal = ChannelPtr->WrDqsDlys[(ChipSel / NBPtr->CsPerDelay) * TechPtr->DlyTableWidth () + ByteLane] + PlatEst; SeedValue[ByteLane] = PlatEst; } else { // For Pass2 // SeedTotalPreScaling = (the total delay values in D18F2x[1,0]9C_x0000_00[24:10] from pass 1 of // DQS receiver enable training) - 20h. Subtract 1UI to get back to preamble left edge. if ((((ChipSel & 1) == 0) || (NBPtr->CsPerDelay == 1)) && NBPtr->FamilySpecificHook[TrainingNibbleZero] (NBPtr, &ChipSel)) {