diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f15tn/Proc/IDS/Library/IdsRegAcc.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f15tn/Proc/IDS/Library/IdsRegAcc.c | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Library/IdsRegAcc.c b/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Library/IdsRegAcc.c new file mode 100644 index 0000000000..02b2ed7be2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Library/IdsRegAcc.c @@ -0,0 +1,316 @@ +/* $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: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $ + */ +/***************************************************************************** + * Copyright 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved. + * + * AMD is granting you permission to use this software (the Materials) + * pursuant to the terms and conditions of your Software License Agreement + * with AMD. This header does *NOT* give you permission to use the Materials + * or any rights under AMD's intellectual property. Your use of any portion + * of these Materials shall constitute your acceptance of those terms and + * conditions. If you do not agree to the terms and conditions of the Software + * License Agreement, please do not use any portion of these Materials. + * + * CONFIDENTIALITY: The Materials and all other information, identified as + * confidential and provided to you by AMD shall be kept confidential in + * accordance with the terms and conditions of the Software License Agreement. + * + * LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION + * PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF + * MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE, + * OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE. + * IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER + * (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS + * INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE, + * GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER + * RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE + * EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, + * THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + * + * AMD does not assume any responsibility for any errors which may appear in + * the Materials or any other related information provided to you by AMD, or + * result from use of the Materials or any related information. + * + * You agree that you will not reverse engineer or decompile the Materials. + * + * NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any + * further information, software, technical information, know-how, or show-how + * available to you. Additionally, AMD retains the right to modify the + * Materials at any time, without notice, and is not obligated to provide such + * modified Materials to you. + * + * U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with + * "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is + * subject to the restrictions as set forth in FAR 52.227-14 and + * DFAR252.227-7013, et seq., or its successor. Use of the Materials by the + * Government constitutes acknowledgement of AMD's proprietary rights in them. + * + * EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any + * direct product thereof will be exported directly or indirectly, into any + * country prohibited by the United States Export Administration Act and the + * regulations thereunder, without the required authorization from the U.S. + * government nor will be used for any purpose prohibited by the same. + ****************************************************************************** + */ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "Filecode.h" +#include "cpuServices.h" +#include "GeneralServices.h" +#include "Ids.h" +#include "IdsLib.h" +#include "IdsRegAcc.h" + +#define FILECODE PROC_IDS_LIBRARY_IDSREGACC_FILECODE + +extern CONST IDS_FAMILY_FEAT_STRUCT* ROMDATA IdsRegAccessTbl[]; + +/** + * + * set the MSR of AP + * + * @param[in] PRegMsr point to REG_MSR + * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. + * + * + **/ +VOID +IdsRegSetMsrCmnTask ( + IN IDS_REG_MSR *PRegMsr, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT64 value; + + LibAmdMsrRead (PRegMsr->MsrAddr, &value, StdHeader); + value &= PRegMsr->AndMask; + value |= PRegMsr->OrMask; + LibAmdMsrWrite (PRegMsr->MsrAddr, &value, StdHeader); +} + +/** + * + * + * IDS Common routine for RMW MSR for both ealry & later stage + * This routine can only be used when AP service have been established + * + * @param[in] PMsrReg Point MSR reg structure, contain TimePoint, Socket, Core,address, andmask, ormask + * @param[in,out] StdHeader - The Pointer of AGESA Header + * + */ +VOID +IdsRegSetMsr ( + IN IDS_REG_MSR *PMsrReg, + 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_REG_AP_SERVICE_TIMEPOINT TimePoint; + + TimePoint = PMsrReg->TimePoint; + ASSERT ((TimePoint == IDS_REG_AP_SERVICE_EARLY) || + (TimePoint == IDS_REG_AP_SERVICE_POST) || + (TimePoint == IDS_REG_AP_SERVICE_LATE)); + + IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &BscCoreNum, &IgnoredSts); + IdsGetStartEndSocket (PMsrReg->Socket, &StartSocket, &EndSocket); + //TaskPtr for both IDS_REG_AP_SERVICE_EARLY, IDS_REG_AP_SERVICE_POST + ApTask.FuncAddress.PfApTaskI = (PF_AP_TASK_I)IdsRegSetMsrCmnTask; + ApTask.ExeFlags = WAIT_FOR_CORE; + ApTask.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (IDS_REG_MSR); + ApTask.DataTransfer.DataPtr = PMsrReg; + ApTask.DataTransfer.DataTransferFlags = 0; + + for (Socket = StartSocket; Socket <= EndSocket; Socket++) { + if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) { + if (PMsrReg->Core == IDS_ALL_CORE) { + StartCore = 0; + EndCore = (UINT8)NumberOfCores - 1; + } else { + StartCore = PMsrReg->Core; + EndCore = PMsrReg->Core; + } + for (Core = StartCore; (Core <= EndCore) && (Core <= (NumberOfCores - 1)); Core++) { + if ((Core == BscCoreNum) && (Socket == BscSocket)) { + IdsRegSetMsrCmnTask (PMsrReg, StdHeader); + } else { + if (IsProcessorPresent (Socket, StdHeader)) { + if (TimePoint == IDS_REG_AP_SERVICE_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_REG_AP_SERVICE_POST) { + ApUtilRunCodeOnSocketCore (Socket, Core, &ApTask, StdHeader); + } else if (TimePoint == IDS_REG_AP_SERVICE_LATE) { + IdsLateTask.ApTask = (PF_IDS_AP_TASK)IdsRegSetMsrCmnTask; + IdsLateTask.ApTaskPara = PMsrReg; + GetLocalApicIdForCore (Socket, Core, &ApicIdOfCore, StdHeader); + IdsAgesaRunFcnOnApLate (ApicIdOfCore, &IdsLateTask, StdHeader); + } + } + } + } + } + } +} + +/** + * + * + * IDS Common routine for set Memory bit field using memory sevice + * + * @param[in] PMemReg Point to MEM reg structure + * @param[in,out] NBPtr - The Pointer of NBPtr + * + */ + +AGESA_STATUS +IdsRegSetMemBitField ( + IN IDS_REG_MEM *PMemReg, + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 CurDct; + UINT32 BfType; + UINT32 BfIndex; + UINT8 HighBit; + UINT8 LowBit; + UINT32 RegValue; + UINT8 Dct; + HighBit = 31; + LowBit = 0; + //Check if current module need set + if ((PMemReg->Module == IDS_ALL_MODULE) || (PMemReg->Module == NBPtr->Node)) { + //Save Current DCT + CurDct = NBPtr->Dct; + //Set BfType for MAKE_TSEFO + for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { + if ((PMemReg->Dct == IDS_ALL_DCT) || (PMemReg->Dct == Dct)) { + if (PMemReg->Type == IDS_REG_MEM_NB) { + BfType = NB_ACCESS; + BfIndex = _FN (PMemReg->Addr.PciAddr.Func, PMemReg->Addr.PciAddr.Offset); + } else if (PMemReg->Type == IDS_REG_MEM_PHY) { + if ((PMemReg->Addr.Index & 0xFFF00000) == 0x0D000000) { + BfType = DCT_PHY_DIRECT; + //Dram debug PHY only support 16 bits access + HighBit = 15; + LowBit = 0; + } else { + BfType = DCT_PHY_ACCESS; + } + BfIndex = PMemReg->Addr.Index; + } else if (PMemReg->Type == IDS_REG_MEM_EXTRA) { + BfType = DCT_EXTRA; + BfIndex = PMemReg->Addr.Index; + } else { + return AGESA_UNSUPPORTED; + } + MAKE_TSEFO (NBPtr->NBRegTable, BfType, BfIndex, HighBit, LowBit, BFIdsCmnMemReg); + + NBPtr->SwitchDCT (NBPtr, Dct); + RegValue = NBPtr->GetBitField (NBPtr, BFIdsCmnMemReg); + RegValue &= PMemReg->AndMask; + RegValue |= PMemReg->OrMask; + NBPtr->SetBitField (NBPtr, BFIdsCmnMemReg, RegValue); + } + } + //Restore DCT + NBPtr->SwitchDCT (NBPtr, CurDct); + } + return AGESA_SUCCESS; +} + +/** + * + * + * IDS routine for set family specific register + * + * @param[in] PFamReg Point Famreg structure, contain register define, and type + * @param[in,out] StdHeader - The Pointer of AGESA Header + * + */ + +VOID +IdsFamRegAccess ( + IN IDS_FAM_REG *PFamReg, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_IDS_OPTION RegFamId; + + switch (PFamReg->Type) { + case IDS_FAM_REG_TYPE_GMMX: + RegFamId = IDS_FAM_REG_GMMX; + break; + default: + RegFamId = IDS_OPTION_END; + } + if (RegFamId != IDS_OPTION_END) { + IdsParseFeatTbl (RegFamId, IdsRegAccessTbl, &PFamReg->Reg, NULL, StdHeader); + } +} + +/** + * Set PCI indirect registers + * + * + * @param[in] PPciIndirectReg Point to IDS_REG_PCI_INDIRECT structure + * @param[in,out] StdHeader - The Pointer of AGESA Header + */ + +VOID +IdsRegSetPciIndirect ( + IN IDS_REG_PCI_INDIRECT *PPciIndirectReg, + IN OUT AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 IndexOffset; + UINT32 IndexValue; + UINT32 Value; + PCI_ADDR PciIndexPortAddr; + PCI_ADDR PciDataPortAddr; + + IndexOffset = LibAmdAccessWidth (PPciIndirectReg->Width); + PciIndexPortAddr.AddressValue = PPciIndirectReg->PciAddr; + PciDataPortAddr.AddressValue = PPciIndirectReg->PciAddr + IndexOffset; + //Read + LibAmdPciWrite (PPciIndirectReg->Width, PciIndexPortAddr, &PPciIndirectReg->IndirectRegOff, StdHeader); + LibAmdPciRead (PPciIndirectReg->Width, PciDataPortAddr, &Value, StdHeader); + //Modify + IdsLibDataMaskSet32 (&Value, PPciIndirectReg->AndMask, PPciIndirectReg->OrMask); + //Write + IndexValue = PPciIndirectReg->IndirectRegOff | PPciIndirectReg->WriteEnBit; + LibAmdPciWrite (PPciIndirectReg->Width, PciIndexPortAddr, &IndexValue, StdHeader); + LibAmdPciWrite (PPciIndirectReg->Width, PciDataPortAddr, &Value, StdHeader); +} + + |