diff options
Diffstat (limited to 'src/vendorcode/amd/cimx/rd890/nbInit.c')
-rw-r--r-- | src/vendorcode/amd/cimx/rd890/nbInit.c | 417 |
1 files changed, 417 insertions, 0 deletions
diff --git a/src/vendorcode/amd/cimx/rd890/nbInit.c b/src/vendorcode/amd/cimx/rd890/nbInit.c new file mode 100644 index 0000000000..8a5c5dba96 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbInit.c @@ -0,0 +1,417 @@ +/** + * @file + * + * NB Initialization. + * + * Init IOAPIC/IOMMU/Misc NB features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 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 "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Early post validate input parameters + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbLibEarlyPostInitValidateInput ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + NB_CONFIG *pNbConfig; + NB_INFO NbInfo; + + Status = AGESA_SUCCESS; + NbInfo = LibNbGetRevisionInfo (pConfig); + if (NbInfo.Type == NB_UNKNOWN) { + return AGESA_FATAL; + } + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (pNbConfig->sHeader.InitializerID != INITIALIZED_BY_INITIALIZER) { + Status = NbLibInitializer (pConfig); + } + if (pNbConfig->SysMemoryTomBelow4G == 0) { + Status = AGESA_FATAL; + } + //pNbConfig->sHeader.InitializerID = PH_AmdEarlyPostInit; + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Mid/Late post validate input parameters + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbLibPostInitValidateInput ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + NB_CONFIG *pNbConfig; + NB_INFO NbInfo; + + NbInfo = LibNbGetRevisionInfo (pConfig); + Status = AGESA_SUCCESS; + if (NbInfo.Type == NB_UNKNOWN) { + return AGESA_FATAL; + } + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (pNbConfig->sHeader.InitializerID != INITIALIZED_BY_INITIALIZER) { + Status = AGESA_FATAL; + } + //pNbConfig = GET_NB_CONFIG_PTR (pConfig); + //if (pNbConfig->sHeader.InitializerID != PH_AmdEarlyPostInit) { + // return AGESA_FATAL; + //} + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Prepare NB to boot to OS. + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbLibPrepareToOS ( + IN AMD_NB_CONFIG *pConfig + ) +{ + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessS3SaveWidth32, 0xffffffff, BIT7, pConfig); + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set Multiple NB support + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +VOID +NbMultiNbIocInit ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 Value; + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (GET_BLOCK_CONFIG_PTR (pConfig)->NumberOfNorthbridges > 0) { + if (pConfig->NbPciAddress.AddressValue == 0) { + //Primary NB + Value = BIT3 + (HT_INTERRUPT_ENCODING_OFFSET << 4); + } else { + //Secondary NB + Value = BIT2 + (HT_INTERRUPT_ENCODING_OFFSET << 4); + } + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG75, AccessS3SaveWidth32, (UINT32)~((0x7f << 2) + BIT28) , Value, pConfig); + } + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG75, AccessS3SaveWidth32, (UINT32)~(BIT9 + BIT10 + BIT28), pNbConfig->P2PMode << 9, pConfig); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set NB SSID/SVID. + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +VOID +NbLibSetSSID ( + IN AMD_NB_CONFIG *pConfig + ) +{ + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (pNbConfig->SSID == 0xffffffff) { + LibNbPciRead (pConfig->NbPciAddress.AddressValue, AccessWidth32, &pNbConfig->SSID, pConfig); + } + if (pNbConfig->SSID != 0) { + LibNbPciWrite (pConfig->NbPciAddress.AddressValue | NB_PCI_REG50, AccessS3SaveWidth32, &pNbConfig->SSID, pConfig); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Setup UnitId clamping + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +VOID +NbLibSetupClumping ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT16 ClumpingCapability; + UINT16 Value; + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + Value = 0; + if (LibNbGetCpuFamily () == CPU_FAMILY_NPT) { + return; + } + LibNbPciRead (pConfig->NbPciAddress.AddressValue | NB_PCI_REG58, AccessS3SaveWidth16, &ClumpingCapability, pConfig); + if ((ClumpingCapability & BIT3) != 0 && + (pNbConfig->UnitIdClumping & DEV3_CLUMPING) != 0 && + !LibNbIsDevicePresent (PcieLibGetPortPciAddress (3, pConfig), pConfig)) { + Value |= BIT3; + } + if ((ClumpingCapability & BIT12) != 0 && + (pNbConfig->UnitIdClumping & DEV12_CLUMPING) != 0 && + !LibNbIsDevicePresent (PcieLibGetPortPciAddress (12, pConfig), pConfig)) { + Value |= BIT12; + } + if (Value != 0) { + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG5C, AccessS3SaveWidth16, 0xffff, Value, pConfig); + LibNbPciRMW (MAKE_SBDFO (0, 0, pConfig->NbHtPath.NodeID + 0x18, 0, HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x110), AccessS3SaveWidth16, 0xffff, Value, pConfig); + } +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set top of memory in NB. + * NB will not pass to CPU any upstream DMA request to address above TOM and TOM2 + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbLibSetTopOfMemory ( + IN AMD_NB_CONFIG *pConfig + ) +{ + NB_CONFIG *pNbConfig; + UINT32 RD890_TOM2; + UINT32 RD890_TOM3; + + RD890_TOM2 = 0; + RD890_TOM3 = 0; + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (pNbConfig->SysMemoryTomBelow4G != 0) { + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG90, AccessS3SaveWidth32, 0, ((UINT32)pNbConfig->SysMemoryTomBelow4G) << 20, pConfig); + } + if (pNbConfig->SysMemoryTomAbove4G != 0) { + if ((pNbConfig->SysMemoryTomAbove4G - 1) <= 0xfffff) { + RD890_TOM2 = pNbConfig->SysMemoryTomAbove4G; + } else { + RD890_TOM2 = (UINT32) (0xFD00000000 >> 20); + RD890_TOM3 = pNbConfig->SysMemoryTomAbove4G; + } + } + if (RD890_TOM2 != 0) { + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG31, AccessS3SaveWidth32, 0, (RD890_TOM2 >> 12), pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG30, AccessS3SaveWidth32, 0, (RD890_TOM2 << 20) | 1, pConfig); + } + if (RD890_TOM3 != 0) { + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG4E, AccessS3SaveWidth32, 0, ((UINT32)pNbConfig->SysMemoryTomAbove4G >> 2) | BIT31, pConfig); + } + return AGESA_SUCCESS; +} +/*----------------------------------------------------------------------------------------*/ +/** + * Loget COre APic ID and dtore to scratch + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +NbLibGetCore0ApicId ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT64 Value; + UINT32 Apic20; + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + LibAmdMsrRead (0x0000001B, &Value, (AMD_CONFIG_PARAMS *)pConfig); + LibNbMemRead ((Value & 0xfffffffff000) + 0x20, AccessWidth32, &Apic20, pConfig); + pNbConfig->Reserved = (UINT16) (Apic20 >> 24); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Direct NMI message to Core 0 + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +NbLibSetNmiRouting ( + IN AMD_NB_CONFIG *pConfig + ) +{ + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + NB_MISC_REG12, + AccessS3SaveWidth32, + 0x00ffffff, + (UINT32)pNbConfig->Reserved << 24, + pConfig); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * AMD structures initializer for all NB. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdNbInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + Status = LibNbApiCall (NbLibInitializer, ConfigPtr); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NB config structure initializer + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +NbLibInitializer ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + UINT64 Value64; + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (pNbConfig == NULL) { + return AGESA_WARNING; + } + if (pNbConfig->sHeader.InitializerID == INITIALIZED_BY_INITIALIZER) { + return AGESA_SUCCESS; + } + LibAmdMemFill (pNbConfig, 0, sizeof (NB_CONFIG), (AMD_CONFIG_PARAMS *)&(pNbConfig->sHeader)); + pNbConfig->sHeader.InitializerID = INITIALIZED_BY_INITIALIZER; + // Get TOM and TOM2 + LibAmdMsrRead (0xC001001a, &Value64, (AMD_CONFIG_PARAMS *)pConfig); + pNbConfig->SysMemoryTomBelow4G = (UINT16) (Value64 >> 20); + LibAmdMsrRead (0xC0010010, &Value64, (AMD_CONFIG_PARAMS *)pConfig); + if ((Value64 & BIT21) != 0) { + LibAmdMsrRead (0xC001001d, &Value64, (AMD_CONFIG_PARAMS *)pConfig); + pNbConfig->SysMemoryTomAbove4G = (UINT32) (Value64 >> 20); + } + pNbConfig->P2PMode = 1; + pNbConfig->UnitIdClumping = 3; + return AGESA_SUCCESS; +} + + |