/* $NoKeywords:$ */ /** * @file * * AMD Integrated Debug library Routines * * Contains AMD AGESA debug macros and library functions * * @xrefitem bom "File Content Label" "Release Content" * @e project: AGESA * @e sub-project: IDS * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ */ /***************************************************************************** * Copyright (c) 2008 - 2013, 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. ****************************************************************************** */ /*---------------------------------------------------------------------------------------- * M O D U L E S U S E D *---------------------------------------------------------------------------------------- */ #include "AGESA.h" #include "Ids.h" #include "amdlib.h" #include "GeneralServices.h" #include "cpuServices.h" #include "cpuFamilyTranslation.h" #include "cpuPstateTables.h" #include "IdsLib.h" #include "heapManager.h" #include "mm.h" #include "mn.h" #include "cpuLateInit.h" #include "Filecode.h" CODE_GROUP (G1_PEICC) RDATA_GROUP (G1_PEICC) #define FILECODE PROC_IDS_LIBRARY_IDSLIB_FILECODE /*---------------------------------------------------------------------------- * DEFINITIONS AND MACROS * *---------------------------------------------------------------------------- */ extern CPU_FAMILY_SUPPORT_TABLE PstateFamilyServiceTable; /*---------------------------------------------------------------------------- * EXPORTED FUNCTIONS * *---------------------------------------------------------------------------- */ AGESA_STATUS AmdGetIdsImagebase ( IN OUT UINT64 *IdsImageBase, IN OUT AMD_CONFIG_PARAMS *StdHeader ); /** * * Get IDS NV table pointer in the AGESA Heap. * * @param[in,out] IdsNvTable The Pointer of IDS NV Table. * @param[in,out] StdHeader The Pointer of Standard Header. * * @retval AGESA_SUCCESS Success to get the pointer of NV Table. v * @retval AGESA_ERROR Fail to get the pointer of NV Table. **/ AGESA_STATUS AmdGetIdsNvTable ( IN OUT VOID **IdsNvTable, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS status; LOCATE_HEAP_PTR LocateHeapStructPtr; IDS_CONTROL_STRUCT *IdsCtrlPtr; LocateHeapStructPtr.BufferHandle = IDS_CONTROL_HANDLE; LocateHeapStructPtr.BufferPtr = NULL; status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader); if (status == AGESA_SUCCESS) { IdsCtrlPtr = (IDS_CONTROL_STRUCT *) LocateHeapStructPtr.BufferPtr; *IdsNvTable = LocateHeapStructPtr.BufferPtr + IdsCtrlPtr->IdsNvTableOffset; } return status; } /** * * Get IDS Override Image Base Address * * @param[in,out] IdsImageBase The Base Address of IDS Override Image. * @param[in,out] StdHeader The Pointer of Standard Header. * * @retval AGESA_SUCCESS Success to get the pointer of NV Table. * @retval AGESA_ERROR Fail to get the pointer of NV Table. * **/ AGESA_STATUS AmdGetIdsImagebase ( IN OUT UINT64 *IdsImageBase, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS status; LOCATE_HEAP_PTR LocateHeapStructPtr; IDS_CONTROL_STRUCT *IdsCtrlPtr; LocateHeapStructPtr.BufferHandle = IDS_CONTROL_HANDLE; LocateHeapStructPtr.BufferPtr = NULL; status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader); if (status == AGESA_SUCCESS) { IdsCtrlPtr = (IDS_CONTROL_STRUCT *) LocateHeapStructPtr.BufferPtr; *IdsImageBase = IdsCtrlPtr->IdsImageBase; } return status; } /** * * Read IDS NV value in NV table. * * It searches the table until the Nv Id is found and return the NV value * in the table. Otherwise, return IDS_UNSUPPORTED. * * @param[in] IdsNvId IDS NV ID * @param[in] NvTablePtr NV Table pointer. * @param[in,out] StdHeader The Pointer of Standard Header. * * @retval IDS_UNSUPPORTED NV ID is not found in the table * Other Value The NV value * **/ IDS_STATUS AmdIdsNvReader ( IN UINT16 IdsNvId, IN IDS_NV_ITEM *NvTablePtr, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { IDS_STATUS Status; IDS_NV_ITEM *NvPtr; BOOLEAN IgnoreIdsDefault; AGESA_STATUS status; LOCATE_HEAP_PTR LocateHeapStructPtr; IDS_CONTROL_STRUCT *IdsCtrlPtr; IgnoreIdsDefault = FALSE; Status = IDS_UNSUPPORTED; NvPtr = NvTablePtr; if (NvPtr != NULL) { while (NvPtr->IdsNvId != AGESA_IDS_NV_END) { if (NvPtr->IdsNvId == IdsNvId) { break; } else { NvPtr ++; } } if ((NvPtr->IdsNvId != AGESA_IDS_NV_END)) { //Get IgnoreIdsDefault from heap LocateHeapStructPtr.BufferHandle = IDS_CONTROL_HANDLE; LocateHeapStructPtr.BufferPtr = NULL; status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader); if (status == AGESA_SUCCESS) { IdsCtrlPtr = (IDS_CONTROL_STRUCT *) LocateHeapStructPtr.BufferPtr; IgnoreIdsDefault = IdsCtrlPtr->IgnoreIdsDefault; } if (IgnoreIdsDefault || (NvPtr->IdsNvValue != AGESA_IDS_DFT_VAL)) { Status = NvPtr->IdsNvValue; } } } return Status; } /** * IDS function for only return IDS_SUCCESS * * * @param[in,out] DataPtr meaningless data pointer * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. * @param[in] IdsNvPtr The Pointer of NV Table. * * @retval IDS_SUCCESS Always succeeds. * **/ IDS_STATUS IdsCommonReturn ( IN OUT VOID *DataPtr, IN OUT AMD_CONFIG_PARAMS *StdHeader, IN IDS_NV_ITEM *IdsNvPtr ) { return IDS_SUCCESS; } /** * IDS function for ap run specific task after amdinitpost * * * @param[in] ApicIdOfCore apic id of specific AP * @param[in] ApLateTaskPtr The Pointer of IDSAPLATETASK. * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. * * @retval AGESA_SUCCESS Success * @retval AGESA_ERROR meet some error * **/ AGESA_STATUS IdsAgesaRunFcnOnApLate ( IN UINTN ApicIdOfCore, IN IDSAPLATETASK *ApLateTaskPtr, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; AP_EXE_PARAMS LaunchApParams; //init AgesaRunFcnOnAp parameters LaunchApParams.FunctionNumber = IDS_LATE_RUN_AP_TASK_ID; LaunchApParams.RelatedBlockLength = SIZE_IN_DWORDS (IDSAPLATETASK); LaunchApParams.RelatedDataBlock = ApLateTaskPtr; LaunchApParams.StdHeader = *StdHeader; AGESA_TESTPOINT (TpIfBeforeRunApFromIds, StdHeader); Status = AgesaRunFcnOnAp ((UINTN) ApicIdOfCore, &LaunchApParams); AGESA_TESTPOINT (TpIfAfterRunApFromIds, StdHeader); return Status; } /** * IDS function force all cores run specific task after amdinitpost * * * @param[in] ApLateTaskPtr The Pointer of IDSAPLATETASK. * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. * * @retval AGESA_SUCCESS Success * @retval AGESA_ERROR meet some error * **/ AGESA_STATUS IdsAgesaRunFcnOnAllCoresLate ( IN IDSAPLATETASK *ApLateTaskPtr, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { AP_EXE_PARAMS LaunchApParams; AGESA_STATUS Status; //init AgesaRunFcnOnAp parameters Status = AGESA_SUCCESS; LaunchApParams.FunctionNumber = IDS_LATE_RUN_AP_TASK_ID; LaunchApParams.RelatedBlockLength = SIZE_IN_DWORDS (IDSAPLATETASK); LaunchApParams.RelatedDataBlock = ApLateTaskPtr; LaunchApParams.StdHeader = *StdHeader; Status = RunLateApTaskOnAllAPs (&LaunchApParams, StdHeader); //do it on Bsp Status = ApLateTaskPtr->ApTask (ApLateTaskPtr->ApTaskPara, StdHeader); return Status; } /** * IDS call-back function for ApDispatchTable * * @param[in] AmdApExeParams AP_EXE_PARAMS. * * @retval AGESA_SUCCESS Success * @retval AGESA_ERROR meet some error * **/ AGESA_STATUS AmdIdsRunApTaskLate ( IN AP_EXE_PARAMS *AmdApExeParams ) { IDSAPLATETASK *ApLateTaskPtr; AGESA_STATUS Status; ApLateTaskPtr = (IDSAPLATETASK *)AmdApExeParams->RelatedDataBlock; Status = ApLateTaskPtr->ApTask (ApLateTaskPtr->ApTaskPara, &AmdApExeParams->StdHeader); return Status; } /** * * * IDS Common routine for run code on AP for both ealry & later stage * This routine can only be used when AP service have been established * * @param[in] PIdsRuncodeParams Point to parameters structure * @param[in,out] StdHeader - The Pointer of AGESA Header * */ VOID IdsRunCodeOnCores ( IN IDS_RUNCODE_PARAMS *PIdsRuncodeParams, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { AP_TASK ApTask; IDSAPLATETASK IdsLateTask; UINT32 NumberOfCores; UINT8 StartSocket; UINT8 EndSocket; UINT8 Socket; UINT8 StartCore; UINT8 EndCore; UINT8 Core; UINT32 BscCoreNum; UINT32 BscSocket; UINT32 IgnoredModule; UINT32 ApicIdOfCore; AGESA_STATUS IgnoredSts; IDS_AP_RUN_CODE_TIMEPOINT TimePoint; TimePoint = PIdsRuncodeParams->TimePoint; ASSERT ((TimePoint == IDS_AP_RUN_CODE_EARLY) || (TimePoint == IDS_AP_RUN_CODE_POST) || (TimePoint == IDS_AP_RUN_CODE_LATE)); IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &BscCoreNum, &IgnoredSts); IdsGetStartEndSocket (PIdsRuncodeParams->Socket, &StartSocket, &EndSocket); //TaskPtr for both IDS_AP_RUN_CODE_EARLY, IDS_AP_RUN_CODE_POST ApTask.FuncAddress.PfApTaskIO = PIdsRuncodeParams->ApTask; ApTask.ExeFlags = WAIT_FOR_CORE; ApTask.DataTransfer.DataSizeInDwords = PIdsRuncodeParams->ParamsDataSizeInDwords; ApTask.DataTransfer.DataPtr = PIdsRuncodeParams->ParamsDataPtr; ApTask.DataTransfer.DataTransferFlags = 0; for (Socket = StartSocket; Socket <= EndSocket; Socket++) { if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { if (PIdsRuncodeParams->Core == IDS_ALL_CORE) { StartCore = 0; EndCore = (UINT8)NumberOfCores - 1; } else { StartCore = PIdsRuncodeParams->Core; EndCore = PIdsRuncodeParams->Core; } for (Core = StartCore; (Core <= EndCore) && (Core <= (NumberOfCores - 1)); Core++) { if ((Core == BscCoreNum) && (Socket == BscSocket)) { //Call function directly PIdsRuncodeParams->ApTask (PIdsRuncodeParams->ParamsDataPtr, StdHeader); } else { if (IsProcessorPresent (Socket, StdHeader)) { if (TimePoint == IDS_AP_RUN_CODE_EARLY) { // At early stage, the AP's task has to be called by core 0, not by bsc IdsRunCodeOnCoreEarly (Socket, Core, &ApTask, StdHeader); } else if (TimePoint == IDS_AP_RUN_CODE_POST) { ApUtilRunCodeOnSocketCore (Socket, Core, &ApTask, StdHeader); } else if (TimePoint == IDS_AP_RUN_CODE_LATE) { IdsLateTask.ApTask = (PF_IDS_AP_TASK)PIdsRuncodeParams->ApTask; IdsLateTask.ApTaskPara = PIdsRuncodeParams->ParamsDataPtr; GetLocalApicIdForCore (Socket, Core, &ApicIdOfCore, StdHeader); IdsAgesaRunFcnOnApLate (ApicIdOfCore, &IdsLateTask, StdHeader); } } } } } } } /** * Get the number of P-State to support * * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. * * @retval num The number of P-State to support. * **/ UINT8 IdsGetNumPstatesFamCommon ( IN OUT AMD_CONFIG_PARAMS *StdHeader ) { UINT8 pstatesnum; UINT8 i; UINT8 IgnoredByte; UINT32 Ignored; BOOLEAN PStateEnabled; UINT32 TempVar_c; PSTATE_CPU_FAMILY_SERVICES *FamilyServices; pstatesnum = 0; GetFeatureServicesOfCurrentCore (&PstateFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader); ASSERT (FamilyServices != NULL); FamilyServices->GetPstateMaxState (FamilyServices, &TempVar_c, &IgnoredByte, StdHeader); for (i = 0; i <= TempVar_c; i++) { // Check if PState is enabled FamilyServices->GetPstateRegisterInfo ( FamilyServices, (UINT32) i, &PStateEnabled, &Ignored, &Ignored, &Ignored, StdHeader); if (PStateEnabled) { pstatesnum++; } } return pstatesnum; } /*---------------------------------------------------------------------------------------*/ /** * Runs the given task on all cores (including self) on the socket of the executing * core 0. * * This function is used to invoke all APs on the socket of the executing core 0 to * run a specified AGESA procedure. * * @param[in] TaskPtr Function descriptor * @param[in] StdHeader Config handle for library and services * */ VOID IdsApRunCodeOnAllLocalCores ( IN AP_TASK *TaskPtr, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Core; UINT32 BscCoreNum; UINT32 Socket; UINT32 BscSocket; UINT32 IgnoredModule; UINT32 NumberOfCores; UINT32 NumberOfSockets; AGESA_STATUS IgnoredSts; IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &BscCoreNum, &IgnoredSts); NumberOfSockets = GetPlatformNumberOfSockets (); for (Socket = 0; Socket < NumberOfSockets; Socket++) { if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { for (Core = 0; Core < NumberOfCores; Core++) { if ((Socket != (UINT32) BscSocket) || (Core != (UINT32) BscCoreNum)) { ApUtilRunCodeOnSocketCore ((UINT8) Socket, (UINT8) Core, TaskPtr, StdHeader); } } } } // BSP codes ApUtilTaskOnExecutingCore (TaskPtr, StdHeader, NULL); } /** * IdsMakePciRegEntry * * * @param[in,out] TableEntry The Pointer of TableEntry * @param[in] Family Family * @param[in] Revision Revision * @param[in] PciAddr PCI address * @param[in] Data Or Mask * @param[in] Mask And Mask * * */ VOID IdsMakePciRegEntry ( IN OUT TABLE_ENTRY_FIELDS **TableEntry, IN UINT64 Family, IN UINT64 Revision, IN UINT32 PciAddr, IN UINT32 Data, IN UINT32 Mask ) { (*TableEntry)->EntryType = PciRegister; (*TableEntry)->CpuRevision.Family = Family; (*TableEntry)->CpuRevision.Revision = Revision; (*TableEntry)->Features.PlatformValue = AMD_PF_ALL; (*TableEntry)->Entry.PciEntry.Address.AddressValue = PciAddr; (*TableEntry)->Entry.PciEntry.Data = Data; (*TableEntry)->Entry.PciEntry.Mask = Mask; (*TableEntry)++; } /** * IdsMakeHtLinkPciRegEntry * * * @param[in,out] TableEntry The Pointer of TableEntry * @param[in] Family Family * @param[in] Revision Revision * @param[in] HtHostFeat HtHostFeat * @param[in] PciAddr PCI address * @param[in] Data Or Mask * @param[in] Mask And Mask * * */ VOID IdsMakeHtLinkPciRegEntry ( IN OUT TABLE_ENTRY_FIELDS **TableEntry, IN UINT64 Family, IN UINT64 Revision, IN UINT32 HtHostFeat, IN UINT32 PciAddr, IN UINT32 Data, IN UINT32 Mask ) { (*TableEntry)->EntryType = HtLinkPciRegister; (*TableEntry)->CpuRevision.Family = Family; (*TableEntry)->CpuRevision.Revision = Revision; (*TableEntry)->Features.PlatformValue = AMD_PF_ALL; (*TableEntry)->Entry.HtLinkPciEntry.LinkFeats.HtHostValue = HtHostFeat; (*TableEntry)->Entry.HtLinkPciEntry.PciEntry.Address.AddressValue = PciAddr; (*TableEntry)->Entry.HtLinkPciEntry.PciEntry.Data = Data; (*TableEntry)->Entry.HtLinkPciEntry.PciEntry.Mask = Mask; (*TableEntry)++; } /** * IdsMakeHtFeatPciRegEntry * * * @param[in,out] TableEntry The Pointer of TableEntry * @param[in] Family Family * @param[in] Revision Revision * @param[in] HtHostFeat HtHostFeat * @param[in] PackageType PackageType * @param[in] PciAddr PCI address * @param[in] Data Or Mask * @param[in] Mask And Mask * * */ VOID IdsMakeHtFeatPciRegEntry ( IN OUT TABLE_ENTRY_FIELDS **TableEntry, IN UINT64 Family, IN UINT64 Revision, IN UINT32 HtHostFeat, IN UINT32 PackageType, IN UINT32 PciAddr, IN UINT32 Data, IN UINT32 Mask ) { (*TableEntry)->EntryType = HtFeatPciRegister; (*TableEntry)->CpuRevision.Family = Family; (*TableEntry)->CpuRevision.Revision = Revision; (*TableEntry)->Features.PlatformValue = AMD_PF_ALL; (*TableEntry)->Entry.HtFeatPciEntry.LinkFeats.HtHostValue = HtHostFeat; (*TableEntry)->Entry.HtFeatPciEntry.PackageType.PackageTypeValue = PackageType; (*TableEntry)->Entry.HtFeatPciEntry.PciEntry.Address.AddressValue = PciAddr; (*TableEntry)->Entry.HtFeatPciEntry.PciEntry.Data = Data; (*TableEntry)->Entry.HtFeatPciEntry.PciEntry.Mask = Mask; (*TableEntry)++; } /** * IdsMakeHostPciRegEntry * * * @param[in,out] TableEntry The Pointer of TableEntry * @param[in] Family Family * @param[in] Revision Revision * @param[in] HtHostFeat HtHostFeat * @param[in] PciAddr PCI address * @param[in] Data Or Mask * @param[in] Mask And Mask * * */ VOID IdsMakeHtHostPciRegEntry ( IN OUT TABLE_ENTRY_FIELDS **TableEntry, IN UINT64 Family, IN UINT64 Revision, IN UINT32 HtHostFeat, IN UINT32 PciAddr, IN UINT32 Data, IN UINT32 Mask ) { (*TableEntry)->EntryType = HtHostPciRegister; (*TableEntry)->CpuRevision.Family = Family; (*TableEntry)->CpuRevision.Revision = Revision; (*TableEntry)->Features.PlatformValue = AMD_PF_ALL; (*TableEntry)->Entry.HtHostEntry.TypeFeats.HtHostValue = HtHostFeat; (*TableEntry)->Entry.HtHostEntry.Address.AddressValue = PciAddr; (*TableEntry)->Entry.HtHostEntry.Data = Data; (*TableEntry)->Entry.HtHostEntry.Mask = Mask; (*TableEntry)++; } /** * IdsMakeHtPhyRegEntry * * * @param[in,out] TableEntry The Pointer of TableEntry * @param[in] Family Family * @param[in] Revision Revision * @param[in] HtPhyLinkFeat HtPhyLinkFeat * @param[in] Address PCI address * @param[in] Data Or Mask * @param[in] Mask And Mask * * */ VOID IdsMakeHtPhyRegEntry ( IN OUT TABLE_ENTRY_FIELDS **TableEntry, IN UINT64 Family, IN UINT64 Revision, IN UINT32 HtPhyLinkFeat, IN UINT32 Address, IN UINT32 Data, IN UINT32 Mask ) { (*TableEntry)->EntryType = HtPhyRegister; (*TableEntry)->CpuRevision.Family = Family; (*TableEntry)->CpuRevision.Revision = Revision; (*TableEntry)->Features.PlatformValue = AMD_PF_ALL; (*TableEntry)->Entry.HtPhyEntry.TypeFeats.HtPhyLinkValue = HtPhyLinkFeat; (*TableEntry)->Entry.HtPhyEntry.Address = Address; (*TableEntry)->Entry.HtPhyEntry.Data = Data; (*TableEntry)->Entry.HtPhyEntry.Mask = Mask; (*TableEntry)++; } /** * IdsOptionCallout * * Description * Call the host environment interface to provide a user hook opportunity. * * @param[in] CallOutId This parameter indicates the IDS Call-Out-function desired. * @param[in,out] DataPtr The pointer for callout function use * @param[in,out] StdHeader Config handle for library and services * * @retval AGESA_SUCCESS Success * @retval AGESA_ERROR meet some error * */ AGESA_STATUS IdsOptionCallout ( IN UINTN CallOutId, IN OUT VOID *DataPtr, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { IDS_CALLOUT_STRUCT IdsCalloutData; IDS_NV_ITEM NullEntry; NullEntry.IdsNvId = 0xFFFF; NullEntry.IdsNvValue = 0xFFFF; IdsCalloutData.StdHeader = *StdHeader; IdsCalloutData.IdsNvPtr = &NullEntry; IdsCalloutData.Reserved = (UINTN) DataPtr; return AgesaGetIdsData (CallOutId, &IdsCalloutData); } /** * Ids Write PCI register to All node * * * @param[in] PciAddress Pci address * @param[in] Highbit High bit position of the field in DWORD * @param[in] Lowbit Low bit position of the field in DWORD * @param[in] Value Pointer to input value * @param[in] StdHeader Standard configuration header * */ VOID IdsLibPciWriteBitsToAllNode ( IN PCI_ADDR PciAddress, IN UINT8 Highbit, IN UINT8 Lowbit, IN UINT32 *Value, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Socket; UINT32 Module; AGESA_STATUS IgnoreStatus; PCI_ADDR PciAddr; for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddr, &IgnoreStatus)) { PciAddr.Address.Function = PciAddress.Address.Function; PciAddr.Address.Register = PciAddress.Address.Register; LibAmdPciWriteBits (PciAddr, Highbit, Lowbit, Value, StdHeader); } } } } /** * * * Core 0 task to run local ap task at early * * @param[in] PEarlyApTask - point to IDS_EARLY_AP_TASK structure * @param[in,out] StdHeader - The Pointer of AGESA Header * */ STATIC VOID IdsCmnTaskCore0Early ( IN IDS_EARLY_AP_TASK *PEarlyApTask, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Socket; UINT32 IgnoredModule; UINT32 IgnoredCore; AGESA_STATUS IgnoredSts; ASSERT (PEarlyApTask->Ap_Task0.Core != 0); PEarlyApTask->Ap_Task0.ApTask.DataTransfer.DataPtr = &PEarlyApTask->Parameters[0]; IdentifyCore (StdHeader, &Socket, &IgnoredModule, &IgnoredCore, &IgnoredSts); ApUtilRunCodeOnSocketCore ((UINT8)Socket, PEarlyApTask->Ap_Task0.Core, &PEarlyApTask->Ap_Task0.ApTask, StdHeader); } /** * * * BSC task to run Core0 task at early, must only run on BSC * * @param[in] Socket - Socket which run the task * @param[in] Core - Core which run the task * @param[in] ApTask - Task for AP * @param[in,out] StdHeader - The Pointer of AGESA Header * */ VOID IdsRunCodeOnCoreEarly ( IN UINT8 Socket, IN UINT8 Core, IN AP_TASK* ApTask, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { UINT32 BscSocket; UINT32 BscCoreNum; UINT32 IgnoredModule; AGESA_STATUS IgnoredSts; AP_TASK Core0Task; IDS_EARLY_AP_TASK IdsEarlyTask; IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &BscCoreNum, &IgnoredSts); ASSERT (!((Socket == BscSocket) && (Core == BscCoreNum))); if ((Socket == BscSocket) || (Core == 0)) { ApUtilRunCodeOnSocketCore (Socket, Core, ApTask, StdHeader); } else { //Init IDS_EARLY_AP_TASK for Core 0 IdsEarlyTask.Ap_Task0.ApTask = *ApTask; IdsEarlyTask.Ap_Task0.Core = Core; //Init Parameter buffer, Target core can't get the parameter from pointer, which point to Host Core memory space ASSERT ((ApTask->DataTransfer.DataSizeInDwords * sizeof (UINT32)) <= IDS_EARLY_AP_TASK_PARA_NUM); LibAmdMemCopy (&IdsEarlyTask.Parameters[0], ApTask->DataTransfer.DataPtr, sizeof (UINT32) * ApTask->DataTransfer.DataSizeInDwords, StdHeader); if ((ApTask->DataTransfer.DataSizeInDwords * sizeof (UINT32)) <= IDS_EARLY_AP_TASK_PARA_NUM) { //Lauch Core0 1st Core0Task.FuncAddress.PfApTaskI = (PF_AP_TASK_I)IdsCmnTaskCore0Early; Core0Task.ExeFlags = WAIT_FOR_CORE; Core0Task.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (IDS_EARLY_AP_TASK0) + ApTask->DataTransfer.DataSizeInDwords; Core0Task.DataTransfer.DataPtr = &IdsEarlyTask; Core0Task.DataTransfer.DataTransferFlags = 0; ApUtilRunCodeOnSocketCore (Socket, 0, &Core0Task, StdHeader); } } } /** * * * This function get start end Module according to input ModuleId * * @param[in] ModuleId - 0xFF means all nodes, other value Specifies real NodeId * @param[in,out] StartModule - Point to start Node * @param[in,out] EndModule - Point to end Node * */ VOID IdsGetStartEndModule ( IN UINT8 ModuleId, IN OUT UINT8 *StartModule, IN OUT UINT8 *EndModule ) { if (ModuleId == 0xFF) { *StartModule = 0; *EndModule = (UINT8) (GetPlatformNumberOfSockets () * GetPlatformNumberOfModules () - 1); if (*EndModule > 7) { *EndModule = 7; } } else { *StartModule = ModuleId; *EndModule = ModuleId; } } /** * * * This function get start end socket according to input SocketId * * @param[in] SocketId - 0xFF means all sockets, other value Specifies real SokcetId * @param[in,out] StartSocket - Point to start Socket * @param[in,out] EndSocket - Point to end Socket * */ VOID IdsGetStartEndSocket ( IN UINT8 SocketId, IN OUT UINT8 *StartSocket, IN OUT UINT8 *EndSocket ) { if (SocketId == IDS_ALL_SOCKET) { *StartSocket = 0; *EndSocket = (UINT8) (GetPlatformNumberOfSockets () - 1); } else { *StartSocket = SocketId; *EndSocket = SocketId; } } /** * * * This function transfer input High low bit to Mask * * @param[in] RegVal - Regval want to set * @param[in] Highbit - (0~63) * @param[in] Lowbit - (0~63) * @param[in,out] AndMask - point value contain output AndMask * @param[in,out] OrMask - point value contain output OrMask * */ VOID IdsGetMask64bits ( IN UINT64 RegVal, IN UINT8 Highbit, IN UINT8 Lowbit, IN OUT UINT64 *AndMask, IN OUT UINT64 *OrMask ) { UINT64 Mask; if ((Highbit - Lowbit) != 63) { Mask = (((UINT64) 1 << (Highbit - Lowbit + 1)) - 1); } else { Mask = (UINT64) 0xFFFFFFFFFFFFFFFF; } *AndMask = ~(Mask << Lowbit); *OrMask = (RegVal & Mask) << Lowbit; } /** * * * This function transfer input High low bit to Mask * * @param[in] RegVal - Regval want to set * @param[in] Highbit - (0~31) * @param[in] Lowbit - (0~31) * @param[in,out] AndMask - point value contain output AndMask * @param[in,out] OrMask - point value contain output OrMask * */ VOID IdsGetMask32bits ( IN UINT32 RegVal, IN UINT8 Highbit, IN UINT8 Lowbit, IN OUT UINT32 *AndMask, IN OUT UINT32 *OrMask ) { UINT32 Mask; if ((Highbit - Lowbit) != 31) { Mask = (((UINT32) 1 << (Highbit - Lowbit + 1)) - 1); } else { Mask = (UINT32) 0xFFFFFFFF; } *AndMask = ~(Mask << Lowbit); *OrMask = (RegVal & Mask) << Lowbit; } /** * * * This function transfer input High low bit to Mask * * @param[in] RegVal - Regval want to set * @param[in] Highbit - (0~15) * @param[in] Lowbit - (0~15) * @param[in,out] AndMask - point value contain output AndMask * @param[in,out] OrMask - point value contain output OrMask * */ VOID IdsGetMask16bits ( IN UINT16 RegVal, IN UINT8 Highbit, IN UINT8 Lowbit, IN OUT UINT32 *AndMask, IN OUT UINT32 *OrMask ) { UINT16 Mask; if ((Highbit - Lowbit) != 15) { Mask = (((UINT16) 1 << (Highbit - Lowbit + 1)) - 1); } else { Mask = (UINT16) 0xFFFF; } *AndMask = ~(Mask << Lowbit); *OrMask = (RegVal & Mask) << Lowbit; } /** * * * IdsCheckPciExisit * Use to check is the PCI device exisit of given address * * @param[in] PciAddr - Given PCI address * @param[in,out] StdHeader - The Pointer of AGESA Header * * @retval TRUE The PCI device exisit * @retval FALSE The PCI device doesn't exisit * * */ BOOLEAN IdsCheckPciExisit ( IN PCI_ADDR PciAddr, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR _pciaddr; UINT32 _pcidata; BOOLEAN status; status = FALSE; _pciaddr = PciAddr; _pciaddr.Address.Register = 0; LibAmdPciRead (AccessWidth32, _pciaddr, &_pcidata, StdHeader); if (_pcidata != 0xFFFFFFFF || _pcidata != 0) { status = TRUE; } return status; } /** * * * This function transfer input High low bit to Mask * * @param[in,out] Value - Regval want to And Or with Mask * @param[in] AndMask - AndMask * @param[in] OrMask - OrMask * */ VOID IdsLibDataMaskSet32 ( IN OUT UINT32 *Value, IN UINT32 AndMask, IN UINT32 OrMask ) { *Value &= AndMask; *Value |= OrMask; } VOID IdsOutPort ( IN UINT32 Addr, IN UINT32 Value, IN UINT32 Flag ) { __outdword ((UINT16) Addr, Value); }