BOOLEAN MemNInitMCTNb ( IN OUT MEM_NB_BLOCK *NBPtr ) { MEM_TECH_BLOCK *TechPtr; UINT8 Dct; BOOLEAN Flag; ID_INFO CallOutIdInfo; TechPtr = NBPtr->TechPtr; // Switch Tech functions for Nb NBPtr->TechBlockSwitch (NBPtr); // Start Memory controller initialization sequence Flag = FALSE; if (TechPtr->DimmPresence (TechPtr)) { AGESA_TESTPOINT (TpProcMemPlatformSpecificInit, &(NBPtr->MemPtr->StdHeader)); if (NBPtr->MemNPlatformSpecificFormFactorInitNb (NBPtr)) { AGESA_TESTPOINT (TpProcMemSpdTiming, &(NBPtr->MemPtr->StdHeader)); if (TechPtr->SpdCalcWidth (TechPtr)) { AGESA_TESTPOINT (TpProcMemSpeedTclConfig, &(NBPtr->MemPtr->StdHeader)); if (TechPtr->SpdGetTargetSpeed (TechPtr)) { for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { NBPtr->SwitchDCT (NBPtr, Dct); Flag |= MemNInitDCTNb (NBPtr); } if (Flag && !NBPtr->IsSupported[TwoStageDramInit] && (NBPtr->MCTPtr->ErrCode != AGESA_FATAL)) { MemFInitTableDrive (NBPtr, MTBeforeDInit); AGESA_TESTPOINT (TpProcMemBeforeAgesaHookBeforeDramInit, &(NBPtr->MemPtr->StdHeader)); CallOutIdInfo.IdField.SocketId = NBPtr->MCTPtr->SocketId; CallOutIdInfo.IdField.ModuleId = NBPtr->MCTPtr->DieId; IDS_HDT_CONSOLE (MEM_FLOW, "\nCalling out to Platform BIOS on Socket %d Module %d...\n", CallOutIdInfo.IdField.SocketId, CallOutIdInfo.IdField.ModuleId); AgesaHookBeforeDramInit ((UINTN) CallOutIdInfo.IdInformation, NBPtr->MemPtr); IDS_HDT_CONSOLE (MEM_FLOW, "\nVDDIO = 1.%dV\n", (NBPtr->RefPtr->DDR3Voltage == VOLT1_5) ? 5 : (NBPtr->RefPtr->DDR3Voltage == VOLT1_35) ? 35 : (NBPtr->RefPtr->DDR3Voltage == VOLT1_25) ? 25 : 999); AGESA_TESTPOINT (TpProcMemAfterAgesaHookBeforeDramInit, &(NBPtr->MemPtr->StdHeader)); IDS_OPTION_HOOK (IDS_BEFORE_DRAM_INIT, NBPtr, &(NBPtr->MemPtr->StdHeader)); NBPtr->StartupDCT (NBPtr); } } } } } return (BOOLEAN) (NBPtr->MCTPtr->ErrCode != AGESA_FATAL); }
BOOLEAN MemNInitMCTNb ( IN OUT MEM_NB_BLOCK *NBPtr ) { MEM_TECH_BLOCK *TechPtr; UINT8 Dct; BOOLEAN Flag; TechPtr = NBPtr->TechPtr; // Switch Tech functions for Nb NBPtr->TechBlockSwitch (NBPtr); // Start Memory controller initialization sequence Flag = FALSE; if (TechPtr->DimmPresence (TechPtr)) { AGESA_TESTPOINT (TpProcMemPlatformSpecificInit, &(NBPtr->MemPtr->StdHeader)); if (NBPtr->MemNPlatformSpecificFormFactorInitNb (NBPtr)) { AGESA_TESTPOINT (TpProcMemSpdTiming, &(NBPtr->MemPtr->StdHeader)); if (TechPtr->SpdCalcWidth (TechPtr)) { AGESA_TESTPOINT (TpProcMemSpeedTclConfig, &(NBPtr->MemPtr->StdHeader)); if (TechPtr->SpdGetTargetSpeed (TechPtr)) { for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { NBPtr->SwitchDCT (NBPtr, Dct); Flag |= MemNInitDCTNb (NBPtr); } if (Flag && (NBPtr->MCTPtr->ErrCode != AGESA_FATAL)) { MemFInitTableDrive (NBPtr, MTBeforeDInit); AGESA_TESTPOINT (TpProcMemBeforeAgesaHookBeforeDramInit, &(NBPtr->MemPtr->StdHeader)); AgesaHookBeforeDramInit (0, NBPtr->MemPtr); AGESA_TESTPOINT (TpProcMemAfterAgesaHookBeforeDramInit, &(NBPtr->MemPtr->StdHeader)); IDS_OPTION_HOOK (IDS_BEFORE_DRAM_INIT, NBPtr, &(NBPtr->MemPtr->StdHeader)); NBPtr->StartupDCT (NBPtr); } } } } } return (BOOLEAN) (NBPtr->MCTPtr->ErrCode != AGESA_FATAL); }
BOOLEAN MemFLvDdr3 ( IN OUT MEM_NB_BLOCK *NBPtr ) { CH_DEF_STRUCT *ChannelPtr; MEM_TECH_BLOCK *TechPtr; MEM_SHARED_DATA *mmSharedPtr; UINT8 Dct; UINT8 Channel; UINT8 Dimm; UINT8 *SpdBufferPtr; UINT8 VDDByte; UINT8 VoltageMap; mmSharedPtr = NBPtr->SharedPtr; TechPtr = NBPtr->TechPtr; VoltageMap = 0xFF; for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { NBPtr->SwitchDCT (NBPtr, Dct); for (Channel = 0; Channel < NBPtr->ChannelCount; Channel++) { NBPtr->SwitchChannel (NBPtr, Channel); ChannelPtr = NBPtr->ChannelPtr; for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm++) { if (TechPtr->GetDimmSpdBuffer (TechPtr, &SpdBufferPtr, Dimm)) { // SPD byte 6: Module Nominal Voltage, VDD // 1.5v - bit 0 // 1.35v - bit 1 // 1.2v - bit 2 VDDByte = SpdBufferPtr[MNVVDD]; IDS_HDT_CONSOLE (MEM_FLOW, "Node%d DCT%d Channel%d Dimm%d VDD Byte: 0x%02x\n", NBPtr->Node, Dct, Channel, Dimm, VDDByte); // Reverse the 1.5V operable bit. So its encoding can be consistent // with that of 1.35V and 1.25V operable bit. VDDByte ^= 1; ASSERT (VDDByte != 0); if (mmSharedPtr->VoltageMap != 0) { // Get the common supported voltage map VoltageMap &= VDDByte; } else { // This is the second execution of all the loop as no common voltage is found if (VDDByte == (1 << VOLT1_5_ENCODED_VAL)) { // Always exclude 1.5V dimm if no common voltage is found ChannelPtr->DimmExclude |= (UINT16) 1 << Dimm; } } } } if (mmSharedPtr->VoltageMap == 0) { NBPtr->DCTPtr->Timings.DimmExclude |= ChannelPtr->DimmExclude; } } } if (mmSharedPtr->VoltageMap != 0) { mmSharedPtr->VoltageMap &= VoltageMap; } return TRUE; }
/** * * Process Conditional Platform Specific Overrides * * @param[in] PlatformMemoryConfiguration - Pointer to Platform config table * @param[in] NBPtr - Pointer to Current NBBlock * @param[in] PsoAction - Action type * @param[in] Dimm - Dimm Number * * @return BOOLEAN - TRUE : Action was performed * FALSE: Action was not performed * * ---------------------------------------------------------------------------- */ BOOLEAN MemProcessConditionalOverrides ( IN PSO_TABLE *PlatformMemoryConfiguration, IN OUT MEM_NB_BLOCK *NBPtr, IN UINT8 PsoAction, IN UINT8 Dimm ) { BOOLEAN Result; MEM_TECH_BLOCK *TechPtr; UINT8 *Buffer; UINT8 *ConditionStartPtr; UINT8 *ActionStartPtr; UINT8 *SpdBufferPtr; UINT8 i; UINT8 DimmMask; UINT8 CurDimmMask; BOOLEAN Condition; BOOLEAN TmpCond; PSO_STATE State; ASSERT (PlatformMemoryConfiguration != NULL); ASSERT (NBPtr != NULL); ASSERT ((PsoAction >= PSO_ACTION_MIN) && (PsoAction <= PSO_ACTION_MAX)); // // Set up local data // TechPtr = NBPtr->TechPtr; Buffer = PlatformMemoryConfiguration; State = PSO_FIND_CONDITION; ConditionStartPtr = NULL; ActionStartPtr = NULL; Condition = FALSE; DimmMask = 0xFF; CurDimmMask = 0xFF; Result = FALSE; if (Dimm != 0xFF) { DimmMask = ( 1 << Dimm); } DimmMask &= (UINT8) (NBPtr->ChannelPtr->ChDimmValid & 0xFF); if (DimmMask == 0) { return Result; } // // Search for Condition Entry // while (State != PSO_COMPLETE) { switch (State) { // // Searching for initial Condition statement // case PSO_FIND_CONDITION: ASSERT (Buffer != NULL); while (Buffer[PSO_TYPE] != PSO_CONDITION_AND) { // // If end of table is reached, Change state to complete and break. // if (Buffer[PSO_TYPE] == PSO_END) { State = PSO_COMPLETE; break; } // // Otherwise, increment Buffer Pointer to the next PSO entry. // Buffer += (Buffer[PSO_LENGTH] + 2); } // // If Condition statement has been found, save the Condition Start Pointer, // and change to next state // if (State != PSO_COMPLETE) { ASSERT (Buffer != NULL); State = PSO_FIND_ACTION; ConditionStartPtr = Buffer; Buffer += (Buffer[PSO_LENGTH] + 2); } break; // // Searching for an action that matches the caller's request // case PSO_FIND_ACTION: ASSERT (Buffer != NULL); while (Buffer[PSO_TYPE] != PsoAction) { // // If non-conditional entry, change state to complete and break. // if ((Buffer[PSO_TYPE] < CONDITIONAL_PSO_MIN) || (Buffer[PSO_TYPE] > CONDITIONAL_PSO_MAX)) { State = PSO_COMPLETE; break; } // // Check for the Start of a new condition block // if (Buffer[PSO_TYPE] == PSO_CONDITION_AND) { ConditionStartPtr = Buffer; } // // Otherwise, increment buffer pointer to the next PSO entry. // Buffer += (Buffer[PSO_LENGTH] + 2); } // // If Action statement has been found, Save the Action Start Pointer, Reset Buffer to Condition Start // and Change to next state. // if (State != PSO_COMPLETE) { State = PSO_CHECK_CONDITION; ASSERT (Buffer != NULL); ActionStartPtr = Buffer; Buffer = ConditionStartPtr; Condition = TRUE; } break; // // Checking the condition that preceded the found action // case PSO_CHECK_CONDITION: ASSERT (Buffer != NULL); // // Point to the next Condition // Buffer += (Buffer[PSO_LENGTH] + 2); ASSERT ((Buffer[PSO_TYPE] >= CONDITIONAL_PSO_MIN) && (Buffer[PSO_TYPE] <= CONDITIONAL_PSO_MAX)); // // This section has already been checked for invalid statements so just exit on ACTION_xx // if ((Buffer[PSO_TYPE] >= PSO_ACTION_MIN) && (Buffer[PSO_TYPE] <= PSO_ACTION_MAX)) { if (Condition) { ASSERT (Buffer != NULL); State = PSO_DO_ACTION; // Perform the Action } else { State = PSO_FIND_CONDITION; // Go back and look for another condition/action } Buffer = ActionStartPtr; // Restore Action Pointer break; } switch (Buffer[PSO_TYPE]) { case PSO_CONDITION_AND: // // Additional CONDITION_AND is ORed with Previous ones, so if Previous result is TRUE // just restore action pointer and perform the action. // if (Condition) { State = PSO_DO_ACTION; Buffer = ActionStartPtr; } else { // // If its false, Start over and evaluate next cond. // reset the Current Dimm Mask // Condition = TRUE; CurDimmMask = 0xFF; } break; case PSO_CONDITION_LOC: // // Condition location // CurDimmMask = Buffer[4]; Condition &= ( ((Buffer[2] & (1 << (NBPtr->MCTPtr->SocketId))) != 0) && ((Buffer[3] & (1 << (NBPtr->ChannelPtr->ChannelID))) != 0) && ((CurDimmMask & DimmMask) != 0) ); break; case PSO_CONDITION_SPD: // // Condition SPD // TmpCond = FALSE; for (i = 0; i < MAX_DIMMS_PER_CHANNEL; i ++) { if ( ((DimmMask & CurDimmMask) & ((UINT16) (1 << i))) != 0) { if (TechPtr->GetDimmSpdBuffer (TechPtr, &SpdBufferPtr, i)) { TmpCond |= ( (SpdBufferPtr[Buffer[2]] & Buffer[3]) == Buffer[4]); } } } Condition &= TmpCond; break; case PSO_CONDITION_REG: // // Condition Register - unsupported at this time // break; default: ASSERT (FALSE); } // End Condition Switch break; case PSO_DO_ACTION: ASSERT (Buffer != NULL); // // Performing Action // if ((Buffer[PSO_TYPE] < PSO_ACTION_MIN) || (Buffer[PSO_TYPE] > PSO_ACTION_MAX)) { State = PSO_COMPLETE; } if (Buffer[PSO_TYPE] == PsoAction) { switch (Buffer[PSO_TYPE]) { case PSO_ACTION_ODT: Result = MemPSODoActionODT (NBPtr, &Buffer[PSO_DATA]); break; case PSO_ACTION_ADDRTMG: Result = MemPSODoActionAddrTmg (NBPtr, &Buffer[PSO_DATA]); break; case PSO_ACTION_ODCCONTROL: Result = MemPSODoActionODCControl (NBPtr, &Buffer[PSO_DATA]); break; case PSO_ACTION_SLEWRATE: Result = MemPSODoActionSlewRate (NBPtr, &Buffer[PSO_DATA]); break; case PSO_ACTION_SPEEDLIMIT: Result = MemPSODoActionGetFreqLimit (NBPtr, &Buffer[PSO_DATA]); break; case PSO_ACTION_REG: break; default: ASSERT (FALSE); } // End Action Switch // // If Action was performed, mark complete. // if (Result) { State = PSO_COMPLETE; } }// End Action // // Point to the next PSO Entry // Buffer += (Buffer[PSO_LENGTH] + 2); break; case PSO_COMPLETE: // // Completed processing of this request // break; default: ASSERT (FALSE); } // End State Switch } // End While return Result; }