diff options
author | Elliott Dahle <dedahle@us.ibm.com> | 2013-11-13 10:35:18 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-12-14 17:42:08 -0600 |
commit | 178ea26dbd10dd1989b2311a209b00e2642af10a (patch) | |
tree | 666892b2b904c487faa477064eccb05e95a6e64b | |
parent | 915c24391f2d71ff7eca4b19ca9680b9496c44f3 (diff) | |
download | blackbird-hostboot-178ea26dbd10dd1989b2311a209b00e2642af10a.tar.gz blackbird-hostboot-178ea26dbd10dd1989b2311a209b00e2642af10a.zip |
Integrate IPL Flow Reconfig Loop Memory HWPs
Change-Id: I024737b0685164d3e79ee847d53ba1b46721ce5a
RTC:89843
CMVC-Coreq:906058
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/7452
Tested-by: Jenkins Server
Reviewed-by: Brian H. Horton <brianh@linux.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
38 files changed, 3635 insertions, 280 deletions
diff --git a/src/build/tools/listdeps.pl b/src/build/tools/listdeps.pl index 29087c828..5835d884f 100755 --- a/src/build/tools/listdeps.pl +++ b/src/build/tools/listdeps.pl @@ -35,7 +35,7 @@ use File::Find (); use File::Path; use Cwd; -use constant MAX_DEPENDENT_MODULES => 6; +use constant MAX_DEPENDENT_MODULES => 7; # validate the number of input args if( $#ARGV == -1 || $#ARGV > 4 ) diff --git a/src/include/usr/hwas/common/deconfigGard.H b/src/include/usr/hwas/common/deconfigGard.H index 2c974c9fb..1561c5ee6 100644 --- a/src/include/usr/hwas/common/deconfigGard.H +++ b/src/include/usr/hwas/common/deconfigGard.H @@ -118,6 +118,9 @@ public: // set for SPCN initiated deconfigure DECONFIGURED_BY_SPCN, // BASE | 0x08 + + // mask - these bits mean it's a PLID and not an enum + DECONFIGURED_BY_PLID_MASK = 0xFFFF0000, }; /** diff --git a/src/include/usr/initservice/initsvcstructs.H b/src/include/usr/initservice/initsvcstructs.H index daf52bd3b..49114e5d5 100644 --- a/src/include/usr/initservice/initsvcstructs.H +++ b/src/include/usr/initservice/initsvcstructs.H @@ -38,7 +38,7 @@ #include <initservice/initsvcreasoncodes.H> // This constant has a corresponding entry in src/build/tools/listdeps.pl. -#define MAX_DEPENDENT_MODULES 6 +#define MAX_DEPENDENT_MODULES 7 namespace INITSERVICE diff --git a/src/include/usr/isteps/istep10list.H b/src/include/usr/isteps/istep10list.H index f284e0cf9..eea23b4f4 100644 --- a/src/include/usr/isteps/istep10list.H +++ b/src/include/usr/isteps/istep10list.H @@ -239,6 +239,7 @@ const DepModInfo g_istep10Dependancies = { DEP_LIB(libporeve.so), DEP_LIB(libbuild_winkle_images.so), DEP_LIB(libsbe.so), + DEP_LIB(libproc_hwreconfig.so), { 0 }, } }; diff --git a/src/include/usr/isteps/istep14list.H b/src/include/usr/isteps/istep14list.H index 04ba0d3cd..8bb10ab89 100644 --- a/src/include/usr/isteps/istep14list.H +++ b/src/include/usr/isteps/istep14list.H @@ -27,7 +27,7 @@ * @file istep14list.H * * IStep 14 Dram Initialization - * IPL FLow Doc v1.28 (12/03/12) + * IPL FLow Doc v1.41 (11/08/13) * * 14.1 host_startprd_dram * : Load prd for DRAM domain @@ -35,14 +35,14 @@ * : MSS Extent Setup * 14.3 mss_memdiag * : Mainstore Pattern Testing - * 14.4 mss_scrub - * : Start background scrub - * 14.5 mss_thermal_init + * 14.4 mss_thermal_init * : Initialize the thermal sensor - * 14.6 proc_setup_bars - * : Setup Memory BARs - * 14.7 proc_pcie_config + * 14.5 proc_pcie_config * : Configure the PHBs + * 14.6 mss_power_cleanup + * : Clean up any MCS/Centaurs + * 14.7 proc_setup_bars + * : Setup Memory BARs * 14.8 proc_exit_cache_contained * : Allow execution from memory * 14.9 host_mpipl_service @@ -106,9 +106,11 @@ namespace INITSERVICE true, } }, + + { - ISTEPNAME(14,04,"mss_scrub"), - DRAM_INITIALIZATION::call_mss_scrub, + ISTEPNAME(14,04,"mss_thermal_init"), + DRAM_INITIALIZATION::call_mss_thermal_init, { START_FN, EXT_IMAGE, @@ -119,8 +121,8 @@ namespace INITSERVICE { - ISTEPNAME(14,05,"mss_thermal_init"), - DRAM_INITIALIZATION::call_mss_thermal_init, + ISTEPNAME(14,05,"proc_pcie_config"), + DRAM_INITIALIZATION::call_proc_pcie_config, { START_FN, EXT_IMAGE, @@ -129,10 +131,9 @@ namespace INITSERVICE } }, - { - ISTEPNAME(14,06,"proc_setup_bars"), - DRAM_INITIALIZATION::call_proc_setup_bars, + ISTEPNAME(14,06,"mss_power_cleanup"), + DRAM_INITIALIZATION::call_mss_power_cleanup, { START_FN, EXT_IMAGE, @@ -143,8 +144,8 @@ namespace INITSERVICE { - ISTEPNAME(14,07,"proc_pcie_config"), - DRAM_INITIALIZATION::call_proc_pcie_config, + ISTEPNAME(14,07,"proc_setup_bars"), + DRAM_INITIALIZATION::call_proc_setup_bars, { START_FN, EXT_IMAGE, @@ -164,6 +165,8 @@ namespace INITSERVICE true, } }, + + { ISTEPNAME(14,09,"host_mpipl_service"), DRAM_INITIALIZATION::call_host_mpipl_service, @@ -182,6 +185,7 @@ namespace INITSERVICE const DepModInfo g_istep14Dependancies = { { DEP_LIB(libdram_initialization.so), + DEP_LIB(libdram_training.so), DEP_LIB(libdump.so), { 0 }, } diff --git a/src/include/usr/isteps/istep16list.H b/src/include/usr/isteps/istep16list.H index 77c9bcaa9..43821c786 100644 --- a/src/include/usr/isteps/istep16list.H +++ b/src/include/usr/isteps/istep16list.H @@ -28,13 +28,15 @@ * @file istep16list.H * * IStep 16 Core Activate - * IPL FLow Doc v1.28 (12/03/12) + * IPL FLow Doc v1.41 (11/08/13) * * 16.1 host_activate_master * : Activate master core * 16.2 host_activate_slave_cores * : Activate slave cores - * 16.3 host_ipl_complete + * 16.3 mss_scrub + * : Start background scrub + * 16.4 host_ipl_complete * : Notify FSP drawer ipl complete * * ***************************************************************** @@ -93,7 +95,19 @@ namespace INITSERVICE { - ISTEPNAME(16,03,"host_ipl_complete"), + ISTEPNAME(16,03,"mss_scrub"), + CORE_ACTIVATE::call_mss_scrub, + { + START_FN, + EXT_IMAGE, + NORMAL_IPL_OP, + false, + } + }, + + + { + ISTEPNAME(16,04,"host_ipl_complete"), CORE_ACTIVATE::call_host_ipl_complete, { START_FN, diff --git a/src/include/usr/targeting/common/utilFilter.H b/src/include/usr/targeting/common/utilFilter.H index 85d123780..551f4cf85 100644 --- a/src/include/usr/targeting/common/utilFilter.H +++ b/src/include/usr/targeting/common/utilFilter.H @@ -38,6 +38,44 @@ namespace TARGETING { + /** + * Enum of functional states for use with calls to getChip/ChipletResources + */ + enum ResourceState + { + UTIL_FILTER_ALL, // All targets + UTIL_FILTER_PRESENT, // Present at minimum + UTIL_FILTER_FUNCTIONAL // Functional targets only + }; + + +/** + * @brief Populate the o_vector with target chip pointers based on the + * requested type, and functional state. + * + * @parm[out] o_vector, reference of vector of target pointers. + * @parm[in] i_type, the type of the chip targets to be obtained + * @parm[in] i_state, Selection filter based on ResourceState enum + * + * @return N/A + */ +void getChipResources(TARGETING::TargetHandleList & o_vector, + TYPE i_type, ResourceState i_state ); + +/** + * @brief Populate the o_vector with target chiplet pointers based on the + * requested type, and functional state. + * + * @parm[out] o_vector, reference of vector of target pointers. + * @parm[in] i_type, the type of the chiplet targets to be obtained + * @parm[in] i_state, Selection filter based on ResourceState enum + * + * @return N/A + */ +void getChipletResources(TARGETING::TargetHandleList & o_vector, + TYPE i_type, ResourceState i_state ); + + /** * @brief Populate the o_vector with target chip pointers based on the * requested type, and functional state. diff --git a/src/makefile b/src/makefile index 79abda197..8f3425948 100644 --- a/src/makefile +++ b/src/makefile @@ -59,7 +59,7 @@ EXTENDED_MODULES = targeting ecmddatabuffer fapi hwp plat \ establish_system_smp occ\ nest_chiplets start_payload thread_activate slave_sbe \ attn runtime ibscom dump tod_init secureboot_ext \ - devtree sbe + devtree sbe proc_hwreconfig TESTCASE_MODULES = cxxtest testtrace testerrl testdevicefw testsyslib \ testscom testxscom testtargeting testinitservice testkernel \ diff --git a/src/usr/hwas/common/deconfigGard.C b/src/usr/hwas/common/deconfigGard.C index ccdc4a1bc..f062ffe8a 100644 --- a/src/usr/hwas/common/deconfigGard.C +++ b/src/usr/hwas/common/deconfigGard.C @@ -1307,8 +1307,12 @@ void DeconfigGard::_deconfigureTarget(Target & i_target, l_state.deconfiguredByEid = i_errlEid; i_target.setAttr<ATTR_HWAS_STATE>(l_state); - // increment the counter - iv_deconfigCount++; + // if this is a real error, deconfigure + if (i_errlEid & DECONFIGURED_BY_PLID_MASK) + { + // increment the counter + iv_deconfigCount++; + } // Do any necessary Deconfigure Actions _doDeconfigureActions(i_target); diff --git a/src/usr/hwas/hostbootIstep.C b/src/usr/hwas/hostbootIstep.C index adeec948b..34c3e040b 100644 --- a/src/usr/hwas/hostbootIstep.C +++ b/src/usr/hwas/hostbootIstep.C @@ -37,15 +37,33 @@ #include <fsi/fsiif.H> #include <initservice/taskargs.H> #include <initservice/isteps_trace.H> +#include <hwpisteperror.H> #include <targeting/attrsync.H> #include <diag/prdf/prdfMain.H> #include <intr/interrupt.H> #include <ibscom/ibscomif.H> +// fapi support +#include <fapi.H> +#include <fapiPlatHwpInvoker.H> + +// targeting support. +#include <targeting/common/utilFilter.H> +#include <targeting/common/commontargeting.H> + +#include <errl/errludtarget.H> + +#include <proc_enable_reconfig.H> + namespace HWAS { +using namespace TARGETING; +using namespace fapi; +using namespace ISTEP; +using namespace ISTEP_ERROR; + // functions called from the istep dispatcher -- hostboot only //****************************************************************************** @@ -88,8 +106,7 @@ void* host_discover_targets( void *io_pArgs ) errlHndl_t errl = NULL; // Check whether we're in MPIPL mode - using namespace TARGETING; - Target* l_pTopLevel = NULL; + TARGETING::Target* l_pTopLevel = NULL; targetService().getTopLevelTarget( l_pTopLevel ); if( l_pTopLevel == NULL ) @@ -154,8 +171,7 @@ void* host_gard( void *io_pArgs ) errlHndl_t errl; // Check whether we're in MPIPL mode - using namespace TARGETING; - Target* l_pTopLevel = NULL; + TARGETING::Target* l_pTopLevel = NULL; targetService().getTopLevelTarget( l_pTopLevel ); if( l_pTopLevel == NULL ) @@ -231,24 +247,115 @@ void* host_prd_hwreconfig( void *io_pArgs ) "host_prd_hwreconfig entry" ); errlHndl_t errl = NULL; + IStepError l_stepError; + do + { + // Flip the scom path back to FSI in case we enabled IBSCOM previously + IBSCOM::enableInbandScoms(IBSCOM_DISABLE); - // Flip the scom path back to FSI in case we enabled IBSCOM previously - IBSCOM::enableInbandScoms(IBSCOM_DISABLE); + // Call PRDF to remove non-function chips from its system model + errl = PRDF::refresh(); - // Call PRDF to remove non-function chips from its system model - errl = PRDF::refresh(); + if (errl) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "host_prd_hwreconfig ERROR 0x%.8X returned from" + " call to PRDF::refresh", errl->reasonCode()); - if (errl) - { - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "host_prd_hwreconfig ERROR 0x%.8X returned from" - " call to PRDF::refresh", errl->reasonCode()); - } + // Create IStep error log and cross reference error that occurred + l_stepError.addErrorDetails(errl); + // Commit Error + errlCommit(errl, HWPF_COMP_ID); + + break; + } + + // Lists for functional MCS/Centaurs + TARGETING::TargetHandleList l_fncMcsList; + TARGETING::TargetHandleList l_fncCentaurList; + + // find all functional MCS chiplets of all procs + getChipletResources(l_fncMcsList, TYPE_MCS, UTIL_FILTER_FUNCTIONAL); + + for (TargetHandleList::const_iterator + l_mcs_iter = l_fncMcsList.begin(); + l_mcs_iter != l_fncMcsList.end(); + ++l_mcs_iter) + { + // make a local copy of the MCS target + const TARGETING::Target * l_pMcs = *l_mcs_iter; + // Retrieve HUID of current MCS + TARGETING::ATTR_HUID_type l_currMcsHuid = + TARGETING::get_huid(l_pMcs); + + // Find all the functional Centaurs that are associated with this MCS + getChildAffinityTargets(l_fncCentaurList, l_pMcs, + CLASS_CHIP, TYPE_MEMBUF); + + // There will always be 1 Centaur associated with a MCS. + if(1 != l_fncCentaurList.size()) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "No functional Centaurs found for " + "MCS target HUID %.8X , skipping this MCS", + l_currMcsHuid); + continue; + } + + // Make a local copy + const TARGETING::Target * l_pCentaur = l_fncCentaurList[0]; + // Retrieve HUID of current Centaur + TARGETING::ATTR_HUID_type l_currCentaurHuid = + TARGETING::get_huid(l_pCentaur); + + // Dump current run on target + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Running proc_enable_reconfig HWP on " + "MCS target HUID %.8X CENTAUR target HUID %.8X", + l_currMcsHuid, l_currCentaurHuid); + + // Create FAPI Targets. + fapi::Target l_fapiMcsTarget(TARGET_TYPE_MCS_CHIPLET, + (const_cast<TARGETING::Target*>(l_pMcs))); + fapi::Target l_fapiCentaurTarget(TARGET_TYPE_MEMBUF_CHIP, + (const_cast<TARGETING::Target*>(l_pCentaur))); + + // Call the HWP with each fapi::Target + FAPI_INVOKE_HWP(errl, proc_enable_reconfig, + l_fapiMcsTarget, l_fapiCentaurTarget); + + if (errl) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR 0x%.8X: proc_enable_reconfig HWP returns error", + errl->reasonCode()); + + // Capture the target data in the elog + ERRORLOG::ErrlUserDetailsTarget(l_pMcs).addToLog( errl ); + + // Create IStep error log and cross reference error that occurred + l_stepError.addErrorDetails(errl); + + // Commit Error + errlCommit(errl, HWPF_COMP_ID); + } + else + { + // Success + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Successfully ran proc_enable_reconfig HWP on " + "MCS target HUID %.8X CENTAUR target HUID %.8X", + l_currMcsHuid, + l_currCentaurHuid); + } + } + } + while(0); TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_prd_hwreconfig exit" ); - - return errl; + // end task, returning any errorlogs to IStepDisp + return l_stepError.getErrorHandle(); } //****************************************************************************** diff --git a/src/usr/hwas/makefile b/src/usr/hwas/makefile index a37f7a8a9..8938a99c0 100644 --- a/src/usr/hwas/makefile +++ b/src/usr/hwas/makefile @@ -24,6 +24,16 @@ ROOTPATH = ../../.. EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwas EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwas/common +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig + +## support for Targeting and fapi +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp + +## pointer to common HWP files +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include VPATH += ${ROOTPATH}/src/usr/hwas/plat VPATH += ${ROOTPATH}/src/usr/hwas/common diff --git a/src/usr/hwpf/hwp/bus_training/io_cleanup.C b/src/usr/hwpf/hwp/bus_training/io_cleanup.C new file mode 100644 index 000000000..14e5f0d76 --- /dev/null +++ b/src/usr/hwpf/hwp/bus_training/io_cleanup.C @@ -0,0 +1,327 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/bus_training/io_cleanup.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: io_cleanup.C,v 1.3 2013/12/12 08:41:30 varkeykv Exp $
+// *!***************************************************************************
+// *! (C) Copyright International Business Machines Corp. 1997, 1998
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+// *!***************************************************************************
+// *! FILENAME : io_cleanup.C
+// *! TITLE :
+// *! DESCRIPTION : Cleanup procedure for re-init loop
+// *! CONTEXT :
+// *!
+// *! OWNER NAME : Varghese, Varkey Email: varkey.kv@in.ibm.com
+// *! BACKUP NAME : Janani Swaminathan Email: jaswamin@in.ibm.com
+// *!
+// *!***************************************************************************
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:|Author: | Date: | Comment:
+// --------|--------|--------|--------------------------------------------------
+// 1.0 |varkeykv|07/30/11|Initial check in .
+//------------------------------------------------------------------------------
+#include <fapi.H>
+#include "io_cleanup.H"
+#include "gcr_funcs.H"
+
+
+
+extern "C" {
+ using namespace fapi;
+// For clearing the FIR mask , used by io run training
+// As per Irving , it should be ok to clear all FIRs here since we will scom init , also we dont touch mask values
+ReturnCode clear_fir_reg(const Target &i_target,fir_io_interface_t i_chip_interface){
+ ReturnCode rc;
+ ecmdDataBufferBase data(64);
+ FAPI_INF("io_cleanup:In the Clear FIR RW register function ");
+
+ // use FIR AND mask register to un-mask selected bits
+ rc = fapiPutScom(i_target, fir_rw_reg_addr[i_chip_interface], data);
+ if (!rc.ok())
+ {
+ FAPI_ERR("Error writing FIR mask register (=%08X)!",
+ fir_rw_reg_addr[i_chip_interface]);
+ }
+ return(rc);
+}
+
+/*
+ from Megan's ipl1.sh
+
+ istep -s0..11
+## forcing channel fail
+getscom pu 02011C4A -pall -call -vs1
+ getscom cen 0201080A -pall -call -vs1
+ putscom pu 02011C4A 8000000480400000 -pall -call
+ putscom cen 0201080A 8000000000000000 -pall -call
+ getscom pu 02011C4A -pall -call -vs1
+ getscom cen 0201080A -pall -call -vs1
+## masking fir bit
+putscom pu.mcs 2011843 FFFFFFFFFFFFFFFF -all
+### IO reset
+iotk put rx_fence=1 -t=p8:bmcs
+iotk put rx_fence=1 -t=cn
+iotk put ioreset_hard_bus0=111111 -t=p8:bmcs
+iotk put ioreset_hard_bus0=111111 -t=cn
+
+#exit
+##clear_fir
+./clear_fir.pl
+### Reload
+istep proc_dmi_scominit
+istep dmi_scominit
+##checking Zcal
+iotk get tx_zcal_p_4x -t=p8:bmcs
+iotk get tx_zcal_p_4x -t=cn
+iotk get tx_zcal_sm_min_val -t=p8:bmcs
+iotk get tx_zcal_sm_min_val -t=cn
+iotk get tx_zcal_sm_max_val -t=p8:bmcs
+iotk get tx_zcal_sm_max_val -t=cn
+### Loading Zcal
+iotk put tx_zcal_p_4x=00100
+iotk put tx_zcal_sm_min_val=0010101
+iotk put tx_zcal_sm_max_val=1000110
+## Runing Zcal
+istep dmi_io_dccal
+## forcing channel fail
+ getscom pu 02011C4A -pall -call -vs1
+ getscom cen 0201080A -pall -call -vs1
+ putscom pu 02011C4A 8000000480400000 -pall -call
+ putscom cen 0201080A 8000000000000000 -pall -call
+ getscom pu 02011C4A -pall -call -vs1
+ getscom cen 0201080A -pall -call -vs1
+
+
+
+
+
+*/
+
+ReturnCode do_cleanup(const Target &master_target,io_interface_t master_interface,uint32_t master_group,const Target &slave_target,io_interface_t slave_interface,uint32_t slave_group)
+{
+ ReturnCode rc;
+ uint32_t rc_ecmd = 0;
+ uint8_t chip_unit = 0;
+ // uint8_t link_fir_unmask_data = 0x8F;
+ ecmdDataBufferBase data(64);
+ ecmdDataBufferBase reg_data(16),set_bits(16),clear_bits(16),temp_bits(16);
+
+ //iotk put rx_fence=1 -t=p8:bmcs
+ // No other field in this reg , so no need for RMW
+ rc_ecmd = temp_bits.setBit(0);
+ if(rc_ecmd)
+ {
+ rc.setEcmdError(rc_ecmd);
+ return(rc);
+ }
+ rc=GCR_write(master_target, master_interface, rx_fence_pg, master_group,0, temp_bits, temp_bits,1,1);
+ if(rc) return rc;
+
+ //iotk put rx_fence=1 -t=cn
+ rc=GCR_write(slave_target, slave_interface, rx_fence_pg, slave_group,0, temp_bits, temp_bits,1,1);
+ if(rc) return rc;
+
+ rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS,
+ &master_target,
+ chip_unit);
+ if (!rc.ok())
+ {
+ FAPI_ERR("Error retreiving MCS chiplet number!");
+ return rc;
+ }
+
+ // swizzle to DMI number
+ if (master_interface == CP_IOMC0_P0)
+ {
+ chip_unit = 3-(chip_unit % 4);
+ // swap 0 and 1 due to Clock group swap in layout
+ if(chip_unit==1){
+ chip_unit=0;
+ }
+ else if(chip_unit==0){
+ chip_unit=1;
+ }
+
+
+ FAPI_DBG("CHIP UNIT IS %d",chip_unit);
+
+ }
+ rc = fapiGetScom(master_target, scom_mode_pb_reg_addr[FIR_CP_IOMC0_P0], data);
+ if (!rc.ok())
+ {
+ FAPI_ERR("Error Reading SCOM mode PB register for ioreset_hard_bus0 on master side(=%08X)!",
+ scom_mode_pb_reg_addr[FIR_CP_IOMC0_P0]);
+ return rc;
+ }
+
+ rc_ecmd = data.setBit(2+chip_unit,1); // Scom_mode_pb ,ioreset starts at bit 2
+ if(rc_ecmd)
+ {
+ rc.setEcmdError(rc_ecmd);
+ return(rc);
+ }
+ FAPI_DBG("Writing the Hard reset on PU ");
+ // use FIR AND mask register to un-mask selected bits
+ rc = fapiPutScom(master_target, scom_mode_pb_reg_addr[FIR_CP_IOMC0_P0], data);
+ if (!rc.ok())
+ {
+ FAPI_ERR("Error writing SCOM mode PB register for ioreset_hard_bus0 on master side(=%08X)!",
+ scom_mode_pb_reg_addr[FIR_CP_IOMC0_P0]);
+ return rc;
+ }
+
+ rc_ecmd = data.flushTo0();
+ if(rc_ecmd)
+ {
+ rc.setEcmdError(rc_ecmd);
+ return(rc);
+ }
+ // Centaur is always bus0 in reset register
+ if(slave_interface == CEN_DMI){
+ chip_unit=0;
+ }
+ rc = fapiGetScom(slave_target, scom_mode_pb_reg_addr[FIR_CEN_DMI], data);
+ if (!rc.ok())
+ {
+ FAPI_ERR("Error Reading SCOM mode PB register for ioreset_hard_bus0 on Slave side(=%08X)!",
+ scom_mode_pb_reg_addr[FIR_CEN_DMI]);
+ return rc;
+ }
+ rc_ecmd = data.setBit(2+chip_unit,1); // Scom_mode_pb ,ioreset starts at bit 2
+ if(rc_ecmd)
+ {
+ rc.setEcmdError(rc_ecmd);
+ return(rc);
+ }
+ // use FIR AND mask register to un-mask selected bits
+ rc = fapiPutScom(slave_target, scom_mode_pb_reg_addr[FIR_CEN_DMI], data);
+ if (!rc.ok())
+ {
+ FAPI_ERR("Error writing SCOM mode PB register for ioreset_hard_bus0 on Slave side(=%08X)!",
+ scom_mode_pb_reg_addr[FIR_CEN_DMI]);
+ return rc;
+ }
+
+
+ // NOW We clear FIRS.. need to see if we need to do this or some other procedure will do this . Bellows/Irving to respond
+
+ rc = clear_fir_reg(slave_target,FIR_CEN_DMI);
+ if(rc)
+ {
+ return(rc);
+ }
+ rc = clear_fir_reg(master_target,FIR_CP_IOMC0_P0);
+ if(rc)
+ {
+ return(rc);
+ }
+ return rc;
+}
+
+// Determines if target is a master...
+static ReturnCode isChipMaster(const Target& chip_target, io_interface_t chip_interface,uint32_t current_group, bool & masterchip_found ) {
+ ReturnCode rc;
+ ecmdDataBufferBase mode_data(16);
+ masterchip_found=false;
+
+ // Check if rx_master_mode bit is set for chip
+ // Read rx_master_mode for chip
+ if(chip_interface==CP_FABRIC_X0)
+ {
+ rc=GCR_read(chip_target , chip_interface, ei4_rx_mode_pg, current_group,0, mode_data);
+ }
+ else
+ {
+ rc=GCR_read(chip_target , chip_interface, rx_mode_pg, current_group,0, mode_data);
+ }
+ if (rc) {
+ FAPI_ERR("io_cleanup: Error reading master mode bit\n");
+ }
+ else
+ {
+ // Check if chip is master
+ if (mode_data.isBitSet(0)) {
+ FAPI_DBG("This chip is a master\n");
+ masterchip_found =true;
+ }
+ }
+ return(rc);
+}
+
+
+// Cleans up for Centaur Reconfig or Abus hot plug case
+ReturnCode io_cleanup(const Target &master_target,const Target &slave_target){
+ ReturnCode rc;
+ io_interface_t master_interface,slave_interface;
+ uint32_t master_group=0;
+ uint32_t slave_group=0;
+ // const uint32_t max_group=4; // Num of X bus groups in one bus
+
+ bool is_master=false;
+
+
+ // This is a DMI/MC bus
+ if( (master_target.getType() == fapi::TARGET_TYPE_MCS_CHIPLET )&& (slave_target.getType() == fapi::TARGET_TYPE_MEMBUF_CHIP)){
+ FAPI_DBG("This is a DMI bus using base DMI scom address");
+ master_interface=CP_IOMC0_P0; // base scom for MC bus
+ slave_interface=CEN_DMI; // Centaur scom base
+ master_group=3; // Design requires us to do this as per scom map and layout
+ slave_group=0;
+ rc=isChipMaster(master_target,master_interface,master_group,is_master);
+ if(rc.ok()){
+ if(!is_master)
+ {
+ FAPI_DBG("DMI Bus ..target swap performed");
+ rc=do_cleanup(slave_target,slave_interface,slave_group,master_target,master_interface,master_group);
+ if(rc) return rc;
+ }
+ else
+ {
+ rc=do_cleanup(master_target,master_interface,master_group,slave_target,slave_interface,slave_group);
+ if(rc) return rc;
+ }
+ }
+ }
+ //This is an A Bus
+ else if( (master_target.getType() == fapi::TARGET_TYPE_ABUS_ENDPOINT )&& (slave_target.getType() == fapi::TARGET_TYPE_ABUS_ENDPOINT)){
+ FAPI_DBG("This is an A Bus training invocation");
+ master_interface=CP_FABRIC_A0; // base scom for A bus , assume translation to A1 by PLAT
+ slave_interface=CP_FABRIC_A0; //base scom for A bus
+ master_group=0; // Design requires us to do this as per scom map and layout
+ slave_group=0;
+ rc=isChipMaster(master_target,master_interface,master_group,is_master);
+ if(rc.ok()){
+ // Now only for DMI
+ }
+ }
+ else{
+ FAPI_ERR("Invalid io_cleanup HWP invocation . Pair of targets dont belong to DMI or A bus instances");
+ FAPI_SET_HWP_ERROR(rc, IO_RUN_TRAINING_INVALID_INVOCATION_RC);
+ }
+ return rc;
+}
+
+
+
+} // extern
diff --git a/src/usr/hwpf/hwp/bus_training/io_cleanup.H b/src/usr/hwpf/hwp/bus_training/io_cleanup.H new file mode 100644 index 000000000..3368d20a2 --- /dev/null +++ b/src/usr/hwpf/hwp/bus_training/io_cleanup.H @@ -0,0 +1,55 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/bus_training/io_cleanup.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +//$Id: io_cleanup.H,v 1.1 2013/07/30 12:00:50 varkeykv Exp $
+#ifndef IO_CLEANUP_H_
+#define IO_CLEANUP_H_
+
+#include <fapi.H>
+#include "io_clear_firs.H"
+
+using namespace fapi;
+
+/**
+ * io_cleanup func pointer Typedef for hostboot
+ *
+ */
+typedef fapi::ReturnCode (*io_cleanup_FP_t)(const fapi::Target &,const fapi::Target &);
+
+extern "C"
+{
+
+/**
+ * io_cleanup
+ *
+ * master_target is the master side of a bus ..p8.mcs in a DMI .. or a p8.abus/p8.xbus in fabric
+ * slave_target - slave side of the bus .. Centaur in DMI , p8.xbus or p8.abus for fabric
+ * while these are called master or slave... I actually do a check in the code to see
+ * whether these are actually master chips by reading a GCR master_mode bit
+ * and accordingly will perform a target swap if required
+ * @return ReturnCode
+ */
+fapi::ReturnCode io_cleanup(const fapi::Target &master_target,const fapi::Target & slave_target);
+
+} // extern "C"
+
+#endif // IO_cleanup_H
diff --git a/src/usr/hwpf/hwp/bus_training/makefile b/src/usr/hwpf/hwp/bus_training/makefile index bbda4eb5a..03a29a6ef 100644 --- a/src/usr/hwpf/hwp/bus_training/makefile +++ b/src/usr/hwpf/hwp/bus_training/makefile @@ -46,7 +46,8 @@ OBJS = gcr_funcs.o io_funcs.o io_run_training.o pbusLinkSvc.o proc_fab_smp.o \ erepairGetFailedLanesHwp.o \ erepairSetFailedLanesHwp.o \ io_post_trainadv.o \ - io_pre_trainadv.o + io_pre_trainadv.o \ + io_cleanup.o ## NOTE: add a new directory onto the vpaths when you add a new HWP diff --git a/src/usr/hwpf/hwp/core_activate/core_activate.C b/src/usr/hwpf/hwp/core_activate/core_activate.C index f903834d3..bf570bcef 100644 --- a/src/usr/hwpf/hwp/core_activate/core_activate.C +++ b/src/usr/hwpf/hwp/core_activate/core_activate.C @@ -409,6 +409,31 @@ void* call_host_activate_slave_cores( void *io_pArgs ) // +// Wrapper function to call mss_scrub +// +void* call_mss_scrub( void *io_pArgs ) +{ + errlHndl_t l_errl = NULL; + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_mss_scrub entry" ); + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "Note: call_mss_scrub is not directly executed by Hostboot " + "but is instead triggered by PRD. " + "Cronus executes this HWP directly" ); + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_mss_scrub exit" ); + + // end task, returning any errorlogs to IStepDisp + return l_errl; +} + + + + +// // Wrapper function to call host_ipl_complete // void* call_host_ipl_complete( void *io_pArgs ) diff --git a/src/usr/hwpf/hwp/core_activate/core_activate.H b/src/usr/hwpf/hwp/core_activate/core_activate.H index b38a43f98..10c85081e 100644 --- a/src/usr/hwpf/hwp/core_activate/core_activate.H +++ b/src/usr/hwpf/hwp/core_activate/core_activate.H @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/usr/hwpf/hwp/core_activate/core_activate.H $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/core_activate/core_activate.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __CORE_ACTIVATE_CORE_ACTIVATE_H #define __CORE_ACTIVATE_CORE_ACTIVATE_H @@ -60,6 +59,12 @@ * @} * @{ * @substepnum 3 + * @substepname mss_scrub + * @substepdesc : Start background scrub + * @target_sched serial + * @} + * @{ + * @substepnum 4 * @substepname host_ipl_complete * @substepdesc : Notify FSP drawer ipl complete * * @target_sched serial @@ -104,6 +109,18 @@ void* call_host_activate_master( void *io_pArgs ); void* call_host_activate_slave_cores( void *io_pArgs ); +/** + * @brief mss_scrub + * + * Start background scrub + * + * param[in,out] - pointer to any arguments, usually NULL + * + * return pointer to any errlogs + * + */ +void* call_mss_scrub( void *io_pArgs ); + /** * @brief host_ipl_complete diff --git a/src/usr/hwpf/hwp/dmi_training/mss_getecid/mss_get_cen_ecid.C b/src/usr/hwpf/hwp/dmi_training/mss_getecid/mss_get_cen_ecid.C index 13f734e76..828af5a2f 100644 --- a/src/usr/hwpf/hwp/dmi_training/mss_getecid/mss_get_cen_ecid.C +++ b/src/usr/hwpf/hwp/dmi_training/mss_getecid/mss_get_cen_ecid.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_get_cen_ecid.C,v 1.28 2013/10/03 08:07:44 bellows Exp $ +// $Id: mss_get_cen_ecid.C,v 1.30 2013/11/14 16:55:39 bellows Exp $ //------------------------------------------------------------------------------ // *| // *! (C) Copyright International Business Machines Corp. 2012 @@ -39,7 +39,9 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|---------|----------------------------------------------- -// 1.28 | bellows |02-OCT-13| Minor Review Comments addressed +// 1.30 | bellows |11-NOV-13| Gerrit review updates +// 1.29 | bellows |08-NOV-13| Added ATTR_MSS_INIT_STATE to track IPL states +// 1.28 | bellows |02-OCT-13| Minor Review Comments addressed // 1.27 | bellows |26-SEP-13| Fixed Minor firware comment // 1.26 | bellows |19-SEP-13| Fixed the bug in 1.24 // 1.25 | bellows |18-SEP-13| Back to 1.23 because of some issue @@ -73,6 +75,7 @@ extern "C" { +using namespace fapi; //------------------------------------------------------------------------------ // Function definitions //------------------------------------------------------------------------------ @@ -106,6 +109,14 @@ extern "C" { ecid_struct.o_psro, ecid_struct.o_bluewaterfall_broken, ecid_struct.o_nwell_misplacement ); + if(rc) return rc; + + // set the init state attribute to CLOCKS_ON + uint8_t l_attr_mss_init_state; + l_attr_mss_init_state=ENUM_ATTR_MSS_INIT_STATE_CLOCKS_ON; + rc = FAPI_ATTR_SET(ATTR_MSS_INIT_STATE, &i_target, l_attr_mss_init_state); + if(rc) return rc; + return rc; } diff --git a/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C b/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C index 824e63265..4e669d1a1 100644 --- a/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C +++ b/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C @@ -70,6 +70,7 @@ #include "proc_setup_bars/proc_setup_bars.H" #include "proc_pcie_config/proc_pcie_config.H" #include "proc_exit_cache_contained/proc_exit_cache_contained.H" +#include "mss_power_cleanup/mss_power_cleanup.H" //remove these once memory setup workaround is removed #include <devicefw/driverif.H> #include <vpd/spdenums.H> @@ -237,56 +238,6 @@ void* call_mss_memdiag( void *io_pArgs ) return l_stepError.getErrorHandle(); } - -// -// Wrapper function to call mss_scrub -// -void* call_mss_scrub( void *io_pArgs ) -{ - errlHndl_t l_errl = NULL; - - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "call_mss_scrub entry" ); - -#if 0 - // @@@@@ CUSTOM BLOCK: @@@@@ - // figure out what targets we need - // customize any other inputs - // set up loops to go through all targets (if parallel, spin off a task) - - // write HUID of target - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "target HUID %.8X", TARGETING::get_huid(l)); - - // cast OUR type of target to a FAPI type of target. - const fapi::Target l_fapi_@targetN_target( TARGET_TYPE_MEMBUF_CHIP, - (const_cast<TARGETING::Target*>(l_@targetN_target)) ); - - // call the HWP with each fapi::Target - FAPI_INVOKE_HWP( l_errl, mss_scrub, _args_...); - if ( l_errl ) - { - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "ERROR : .........." ); - errlCommit( l_errl, HWPF_COMP_ID ); - } - else - { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "SUCCESS : .........." ); - } - // @@@@@ END CUSTOM BLOCK: @@@@@ -#endif - - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "call_mss_scrub exit" ); - - // end task, returning any errorlogs to IStepDisp - return l_errl; -} - - - // // Wrapper function to call mss_thermal_init // @@ -360,6 +311,169 @@ void* call_mss_thermal_init( void *io_pArgs ) } +// +// Wrapper function to call proc_pcie_config +// +void* call_proc_pcie_config( void *io_pArgs ) +{ + errlHndl_t l_errl = NULL; + + IStepError l_stepError; + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_proc_pcie_config entry" ); + + TARGETING::TargetHandleList l_procTargetList; + getAllChips(l_procTargetList, TYPE_PROC ); + + for ( TargetHandleList::const_iterator + l_iter = l_procTargetList.begin(); + l_iter != l_procTargetList.end(); + ++l_iter ) + { + const TARGETING::Target* l_pTarget = *l_iter; + + // write HUID of target + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "target HUID %.8X", TARGETING::get_huid(l_pTarget)); + + // build a FAPI type of target. + const fapi::Target l_fapi_pTarget( TARGET_TYPE_PROC_CHIP, + (const_cast<TARGETING::Target*>(l_pTarget)) ); + + // call the HWP with each fapi::Target + FAPI_INVOKE_HWP( l_errl, proc_pcie_config, l_fapi_pTarget ); + + if ( l_errl ) + { + // capture the target data in the elog + ErrlUserDetailsTarget(l_pTarget).addToLog( l_errl ); + + // Create IStep error log and cross reference to error that occurred + l_stepError.addErrorDetails( l_errl ); + + // Commit Error + errlCommit( l_errl, HWPF_COMP_ID ); + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR : proc_pcie_config" ); + + break; + } + else + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "SUCCESS : proc_pcie_config" ); + } + } + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_proc_pcie_config exit" ); + + // end task, returning any errorlogs to IStepDisp + return l_stepError.getErrorHandle(); +} + + +// +// Wrapper function to call mss_power_cleanup +// +void* call_mss_power_cleanup( void *io_pArgs ) +{ + errlHndl_t l_err = NULL; + IStepError l_stepError; + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_mss_power_cleanup entry" ); + + // Get a list of all present Centaurs + TargetHandleList l_presCentaurs; + getChipResources(l_presCentaurs, TYPE_MEMBUF, UTIL_FILTER_PRESENT); + // Associated MBA targets + TARGETING::TargetHandleList l_mbaList; + + // Define predicate for associated MBAs + PredicateCTM predMba(CLASS_UNIT, TYPE_MBA); + PredicatePostfixExpr presMba; + PredicateHwas predPres; + predPres.present(true); + presMba.push(&predMba).push(&predPres).And(); + + for (TargetHandleList::const_iterator + l_cenIter = l_presCentaurs.begin(); + l_cenIter != l_presCentaurs.end(); + ++l_cenIter) + { + // Make a local copy of the target for ease of use + TARGETING::Target * l_pCentaur = *l_cenIter; + // Retrieve HUID of current Centaur + TARGETING::ATTR_HUID_type l_currCentaurHuid = + TARGETING::get_huid(l_pCentaur); + + // Dump current run on target + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Running mss_power_cleanup HWP on " + "target HUID %.8X", l_currCentaurHuid); + + // find all present MBAs associated with this Centaur + TARGETING::TargetHandleList l_presMbas; + targetService().getAssociated(l_presMbas, + l_pCentaur, + TargetService::CHILD, + TargetService::IMMEDIATE, + &presMba); + + // If not at least two MBAs found + if (l_presMbas.size() < 2) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Not enough MBAs found for Centaur target HUID %.8X, " + "skipping this Centaur.", + l_currCentaurHuid); + continue; + } + + // Create FAPI Targets. + const fapi::Target l_fapiCentaurTarget(TARGET_TYPE_MEMBUF_CHIP, + (const_cast<TARGETING::Target*>(l_pCentaur))); + const fapi::Target l_fapiMba0Target(TARGET_TYPE_MBA_CHIPLET, + (const_cast<TARGETING::Target*>(l_presMbas[0]))); + const fapi::Target l_fapiMba1Target(TARGET_TYPE_MBA_CHIPLET, + (const_cast<TARGETING::Target*>(l_presMbas[1]))); + // call the HWP with each fapi::Target + FAPI_INVOKE_HWP(l_err, mss_power_cleanup, l_fapiCentaurTarget, + l_fapiMba0Target, l_fapiMba1Target); + + if (l_err) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR 0x%.8X: mss_power_cleanup HWP returns error", + l_err->reasonCode()); + // capture the target data in the elog + ErrlUserDetailsTarget(l_pCentaur).addToLog(l_err); + // Create IStep error log and cross reference error that occurred + l_stepError.addErrorDetails(l_err); + // Commit Error + errlCommit(l_err, HWPF_COMP_ID); + } + else + { + // Success + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Successfully ran mss_power_cleanup HWP on " + "CENTAUR target HUID %.8X " + "and associated MBAs", + l_currCentaurHuid); + } + } + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_mss_power_cleanup exit" ); + + // end task, returning any errorlogs to IStepDisp + return l_stepError.getErrorHandle(); +} + // // Wrapper function to call proc_setup_bars @@ -532,72 +646,6 @@ void* call_proc_setup_bars( void *io_pArgs ) } - -// -// Wrapper function to call proc_pcie_config -// -void* call_proc_pcie_config( void *io_pArgs ) -{ - errlHndl_t l_errl = NULL; - - IStepError l_stepError; - - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "call_proc_pcie_config entry" ); - - TARGETING::TargetHandleList l_procTargetList; - getAllChips(l_procTargetList, TYPE_PROC ); - - for ( TargetHandleList::const_iterator - l_iter = l_procTargetList.begin(); - l_iter != l_procTargetList.end(); - ++l_iter ) - { - const TARGETING::Target* l_pTarget = *l_iter; - - // write HUID of target - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "target HUID %.8X", TARGETING::get_huid(l_pTarget)); - - // build a FAPI type of target. - const fapi::Target l_fapi_pTarget( TARGET_TYPE_PROC_CHIP, - (const_cast<TARGETING::Target*>(l_pTarget)) ); - - // call the HWP with each fapi::Target - FAPI_INVOKE_HWP( l_errl, proc_pcie_config, l_fapi_pTarget ); - - if ( l_errl ) - { - // capture the target data in the elog - ErrlUserDetailsTarget(l_pTarget).addToLog( l_errl ); - - // Create IStep error log and cross reference to error that occurred - l_stepError.addErrorDetails( l_errl ); - - // Commit Error - errlCommit( l_errl, HWPF_COMP_ID ); - - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "ERROR : proc_pcie_config" ); - - break; - } - else - { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "SUCCESS : proc_pcie_config" ); - } - } - - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "call_proc_pcie_config exit" ); - - // end task, returning any errorlogs to IStepDisp - return l_stepError.getErrorHandle(); -} - - - // // Wrapper function to call proc_exit_cache_contained // diff --git a/src/usr/hwpf/hwp/dram_initialization/dram_initialization.H b/src/usr/hwpf/hwp/dram_initialization/dram_initialization.H index 935b3824d..87f752e97 100644 --- a/src/usr/hwpf/hwp/dram_initialization/dram_initialization.H +++ b/src/usr/hwpf/hwp/dram_initialization/dram_initialization.H @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/usr/hwpf/hwp/dram_initialization/dram_initialization.H $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_initialization/dram_initialization.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __DRAM_INITIALIZATION_DRAM_INITIALIZATION_H #define __DRAM_INITIALIZATION_DRAM_INITIALIZATION_H @@ -68,26 +67,26 @@ * @} * @{ * @substepnum 4 - * @substepname mss_scrub - * @substepdesc : Start background scrub + * @substepname mss_thermal_init + * @substepdesc : Initialize the thermal sensor * @target_sched serial * @} * @{ * @substepnum 5 - * @substepname mss_thermal_init - * @substepdesc : Initialize the thermal sensor + * @substepname proc_pcie_config + * @substepdesc : Configure the PHBs * @target_sched serial * @} * @{ * @substepnum 6 - * @substepname proc_setup_bars - * @substepdesc : Setup Memory BARs + * @substepname mss_power_cleanup + * @substepdesc : Clean up any MCS/Centuars * @target_sched serial * @} * @{ * @substepnum 7 - * @substepname proc_pcie_config - * @substepdesc : Configure the PHBs + * @substepname proc_setup_bars + * @substepdesc : Setup Memory BARs * @target_sched serial * @} * @{ @@ -146,60 +145,55 @@ void* call_mss_extent_setup( void *io_pArgs ); */ void* call_mss_memdiag( void *io_pArgs ); + /** - * @brief mss_scrub + * @brief mss_thermal_init * - * Start background scrub + * Initialize the thermal sensor * * param[in,out] - pointer to any arguments, usually NULL * * return pointer to any errlogs * */ -void* call_mss_scrub( void *io_pArgs ); - - +void* call_mss_thermal_init( void *io_pArgs ); /** - * @brief mss_thermal_init + * @brief proc_pcie_config * - * Initialize the thermal sensor + * Configure the PHBs * * param[in,out] - pointer to any arguments, usually NULL * * return pointer to any errlogs * */ -void* call_mss_thermal_init( void *io_pArgs ); - - +void* call_proc_pcie_config( void *io_pArgs ); /** - * @brief proc_setup_bars + * @brief mss_power_cleanup * - * Setup Memory BARs + * Clean up any MCS/Centaurs * * param[in,out] - pointer to any arguments, usually NULL * * return pointer to any errlogs * */ -void* call_proc_setup_bars( void *io_pArgs ); - +void* call_mss_power_cleanup( void *io_pArgs ); /** - * @brief proc_pcie_config + * @brief proc_setup_bars * - * Configure the PHBs + * Setup Memory BARs * * param[in,out] - pointer to any arguments, usually NULL * * return pointer to any errlogs * */ -void* call_proc_pcie_config( void *io_pArgs ); - +void* call_proc_setup_bars( void *io_pArgs ); /** diff --git a/src/usr/hwpf/hwp/dram_initialization/makefile b/src/usr/hwpf/hwp/dram_initialization/makefile index 6f0e9461d..e796a8c23 100644 --- a/src/usr/hwpf/hwp/dram_initialization/makefile +++ b/src/usr/hwpf/hwp/dram_initialization/makefile @@ -34,6 +34,8 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/bus_training +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/cen_stopclocks + ## NOTE: add the base istep dir here. EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization @@ -50,6 +52,8 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/host_mpipl_servi EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/mss_thermal_init EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp/dram_initialization/mss_memdiag EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_config/ +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/mss_power_cleanup + ## NOTE: add new object files when you add a new HWP OBJS = dram_initialization.o \ @@ -61,7 +65,8 @@ OBJS = dram_initialization.o \ proc_pcie_config.o \ proc_mpipl_ex_cleanup.o \ proc_mpipl_chip_cleanup.o \ - mss_thermal_init.o + mss_thermal_init.o \ + mss_power_cleanup.o ## NOTE: add a new directory onto the vpaths when you add a new HWP @@ -74,6 +79,7 @@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/mss_memdiag VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/proc_pcie_config VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/host_mpipl_service VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/mss_thermal_init +VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/mss_power_cleanup include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/dram_initialization/mss_power_cleanup/mss_power_cleanup.C b/src/usr/hwpf/hwp/dram_initialization/mss_power_cleanup/mss_power_cleanup.C new file mode 100644 index 000000000..c1fdfe800 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_initialization/mss_power_cleanup/mss_power_cleanup.C @@ -0,0 +1,393 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_initialization/mss_power_cleanup/mss_power_cleanup.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_power_cleanup.C,v 1.4 2013/11/22 04:53:06 bellows Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_power_cleanup.C,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2012 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : mss_power_cleanup +// *! DESCRIPTION : see additional comments below +// *! OWNER NAME : Mark Bellows Email: bellows@us.ibm.com +// *! BACKUP NAME : Anuwat Saetow Email: asaetow@us.ibm.com + +// *! ADDITIONAL COMMENTS : +// +// power clean up +// needs to deconfig centaurs and mba - (needs three targets) +// Two reasons: centaur is bad and no DIMMs +// Needed to set up fences and turn off power / clock drivers +// +// There is a sub function that cleans up an mba that needs to be called if we deconfigure an mba +// this procedure does not write attributes just shuts down hardware +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.4 |bellows |21-Nov-13| Gerrit Review Updates - unused variable removed +// 1.3 |bellows |11-Nov-13| Gerrit Review Updates +// 1.2 |bellows |11-Nov-13| Update due to new istep location +// 1.1 |bellows |07-Nov-13| copied from mss_cnfg_cleanup version 1.3 +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// My Includes +//------------------------------------------------------------------------------ +#include "cen_stopclocks.H" +#include "mss_power_cleanup.H" +#include "cen_scom_addresses.H" +#include "mss_eff_config.H" +#include "common_scom_addresses.H" + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <fapi.H> + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const uint8_t PORT_SIZE = 2; +const uint8_t DIMM_SIZE = 2; + + +//------------------------------------------------------------------------------ +// extern encapsulation +//------------------------------------------------------------------------------ +extern "C" +{ + fapi::ReturnCode mss_power_cleanup_centaur(const fapi::Target & i_target_centaur); + fapi::ReturnCode mss_power_cleanup_mba_part1(const fapi::Target & i_target_centaur, const fapi::Target & i_target_mba); + fapi::ReturnCode mss_power_cleanup_mba_fence(const fapi::Target & i_target_centaur, const fapi::Target & i_target_mba0, const fapi::Target & i_target_mba1 ); + + fapi::ReturnCode mss_power_cleanup_mba(const fapi::Target & i_target_mba); // clean up an mba + +//------------------------------------------------------------------------------ +// @brief mss_power_cleanup(): This function will disable a centaur - fencing it and powering it down +// +// @param const fapi::Target i_target_centaur: the fapi target of the centaur +// @param const fapi::Target i_target_mba0: the mba0 target +// @param const fapi::Target i_target_mba1: the mba1 target +// +// @return fapi::ReturnCode +//------------------------------------------------------------------------------ + fapi::ReturnCode mss_power_cleanup(const fapi::Target & i_target_centaur, const fapi::Target & i_target_mba0, const fapi::Target & i_target_mba1) + { + fapi::ReturnCode rc; + + FAPI_INF("Running mss_power_cleanupon %s\n", i_target_centaur.toEcmdString()); + + do { + rc = mss_power_cleanup_mba_part1(i_target_centaur, i_target_mba0); + if(rc) break; + rc = mss_power_cleanup_mba_part1(i_target_centaur, i_target_mba1); + if(rc) break; + + rc = mss_power_cleanup_mba_fence(i_target_centaur, i_target_mba0, i_target_mba1); + if(rc) break; + + rc = mss_power_cleanup_centaur(i_target_centaur); + if(rc) break; + + + /* need to add code that fences and centaur and powers off clocks */ + } while(0); + + return rc; + } // end mss_power_cleanup() + + fapi::ReturnCode set_powerdown_bits(int mba_functional, ecmdDataBufferBase &data_buffer_64) { + fapi::ReturnCode rc; + uint32_t rc_num = 0; + + if(mba_functional == 0) { + FAPI_INF("set_powerdown_bits MBA not Functional"); + rc_num |= data_buffer_64.setBit(0 +48); // MASTER_PD_CNTL (48) + rc_num |= data_buffer_64.setBit(1 +48); // ANALOG_INPUT_STAB2 (49) + rc_num |= data_buffer_64.setBit(7 +48); // ANALOG_INPUT_STAB1 (55) + rc_num |= data_buffer_64.setBit(8 +48,2); // SYSCLK_CLK_GATE (56:57) + rc_num |= data_buffer_64.setBit(10 +48); // DP18_RX_PD(0) (58) + rc_num |= data_buffer_64.setBit(11 +48); // DP18_RX_PD(1) (59) + rc_num |= data_buffer_64.setBit(14 +48); // TX_TRISTATE_CNTL (62) + rc_num |= data_buffer_64.setBit(15 +48); // VCC_REG_PD (63) + } + else { + rc_num |= data_buffer_64.clearBit(0 +48); // MASTER_PD_CNTL (48) + rc_num |= data_buffer_64.clearBit(1 +48); // ANALOG_INPUT_STAB2 (49) + rc_num |= data_buffer_64.clearBit(7 +48); // ANALOG_INPUT_STAB1 (55) + rc_num |= data_buffer_64.clearBit(8 +48,2); // SYSCLK_CLK_GATE (56:57) + rc_num |= data_buffer_64.clearBit(10 +48); // DP18_RX_PD(0) (58) + rc_num |= data_buffer_64.clearBit(11 +48); // DP18_RX_PD(1) (59) + rc_num |= data_buffer_64.clearBit(14 +48); // TX_TRISTATE_CNTL (62) + rc_num |= data_buffer_64.clearBit(15 +48); // VCC_REG_PD (63) + } + + if (rc_num) { + FAPI_ERR( "Error setting up buffers"); + rc.setEcmdError(rc_num); + } + + return rc; + } + + fapi::ReturnCode mss_power_cleanup_mba_part1(const fapi::Target & i_target_centaur, const fapi::Target & i_target_mba) { + // turn off functional vector + fapi::ReturnCode rc; + uint8_t mba_functional; + ecmdDataBufferBase data_buffer_64(64); + uint32_t rc_num = 0; + uint8_t unit_pos = 0; + ecmdDataBufferBase cfam_data(32); + int memon=0; + + do + { + FAPI_INF("Starting mss_power_cleanup_mba_part1"); + rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL, &i_target_mba, mba_functional); + if(rc) { FAPI_ERR("ERROR: Cannot get ATTR_FUNCTIONAL"); break; } + FAPI_INF("working on an mba whose functional is %d", mba_functional); + +// But to clarify so there's no misconception, you can only turn off the clocks to the MEMS grid (Ports 2/3). If you want to deconfigure Ports 0/1, there is no way to turn those clocks off. The best you can do there is shut down the PHY inside DDR (I think they have an ultra low power mode where you can turn off virtually everything including their PLLs, phase rotators, analogs , FIFOs, etc) plus of course you can disable their I/O. I think those steps should be done no matter which port you're deconfiguring, but in terms of the chip clock grid, you only get that additional power savings in the bad Port 2/3 case. + if(mba_functional == 0) { + FAPI_INF("cleanup_part1 MBA not functional"); + // check that clocks are up to the DDR partition before turning it off + // this case will only happen if we get memory up and later come back and want to + // deconfigure it. The first time, it may not even be up yet. + rc = fapiGetScom(i_target_centaur, TP_CLK_STATUS_0x01030008, data_buffer_64); + if(rc) { FAPI_ERR("ERROR: Cannot getScom 0x1030008"); break; } + if(data_buffer_64.getDoubleWord(0) == 0x000007FFFFFFFFFFull) { // pervasive clocks are on + rc = fapiGetScom(i_target_centaur, MEM_CLK_STATUS_0x03030008, data_buffer_64); + if(rc) { FAPI_ERR("ERROR: Cannot getScom 0x3030008"); break; } + if(data_buffer_64.getDoubleWord(0) == 0x0000001FFFFFFFFFull) { + memon=1; + } + } + + + if(memon) { + FAPI_INF("Mem Clocks On"); + + if(mba_functional == 0) { + + FAPI_INF("This mba is not functional, doing more transactions"); + + // Do Port 0 + rc = fapiGetScom(i_target_mba, DPHY01_DDRPHY_PC_POWERDOWN_1_P0_0x8000C0100301143F, data_buffer_64); + if(rc) { FAPI_ERR("ERROR: Cannot getScom DPHY01_DDRPHY_PC_POWERDOWN_1_P0_0x8000C0100301143F"); break; } + + rc = set_powerdown_bits(mba_functional, data_buffer_64); + if(rc) break; + + rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_PC_POWERDOWN_1_P0_0x8000C0100301143F, data_buffer_64); + if(rc) { FAPI_ERR("ERROR: Cannot putScom DPHY01_DDRPHY_PC_POWERDOWN_1_P0_0x8000C0100301143F"); break; } + + // Do Port 1 + rc = fapiGetScom(i_target_mba, DPHY01_DDRPHY_PC_POWERDOWN_1_P1_0x8001C0100301143F, data_buffer_64); + if(rc) { FAPI_ERR("ERROR: Cannot getScom DPHY01_DDRPHY_PC_POWERDOWN_1_P1_0x8001C0100301143F"); break; } + + rc = set_powerdown_bits(mba_functional, data_buffer_64); + if(rc) break; + + rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_PC_POWERDOWN_1_P1_0x8001C0100301143F, data_buffer_64); + if(rc) { FAPI_ERR("ERROR: Cannot putScom DPHY01_DDRPHY_PC_POWERDOWN_1_P1_0x8001C0100301143F"); break; } +// From Section 10.4 + } // mba functional + } +//12. Grid Clock off , South Port Pair. This is done by asserting the GP bit controlling +//TP_CHIP_DPHY23_GRID_DISABLE (Table 57 ). This must be decided during CFAMINIT . it may not be +//dynamically updated + rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target_mba, unit_pos); // 0 = MBA01 and 1 = MBA23 + if(rc) { FAPI_ERR("ERROR: Cannot get ATTR_CHIP_UNIT_POS"); break; } + + if(unit_pos == 1) { + rc = fapiGetCfamRegister( i_target_centaur, CFAM_FSI_GP4_0x00001013, cfam_data); + if(rc) { FAPI_ERR("ERROR: Cannot getCfamRegister CFAM_FSI_GP4_0x00001013"); break; } + + if(mba_functional == 0) { + rc_num |= cfam_data.setBit(1); + } + else { + rc_num |= cfam_data.clearBit(1); + } + + if (rc_num) { + FAPI_ERR( "Error setting up buffers"); + rc.setEcmdError(rc_num); + break; + } + + rc = fapiPutCfamRegister( i_target_centaur, CFAM_FSI_GP4_0x00001013, cfam_data); + if(rc) { FAPI_ERR("ERROR: Cannot putCfamRegister CFAM_FSI_GP4_0x00001013"); break; } + } // mba 1 only code + + } + } + while(0); + + if(rc) { FAPI_ERR("ERROR: Bad RC in mss_power_cleanup_mba_part1"); } + return rc; + } // end of mss_power_cleanup_mba_part1 + + fapi::ReturnCode mss_power_cleanup_mba_fence(const fapi::Target & i_target_centaur, const fapi::Target & i_target_mba0, const fapi::Target & i_target_mba1) { + // turn off functional vector + fapi::ReturnCode rc; + uint8_t mba_functional0, mba_functional1; + ecmdDataBufferBase data_buffer_64(64); + uint32_t rc_num = 0; + ecmdDataBufferBase cfam_data(32); + int memon=0; + + do + { + FAPI_INF("Starting mss_power_cleanup_mba_fence"); + rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL, &i_target_mba0, mba_functional0); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL, &i_target_mba1, mba_functional1); + if(rc) break; + FAPI_INF("mba0 functional is %d", mba_functional0); + FAPI_INF("mba1 functional is %d", mba_functional1); + + +//enable_partial_good_dc memn_fence_dc mems_fence_dc Fencing Behavior +//0 0 0 Normal operation, no fencing enabled +//0 1 1 Chiplet boundary (inter chiplet nets) fencing enabled. Both +// bits set for full fencing. Both MBAs fenced from MBS but +// not from each other +//0 0 1 Not a valid setting. Fencing enabled for MEMS chiplet boundary only. +//0 1 0 Not a valid setting. Fencing enabled for MEMS chiplet boundary only. +//1 0 0 No Fencing enabled . +//1 0 1 MEMS (Ports 2/3) bad, fencing enabled to MEMN and at chiplet boundary of MEMS +//1 1 0 MEMN (Ports 0/1) bad, fencing enabled to MEMS and at chiplet boundary of MEMN +//1 1 1 Fencing enabled between MEMN and MEMS and at chiplet boundary. + rc = fapiGetScom(i_target_centaur, TP_CLK_STATUS_0x01030008, data_buffer_64); + if(rc) break; + if(data_buffer_64.getDoubleWord(0) == 0x000007FFFFFFFFFFull) { // pervasive clocks are on + rc = fapiGetScom(i_target_centaur, MEM_CLK_STATUS_0x03030008, data_buffer_64); + if(rc) break; + if(data_buffer_64.getDoubleWord(0) == 0x0000001FFFFFFFFFull) { + memon=1; + } + } + + if(memon) { + FAPI_INF("Mem Clocks On"); + rc = fapiGetScom( i_target_centaur, MEM_GP3_0x030F0012, data_buffer_64); + if (rc) break; + + if(mba_functional0 == 0 || mba_functional1 == 0) { // one of the two are non-functional + rc_num |= data_buffer_64.setBit(31); // enable_partial_good_dc + } + else { + rc_num |= data_buffer_64.clearBit(31); + } + + if(mba_functional0 == 0) { + rc_num |= data_buffer_64.setBit(18); // memn_fence_dc + } + else { + rc_num |= data_buffer_64.clearBit(18); // memn_fence_dc + } + if(mba_functional1 == 0) { + rc_num |= data_buffer_64.setBit(17); // mems_fence_dc + } + else { + rc_num |= data_buffer_64.clearBit(17); // mems_fence_dc + } + + if (rc_num) { + FAPI_ERR( "Error setting up buffers"); + rc.setEcmdError(rc_num); + break; + } + + rc = fapiPutScom( i_target_centaur, MEM_GP3_0x030F0012, data_buffer_64); + if (rc) break; + } + + + } while(0); + + if(rc) { FAPI_ERR("ERROR: during mss_power_cleanup_mba_fence"); } + return rc; + } // end of mss_power_cleanup_mba_fense + + fapi::ReturnCode mss_power_cleanup_centaur(const fapi::Target & i_target_centaur) { + // turn off functional vector + fapi::ReturnCode rc; + uint8_t centaur_functional; + + do + { + FAPI_INF("Starting mss_power_cleanup_centaur"); + rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL, &i_target_centaur, centaur_functional); + if(rc) { FAPI_ERR("ERROR: Cannot get ATTR_FUNCTIONAL"); break; } + + int memon=0; + int pervon=0; + ecmdDataBufferBase data_buffer_64(64); + + if(centaur_functional == 0) { + // check that clocks are up to the DDR partition before turning it off + // this case will only happen if we get memory up and later come back and want to + // deconfigure it. The first time, it may not even be up yet. + rc = fapiGetScom(i_target_centaur, TP_CLK_STATUS_0x01030008, data_buffer_64); + if(rc) { FAPI_ERR("ERROR: Cannot getScom 0x1030008"); break; } + if(data_buffer_64.getDoubleWord(0) == 0x000007FFFFFFFFFFull) { // pervasive clocks are on + pervon=1; + rc = fapiGetScom(i_target_centaur, MEM_CLK_STATUS_0x03030008, data_buffer_64); + if(rc) { FAPI_ERR("ERROR: Cannot getScom 0x3030008"); break; } + if(data_buffer_64.getDoubleWord(0) == 0x0000001FFFFFFFFFull) { + memon=1; + } + } + + + if(pervon || memon) { + bool l_stop_mem_clks=true; + bool l_stop_nest_clks=true; + bool l_stop_dram_rfrsh_clks=true; + bool l_stop_tp_clks=false; + bool l_stop_vitl_clks=false; + FAPI_INF("Calling cen_stopclocks"); + rc = cen_stopclocks(i_target_centaur, l_stop_mem_clks, l_stop_nest_clks, l_stop_dram_rfrsh_clks, l_stop_tp_clks, l_stop_vitl_clks ); + + } // clocks are on, so kill them + } // non functional centaurs + FAPI_INF("Ending mss_power_cleanup_centaur"); + } + while(0); + + if(rc) { FAPI_ERR("ERROR: Bad RC in mss_power_cleanup_centaur"); } + return rc; + } // end of mss_power_cleanup_centaur + + +} // extern "C" + diff --git a/src/usr/hwpf/hwp/dram_initialization/mss_power_cleanup/mss_power_cleanup.H b/src/usr/hwpf/hwp/dram_initialization/mss_power_cleanup/mss_power_cleanup.H new file mode 100644 index 000000000..43c5bc492 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_initialization/mss_power_cleanup/mss_power_cleanup.H @@ -0,0 +1,91 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_initialization/mss_power_cleanup/mss_power_cleanup.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_power_cleanup.H,v 1.2 2013/11/14 16:55:43 bellows Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_power_cleanup.H,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2012 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : mss_power_cleanup.H +// *! DESCRIPTION : Header file for mss_eff_config. +// *! OWNER NAME : Mark Bellows Email: bellows@us.ibm.com +// *! BACKUP NAME : Anuwat Saetow Email: asaetow@us.ibm.com +// *! ADDITIONAL COMMENTS : +// +// +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.2 |bellows |11-Nov-13| Gerrit Review Comments +// 1.1 |bellows |07-Nov-13| copied from mss_cnfg_cleanup.H version 1.2 +//------------------------------------------------------------------------------ + + +#ifndef mss_power_cleanup_H_ +#define mss_power_cleanup_H_ + +//------------------------------------------------------------------------------ +// My Includes +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <fapi.H> + +typedef fapi::ReturnCode (*mss_power_cleanup_FP_t)(const fapi::Target & i_target_centaur, + const fapi::Target & i_target_mba0, const fapi::Target & i_target_mba1); +typedef fapi::ReturnCode (*mss_power_cleanup_mba_FP_t)( const fapi::Target & i_target_mba); + +extern "C" { + +//------------------------------------------------------------------------------ +// @brief mss_power_cleanup(): Clean up a centaur and also MBAs, also calls the mba cleanup under the covers +// +// @param const fapi::Target i_target_centaur: the centaur +// @param const fapi::Target i_target_mba0: the mba0 +// @param const fapi::Target i_target_mba1: the mba1 +// +// @return fapi::ReturnCode +//------------------------------------------------------------------------------ +fapi::ReturnCode mss_power_cleanup(const fapi::Target & i_target_centaur, + const fapi::Target & i_target_mba0, const fapi::Target & i_target_mba1); +//------------------------------------------------------------------------------ +// @brief mss_power_cleanup_mba(): Clean up a centaur and also MBAs +// +// @param const fapi::Target i_target_mba0: the mba0 +// +// @return fapi::ReturnCode +//------------------------------------------------------------------------------ +fapi::ReturnCode mss_power_cleanup_mba(const fapi::Target & i_target_mba); // clean up an mba + +} // extern "C" + +#endif // mss_power_cleanup_H + diff --git a/src/usr/hwpf/hwp/dram_training/cen_stopclocks/cen_stopclocks.C b/src/usr/hwpf/hwp/dram_training/cen_stopclocks/cen_stopclocks.C new file mode 100644 index 000000000..fea1632da --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/cen_stopclocks/cen_stopclocks.C @@ -0,0 +1,1174 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/cen_stopclocks/cen_stopclocks.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: cen_stopclocks.C,v 1.15 2013/10/16 14:39:32 mfred Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/cen_stopclocks.C,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2011 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : cen_stopclocks +// *! DESCRIPTION : see additional comments below +// *! OWNER NAME : Mark Fredrickson Email: mfred@us.ibm.com +// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com +// *! SCREEN : pervasive_screen +// *! ADDITIONAL COMMENTS : +// +// The purpose of this procedure is to stop the clocks in the Centaur chip +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <cen_scom_addresses.H> +#include <cen_stopclocks.H> + +//------------------------------------------------------------------------------ +// Constant definitions +//------------------------------------------------------------------------------ +// CFAM FSI GP4 register bit/field definitions +const uint8_t FSI_GP4_MEMRESET_STABILITY_BIT = 2; +const uint8_t FSI_GP4_DPHY_PLLRESET_BIT = 4; + +// PERVGP3 register bit/field definitions +const uint8_t PERVGP3_VITL_CLKOFF_BIT = 16; + +// GP3 register bit/field definitions +const uint8_t GP3_VITAL_THOLD_BIT = 16; +const uint8_t GP3_FENCE_EN_BIT = 18; +const uint8_t GP3_EDRAM_ENABLE_BIT = 28; + +// GP0 register bit/field definitions +const uint8_t GP0_SYNCCLK_MUXSEL_BIT = 1; +const uint8_t GP0_FLUSHMODE_INHIBIT_BIT = 2; +const uint8_t GP0_FORCE_ALIGN_BIT = 3; +const uint8_t GP0_SCAN_DIS_DC_B_BIT = 6; +const uint8_t GP0_ABIST_MODE_BIT = 11; +const uint8_t GP0_PERV_FENCE_BIT = 63; + +// FSIGP3 register bit/field definitions +const uint8_t FSIGP3_PIB2PCB_BYPASS_BIT = 20; +const uint8_t FSIGP3_FSI_FENCE4_BIT = 25; +const uint8_t FSIGP3_FSI_FENCE5_BIT = 26; + +// Global bit definitions for all CLK_REGIONS +const uint8_t CLK_REGION_CLOCK_CMD_BIT = 0; +const uint8_t CLK_REGION_CLOCK_CMD_LEN = 2; +const uint8_t CLK_REGION_CLOCK_CMD_STOP = 2; + +const uint8_t TP_CLK_STAT_NET_SL = 3; +const uint8_t TP_CLK_STAT_NET_NSL = 4; +const uint8_t TP_CLK_STAT_NET_ARY = 5; +const uint8_t TP_CLK_STAT_PIB_SL = 6; +const uint8_t TP_CLK_STAT_PIB_NSL = 7; +const uint8_t TP_CLK_STAT_PIB_ARY = 8; + + +// Clock Region Register clock stop data patterns +// const uint64_t CLK_REGION_REG_DATA_TO_STOP_NSL_ARY = 0x8FE0060000000000ull; +const uint64_t CLK_REGION_REG_DATA_TO_STOP_ALL = 0x8FE00E0000000000ull; +// const uint64_t CLK_REGION_STOP_NSL_ARY_W_REFRESH = 0x8FC0060000000000ull; +const uint64_t CLK_REGION_STOP_ALL_BUT_REFRESH = 0x8FC00E0000000000ull; +const uint64_t EXPECTED_CLOCK_STATUS = 0xFFFFFFFFFFFFFFFFull; +const uint64_t EXPECTED_CLOCK_STATUS_W_REFRESH = 0xFFFFFF1FFFFFFFFFull; // Bits 24,25,26 should be OFF for refresh clocks to be active. + +// Expected CLK_STAT after execution of stopclocks +const uint32_t FSI_SHIFT_SET_PULSE_LENGTH = 0x0000000F; + + + + +extern "C" { + +using namespace fapi; + +//------------------------------------------------------------------------------ +// Function definition: cen_stopclocks +// parameters: i_target => chip target +// i_stop_mem_clks => True to stop MEM chiplet clocks (should default TRUE) +// i_stop_nest_clks => True to stop NEST chiplet clocks (except DRAM refresh clk) (should default TRUE) +// i_stop_dram_rfrsh_clks => True to stop NEST chiplet DRAM refresh clocks (cache) (should default FALSE) +// i_stop_tp_clks => True to stop PERVASIVE (TP) chiplet clocks (should default FALSE) +// i_stop_vitl_clks => True to stop PERVASIVE VITL clocks (should default FALSE) +// returns: FAPI_RC_SUCCESS if operation was successful, else error +//------------------------------------------------------------------------------ +fapi::ReturnCode cen_stopclocks(const fapi::Target & i_target, + const bool i_stop_mem_clks, + const bool i_stop_nest_clks, + const bool i_stop_dram_rfrsh_clks, + const bool i_stop_tp_clks, + const bool i_stop_vitl_clks) +{ + // Target is centaur chip + + bool i2_stop_mem_clks; + bool i2_stop_nest_clks; + fapi::ReturnCode rc; + uint32_t rc_ecmd = 0; + ecmdDataBufferBase scom_data(64); + ecmdDataBufferBase cfam_data(32); + + FAPI_INF("********* cen_stopclocks start *********"); + do + { + // The instructions for coding this procedure came from Tobias Webel's Common POR Spreadsheet step 30.1 + // Start with instructions common to all eclipz chips + + // Set flushmode_inhibit in Chiplet GP0 + // Set force_align in Chiplet GP0 + // Write ClockControl, Scan Region Register, set all bits to zero prior clock stop + // Write ClockControl, Clock Region Register, Clock Stop command (arrays + nsl only, not refresh clock region) MEM chiplet + // Write ClockControl, Clock Region Register, Clock Stop command (sl + refresh clock region) MEM chiplet + // Read Clock Status Register (MEM chiplet) + // Write ClockControl, Clock Region Register, Clock Stop command (arrays + nsl only, not refresh clock region) NEST chiplet + // Write ClockControl, Clock Region Register, Clock Stop command (sl + refresh clock region) NEST chiplet + // Read Clock Status Register (NEST chiplet) + // Reset MemReset Stablilty Control + // Reset D3PHY PLL Control (Reset all PLLs) + // reset abist_mode_dc for core chiplets (core recovery) + // set synclk_muxsel (io_clk_sel) + // assert perv fence GP0.63 + // GP3(28) disable EDRAM (just chiplets with EDRAM logic)(skip this step if refresh clock domain stays running) + // assert fence GP3.18 + + // The following instructions were added by Jeshua Smith to put each chiplet in a good state for scanning: + // Set tc_scan_dis_dc_b to a '1' in each chiplet to allow rings to be scanned. + // TODO - compare these instructions agains the P7+ procedure to see if we are missing anything. + + // Note: This procedure should not do multicast to do all non-perv chiplets at the same time because the user could + // wish to skip some of the chiplets! + + + + + //----------------- + // Check options, VITL clock and PCB fabric clocks. @@@ + //----------------- + + i2_stop_mem_clks = i_stop_mem_clks; + i2_stop_nest_clks = i_stop_nest_clks; + + // Before attempting to stop the clocks in any chiplet, check to see that the pervasive VITL clocks are running. + // Do this by checking bit 16 of the PERV GP3 register. + FAPI_DBG("Checking PERV GPP3 Register bit 16 to see if the VITL clock is ON."); + rc = fapiGetCfamRegister(i_target, CFAM_FSI_GP3_MIRROR_0x0000101B, cfam_data); + if (rc) + { + FAPI_ERR("Error getting PERV GP3 via CFAM"); + break; + } + if (cfam_data.isBitSet(PERVGP3_VITL_CLKOFF_BIT)) + { + // The Pervasive VITL clock is OFF. So we cannot talk to the chiplets. There is nothing left to do, so just return. + FAPI_INF("The Pervasive VITL clock is OFF. The procedure cannot access the chiplets or check other clocks."); + break; + } + + // If we have gotten this far the Pervasive VITL clock must be ON. + // Check to see if the PCB fabric clocks are running. + // Do this by checking the PIB and NET clock regions in the TP chiplet (chiplet 01). + // Read Clock Status Register (TP chiplet) 0x0100008 + // Bits 3-8 should be ZERO if the PIB and NET clocks are running. + FAPI_DBG("Reading Clock Status Register in the TP chiplet to see if PIB and NET clocks are running. Bits 3-8 should be zero."); + rc = fapiGetScom( i_target, TP_CLK_STATUS_0x01030008, scom_data); + if (rc) + { + FAPI_ERR("Error reading TP chiplet Clock Status Register."); + break; + } + if ( scom_data.isBitSet(TP_CLK_STAT_NET_SL) || + scom_data.isBitSet(TP_CLK_STAT_NET_NSL) || + scom_data.isBitSet(TP_CLK_STAT_NET_ARY) || + scom_data.isBitSet(TP_CLK_STAT_PIB_SL) || + scom_data.isBitSet(TP_CLK_STAT_PIB_NSL) || + scom_data.isBitSet(TP_CLK_STAT_PIB_ARY) ) + { + // At least one of the NET or PIB clocks is NOT running. + FAPI_INF("At least one of the NET or PIB clocks is NOT running. May not be able to use the PCB fabric to access chiplets."); + FAPI_INF("Procedure will not attempt to turn off clocks in the individual chiplets.."); + i2_stop_mem_clks = false; + i2_stop_nest_clks = false; + } + + FAPI_INF(" Input parameters: "); + FAPI_INF(" stop_mem_clks = %s", i2_stop_mem_clks ? "true":"false"); + FAPI_INF(" stop_nest_clks = %s", i2_stop_nest_clks ? "true":"false"); + FAPI_INF(" stop_dram_rfrsh_clks = %s", i_stop_dram_rfrsh_clks ? "true":"false"); + FAPI_INF(" stop_tp_clks = %s", i_stop_tp_clks ? "true":"false"); + FAPI_INF(" stop_vitl_clks = %s", i_stop_vitl_clks ? "true":"false"); + + if ((!i2_stop_mem_clks) && + (!i2_stop_nest_clks) && + (!i_stop_tp_clks) && + (!i_stop_vitl_clks)) + { + FAPI_INF("Specified input options are set to skip both the NEST and MEM chiplets, so there is nothing to do. Returning.\n"); + break; + } + + if ((!i2_stop_nest_clks) && (i_stop_dram_rfrsh_clks)) + { + FAPI_INF("Specified input options are incompatible.\n"); + FAPI_INF("This procedure cannot stop the DRAM refresh clocks unless the NEST clocks are being stopped..\n"); + break; + } + + + + //----------------- + // MEM Chiplet @@@ 03 + //----------------- + if ( i2_stop_mem_clks ) + { + // FW team requested that we check to see if the vital clock region is running before stopping the clocks. + // If the vital clocks are not running, then other clocks are not running either, so we are done. + // If the vital clocks are running, then we should be able to access the necessary registers to stop the other clocks. + FAPI_DBG("Reading GP3 Register, bit 16, to see if VITAL clocks are running."); + rc = fapiGetScom( i_target, MEM_GP3_0x030F0012, scom_data); + if (rc) + { + FAPI_ERR("Error reading GP3 register in attempt to verify that VITAL clocks are running."); + break; + } + if (scom_data.isBitSet(GP3_VITAL_THOLD_BIT)) + { + // The VITAL thold is asserted, so no clocks are running in this chiplet. Nothing left to do, so just return. + FAPI_INF("The VITAL clocks are not running for this chiplet, so all other clocks should be already stopped."); + } + else + { + + // Start with instructions common to eclipz chips + + // Set flushmode_inhibit in Chiplet GP0 + // multicast address "0x[xx]00 0005 WOR codepoint" Data: bit(2) = 0b1 (0x2000 0000 0000 0000) + // MEM_GP0_OR_0x03000005 + FAPI_DBG("Setting flushmode_inhibit in MEM chiplet GP0 Register (bit 2).\n"); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_FLUSHMODE_INHIBIT_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set flushmode_inhibit in MEM chiplet GP0 Register.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, MEM_GP0_OR_0x03000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing GP0 registers in MEM chiplet to set flushmode inhibit (bit 2)."); + break; + } + + + // Set force_align in Chiplet GP0 + // multicast address "0x[xx]00 0005 WOR codepoint" Data: bit(3) = 0b1 (0x1000 0000 0000 0000) Cannot combine with previous step. + // MEM_GP0_OR_0x03000005 + FAPI_DBG("Setting force_align in MEM chiplet GP0 register (bit 3).\n"); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_FORCE_ALIGN_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to Set force_align in MEM chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, MEM_GP0_OR_0x03000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing GP0 registers in MEM chiplet to set force_align (bit 3)."); + break; + } + + + // Write ClockControl, Scan Region Register, set all bits to zero prior clock stop + // multicast address 0x[xx]03 0007 Data: 0x0000 0000 0000 0000 + // MEM_CLK_SCANSEL_0x03030007 + FAPI_DBG("Writing Clock Control Scan Region Register to all zeros in MEM chiplet prior clock stop.\n"); + rc_ecmd |= scom_data.flushTo0(); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to write CC Scan Region Register to all zeros..", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, MEM_CLK_SCANSEL_0x03030007, scom_data); + if (rc) + { + FAPI_ERR("Error writing CC Scan Region Registers in MEM chiplet."); + break; + } + + + // Now do Centaur-specific instructions + + + + // Write ClockControl, Clock Region Register, Clock Stop command for MEM chiplet + // 0x0303 0006 Data: 0x8FE00E0000000000 + // MEM_CLK_REGION_0x03030006 + FAPI_DBG("Writing Clock Control Clock Region Register in MEM chiplet to stop the clocks.\n"); + rc_ecmd |= scom_data.setDoubleWord(0, CLK_REGION_REG_DATA_TO_STOP_ALL); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set general clock stop command in MEM chiplet CC Clock Region Register.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, MEM_CLK_REGION_0x03030006, scom_data); + if (rc) + { + FAPI_ERR("Error writing MEM chiplet CC Clock Region Register to stop the clocks."); + break; + } + + + // Read Clock Status Register (MEM chiplet) + // 0x0303 0008 Data: expected value: 0xFFFF FFFF FFFF FFFF + // MEM_CLK_STATUS_0x03030008 + FAPI_DBG("Reading Clock Status Register in the MEM chiplet to see if clocks are stopped. Expected value = 0xFFFF FFFF FFFF FFFF.\n"); + rc = fapiGetScom( i_target, MEM_CLK_STATUS_0x03030008, scom_data); + if (rc) + { + FAPI_ERR("Error reading MEM chiplet Clock Status Register."); + break; + } + if ( scom_data.getDoubleWord(0) != EXPECTED_CLOCK_STATUS ) + { + FAPI_ERR("MEM chiplet clock status 0xFFFFFFFFFFFFFFFF was expected but read clock status = %16llX",scom_data.getDoubleWord(0)); + FAPI_SET_HWP_ERROR(rc, RC_MSS_UNEXPECTED_CLOCK_STATUS); + break; + } + else + { + FAPI_INF("Expected clock status was read in MEM chiplet after stopping the clocks: %016llX ", EXPECTED_CLOCK_STATUS); + } + + + + // Reset MemReset Stablilty Control + // CFAM 0x13 bit(02) = 0 + // CFAM_FSI_GP4_0x00001013 + FAPI_DBG("Clearing CFAM FSI GP4 Register, bit 2 to reset MemReset Stablilty Control.\n"); + rc = fapiGetCfamRegister( i_target, CFAM_FSI_GP4_0x00001013, cfam_data); + if (rc) + { + FAPI_ERR("Error reading CFAM FSI GP4 Register."); + break; + } + rc_ecmd |= cfam_data.clearBit(FSI_GP4_MEMRESET_STABILITY_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set MemReset Stability Control (FSI GP4 bit 2).", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutCfamRegister( i_target, CFAM_FSI_GP4_0x00001013, cfam_data); + if (rc) + { + FAPI_ERR("Error writing FSI GP4 Register to reset the MemReset Stability Control (bit2)."); + break; + } + + + // Reset D3PHY PLL Control (Reset all D3PHY PLLs) + // CFAM 0x13 bit(04) = 0 + // CFAM_FSI_GP4_0x00001013 + FAPI_DBG("Clearing CFAM FSI GP4 Register, bit 4 to reset D3PHY PLL Control (Reset all D3PHY PLLs).\n"); + rc = fapiGetCfamRegister( i_target, CFAM_FSI_GP4_0x00001013, cfam_data); + if (rc) + { + FAPI_ERR("Error reading CFAM FSI GP4 register."); + break; + } + rc_ecmd |= cfam_data.clearBit(FSI_GP4_DPHY_PLLRESET_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to reset the D3PHY PLLs .", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutCfamRegister( i_target, CFAM_FSI_GP4_0x00001013, cfam_data); + if (rc) + { + FAPI_ERR("Error writing FSI GP4 register to reset the D3PHY PLLs (by clearing bit 4)."); + break; + } + + + // Resume instructions that are common to eclipz chips. + + + // reset abist_mode_dc for core chiplets (core recovery) + // Does this make sense for Centaur? (Centaur has no cores.) + // Multicast address: "0x[xx]00 0004 WAND codepoint" Data: bit(11) = 0b0 0xFFEF FFFF FFFF FFFF + // MEM_GP0_AND_0x03000004 + FAPI_DBG("Clearing GP0 Register bit 11 in MEM chiplet to reset abist_mode_dc.\n"); + rc_ecmd |= scom_data.flushTo1(); + rc_ecmd |= scom_data.clearBit(GP0_ABIST_MODE_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to clear bit 11 of the GP0 registers in the MEM chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, MEM_GP0_AND_0x03000004, scom_data); + if (rc) + { + FAPI_ERR("Error writing the GP0 registers in the MEM chiplet to reset abist mode.."); + break; + } + + + // set synclk_muxsel (io_clk_sel) + // Multicast address: "0x[xx]00 0005 WOR codepoint" bit(1) = 0b1 0x4000 0000 0000 0000 + // MEM_GP0_OR_0x03000005 + // assert perv fence GP0.63 + // Multicast address: "0x[xx]00 0005 WOR codepoint" bit(63) = 0b1 0x4000 0000 0000 0001 (Can be combined with previous step) + // MEM_GP0_OR_0x03000005 + FAPI_DBG("Setting GP0 Register bit 1 in MEM chiplet to set synclk_muxsel (io_clk_sel).\n"); + FAPI_DBG("Setting GP0 Register bit 63 in MEM chiplet to assert the pervasive fence.\n"); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_SYNCCLK_MUXSEL_BIT); + rc_ecmd |= scom_data.setBit(GP0_PERV_FENCE_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set syncclk_muxsel and pervasive fence in GP0 registers..", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, MEM_GP0_OR_0x03000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing GP0 registers in MEM chiplet to set syncclk_muxsel and pervasive fence.."); + break; + } + + + // GP3(28) disable EDRAM (just chiplets with EDRAM logic) + // Note: This action is probably un-needed for the MEM chiplet since it does not contain any EDRAM. + // Multicast address: "0x[xx]0F 0013 WAND codepoint" bit(28) = 0b0 0xFFFF FFF7 FFFF FFFF + // MEM_GP3_AND_0x030F0013 + FAPI_DBG("Clearing GP3 Register bit 28 in MEM chiplet to disable any EDRAM.\n"); + rc_ecmd |= scom_data.flushTo1(); + rc_ecmd |= scom_data.clearBit(GP3_EDRAM_ENABLE_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to clear GP3(bit 28), to disable EDRAM in MEM chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, MEM_GP3_AND_0x030F0013, scom_data); + if (rc) + { + FAPI_ERR("Error writing GP3 Registers in MEM chiplet to disable any EDRAM."); + break; + } + + + // assert fence GP3.18 + // Multicast address: "0x[xx]0F 0014 WOR codepoint" bit(18) = 0b1 0x0000 2000 0000 0000 + // MEM_GP3_OR_0x030F0014 + FAPI_DBG("Setting GP3 Regsiter bit 18 in MEM chiplet to assert the fence.\n"); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP3_FENCE_EN_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set GP3(bit18) to assert the fence in the MEM chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, MEM_GP3_OR_0x030F0014, scom_data); + if (rc) + { + FAPI_ERR("Error writing GP3 registers in MEM chiplet to assert the fence."); + break; + } + + // Set scan_dis_dc_b bit in Chiplet GP0 + // unicast address "0x[xx]00 0005 WOR codepoint" Data: bit(6) = 0b1 (0x0200 0000 0000 0000) + // MEM_GP0_OR_0x03000005 + FAPI_DBG("Setting MEM chiplet GP0 Register bit 6 to set scan_dis_dc_b to allow for scanning."); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_SCAN_DIS_DC_B_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set scan_dis_dc_b in MEM chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, MEM_GP0_OR_0x03000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing MEM chiplet GP0 register to set scan_dis_dc_b for scanning."); + break; + } + } // End of stop clock operations that are done if the vital clock is running. + } // End of MEM chiplet code + + + //----------------- + // NEST Chiplet @@@ 02 + //----------------- + if ( i2_stop_nest_clks ) + { + // FW team requested that we check to see if the vital clock region is running before stopping the clocks. + // If the vital clocks are not running, then other clocks are not running either, so we are done. + // If the vital clocks are running, then we should be able to access the necessary registers to stop the other clocks. + FAPI_DBG("Reading GP3 Register, bit 16, to see if VITAL clocks are running."); + rc = fapiGetScom( i_target, NEST_GP3_0x020F0012, scom_data); + if (rc) + { + FAPI_ERR("Error reading GP3 register in attempt to verify that VITAL clocks are running."); + break; + } + if (scom_data.isBitSet(GP3_VITAL_THOLD_BIT)) + { + // The VITAL thold is asserted, so no clocks are running in this chiplet. Nothing left to do, so just return. + FAPI_INF("The VITAL clocks are not running for this chiplet, so all other clocks should be already stopped."); + } + else + { + + // Start with instructions common to eclipz chips + + // Set flushmode_inhibit in Chiplet GP0 + // multicast address "0x[xx]00 0005 WOR codepoint" Data: bit(2) = 0b1 (0x2000 0000 0000 0000) + // NEST_GP0_OR_0x02000005 + FAPI_DBG("Setting flushmode_inhibit in NEST chiplet GP0 Register (bit 2).\n"); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_FLUSHMODE_INHIBIT_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set flushmode_inhibit in NEST chiplet GP0 Register.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, NEST_GP0_OR_0x02000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing GP0 registers in NEST chiplet to set flushmode inhibit (bit 2)."); + break; + } + + + // Set force_align in Chiplet GP0 + // multicast address "0x[xx]00 0005 WOR codepoint" Data: bit(3) = 0b1 (0x1000 0000 0000 0000) Cannot combine with previous step. + // NEST_GP0_OR_0x02000005 + FAPI_DBG("Setting force_align in NEST chiplet GP0 register (bit 3).\n"); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_FORCE_ALIGN_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to Set force_align in NEST chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, NEST_GP0_OR_0x02000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing GP0 registers in NEST chiplet to set force_align (bit 3)."); + break; + } + + + // Write ClockControl, Scan Region Register, set all bits to zero prior clock stop + // multicast address 0x[xx]03 0007 Data: 0x0000 0000 0000 0000 + // NEST_CLK_SCANSEL_0x02030007 + FAPI_DBG("Writing Clock Control Scan Region Register to all zeros in NEST chiplet prior clock stop.\n"); + rc_ecmd |= scom_data.flushTo0(); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to write CC Scan Region Register to all zeros..", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, NEST_CLK_SCANSEL_0x02030007, scom_data); + if (rc) + { + FAPI_ERR("Error writing CC Scan Region Registers in NEST chiplet."); + break; + } + + + // Now do Centaur-specific instructions + + + + // Write ClockControl, Clock Region Register, Clock Stop command for NEST chiplet + // 0x0203 0006 Data: 0x8FE00E0000000000 + // NEST_CLK_REGION_0x02030006 + FAPI_DBG("Writing Clock Control Clock Region Register in NEST chiplet to stop the clocks.\n"); + if ( i_stop_dram_rfrsh_clks ) + { + rc_ecmd |= scom_data.setDoubleWord(0, CLK_REGION_REG_DATA_TO_STOP_ALL); + } + else + { + rc_ecmd |= scom_data.setDoubleWord(0, CLK_REGION_STOP_ALL_BUT_REFRESH ); + } + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set general clock stop command in NEST chiplet CC Clock Region Register.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, NEST_CLK_REGION_0x02030006, scom_data); + if (rc) + { + FAPI_ERR("Error writing NEST chiplet CC Clock Region Register to stop the clocks."); + break; + } + + + // Read Clock Status Register (NEST chiplet) + // 0x0203 0008 Data: expected value: 0xFFFF FFFF FFFF FFFF + // NEST_CLK_STATUS_0x02030008 + if ( i_stop_dram_rfrsh_clks ) + { + FAPI_DBG("Reading Clock Status Register in the NEST chiplet to see if clocks are stopped. Expected value = 0xFFFF FFFF FFFF FFFF.\n"); + rc = fapiGetScom( i_target, NEST_CLK_STATUS_0x02030008, scom_data); + if (rc) + { + FAPI_ERR("Error reading NEST chiplet Clock Status Register."); + break; + } + if ( scom_data.getDoubleWord(0) != EXPECTED_CLOCK_STATUS ) + { + FAPI_ERR("NEST chiplet clock status 0xFFFFFFFFFFFFFFFF was expected but read clock status = %16llX",scom_data.getDoubleWord(0)); + FAPI_SET_HWP_ERROR(rc, RC_MSS_UNEXPECTED_CLOCK_STATUS); + break; + } + else + { + FAPI_INF("Expected clock status was read in NEST chiplet after stopping the clocks: %016llX ", EXPECTED_CLOCK_STATUS); + } + } + else + { + FAPI_DBG("Reading Clock Status Register in the NEST chiplet to see if clocks are stopped. Expected value = 0xFFFF FF1F FFFF FFFF.\n"); + rc = fapiGetScom( i_target, NEST_CLK_STATUS_0x02030008, scom_data); + if (rc) + { + FAPI_ERR("Error reading NEST chiplet Clock Status Register."); + break; + } + if ( scom_data.getDoubleWord(0) != EXPECTED_CLOCK_STATUS_W_REFRESH ) + { + FAPI_ERR("NEST chiplet clock status 0xFFFFFF1FFFFFFFFF was expected but read clock status = %16llX",scom_data.getDoubleWord(0)); + FAPI_SET_HWP_ERROR(rc, RC_MSS_UNEXPECTED_CLOCK_STATUS); + break; + } + else + { + FAPI_INF("Expected clock status was read in NEST chiplet after stopping the clocks: %016llX ", EXPECTED_CLOCK_STATUS_W_REFRESH); + } + } + + + // Resume instructions that are common to eclipz chips. + + + // reset abist_mode_dc for core chiplets (core recovery) + // Does this make sense for Centaur? (Centaur has no cores.) + // Multicast address: "0x[xx]00 0004 WAND codepoint" Data: bit(11) = 0b0 0xFFEF FFFF FFFF FFFF + // NEST_GP0_AND_0x02000004 + FAPI_DBG("Clearing GP0 Register bit 11 in NEST chiplet to reset abist_mode_dc.\n"); + rc_ecmd |= scom_data.flushTo1(); + rc_ecmd |= scom_data.clearBit(GP0_ABIST_MODE_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to clear bit 11 of the GP0 registers in the NEST chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, NEST_GP0_AND_0x02000004, scom_data); + if (rc) + { + FAPI_ERR("Error writing the GP0 registers in the NEST chiplet to reset abist mode.."); + break; + } + + + // set synclk_muxsel (io_clk_sel) + // Multicast address: "0x[xx]00 0005 WOR codepoint" bit(1) = 0b1 0x4000 0000 0000 0000 + // NEST_GP0_OR_0x02000005 + // assert perv fence GP0.63 + // Multicast address: "0x[xx]00 0005 WOR codepoint" bit(63) = 0b1 0x4000 0000 0000 0001 (Can be combined with previous step) + // NEST_GP0_OR_0x02000005 + FAPI_DBG("Setting GP0 Register bit 1 in NEST chiplet to set synclk_muxsel (io_clk_sel).\n"); + FAPI_DBG("Setting GP0 Register bit 63 in NEST chiplet to assert the pervasive fence.\n"); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_SYNCCLK_MUXSEL_BIT); + rc_ecmd |= scom_data.setBit(GP0_PERV_FENCE_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set syncclk_muxsel and pervasive fence in GP0 registers..", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, NEST_GP0_OR_0x02000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing GP0 registers in NEST chiplet to set syncclk_muxsel and pervasive fence.."); + break; + } + + + // GP3(28) disable EDRAM (just chiplets with EDRAM logic) + // Note: (skip this step if refresh clock domain stays running) + // Multicast address: "0x[xx]0F 0013 WAND codepoint" bit(28) = 0b0 0xFFFF FFF7 FFFF FFFF + // NEST_GP3_AND_0x020F0013 + if ( i_stop_dram_rfrsh_clks ) + { + FAPI_DBG("Clearing GP3 Register bit 28 in NEST chiplet to disable any EDRAM.\n"); + rc_ecmd |= scom_data.flushTo1(); + rc_ecmd |= scom_data.clearBit(GP3_EDRAM_ENABLE_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to clear GP3(bit 28), to disable EDRAM in NEST chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, NEST_GP3_AND_0x020F0013, scom_data); + if (rc) + { + FAPI_ERR("Error writing GP3 Registers in NEST chiplet to disable any EDRAM."); + break; + } + } + + + // assert fence GP3.18 + // Multicast address: "0x[xx]0F 0014 WOR codepoint" bit(18) = 0b1 0x0000 2000 0000 0000 + // NEST_GP3_OR_0x020F0014 + FAPI_DBG("Setting GP3 Regsiter bit 18 in NEST chiplet to assert the fence.\n"); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP3_FENCE_EN_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set GP3(bit18) to assert the fence in the NEST chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, NEST_GP3_OR_0x020F0014, scom_data); + if (rc) + { + FAPI_ERR("Error writing GP3 registers in NEST chiplet to assert the fence."); + break; + } + + // Set scan_dis_dc_b bit in Chiplet GP0 + // unicast address "0x[xx]00 0005 WOR codepoint" Data: bit(6) = 0b1 (0x0200 0000 0000 0000) + // NEST_GP0_OR_0x02000005 + FAPI_DBG("Setting NEST chiplet GP0 Register bit 6 to set scan_dis_dc_b to allow for scanning."); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_SCAN_DIS_DC_B_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set scan_dis_dc_b in NEST chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, NEST_GP0_OR_0x02000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing NEST chiplet GP0 register to set scan_dis_dc_b for scanning."); + break; + } + } // End of stop clock operations that are done if the vital clock is running. + } // End of NEST chiplet code + + + + //----------------- + // TP Chiplet @@@ 01 + //----------------- + + if (i_stop_tp_clks) + { + + // Set the length of the FSI shifter set pulse + // Do this in the CFAM FSI SHIFT_CONTROL_REGISTER_2. + FAPI_DBG("Setting length of the set pulse in the FSI SHIFT_CONTROL_REGISTER_2."); + rc_ecmd |= cfam_data.setWord(0,FSI_SHIFT_SET_PULSE_LENGTH); //Set cfam_data to 0x0000000F + if(rc_ecmd) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase for CFAM operation", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutCfamRegister(i_target, CFAM_FSI_SHIFT_CTRL_0x00000C10, cfam_data); + if (rc) + { + FAPI_ERR("Error attempting to set length of the set pulse in the FSI SHIFT_CONTROL_REGISTER_2."); + break; + } + + + // Go into PIB2PCB bypass path + // Set this in CFAM GP3 register. Read the register first to preserve other contents. + FAPI_DBG("Setting FSI GP3 bit 20 to go into PIB2PCB bypass."); + rc = fapiGetCfamRegister(i_target, CFAM_FSI_GP3_0x00001012, cfam_data); + if (rc) + { + FAPI_ERR("Error getting FSI_GP3 via CFAM"); + break; + } + rc_ecmd |= cfam_data.setBit(FSIGP3_PIB2PCB_BYPASS_BIT); //Set bit 20 to go into PIB2PCB bypass + if(rc_ecmd) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase for CFAM operation", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutCfamRegister(i_target, CFAM_FSI_GP3_0x00001012, cfam_data); + if (rc) + { + FAPI_ERR("Error attempting to go into PIB2PCB bypass."); + break; + } + + + // Set flushmode_inhibit in Chiplet GP0 + // unicast address "0x[xx]00 0005 WOR codepoint" Data: bit(2) = 0b1 (0x2000 0000 0000 0000) + // TP_GP0_OR_0x01000005 + FAPI_DBG("Setting TP chiplet GP0 Register bit 2 to set flushmode_inhibit."); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_FLUSHMODE_INHIBIT_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set flushmode_inhibit in TP chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, TP_GP0_OR_0x01000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing TP chiplet GP0 register to set flushmode inhibit."); + break; + } + + // Set force_align in Chiplet GP0 + // unicast address "0x[xx]00 0005 WOR codepoint" Data: bit(3) = 0b1 (0x1000 0000 0000 0000) Cannot combine with previous step. + // TP_GP0_OR_0x01000005 + FAPI_DBG("Setting TP chiplet GP0 Register bit 3 to set force_align."); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_FORCE_ALIGN_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set force_align in TP chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, TP_GP0_OR_0x01000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing TP chiplet GP0 register to set force_align."); + break; + } + + // Write ClockControl, Scan Region Register, set all bits to zero prior clock stop + // unicast address 0x[xx]03 0007 Data: 0x0000 0000 0000 0000 + // TP_CLK_SCANSEL_0x01030007 + FAPI_DBG("Writing TP chiplet Clock Control Scan Region Register to all zeros prior clock stop."); + rc_ecmd |= scom_data.flushTo0(); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to write CC Scan Region Register to all zeros in TP chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, TP_CLK_SCANSEL_0x01030007, scom_data); + if (rc) + { + FAPI_ERR("Error writing TP chiplet CC Scan Region Register."); + break; + } + + // Write ClockControl, Clock Region Register, Clock Stop command (arrays + nsl only, not refresh clock region) TP chiplet + // TP_CLK_REGION_0x01030006 + FAPI_DBG("Writing Clock Control Clock Region Register in TP chiplet to stop the clocks."); + rc_ecmd |= scom_data.flushTo1(); + rc_ecmd |= scom_data.insertFromRight(CLK_REGION_CLOCK_CMD_STOP, + CLK_REGION_CLOCK_CMD_BIT, + CLK_REGION_CLOCK_CMD_LEN); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set general clock stop command in TP chiplet CC Clock Region Register.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, TP_CLK_REGION_0x01030006, scom_data); + if (rc) + { + FAPI_ERR("Error writing TP chiplet CC Clock Region Register to stop the clocks."); + break; + } + + // Read Clock Status Register (TP chiplet) + // 0x0103 0008 Data: expected value: FFFFFFFFFFFFFFFF + // TP_CLK_STATUS_0x01030008 + FAPI_DBG("Reading Clock Status Register in the TP chiplet to see if clocks are stopped. Expected value = %016llX.", EXPECTED_CLOCK_STATUS); + rc = fapiGetScom( i_target, TP_CLK_STATUS_0x01030008, scom_data); + if (rc) + { + FAPI_ERR("Error reading TP chiplet Clock Status Register."); + break; + } + if ( scom_data.getDoubleWord(0) != EXPECTED_CLOCK_STATUS ) + { + FAPI_ERR("TP chiplet clock status %016llX was expected but read clock status = %016llX.",EXPECTED_CLOCK_STATUS,scom_data.getDoubleWord(0)); + FAPI_SET_HWP_ERROR(rc, RC_MSS_UNEXPECTED_CLOCK_STATUS); + break; + } + else + { + FAPI_INF("Expected clock status was read in TP chiplet after stopping the clocks: %016llX ", EXPECTED_CLOCK_STATUS); + } + + + // Set L3 EDRAM fence in chiplet by setting bit(19) in chiplet GP0 registers (Fence only exists in EX chiplets.) + + + // Resume instructions that are common to all eclipz chips. + + + // reset abist_mode_dc for core chiplets only (core recovery) + + + // set synclk_muxsel (io_clk_sel) + // Unicast address: "0x[xx]00 0005 WOR codepoint" bit(1) = 0b1 0x4000 0000 0000 0000 + // TP_GP0_OR_0x01000005 + // assert perv fence GP0.63 + // Unicast address: "0x[xx]00 0005 WOR codepoint" bit(63) = 0b1 0x4000 0000 0000 0001 (Can be combined with previous step) + // TP_GP0_OR_0x01000005 + FAPI_DBG("Setting TP chiplet GP0 Register bit 1 to set synclk_muxsel (io_clk_sel)."); + FAPI_DBG("Setting TP chiplet GP0 Register bit 63 to assert the pervasive fence."); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_SYNCCLK_MUXSEL_BIT); + rc_ecmd |= scom_data.setBit(GP0_PERV_FENCE_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set syncclk_muxsel and pervasive fence in TP chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, TP_GP0_OR_0x01000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing TP chiplet GP0 register to set syncclk_muxsel and pervasive fence.."); + break; + } + + + // GP3(28) disable EDRAM (just chiplets with EDRAM logic) + + + // Instruction from Johannes Koesters 12 Sept, 2013 + // Leave this commented out for now. Seems to cause problems if we set the fence on the TP chiplet. + // + // Change this to use PERV GP3 Register (CFAM 101B) (Normal GP3 reg N/A in TP chiplet) ? + //// assert fence GP3.18 + //// Unicast address: "0x[xx]0F 0014 WOR codepoint" bit(18) = 0b1 0x0000 2000 0000 0000 + //// TP_GP3_OR_0x010F0014 + //FAPI_DBG("Setting TP chiplet GP3 Regsiter bit 18 to assert the fence."); + //rc_ecmd |= scom_data.flushTo0(); + //rc_ecmd |= scom_data.setBit(GP3_FENCE_EN_BIT); + //if (rc_ecmd) + //{ + // FAPI_ERR("Error 0x%x setting up ecmd data buffer to assert the fence in TP chiplet.", rc_ecmd); + // rc.setEcmdError(rc_ecmd); + // break; + //} + //rc = fapiPutScom( i_target, TP_GP3_OR_0x010F0014, scom_data); + //if (rc) + //{ + // FAPI_ERR("Error writing TP chiplet GP3 register to assert the fence."); + // break; + //} + + + // Set scan_dis_dc_b bit in Chiplet GP0 + // unicast address "0x[xx]00 0005 WOR codepoint" Data: bit(6) = 0b1 (0x0200 0000 0000 0000) + // TP_GP0_OR_0x01000005 + FAPI_DBG("Setting TP chiplet GP0 Register bit 6 to set scan_dis_dc_b to allow for scanning."); + rc_ecmd |= scom_data.flushTo0(); + rc_ecmd |= scom_data.setBit(GP0_SCAN_DIS_DC_B_BIT); + if (rc_ecmd) + { + FAPI_ERR("Error 0x%x setting up ecmd data buffer to set scan_dis_dc_b in TP chiplet.", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutScom( i_target, TP_GP0_OR_0x01000005, scom_data); + if (rc) + { + FAPI_ERR("Error writing TP chiplet GP0 register to set scan_dis_dc_b for scanning."); + break; + } + } // End of TP Chiplet clock section + + + + //----------------- + // VITL Clocks @@@ 00 + //----------------- + + if (i_stop_vitl_clks) + { + + // Set the length of the FSI shifter set pulse + // Do this in the CFAM FSI SHIFT_CONTROL_REGISTER_2. + FAPI_DBG("Setting length of the set pulse in the FSI SHIFT_CONTROL_REGISTER_2."); + rc_ecmd |= cfam_data.setWord(0,FSI_SHIFT_SET_PULSE_LENGTH); //Set cfam_data to 0x0000000F + if(rc_ecmd) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase for CFAM operation", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutCfamRegister(i_target, CFAM_FSI_SHIFT_CTRL_0x00000C10, cfam_data); + if (rc) + { + FAPI_ERR("Error attempting to set length of the set pulse in the FSI SHIFT_CONTROL_REGISTER_2."); + break; + } + + + // Disable the VITL clocks + // Set this in PERV GP3 register. Read the register first to preserve other contents. + FAPI_DBG("Setting PERV GPP3 Register bit 16 to turn OFF the VITL clock."); + rc = fapiGetCfamRegister(i_target, CFAM_FSI_GP3_MIRROR_0x0000101B, cfam_data); + if (rc) + { + FAPI_ERR("Error getting PERV GP3 via CFAM"); + break; + } + rc_ecmd |= cfam_data.setBit(PERVGP3_VITL_CLKOFF_BIT); //Set bit 16 to turn OFF VITL clock + if(rc_ecmd) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase for CFAM operation", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutCfamRegister(i_target, CFAM_FSI_GP3_MIRROR_0x0000101B, cfam_data); + if (rc) + { + FAPI_ERR("Error attempting to set PERV GP3 Reg bit 16 to stop the VITL clocks."); + break; + } + + + // Set Some FSI fences + // Set this in CFAM GP3 register. Read the register first to preserve other contents. + FAPI_DBG("Setting FSI GP3 bits 25 and,26 to set FSI fences 4 and 5."); + rc = fapiGetCfamRegister(i_target, CFAM_FSI_GP3_0x00001012, cfam_data); + if (rc) + { + FAPI_ERR("Error getting FSI_GP3 via CFAM"); + break; + } + rc_ecmd |= cfam_data.setBit(FSIGP3_FSI_FENCE4_BIT); //Set bits 25 to set FSI fence 4 + rc_ecmd |= cfam_data.setBit(FSIGP3_FSI_FENCE5_BIT); //Set bits 26 to set FSI fence 5 + if(rc_ecmd) + { + FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase for CFAM operation", rc_ecmd); + rc.setEcmdError(rc_ecmd); + break; + } + rc = fapiPutCfamRegister(i_target, CFAM_FSI_GP3_0x00001012, cfam_data); + if (rc) + { + FAPI_ERR("Error attempting to set FSI fences in FSI GP3 register."); + break; + } + } // End of VITL clock section + + + } while(0); + + FAPI_INF("********* cen_stopclocks complete *********"); + return rc; +} + +} //end extern C + + + + +/* +*************** Do not edit this area *************** +This section is automatically updated by CVS when you check in this file. +Be sure to create CVS comments when you commit so that they can be included here. + +$Log: cen_stopclocks.C,v $ +Revision 1.15 2013/10/16 14:39:32 mfred +Set the FSI shifter pulse width before stopping the TP or VITL clocks. + +Revision 1.14 2013/10/10 14:23:32 mfred +Updates from Gerrit review. Continue with other chiplet even if clocks are off in MEM chiplet. + +Revision 1.13 2013/09/27 16:44:50 mfred +Separate option to stop the VITL clks, and checks to avoid calling options that will cause failures. + +Revision 1.12 2013/03/04 17:56:33 mfred +Add some header comments for BACKUP and SCREEN. + +Revision 1.11 2013/02/27 21:16:30 mfred +Make change to stop all clock regions simultaneously. + +Revision 1.10 2013/01/17 21:38:55 mfred +Check vital clock before trying to stop clocks. Assert scan_dis_dc_b after stopping clocks. + +Revision 1.9 2012/10/05 20:10:43 mfred +Remove the use of multicast in case only one chiplet is selected. + +Revision 1.8 2012/08/30 12:09:29 mfred +Only disable EDRAM if the refresh clock was turned OFF. + +Revision 1.7 2012/08/30 11:56:08 mfred +Added input options to select chiplet and to stop refresh clock. + +Revision 1.6 2012/08/27 16:53:40 mfred +Exit when unexpected clock status is seen. + +Revision 1.5 2012/07/10 14:29:36 mfred +Removed some bad comments and some whitespace. + +Revision 1.4 2012/06/07 19:31:19 mfred +Fixed calls to CFAM registers. They are not scommable. + +Revision 1.3 2012/05/31 14:02:06 mfred +Committing updates for cen_stopclocks. + +Revision 1.2 2012/03/14 19:26:34 mfred +Replace prototype with functional code. + +Revision 1.1 2012/03/07 14:22:11 mfred +Adding prototype for cen_stopclocks. + +*/ + diff --git a/src/usr/hwpf/hwp/dram_training/cen_stopclocks/cen_stopclocks.H b/src/usr/hwpf/hwp/dram_training/cen_stopclocks/cen_stopclocks.H new file mode 100644 index 000000000..937210cd7 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/cen_stopclocks/cen_stopclocks.H @@ -0,0 +1,89 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/cen_stopclocks/cen_stopclocks.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: cen_stopclocks.H,v 1.5 2013/10/10 14:23:35 mfred Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/cen_stopclocks.H,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2011 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : cen_stopclocks.H +// *! DESCRIPTION : see additional comments below +// *! OWNER NAME : Mark Fredrickson Email: mfred@us.ibm.com +// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com +// *! ADDITIONAL COMMENTS : +// +// This is the header file for cen_stopclocks. +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ + +#ifndef CEN_STOPCLOCKSHWPB_H_ +#define CEN_STOPCLOCKSHWPB_H_ + +#include <fapi.H> + + +// function pointer typedef definition for HWP call support +typedef fapi::ReturnCode (*cen_stopclocks_FP_t)(const fapi::Target &, + const bool, + const bool, + const bool, + const bool, + const bool); + + +//------------------------------------------------------------------------------ +// Function prototypes +//------------------------------------------------------------------------------ + +extern "C" +{ + // Target is centaur chip + +/** + * @brief cen_stopclocks procedure: The purpose of this procedure is to assert the tholds (stop the clocks) in the Centaur chip. + * + * @param[in] i_target Reference to centaur target + * @param[in] i_stop_mem_clks True if MEM chiplet clocks should be stopped, else false + * @param[in] i_stop_nest_clks True if NEST chiplet clocks (except for refresh clks) should be stopped, else false + * @param[in] i_stop_dram_rfrsh_clks If (i_stop_nest_clks==true) then true if NEST chiplet refresh clocks should be stopped, else false + * @param[in] i_stop_tp_clks True if PERV (TP) chiplet clocks should be stopped, else false + * @param[in] i_stop_vitl_clks True if PERV VITL clocks should be stopped, else false + * + * @return ReturnCode + */ + + fapi::ReturnCode cen_stopclocks(const fapi::Target& i_target, + const bool i_stop_mem_clks, + const bool i_stop_nest_clks, + const bool i_stop_dram_rfrsh_clks, + const bool i_stop_tp_clks, + const bool i_stop_vitl_clks); + + // Target is centaur chip + +} // extern "C" + +#endif // CEN_STOPCLOCKSHWPB_H_ diff --git a/src/usr/hwpf/hwp/dram_training/makefile b/src/usr/hwpf/hwp/dram_training/makefile index 93cd54fd5..a64f000c8 100644 --- a/src/usr/hwpf/hwp/dram_training/makefile +++ b/src/usr/hwpf/hwp/dram_training/makefile @@ -51,6 +51,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_dimm_power_test EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/cen_stopclocks ## NOTE: add new object files when you add a new HWP OBJS = dram_training.o \ @@ -72,7 +73,8 @@ OBJS = dram_training.o \ hbVddrMsg.o \ mss_mcbist_address.o \ mss_dimm_power_test.o \ - mss_lrdimm_funcs.o + mss_lrdimm_funcs.o \ + cen_stopclocks.o ## NOTE: add a new directory onto the vpaths when you add a new HWP ##@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/??? @@ -86,5 +88,7 @@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_scominit VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mem_pll_setup VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs +VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/cen_stopclocks + include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/include/cen_scom_addresses.H b/src/usr/hwpf/hwp/include/cen_scom_addresses.H index 12c93fde2..a8130a2cf 100755 --- a/src/usr/hwpf/hwp/include/cen_scom_addresses.H +++ b/src/usr/hwpf/hwp/include/cen_scom_addresses.H @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: cen_scom_addresses.H,v 1.64 2013/08/22 19:46:32 mjjones Exp $ +// $Id: cen_scom_addresses.H,v 1.65 2013/11/05 20:33:31 bellows Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/cen_scom_addresses.H,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 @@ -236,6 +236,7 @@ CONST_UINT64_T( MBI_FIRACT0_0x02010806 , ULL(0x02010806) ); CONST_UINT64_T( MBI_FIRACT1_0x02010807 , ULL(0x02010807) ); CONST_UINT64_T( MBI_CFG_0x0201080A , ULL(0x0201080A) ); CONST_UINT64_T( MBI_STAT_0x0201080B , ULL(0x0201080B) ); +CONST_UINT64_T( MBI_CRCSYN_0x0201080C , ULL(0x0201080C) ); CONST_UINT64_T( NEST_TRACE_DATA_HI_MBI_0x02010C40 , ULL(0x02010C40) ); CONST_UINT64_T( NEST_TRACE_DATA_LO_MBI_0x02010C41 , ULL(0x02010C41) ); @@ -1756,6 +1757,9 @@ This section is automatically updated by CVS when you check in this file. Be sure to create CVS comments when you commit so that they can be included here. $Log: cen_scom_addresses.H,v $ +Revision 1.65 2013/11/05 20:33:31 bellows +Added MBI_CRCSYN + Revision 1.64 2013/08/22 19:46:32 mjjones Added DMI-FIR and WOF registers diff --git a/src/usr/hwpf/hwp/makefile b/src/usr/hwpf/hwp/makefile index 2a3aa1744..4a235e57e 100644 --- a/src/usr/hwpf/hwp/makefile +++ b/src/usr/hwpf/hwp/makefile @@ -49,7 +49,7 @@ SUBDIRS = dmi_training.d sbe_centaur_init.d mc_config.d \ core_activate.d dram_initialization.d edi_ei_initialization.d \ establish_system_smp.d bus_training.d occ.d tod_init.d \ nest_chiplets.d start_payload.d thread_activate.d slave_sbe.d \ - pstates.d + pstates.d proc_hwreconfig.d include mvpd_accessors/mvpd.mk include spd_accessors/spd.mk diff --git a/src/usr/hwpf/hwp/mc_config/makefile b/src/usr/hwpf/hwp/mc_config/makefile index f415c29b8..083d7d7c3 100644 --- a/src/usr/hwpf/hwp/mc_config/makefile +++ b/src/usr/hwpf/hwp/mc_config/makefile @@ -41,6 +41,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_volt EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_freq EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_pre_config +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_attr_cleanup OBJS = mc_config.o \ mss_volt.o \ @@ -56,7 +57,8 @@ OBJS = mc_config.o \ mss_throttle_to_power.o \ mss_eff_config_shmoo.o \ mss_error_support.o \ - mss_eff_pre_config.o + mss_eff_pre_config.o \ + mss_attr_cleanup.o ## NOTE: add a new directory onto the vpaths when you add a new HWP ##@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/??? @@ -64,5 +66,6 @@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_config VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_volt VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_freq VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_pre_config +VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_attr_cleanup include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/mc_config/mc_config.C b/src/usr/hwpf/hwp/mc_config/mc_config.C index dad3fa964..290e7e418 100644 --- a/src/usr/hwpf/hwp/mc_config/mc_config.C +++ b/src/usr/hwpf/hwp/mc_config/mc_config.C @@ -64,6 +64,7 @@ #include "mss_eff_config/mss_eff_config_thermal.H" #include "mss_eff_config/mss_eff_grouping.H" #include "mss_eff_config/opt_memmap.H" +#include "mss_attr_cleanup/mss_attr_cleanup.H" namespace MC_CONFIG { @@ -72,8 +73,7 @@ using namespace ISTEP; using namespace ISTEP_ERROR; using namespace ERRORLOG; using namespace TARGETING; - - +using namespace fapi; // // Wrapper function to call host_collect_dimm_spd @@ -81,13 +81,96 @@ using namespace TARGETING; void* call_host_collect_dimm_spd( void *io_pArgs ) { errlHndl_t l_err = NULL; - + IStepError l_stepError; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_collect_dimm_spd entry" ); + + // Get a list of all present Centaurs + TargetHandleList l_presCentaurs; + getChipResources(l_presCentaurs, TYPE_MEMBUF, UTIL_FILTER_PRESENT); + // Associated MBA targets + TARGETING::TargetHandleList l_mbaList; + + // Define predicate for associated MBAs + PredicateCTM predMba(CLASS_UNIT, TYPE_MBA); + PredicatePostfixExpr presMba; + PredicateHwas predPres; + predPres.present(true); + presMba.push(&predMba).push(&predPres).And(); + + for (TargetHandleList::const_iterator + l_cenIter = l_presCentaurs.begin(); + l_cenIter != l_presCentaurs.end(); + ++l_cenIter) + { + // make a local copy of the target for ease of use + TARGETING::Target * l_pCentaur = *l_cenIter; + // Retrieve HUID of current Centaur + TARGETING::ATTR_HUID_type l_currCentaurHuid = + TARGETING::get_huid(l_pCentaur); + + // Dump current run on target + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Running mss_attr_cleanup HWP on " + "target HUID %.8X", l_currCentaurHuid); + + // find all present MBAs associated with this Centaur + TARGETING::TargetHandleList l_presMbas; + targetService().getAssociated(l_presMbas, + l_pCentaur, + TargetService::CHILD, + TargetService::IMMEDIATE, + &presMba); + + // If not at least two MBAs found + if (l_presMbas.size() < 2) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Not enough MBAs found for Centaur target HUID %.8X, " + "skipping this Centaur.", + l_currCentaurHuid); + continue; + } + + // Create FAPI Targets. + const fapi::Target l_fapiCentaurTarget(TARGET_TYPE_MEMBUF_CHIP, + (const_cast<TARGETING::Target*>(l_pCentaur))); + const fapi::Target l_fapiMba0Target(TARGET_TYPE_MBA_CHIPLET, + (const_cast<TARGETING::Target*>(l_presMbas[0]))); + const fapi::Target l_fapiMba1Target(TARGET_TYPE_MBA_CHIPLET, + (const_cast<TARGETING::Target*>(l_presMbas[1]))); + // call the HWP with each fapi::Target + FAPI_INVOKE_HWP(l_err, mss_attr_cleanup, l_fapiCentaurTarget, + l_fapiMba0Target, l_fapiMba1Target); + if (l_err) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR 0x%.8X: mss_attr_cleanup HWP returns error", + l_err->reasonCode()); + // capture the target data in the elog + ErrlUserDetailsTarget(l_pCentaur).addToLog(l_err); + // Create IStep error log and cross reference error that occurred + l_stepError.addErrorDetails(l_err); + // Commit Error + errlCommit(l_err, HWPF_COMP_ID); + } + else + { + // Success + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Successfully ran mss_attr_cleanup HWP on " + "CENTAUR target HUID %.8X " + "and associated MBAs", + l_currCentaurHuid); + } + } + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_collect_dimm_spd exit" ); - return l_err; + // end task, returning any errorlogs to IStepDisp + return l_stepError.getErrorHandle(); } // diff --git a/src/usr/hwpf/hwp/mc_config/mss_attr_cleanup/mss_attr_cleanup.C b/src/usr/hwpf/hwp/mc_config/mss_attr_cleanup/mss_attr_cleanup.C new file mode 100644 index 000000000..2e2465bd4 --- /dev/null +++ b/src/usr/hwpf/hwp/mc_config/mss_attr_cleanup/mss_attr_cleanup.C @@ -0,0 +1,226 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/mc_config/mss_attr_cleanup/mss_attr_cleanup.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_attr_cleanup.C,v 1.2 2013/11/14 16:52:25 bellows Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_attr_cleanup.C,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2012 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : mss_attr_cleanup +// *! DESCRIPTION : see additional comments below +// *! OWNER NAME : Mark Bellows Email: bellows@us.ibm.com +// *! BACKUP NAME : Anuwat Saetow Email: asaetow@us.ibm.com + +// *! ADDITIONAL COMMENTS : +// +// clean up any centaur and mba attributes if a centaur is not in the system. +// The main attributes are the ones relating to grouping - other attributes may have settings +// but aren't going to be used by initfiles +// +// There is a sub function that cleans up an mba that needs to be called if we deconfigure an mba +// this procedure writes attributes and write hardware +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.2 | bellows |11-NOV-13| Gerrit Review Comments +// 1.1 | bellows |28-NOV-12| First Draft. Functions implemented +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// My Includes +//------------------------------------------------------------------------------ +#include "mss_attr_cleanup.H" +#include "cen_scom_addresses.H" +#include "mss_eff_config.H" + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <fapi.H> + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const uint8_t PORT_SIZE = 2; +const uint8_t DIMM_SIZE = 2; + + +//------------------------------------------------------------------------------ +// extern encapsulation +//------------------------------------------------------------------------------ +extern "C" +{ + fapi::ReturnCode mss_attr_cleanup_mba_attributes(const fapi::Target & i_target_mba); +//------------------------------------------------------------------------------ +// @brief mss_attr_cleanup(): This function will disable a centaur - fencing it and powering it down +// +// @param const fapi::Target i_target_centaur: the fapi target of the centaur +// @param const fapi::Target i_target_mba0: the mba0 target +// @param const fapi::Target i_target_mba1: the mba1 target +// +// @return fapi::ReturnCode +//------------------------------------------------------------------------------ + fapi::ReturnCode mss_attr_cleanup(const fapi::Target & i_target_centaur, const fapi::Target & i_target_mba0, const fapi::Target & i_target_mba1) + { + fapi::ReturnCode rc; + + FAPI_INF("Running mss_attr_cleanup on %s\n", i_target_centaur.toEcmdString()); + + do { + + + rc = mss_attr_cleanup_mba_attributes(i_target_mba0); + if(rc) break; + rc = mss_attr_cleanup_mba_attributes(i_target_mba1); + if(rc) break; + + /* need to add code that fences and centaur and powers off clocks */ + } while(0); + + return rc; + } // end mss_attr_cleanup() + + fapi::ReturnCode mss_attr_cleanup_mba_attributes(const fapi::Target & i_target_mba) { + // turn off functional vector + fapi::ReturnCode rc; + uint8_t dimm_functional_vector=0x00; // ready to set all DIMMs to non functional + uint8_t mba_functional; + uint8_t eff_dimm_size[PORT_SIZE][DIMM_SIZE]; + int i,j; + uint8_t dimm_ranks[PORT_SIZE][DIMM_SIZE]; // Number of ranks for each configured DIMM in each MBA + uint8_t dimm_type; + uint8_t spd_dimm_ranks[PORT_SIZE][DIMM_SIZE]; + uint8_t module_type; + uint8_t custom; + uint8_t mba_port; + uint8_t mba_dimm; + + do + { + rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL, &i_target_mba, mba_functional); + if(rc) break; + + if(! mba_functional ) { + +// read in some SPD attributes that are used in thermal (non functional DIMM/MBA, yet uses power) +// we do this because we are cleaning up a DIMM that may not be functional any more due to whatever reason + std::vector<fapi::Target> target_dimm_array; + rc = fapiGetAssociatedDimms(i_target_mba, target_dimm_array); + if(rc) break; + + for (uint8_t dimm_index = 0; dimm_index < + target_dimm_array.size(); dimm_index += 1) + { + rc = FAPI_ATTR_GET(ATTR_MBA_PORT, &target_dimm_array[dimm_index], mba_port); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_MBA_DIMM, &target_dimm_array[dimm_index], mba_dimm); + if(rc) break; + + if(mba_port == 0 && mba_dimm == 0) { + rc = FAPI_ATTR_GET(ATTR_SPD_CUSTOM, &target_dimm_array[dimm_index], custom); + if (rc) break; + + rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_TYPE, &target_dimm_array[dimm_index], module_type); + if(rc) break; + } + + rc = FAPI_ATTR_GET(ATTR_SPD_NUM_RANKS, &target_dimm_array[dimm_index], spd_dimm_ranks[mba_port][mba_dimm]); + if(rc) break; + } + + // now szap the functional vector and dimm_size + rc = FAPI_ATTR_SET(ATTR_MSS_EFF_DIMM_FUNCTIONAL_VECTOR, &i_target_mba, + dimm_functional_vector); + if (rc) break; + + for(i=0;i<PORT_SIZE;i++) + for(j=0;j<DIMM_SIZE;j++) { + eff_dimm_size[i][j]=0; + switch (spd_dimm_ranks[i][j]) { + case fapi::ENUM_ATTR_SPD_NUM_RANKS_R4: + dimm_ranks[i][j]=4; + break; + case fapi::ENUM_ATTR_SPD_NUM_RANKS_R2: + dimm_ranks[i][j]=2; + break; + case fapi::ENUM_ATTR_SPD_NUM_RANKS_R1: + dimm_ranks[i][j]=1; + break; + default: + dimm_ranks[i][j]=0; + break; + } + switch(module_type) + { + case fapi::ENUM_ATTR_SPD_MODULE_TYPE_CDIMM: + dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM; + break; + case fapi::ENUM_ATTR_SPD_MODULE_TYPE_RDIMM: + dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM; + break; + case fapi::ENUM_ATTR_SPD_MODULE_TYPE_UDIMM: + if(custom) { + dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM; + } + else { + dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM; + } + break; + case fapi::ENUM_ATTR_SPD_MODULE_TYPE_LRDIMM: + dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM; + break; + default: + FAPI_INF("DIMM type set to 0 on %s", i_target_mba.toEcmdString()); + dimm_type = 0; + break; + } + } + + rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_SIZE, &i_target_mba, eff_dimm_size); + if (rc) break; + + rc = FAPI_ATTR_SET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, dimm_ranks); + if (rc) break; + + rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_TYPE, &i_target_mba, dimm_type); + if (rc) break; + + } + else { // reenable -reverse everything + + } + } while(0); + + if(rc) { FAPI_ERR("ERROR: Bad RC in mss_attr_cleanup_mba_attributes"); } + return rc; + } // end of mss_attr_cleanup_mba_attributes +} // extern "C" + diff --git a/src/usr/hwpf/hwp/mc_config/mss_attr_cleanup/mss_attr_cleanup.H b/src/usr/hwpf/hwp/mc_config/mss_attr_cleanup/mss_attr_cleanup.H new file mode 100644 index 000000000..2869b1533 --- /dev/null +++ b/src/usr/hwpf/hwp/mc_config/mss_attr_cleanup/mss_attr_cleanup.H @@ -0,0 +1,82 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/mc_config/mss_attr_cleanup/mss_attr_cleanup.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_attr_cleanup.H,v 1.2 2013/11/14 16:55:37 bellows Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_attr_cleanup.H,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2013 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : mss_attr_cleanup.H +// *! DESCRIPTION : Header file for mss_attr_cleanup. +// *! OWNER NAME : Mark Bellows Email: bellows@us.ibm.com +// *! BACKUP NAME : Anuwat Saetow Email: asaetow@us.ibm.com +// *! ADDITIONAL COMMENTS : +// +// +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.2 | bellows |11-NOV-13| Gerrit Review Comments +// 1.1 | bellows |13-JUN-13| First Draft +//------------------------------------------------------------------------------ + + +#ifndef MSS_ATTR_CLEANUP_H_ +#define MSS_ATTR_CLEANUP_H_ + +//------------------------------------------------------------------------------ +// My Includes +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <fapi.H> + +typedef fapi::ReturnCode (*mss_attr_cleanup_FP_t)(const fapi::Target & i_target_centaur, + const fapi::Target & i_target_mba0, const fapi::Target & i_target_mba1); + +extern "C" { + +//------------------------------------------------------------------------------ +// @brief mss_attr_cleanup(): Clean up attributes of a centaur and also MBAs, +// +// @param const fapi::Target i_target_centaur: the centaur +// @param const fapi::Target i_target_mba0: the mba0 +// @param const fapi::Target i_target_mba1: the mba1 +// +// @return fapi::ReturnCode +//------------------------------------------------------------------------------ +fapi::ReturnCode mss_attr_cleanup(const fapi::Target & i_target_centaur, + const fapi::Target & i_target_mba0, const fapi::Target & i_target_mba1); + +} // extern "C" + +#endif // MSS_ATTR_CLEANUP_H + diff --git a/src/usr/hwpf/hwp/proc_hwreconfig/makefile b/src/usr/hwpf/hwp/proc_hwreconfig/makefile new file mode 100644 index 000000000..114e6af58 --- /dev/null +++ b/src/usr/hwpf/hwp/proc_hwreconfig/makefile @@ -0,0 +1,56 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/hwpf/hwp/edi_ei_initialization/makefile $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2012,2013 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG + +ROOTPATH = ../../../../.. + +MODULE = proc_hwreconfig + +## support for Targeting and fapi +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp + +## pointer to common HWP files +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/bus_training + +## NOTE: add the base istep dir here. +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/proc_hwreconfig + +## Include sub dirs +## NOTE: add a new EXTRAINCDIR when you add a new HWP +## EXAMPLE: +## EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/edi_ei_initialization/<HWP_dir> +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig + +## NOTE: add new object files when you add a new HWP +OBJS = proc_enable_reconfig.o + +## NOTE: add a new directory onto the vpaths when you add a new HWP +## EXAMPLE: +# VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/edi_ei_initialization/<HWP_dir> +VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig + +include ${ROOTPATH}/config.mk + diff --git a/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig/proc_enable_reconfig.C b/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig/proc_enable_reconfig.C new file mode 100644 index 000000000..37205cca0 --- /dev/null +++ b/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig/proc_enable_reconfig.C @@ -0,0 +1,268 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/host_prd_hwreconfig/proc_enable_reconfig/proc_enable_reconfig.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_enable_reconfig.C,v 1.4 2013/11/13 17:21:51 bellows Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_enable_reconfig.C,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2013 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +// *! Licensed material - Program property of IBM +// *! Refer to copyright instructions form no. G120-2083 +// *! Created on Thu Oct 31 2013 at 10:28:49 +//------------------------------------------------------------------------------ +// *! TITLE : proc_enable_reconfig +// *! DESCRIPTION : see additional comments below +// *! OWNER NAME : Mark Bellwos Email: bellows@us.ibm.com +// *! BACKUP NAME : Email: ______@us.ibm.com + +// *! ADDITIONAL COMMENTS : +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.4 | bellows |13-NOV-13| Fixed up rc_ecmd problems from review +// 1.3 | bellows |11-NOV-13| Firmware review updates +// 1.2 | bellows |08-NOV-13| Simpified + added attributes +// 1.1 | bellows |07-NOV-13| Created from proc_prep_for_reconfig.C +#include <fapi.H> +#include "proc_enable_reconfig.H" +#include <p8_scom_addresses.H> +#include <io_cleanup.H> + +extern "C" { + + using namespace fapi; + + ReturnCode proc_enable_reconfig(fapi::Target & i_target_pu_mcs, fapi::Target & i_target_cen) { + + ReturnCode rc; + ecmdDataBufferBase mask_buffer_64(64); + ecmdDataBufferBase data_buffer_64(64); + uint8_t l_attr_mss_init_state; + uint8_t cold=true; + uint8_t dmi_active=false; + uint8_t clocks_on=false; + Target l_target_pu; + uint8_t l_attr_proc_ec_mss_reconfig_possible; + uint32_t rc_ecmd; + + // determine how far into the IPL we have gone + rc = FAPI_ATTR_GET(ATTR_MSS_INIT_STATE, &i_target_cen, l_attr_mss_init_state); + if(rc) return rc; + + if(l_attr_mss_init_state != ENUM_ATTR_MSS_INIT_STATE_COLD ) + cold=false; + + if(l_attr_mss_init_state == ENUM_ATTR_MSS_INIT_STATE_CLOCKS_ON ) + clocks_on=true; + + if(l_attr_mss_init_state == ENUM_ATTR_MSS_INIT_STATE_DMI_ACTIVE ) { + clocks_on=true; + dmi_active=true; + } + + + if(cold) { // If the centaur has not made it past cold, then exit with success + return rc; + } + + rc= fapiGetParentChip(i_target_pu_mcs, l_target_pu); + if(rc) return rc; + + rc = FAPI_ATTR_GET(ATTR_PROC_EC_MSS_RECONFIG_POSSIBLE, &l_target_pu, l_attr_proc_ec_mss_reconfig_possible); + if(rc) return rc; + + if(dmi_active) { + + if(l_attr_proc_ec_mss_reconfig_possible) { + // turn off the FIR propagator + rc_ecmd = data_buffer_64.setBit(42); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + rc_ecmd = mask_buffer_64.setBit(42); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + + rc = fapiPutScomUnderMask(i_target_pu_mcs, MCS_MCICFG_0x0201184A, data_buffer_64, mask_buffer_64); + if(rc) return rc; + + } + else { + FAPI_ERR("This processor cannot go through a reconfig loop. Please upgrade to > DD1\n"); + FAPI_SET_HWP_ERROR(rc, RC_PROC_ENABLE_RECONFIG_UNSUPPORTED); + return rc; + } + } + + // mask firs in the MCS + rc_ecmd = data_buffer_64.setBit(0,64); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + rc = fapiPutScom(i_target_pu_mcs, MCS_MCIFIRMASK_0x02011843, data_buffer_64); + if(rc) return rc; + + + // force a channel fail only if you are up to DMI ACTIVE state on this pair + rc_ecmd = data_buffer_64.clearBit(0,64); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + rc_ecmd = data_buffer_64.setBit(0); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + rc_ecmd = mask_buffer_64.clearBit(0,64); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + rc_ecmd = mask_buffer_64.setBit(0); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + + if(dmi_active) { + rc = fapiPutScomUnderMask(i_target_pu_mcs, MCS_MCICFG_0x0201184A, data_buffer_64, mask_buffer_64); + if(rc) return rc; + } + + rc_ecmd = data_buffer_64.clearBit(0,64); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + rc_ecmd = data_buffer_64.setBit(0); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + if(dmi_active) { + rc = fapiPutScom(i_target_cen, CENTAUR_MBI_CFG_0x0201080A, data_buffer_64); + if(rc) return rc; + } + + // perform IO cleanup on active dmi channels + if(dmi_active) { + + FAPI_INF("mcs %s / cen %s : types %d %d\n", i_target_pu_mcs.toEcmdString(), i_target_cen.toEcmdString(), i_target_pu_mcs.getType(), i_target_cen.getType() ); + + rc = io_cleanup(i_target_pu_mcs, i_target_cen ); + if(rc) return rc; + } + + if(clocks_on ){ + + rc_ecmd = data_buffer_64.clearBit(0,64); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + + // # cen mbi fir + rc = fapiPutScom(i_target_cen, CENTAUR_MBI_FIR_0x02010800, data_buffer_64); + if(rc) return rc; + + // # cen mbicrc syndromes + rc = fapiPutScom(i_target_cen, CENTAUR_MBI_CRCSYN_0x0201080C, data_buffer_64); + if(rc) return rc; + + // # cen mbicfg configuration register + rc = fapiPutScom(i_target_cen, CENTAUR_MBI_CFG_0x0201080A, data_buffer_64); + if(rc) return rc; + + // # cen dmi fir + rc = fapiPutScom(i_target_cen, CENTAUR_CEN_DMIFIR_0x02010400, data_buffer_64); + if(rc) return rc; + + rc = fapiPutScom(i_target_pu_mcs, MCS_MCIFIR_0x02011840, data_buffer_64); + if(rc) return rc; + + // # pu mcicrcsyn + rc = fapiPutScom(i_target_pu_mcs, MCS_MCICRCSYN_0x0201184C, data_buffer_64); + if(rc) return rc; + + // # pu mcicfg + rc = fapiPutScom(i_target_pu_mcs, MCS_MCICFG_0x0201184A, data_buffer_64); + if(rc) return rc; + + // #dmi fir + rc = fapiPutScom(l_target_pu, MC1_BUSCNTL_FIR_0x02011E00, data_buffer_64); + if(rc) return rc; + } + + if(dmi_active) { + ecmdDataBufferBase mask_buffer_64(64); + ecmdDataBufferBase data_buffer_64(64); + + // turn on the FIR propagator so FIR bits shut down the DMI + if(l_attr_proc_ec_mss_reconfig_possible) { + rc_ecmd = data_buffer_64.clearBit(0,64); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + rc_ecmd = mask_buffer_64.clearBit(0,64); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + rc_ecmd = data_buffer_64.clearBit(42); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + rc_ecmd = mask_buffer_64.setBit(42); + if(rc_ecmd) { + rc.setEcmdError(rc_ecmd); + return(rc); + } + rc = fapiPutScomUnderMask(i_target_pu_mcs, MCS_MCICFG_0x0201184A, data_buffer_64, mask_buffer_64); + if(rc) return rc; + } + else { + FAPI_ERR("This processor cannot go through a reconfig loop. Please upgrade to > DD1\n"); + FAPI_SET_HWP_ERROR(rc, RC_PROC_ENABLE_RECONFIG_UNSUPPORTED); + return rc; + } + } + + l_attr_mss_init_state=ENUM_ATTR_MSS_INIT_STATE_COLD; // who knows where we might end on another pass through + rc = FAPI_ATTR_SET(ATTR_MSS_INIT_STATE, &i_target_cen, l_attr_mss_init_state); + return rc; + } + +} // extern C + diff --git a/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig/proc_enable_reconfig.H b/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig/proc_enable_reconfig.H new file mode 100644 index 000000000..5b6453dce --- /dev/null +++ b/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig/proc_enable_reconfig.H @@ -0,0 +1,80 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwas/proc_enable_reconfig/proc_enable_reconfig.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: proc_enable_reconfig.H,v 1.3 2013/11/11 21:29:36 bellows Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ipl/fapi/proc_enable_reconfig.H,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2013 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +// *! Licensed material - Program property of IBM +// *! Refer to copyright instructions form no. G120-2083 +// *! Created on Thu Oct 31 2013 at 15:39:28 +//------------------------------------------------------------------------------ +// *! TITLE : proc_enable_reconfig +// *! DESCRIPTION : see additional comments below +// *! OWNER NAME : Bellows Mark Email: bellows@us.ibm.com +// *! BACKUP NAME : Email: ______@us.ibm.com + +// *! ADDITIONAL COMMENTS : +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.3 | bellows |11-NOV-13| Fixed obsolete comment from when it was part of proc_prep_for_reconfig +// 1.2 | bellows |08-NOV-13| Simplified +// 1.1 | bellows |07-NOV-13| Created from proc_prep_for_reconfig +#ifndef __proc_enable_reconfig_H +#define __proc_enable_reconfig_H + +#include <fapi.H> +#include <p8_scom_addresses.H> + +typedef fapi::ReturnCode (*proc_enable_reconfig_FP_t)(fapi::Target & i_target_pu_mcs, fapi::Target & i_target_cen); + +extern "C" +{ + using namespace fapi; + + CONST_UINT64_T( CENTAUR_MBI_CFG_0x0201080A , ULL(0x0201080A) ); + CONST_UINT64_T( CENTAUR_MBI_FIR_0x02010800 , ULL(0x02010800) ); + CONST_UINT64_T( CENTAUR_MBI_CRCSYN_0x0201080C , ULL(0x0201080C) ); + CONST_UINT64_T( CENTAUR_CEN_DMIFIR_0x02010400 , ULL(0x02010400) ); + +/** + * @brief proc_clear_firs procedure. Turn off FIR spreading and causes a channel fail + * + * @param[in] std::vector<fapi::Target> i_target_mcs, // an MCS with an attached centaur + * @param[in] std::vector<fapi::Target> i_target_cen, // The associated centaur + * + * @return ReturnCode + */ + + ReturnCode proc_enable_reconfig(fapi::Target & i_target_pu_mcs, fapi::Target & i_target_cen); + +} // extern "C" + +#endif diff --git a/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig/proc_enable_reconfig_errors.xml b/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig/proc_enable_reconfig_errors.xml new file mode 100644 index 000000000..5d079acb3 --- /dev/null +++ b/src/usr/hwpf/hwp/proc_hwreconfig/proc_enable_reconfig/proc_enable_reconfig_errors.xml @@ -0,0 +1,31 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: src/usr/hwas/proc_enable_reconfig/proc_enable_reconfig_errors.xml $ --> +<!-- --> +<!-- IBM CONFIDENTIAL --> +<!-- --> +<!-- COPYRIGHT International Business Machines Corp. 2013 --> +<!-- --> +<!-- p1 --> +<!-- --> +<!-- Object Code Only (OCO) source materials --> +<!-- Licensed Internal Code Source Materials --> +<!-- IBM HostBoot Licensed Internal Code --> +<!-- --> +<!-- The source code for this program is not published or otherwise --> +<!-- divested of its trade secrets, irrespective of what has been --> +<!-- deposited with the U.S. Copyright Office. --> +<!-- --> +<!-- Origin: 30 --> +<!-- --> +<!-- IBM_PROLOG_END_TAG --> +<!-- $Id: proc_enable_reconfig_errors.xml,v 1.1 2013/11/08 16:27:51 bellows Exp $ --> +<!-- Error definitions for proc_enable_reconfig procedure --> +<hwpErrors> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PROC_ENABLE_RECONFIG_UNSUPPORTED</rc> + <description>Processor Hardware does not support reconfiguration loops. For Venice and Murano, DD2.0 and greater hardware support this function</description> + </hwpError> +</hwpErrors> diff --git a/src/usr/hwpf/makefile b/src/usr/hwpf/makefile index 979afb3a7..3d72d9eec 100644 --- a/src/usr/hwpf/makefile +++ b/src/usr/hwpf/makefile @@ -126,6 +126,7 @@ HWP_ERROR_XML_FILES = hwp/fapiHwpErrorInfo.xml \ hwp/runtime_errors/p8_gpe_registers.xml \ hwp/runtime_errors/p8_pmc_deconfig_setup_errors.xml \ hwp/runtime_errors/p8_pss_registers.xml \ + hwp/proc_hwreconfig/proc_enable_reconfig/proc_enable_reconfig_errors.xml \ hwp/dram_training/mem_startclocks/cen_mem_startclocks_errors.xml \ hwp/dram_training/mem_pll_setup/cen_mem_pll_initf_errors.xml \ hwp/dram_training/mem_pll_setup/cen_mem_pll_setup_errors.xml diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C index b8f6fcade..5c9295388 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.C +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C @@ -76,10 +76,10 @@ const uint8_t INNER_START_STEP = 12; const uint8_t INNER_START_SUBSTEP = 1; const uint8_t INNER_STOP_STEP = 12; const uint8_t INNER_STOP_SUBSTEP = 5; -const uint8_t OUTER_START_STEP = 13; +const uint8_t OUTER_START_STEP = 10; const uint8_t OUTER_START_SUBSTEP = 1; const uint8_t OUTER_STOP_STEP = 14; -const uint8_t OUTER_STOP_SUBSTEP = 7; +const uint8_t OUTER_STOP_SUBSTEP = 5; const uint8_t HB_START_ISTEP = 6; /** @@ -1329,15 +1329,20 @@ bool IStepDispatcher::checkReconfig(const uint8_t i_curIstep, const uint16_t OUTER_START = (OUTER_START_STEP << 8) | OUTER_START_SUBSTEP; const uint16_t OUTER_STOP = (OUTER_STOP_STEP << 8) | OUTER_STOP_SUBSTEP; + // If current step is within major step 12 if ((current >= INNER_START) && (current <= INNER_STOP)) { doReconfigure = true; + // Loop back to 12.1 o_newIstep = INNER_START_STEP; o_newSubstep = INNER_START_SUBSTEP; } + // Else if current step is outside of 12 but in step 10, 11, 13 or + // 14 (up to 14.5) else if ((current >= OUTER_START) && (current <= OUTER_STOP)) { doReconfigure = true; + // Loop back to 10.1 o_newIstep = OUTER_START_STEP; o_newSubstep = OUTER_START_SUBSTEP; } diff --git a/src/usr/targeting/common/utilFilter.C b/src/usr/targeting/common/utilFilter.C index 2cc0920d5..bb4846074 100644 --- a/src/usr/targeting/common/utilFilter.C +++ b/src/usr/targeting/common/utilFilter.C @@ -31,6 +31,7 @@ #include <targeting/common/predicates/predicateisfunctional.H> #include <targeting/common/predicates/predicatepostfixexpr.H> #include <targeting/common/predicates/predicateattrval.H> +#include <targeting/common/utilFilter.H> /** * Miscellaneous Filter Utility Functions @@ -43,78 +44,176 @@ namespace TARGETING #define TARG_CLASS "" + /** * @brief Populate the o_vector with target object pointers based on the * requested class, type, and functional state. * * @parm[out] o_vector, reference of vector of target pointers. - * @parm[in] i_class, the class of the targets to be obtained - * @parm[in] i_type, the type of the targets to be obtained - * @parm[in] i_functional, set to true to return only functional targets + * @parm[in] i_class, the class of the targets to be obtained + * @parm[in] i_type, the type of the targets to be obtained + * @parm[in] i_state, Selection filter based on ResourceState enum, + * designates all, present, or functional * * @return N/A */ -void _getAllChipsOrChiplets( TARGETING::TargetHandleList & o_vector, - CLASS i_class, TYPE i_type, bool i_functional = true ) +void _getChipOrChipletResources( TARGETING::TargetHandleList & o_vector, + CLASS i_class, TYPE i_type, ResourceState i_state ) { - // Get all chip/chiplet targets - // Use PredicateIsFunctional to filter only functional chips/chiplets - TARGETING::PredicateIsFunctional l_isFunctional; - // filter for functional Chips/Chiplets - TARGETING::PredicateCTM l_Filter(i_class, i_type); - // declare a postfix expression widget - TARGETING::PredicatePostfixExpr l_goodFilter; - // is-a--chip is-functional AND - l_goodFilter.push(&l_Filter).push(&l_isFunctional).And(); - // apply the filter through all targets. - TARGETING::TargetRangeFilter l_filter( TARGETING::targetService().begin(), - TARGETING::targetService().end(), &l_goodFilter ); - if (!i_functional) + #define TARG_FN "_getChipOrChipletResources(...)" + TARG_ENTER(); + switch(i_state) { - l_filter.setPredicate(&l_Filter); + case UTIL_FILTER_ALL: + { + // Type predicate + TARGETING::PredicateCTM l_CtmFilter(i_class, i_type); + // Apply the filter through all targets + TARGETING::TargetRangeFilter l_targetList( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_CtmFilter); + o_vector.clear(); + for ( ; l_targetList; ++l_targetList) + { + o_vector.push_back(*l_targetList); + } + break; + } + case UTIL_FILTER_PRESENT: + { + // Get all present chips or chiplets + // Present predicate + PredicateHwas l_predPres; + l_predPres.present(true); + // Type predicate + TARGETING::PredicateCTM l_CtmFilter(i_class, i_type); + // Set up compound predicate + TARGETING::PredicatePostfixExpr l_present; + l_present.push(&l_CtmFilter).push(&l_predPres).And(); + // Apply the filter through all targets + TARGETING::TargetRangeFilter l_presTargetList( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_present); + o_vector.clear(); + for ( ; l_presTargetList; ++l_presTargetList) + { + o_vector.push_back(*l_presTargetList); + } + break; + } + case UTIL_FILTER_FUNCTIONAL: + { + // Get all functional chips or chiplets + // Functional predicate + TARGETING::PredicateIsFunctional l_isFunctional; + // Type predicate + TARGETING::PredicateCTM l_CtmFilter(i_class, i_type); + // Set up compound predicate + TARGETING::PredicatePostfixExpr l_functional; + l_functional.push(&l_CtmFilter).push(&l_isFunctional).And(); + // Apply the filter through all targets + TARGETING::TargetRangeFilter l_funcTargetList( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_functional); + o_vector.clear(); + for ( ; l_funcTargetList; ++l_funcTargetList) + { + o_vector.push_back(*l_funcTargetList); + } + break; + } + default: + TARG_ASSERT(0, TARG_LOC "Invalid functional state used"); + break; } + TARG_EXIT(); + #undef TARG_FN +} - o_vector.clear(); - for ( ; l_filter; ++l_filter) - { - o_vector.push_back( *l_filter ); - } + +void getChipResources( TARGETING::TargetHandleList & o_vector, + TYPE i_chipType, ResourceState i_state ) +{ + _getChipOrChipletResources(o_vector, CLASS_CHIP, i_chipType, i_state); } +void getChipletResources( TARGETING::TargetHandleList & o_vector, + TYPE i_chipletType, ResourceState i_state ) +{ + _getChipOrChipletResources(o_vector, CLASS_UNIT, i_chipletType, i_state); +} +// Retrofit functions to getChipOrChipletResources void getAllChips( TARGETING::TargetHandleList & o_vector, - TYPE i_chipType, bool i_functional = true ) + TYPE i_chipType, bool i_functional ) { - _getAllChipsOrChiplets(o_vector, CLASS_CHIP, i_chipType, i_functional); + if (i_functional) + { + _getChipOrChipletResources(o_vector, CLASS_CHIP, i_chipType, UTIL_FILTER_FUNCTIONAL); + } + else + { + _getChipOrChipletResources(o_vector, CLASS_CHIP, i_chipType, UTIL_FILTER_ALL); + } } void getAllLogicalCards( TARGETING::TargetHandleList & o_vector, TYPE i_cardType, - bool i_functional = true ) + bool i_functional ) { - _getAllChipsOrChiplets( o_vector, - CLASS_LOGICAL_CARD, - i_cardType, - i_functional ); + if (i_functional) + { + _getChipOrChipletResources( o_vector, + CLASS_LOGICAL_CARD, + i_cardType, + UTIL_FILTER_FUNCTIONAL ); + } + else + { + _getChipOrChipletResources( o_vector, + CLASS_LOGICAL_CARD, + i_cardType, + UTIL_FILTER_ALL ); + } } void getAllCards( TARGETING::TargetHandleList & o_vector, TYPE i_cardType, - bool i_functional = true ) + bool i_functional ) { - _getAllChipsOrChiplets( o_vector, - CLASS_CARD, - i_cardType, - i_functional ); + if (i_functional) + { + _getChipOrChipletResources( o_vector, + CLASS_CARD, + i_cardType, + UTIL_FILTER_FUNCTIONAL ); + } + else + { + _getChipOrChipletResources( o_vector, + CLASS_CARD, + i_cardType, + UTIL_FILTER_ALL ); + } } void getAllChiplets( TARGETING::TargetHandleList & o_vector, - TYPE i_chipletType, bool i_functional = true ) + TYPE i_chipletType, bool i_functional ) { - _getAllChipsOrChiplets(o_vector, CLASS_UNIT, i_chipletType, i_functional); + if (i_functional) + { + _getChipOrChipletResources(o_vector, CLASS_UNIT, i_chipletType, UTIL_FILTER_FUNCTIONAL); + } + else + { + _getChipOrChipletResources(o_vector, CLASS_UNIT, i_chipletType, UTIL_FILTER_ALL); + } } @@ -385,6 +484,7 @@ void getPeerTargets( #undef TARG_FN } + #undef TARG_CLASS #undef TARG_NAMESPACE |