From f945eb6a6bec1076f1b3db00939e6b083d61dcab Mon Sep 17 00:00:00 2001 From: Brian Horton Date: Wed, 20 May 2015 15:03:29 -0500 Subject: start occ checkstop handling during IPL Change-Id: I38e29f0044b982073fc7c24b71b5104515e74024 RTC: 115587 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/18883 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III --- src/include/usr/diag/prdf/prdfWriteHomerFirData.H | 8 +- src/include/usr/hwpf/hwp/occ/occ.H | 9 +- src/include/usr/hwpf/hwp/occ/occAccess.H | 4 +- src/include/usr/hwpf/hwp/occ/occ_common.H | 35 ++- src/include/usr/hwpf/hwpf_reasoncodes.H | 2 + src/include/usr/isteps/istep06list.H | 3 + src/include/usr/isteps/istep08list.H | 3 + src/include/usr/isteps/istep10list.H | 3 + src/include/usr/isteps/istep14list.H | 5 +- src/include/usr/isteps/istep16list.H | 5 +- src/usr/hwas/hostbootIstep.C | 37 ++- src/usr/hwpf/hwp/core_activate/core_activate.C | 26 +++ .../hwp/dram_initialization/dram_initialization.C | 19 +- .../edi_ei_initialization/edi_ei_initialization.C | 56 +++-- src/usr/hwpf/hwp/occ/occ.C | 196 +++++++++++----- src/usr/hwpf/hwp/occ/occ_common.C | 258 +++++++++++++++++++-- 16 files changed, 565 insertions(+), 104 deletions(-) diff --git a/src/include/usr/diag/prdf/prdfWriteHomerFirData.H b/src/include/usr/diag/prdf/prdfWriteHomerFirData.H index f4e3590f0..7fa3a6d5d 100644 --- a/src/include/usr/diag/prdf/prdfWriteHomerFirData.H +++ b/src/include/usr/diag/prdf/prdfWriteHomerFirData.H @@ -1,7 +1,7 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.H $ */ +/* $Source: src/include/usr/diag/prdf/prdfWriteHomerFirData.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ @@ -23,6 +23,9 @@ /* */ /* IBM_PROLOG_END_TAG */ +#ifndef __prdfWriteHomerFirData_H +#define __prdfWriteHomerFirData_H + #include namespace PRDF @@ -41,9 +44,12 @@ enum HwInitialized_t * the OCC to capture in the event of a system checkstop. * @param i_hBuf SRAM pointer to the beginning of the HOMER data buffer. * @param i_hBufSize Total size of the HOMER data buffer. + * @param i_curHW enum indicating which HW is currently known * @return An error log on failure. NULL on success. */ errlHndl_t writeHomerFirData( uint8_t * i_hBuf, size_t i_hBufSize, const HwInitialized_t i_curHw = ALL_HARDWARE ); }; // end namespace PRDF +#endif // __prdfWriteHomerFirData_H + diff --git a/src/include/usr/hwpf/hwp/occ/occ.H b/src/include/usr/hwpf/hwp/occ/occ.H index 9bf494669..c4dba0996 100644 --- a/src/include/usr/hwpf/hwp/occ/occ.H +++ b/src/include/usr/hwpf/hwp/occ/occ.H @@ -35,17 +35,22 @@ namespace HBOCC { * * @param[out] o_failedOccTarget: Pointer to the target failing * loadnStartAllOccs + * @param[in] i_useSRAM: bool - use SRAM for OCC image, ie during IPL + * true if during IPL, false if at end of IPL (default) * @return errlHndl_t Error log if OCC load failed */ - errlHndl_t loadnStartAllOccs(TARGETING::Target *& o_failedOccTarget); + errlHndl_t loadnStartAllOccs(TARGETING::Target *& o_failedOccTarget, + bool i_useSRAM = false); /** * @brief Starts OCCs on all Processors in the node * This is intended to be used for Open Power. * + * @param[in] i_useSRAM: bool - use SRAM for OCC image, ie during IPL + * true if during IPL, false if at end of IPL (default) * @return errlHndl_t Error log if OCC load failed */ - errlHndl_t activateOCCs(); + errlHndl_t activateOCCs(bool i_useSRAM = false); } //end OCC namespace diff --git a/src/include/usr/hwpf/hwp/occ/occAccess.H b/src/include/usr/hwpf/hwp/occ/occAccess.H index b13f280af..f5de96589 100644 --- a/src/include/usr/hwpf/hwp/occ/occAccess.H +++ b/src/include/usr/hwpf/hwp/occ/occAccess.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -30,7 +30,6 @@ #include #include -#ifdef CONFIG_HTMGT namespace HBOCC { @@ -69,6 +68,5 @@ namespace HBOCC ecmdDataBufferBase & i_dataBuf); } //end OCC namespace -#endif // CONFIG_HTMGT #endif diff --git a/src/include/usr/hwpf/hwp/occ/occ_common.H b/src/include/usr/hwpf/hwp/occ/occ_common.H index 7ddb302b7..4dd83cbec 100644 --- a/src/include/usr/hwpf/hwp/occ/occ_common.H +++ b/src/include/usr/hwpf/hwp/occ/occ_common.H @@ -27,6 +27,7 @@ #include #include +#include namespace HBOCC { @@ -69,7 +70,19 @@ namespace HBOCC // FIR Master NOT_FIR_MASTER = 0x00000000, - IS_FIR_MASTER = 0x00000001 + IS_FIR_MASTER = 0x00000001, + + // SRAM Address for OCC Main App + OCC_SRAM_ADDRESS = 0xFFF80000, + + // SRAM Address and length for FIR HOMER data + OCC_SRAM_FIR_DATA = 0xFFFF5000, + OCC_SRAM_FIR_LENGTH = 0x1000, + + // offsets for OCC loading during IPL + OCC_OFFSET_IPL_FLAG = 0x82, + OCC_OFFSET_FREQ = 0x84, + }; enum occAction_t @@ -78,7 +91,7 @@ namespace HBOCC OCC_STOP, }; /** - * @brief Sets up OCC Host data + * @brief Sets up OCC Host data in Homer * * @param[in] i_proc: target processor to load * @param[in] i_occHostDataVirtAddr Virtual @@ -90,6 +103,19 @@ namespace HBOCC errlHndl_t loadHostDataToHomer(TARGETING::Target* i_proc, void* i_occHostDataVirtAddr); +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + /** + * @brief Sets up OCC Host data in SRAM + * + * @param[in] i_proc: target processor to load + * @param[in] i_curHW: enum indicating which HW is currently known + * + * @return errlHndl_t Error log Host data setup failed + */ + errlHndl_t loadHostDataToSRAM(TARGETING::Target* i_proc, + const PRDF::HwInitialized_t i_curHw = PRDF::ALL_HARDWARE); +#endif + /** * @brief Execute procedures and steps required to load * OCC data in a specified processor @@ -101,12 +127,15 @@ namespace HBOCC * proc's OCC image int the homer * @param[in] i_commonPhysAddr: Physical address of common * OCC region + * @param[in] i_useSRAM: bool - use SRAM for OCC image, ie during IPL + * true if duringIPL, false if at end of IPL (default) * @return errlHndl_t Error log if loadOCC failed */ errlHndl_t loadOCC(TARGETING::Target* i_target, uint64_t i_occImgPaddr, uint64_t i_occImgVaddr, - uint64_t i_commonPhysAddr); + uint64_t i_commonPhysAddr, + bool i_useSRAM = false); /** * @brief Start OCC for specified DCM pair of processors. diff --git a/src/include/usr/hwpf/hwpf_reasoncodes.H b/src/include/usr/hwpf/hwpf_reasoncodes.H index 4ef403eb8..80178275d 100644 --- a/src/include/usr/hwpf/hwpf_reasoncodes.H +++ b/src/include/usr/hwpf/hwpf_reasoncodes.H @@ -83,6 +83,7 @@ namespace fapi MOD_GET_WOF_FREQ_UPLIFT_SELECTED = 0x29, MOD_SET_NEST_FREQ = 0x2A, MOD_FIND_MAX_DMI_SPD = 0x2B, + MOD_OCC_LOAD_HOST_DATA_TO_SRAM = 0x2C, }; /** @@ -143,6 +144,7 @@ namespace fapi RC_NO_SINGLE_NODE = HWPF_COMP_ID | 0x3A, RC_INVALID_ULTRA_TURBO_FREQ = HWPF_COMP_ID | 0x3B, RC_INVALID_WOF_INDEX = HWPF_COMP_ID | 0x3C, + RC_ECMD_INSERT_FAILED = HWPF_COMP_ID | 0x3D, }; /** diff --git a/src/include/usr/isteps/istep06list.H b/src/include/usr/isteps/istep06list.H index 8b55f23a0..761b1f662 100644 --- a/src/include/usr/isteps/istep06list.H +++ b/src/include/usr/isteps/istep06list.H @@ -162,6 +162,9 @@ const DepModInfo g_istep06Dependancies = { DEP_LIB(libpstates.so), DEP_LIB(libcore_activate.so), DEP_LIB(libsecure_boot.so), +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + DEP_LIB(libocc.so), +#endif NULL } }; diff --git a/src/include/usr/isteps/istep08list.H b/src/include/usr/isteps/istep08list.H index 0a721c694..90f91f8d5 100644 --- a/src/include/usr/isteps/istep08list.H +++ b/src/include/usr/isteps/istep08list.H @@ -122,6 +122,9 @@ const DepModInfo g_istep08Dependancies = { DEP_LIB(libslave_sbe.so), DEP_LIB(libsbe.so), DEP_LIB(libbuild_winkle_images.so), +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + DEP_LIB(libocc.so), +#endif NULL } }; diff --git a/src/include/usr/isteps/istep10list.H b/src/include/usr/isteps/istep10list.H index 3dace26bb..86f12366f 100644 --- a/src/include/usr/isteps/istep10list.H +++ b/src/include/usr/isteps/istep10list.H @@ -170,6 +170,9 @@ const DepModInfo g_istep10Dependancies = { DEP_LIB(libsbe.so), DEP_LIB(libproc_hwreconfig.so), DEP_LIB(libslave_sbe.so), +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + DEP_LIB(libocc.so), +#endif #endif NULL } diff --git a/src/include/usr/isteps/istep14list.H b/src/include/usr/isteps/istep14list.H index d4ebcd88f..b8da1fab3 100644 --- a/src/include/usr/isteps/istep14list.H +++ b/src/include/usr/isteps/istep14list.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -129,6 +129,9 @@ const DepModInfo g_istep14Dependancies = { DEP_LIB(libdram_training.so), DEP_LIB(libdump.so), DEP_LIB(libnest_chiplets.so), +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + DEP_LIB(libocc.so), +#endif #endif NULL } diff --git a/src/include/usr/isteps/istep16list.H b/src/include/usr/isteps/istep16list.H index 1dc968c18..bde62884e 100644 --- a/src/include/usr/isteps/istep16list.H +++ b/src/include/usr/isteps/istep16list.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -91,6 +91,9 @@ const DepModInfo g_istep16Dependancies = { DEP_LIB(libcore_activate.so), DEP_LIB(libbuild_winkle_images.so), DEP_LIB(libnest_chiplets.so), +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + DEP_LIB(libocc.so), +#endif NULL } }; diff --git a/src/usr/hwas/hostbootIstep.C b/src/usr/hwas/hostbootIstep.C index df994cba7..b3f510a3d 100644 --- a/src/usr/hwas/hostbootIstep.C +++ b/src/usr/hwas/hostbootIstep.C @@ -75,6 +75,9 @@ #include #ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + #include + #include + #include #endif @@ -357,7 +360,17 @@ void* host_cancontinue_clear( void *io_pArgs ) "host_cancontinue_clear entry" ); errlHndl_t errl = NULL; - // stub -- nothing here currently +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + // TODO RTC 115587: current place; could change + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "host_cancontinue_clear: calling activateOCCs" ); + errl = HBOCC::activateOCCs(true); + if (errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "activateOCCs failed"); + } +#endif TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_cancontinue_clear exit" ); @@ -450,9 +463,31 @@ void* host_prd_hwreconfig( void *io_pArgs ) TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "Successfully ran proc_enable_reconfig HWP on " "MCS target HUID %.8X", l_currMcsHuid); + } // for + +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + // update firdata inputs for OCC + TARGETING::Target* masterproc = NULL; + TARGETING::targetService().masterProcChipTargetHandle(masterproc); + errl = HBOCC::loadHostDataToSRAM(masterproc, + PRDF::MASTER_PROC_CORE); + if (errl) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Error returned from call to HBOCC::loadHostDataToSRAM"); + + //Create IStep error log and cross reference error that occurred + l_stepError.addErrorDetails(errl); + + // Commit Error + errlCommit(errl, HWPF_COMP_ID); + break; } +#endif + } while(0); + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_prd_hwreconfig exit" ); // end task, returning any errorlogs to IStepDisp diff --git a/src/usr/hwpf/hwp/core_activate/core_activate.C b/src/usr/hwpf/hwp/core_activate/core_activate.C index b8b01ed5f..8fc317327 100644 --- a/src/usr/hwpf/hwp/core_activate/core_activate.C +++ b/src/usr/hwpf/hwp/core_activate/core_activate.C @@ -85,6 +85,10 @@ #include #include +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + #include +#endif + namespace CORE_ACTIVATE { @@ -637,6 +641,28 @@ void* call_host_activate_slave_cores( void *io_pArgs ) // @@@@@ END CUSTOM BLOCK: @@@@@ +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + if( l_stepError.isNull() ) + { + // update firdata inputs for OCC + TARGETING::Target* masterproc = NULL; + TARGETING::targetService().masterProcChipTargetHandle(masterproc); + l_errl = HBOCC::loadHostDataToSRAM(masterproc, + PRDF::ALL_HARDWARE); + if (l_errl) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Error returned from call to HBOCC::loadHostDataToSRAM"); + + //Create IStep error log and cross reference error that occurred + l_stepError.addErrorDetails(l_errl); + + // Commit Error + errlCommit(l_errl, HWPF_COMP_ID); + } + } +#endif + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_slave_cores exit" ); diff --git a/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C b/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C index b8ee8dd8d..53cde0d53 100644 --- a/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C +++ b/src/usr/hwpf/hwp/dram_initialization/dram_initialization.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -82,6 +82,10 @@ #include #include +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + #include +#endif + namespace DRAM_INITIALIZATION { @@ -133,6 +137,19 @@ void* call_host_startprd_dram( void *io_pArgs ) // @@@@@ END CUSTOM BLOCK: @@@@@ #endif +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + // update firdata inputs for OCC + TARGETING::Target* masterproc = NULL; + TARGETING::targetService().masterProcChipTargetHandle(masterproc); + l_errl = HBOCC::loadHostDataToSRAM(masterproc, + PRDF::ALL_PROC_MEM_MASTER_CORE); + if (l_errl) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Error returned from call to HBOCC::loadHostDataToSRAM"); + } +#endif + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_startPRD_dram exit" ); diff --git a/src/usr/hwpf/hwp/edi_ei_initialization/edi_ei_initialization.C b/src/usr/hwpf/hwp/edi_ei_initialization/edi_ei_initialization.C index e1ab17db2..c02d91985 100644 --- a/src/usr/hwpf/hwp/edi_ei_initialization/edi_ei_initialization.C +++ b/src/usr/hwpf/hwp/edi_ei_initialization/edi_ei_initialization.C @@ -85,6 +85,10 @@ // eRepair Restore #include +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + #include +#endif + namespace EDI_EI_INITIALIZATION { @@ -687,28 +691,46 @@ void* call_host_startprd_pbus( void *io_pArgs ) TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_startprd_pbus entry" ); - l_errl = PRDF::initialize(); - - if (l_errl) + do { - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "Error returned from call to PRDF::initialize"); - } + l_errl = PRDF::initialize(); + if (l_errl) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Error returned from call to PRDF::initialize"); + break; + } - // Perform calculated deconfiguration of procs based on - // bus endpoint deconfigurations, and perform SMP node - // balancing - l_errl = HWAS::theDeconfigGard().deconfigureAssocProc(); + // Perform calculated deconfiguration of procs based on + // bus endpoint deconfigurations, and perform SMP node + // balancing + l_errl = HWAS::theDeconfigGard().deconfigureAssocProc(); + if (l_errl) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Error returned from call to " + "HWAS::theDeconfigGard().deconfigureAssocProc"); + break; + } - if (l_errl) - { - TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "Error returned from call to " - "HWAS::theDeconfigGard().deconfigureAssocProc"); - } +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + // update firdata inputs for OCC + TARGETING::Target* masterproc = NULL; + TARGETING::targetService().masterProcChipTargetHandle(masterproc); + l_errl = HBOCC::loadHostDataToSRAM(masterproc, + PRDF::ALL_PROC_MASTER_CORE); + if (l_errl) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Error returned from call to HBOCC::loadHostDataToSRAM"); + break; + } +#endif + + }while(0); TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "call_host_startprd_pbus exit" ); + "call_host_startprd_pbus exit" ); // end task, returning any errorlogs to IStepDisp return l_errl; diff --git a/src/usr/hwpf/hwp/occ/occ.C b/src/usr/hwpf/hwp/occ/occ.C index fa1a54752..2b062cd87 100644 --- a/src/usr/hwpf/hwp/occ/occ.C +++ b/src/usr/hwpf/hwp/occ/occ.C @@ -84,82 +84,116 @@ namespace HBOCC * @param[in] i_homerPhysAddrBase * IPL: Base Physical address of all HOMER images * Runtime: Ignored - Determined using Attributes + * @param[in] i_useSRAM: bool - use SRAM for OCC image, ie during IPL + * true if during IPL, false if at end of IPL (default) * * @return errlHndl_t Error log */ errlHndl_t primeAndLoadOcc (Target* i_target, void* i_homerVirtAddrBase, - uint64_t i_homerPhysAddrBase) + uint64_t i_homerPhysAddrBase, + bool i_useSRAM) { errlHndl_t l_errl = NULL; TRACUCOMP( g_fapiTd, - ENTER_MRK"primeAndLoadOcc" ); - + ENTER_MRK"primeAndLoadOcc(%d)", i_useSRAM); do { //============================== //Setup Addresses //============================== + uint64_t occImgPaddr, occImgVaddr; + uint64_t commonPhysAddr, homerHostVirtAddr; #ifndef __HOSTBOOT_RUNTIME - uint8_t procPos = i_target->getAttr(); - uint64_t procOffset = (procPos * VMM_HOMER_INSTANCE_SIZE); - uint64_t occImgPaddr = - i_homerPhysAddrBase + procOffset + HOMER_OFFSET_TO_OCC_IMG; + const uint8_t procPos = i_target->getAttr(); + const uint64_t procOffset = (procPos * VMM_HOMER_INSTANCE_SIZE); + + if (i_useSRAM) + { + occImgVaddr = reinterpret_cast(i_homerVirtAddrBase); + } + else + { + occImgVaddr = reinterpret_cast(i_homerVirtAddrBase) + + procOffset + HOMER_OFFSET_TO_OCC_IMG; + } - uint64_t occImgVaddr = reinterpret_cast - (i_homerVirtAddrBase) + procOffset + HOMER_OFFSET_TO_OCC_IMG; + occImgPaddr = + i_homerPhysAddrBase + procOffset + HOMER_OFFSET_TO_OCC_IMG; - uint64_t commonPhysAddr = + commonPhysAddr = i_homerPhysAddrBase + VMM_HOMER_REGION_SIZE; - uint64_t homerHostVirtAddr = reinterpret_cast + homerHostVirtAddr = reinterpret_cast (i_homerVirtAddrBase) + procOffset + HOMER_OFFSET_TO_OCC_HOST_DATA; #else uint64_t homerPaddr = i_target->getAttr(); uint64_t homerVaddr = i_target->getAttr(); - uint64_t occImgPaddr = homerPaddr + HOMER_OFFSET_TO_OCC_IMG; - uint64_t occImgVaddr = homerVaddr + HOMER_OFFSET_TO_OCC_IMG; + occImgPaddr = homerPaddr + HOMER_OFFSET_TO_OCC_IMG; + occImgVaddr = homerVaddr + HOMER_OFFSET_TO_OCC_IMG; TARGETING::Target* sys = NULL; TARGETING::targetService().getTopLevelTarget(sys); - uint64_t commonPhysAddr = + commonPhysAddr = sys->getAttr(); - uint64_t homerHostVirtAddr = + homerHostVirtAddr = homerVaddr + HOMER_OFFSET_TO_OCC_HOST_DATA; - #endif //============================== // Load OCC //============================== - l_errl= HBOCC::loadOCC(i_target, + l_errl = HBOCC::loadOCC(i_target, occImgPaddr, occImgVaddr, - commonPhysAddr); + commonPhysAddr, + i_useSRAM); if(l_errl != NULL) { TRACFCOMP( g_fapiImpTd, ERR_MRK"primeAndLoadOcc: loadOCC failed" ); break; } - //============================== - //Setup host data area of HOMER; - //============================== - void* occHostVirt = reinterpret_cast(homerHostVirtAddr); - l_errl = HBOCC::loadHostDataToHomer(i_target,occHostVirt); - if( l_errl != NULL ) +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS +#ifndef __HOSTBOOT_RUNTIME + if (i_useSRAM) { - TRACFCOMP( g_fapiImpTd, ERR_MRK"loading Host Data Area failed!" ); - break; + //============================== + //Setup host data area in SRAM + //============================== + l_errl = HBOCC::loadHostDataToSRAM(i_target, + PRDF::MASTER_PROC_CORE); + if( l_errl != NULL ) + { + TRACFCOMP( g_fapiImpTd, ERR_MRK"loading Host Data Area failed!" ); + break; + } + } + else +#endif +#endif + { + //============================== + //Setup host data area of HOMER; + //============================== + void* occHostVirt = reinterpret_cast(homerHostVirtAddr); + l_errl = HBOCC::loadHostDataToHomer(i_target,occHostVirt); + if( l_errl != NULL ) + { + TRACFCOMP( g_fapiImpTd, ERR_MRK"loading Host Data Area failed!" ); + break; + } } } while (0); + TRACUCOMP( g_fapiTd, + EXIT_MRK"primeAndLoadOcc" ); return l_errl; } @@ -169,9 +203,12 @@ namespace HBOCC * * @param[out] o_failedOccTarget: Pointer to the target failing * loadnStartAllOccs + * @param[in] i_useSRAM: bool - use SRAM for OCC image, ie during IPL + * true if during IPL, false if at end of IPL (default) * @return errlHndl_t Error log if OCC load failed */ - errlHndl_t loadnStartAllOccs(TARGETING::Target *& o_failedOccTarget) + errlHndl_t loadnStartAllOccs(TARGETING::Target *& o_failedOccTarget, + bool i_useSRAM) { errlHndl_t l_errl = NULL; void* homerVirtAddrBase = NULL; @@ -179,7 +216,7 @@ namespace HBOCC bool winkle_loaded = false; TRACUCOMP( g_fapiTd, - ENTER_MRK"loadnStartAllOccs" ); + ENTER_MRK"loadnStartAllOccs(%d)", i_useSRAM); do { #ifndef __HOSTBOOT_RUNTIME @@ -201,22 +238,71 @@ namespace HBOCC assert(VMM_HOMER_REGION_SIZE <= THIRTYTWO_GB, "loadnStartAllOccs: Unsupported HOMER Region size"); - //If running Sapphire need to place this at the top of memory - if(TARGETING::is_sapphire_load()) + if (!i_useSRAM) + { + //If running Sapphire need to place this at the top of memory + if(TARGETING::is_sapphire_load()) + { + homerPhysAddrBase = TARGETING::get_top_mem_addr(); + assert (homerPhysAddrBase != 0, + "loadnStartAllOccs: Top of memory was 0!"); + homerPhysAddrBase -= VMM_ALL_HOMER_OCC_MEMORY_SIZE; + } + TRACFCOMP( g_fapiTd, "HOMER is at %.16X", homerPhysAddrBase ); + + //Map entire homer region into virtual memory + homerVirtAddrBase = + mm_block_map(reinterpret_cast(homerPhysAddrBase), + VMM_HOMER_REGION_SIZE); + TRACFCOMP( g_fapiTd, "HOMER virtaddrbase %.16X", homerVirtAddrBase ); + } + else { - homerPhysAddrBase = TARGETING::get_top_mem_addr(); - assert (homerPhysAddrBase != 0, - "loadnStartAllOccs: Top of memory was 0!"); - homerPhysAddrBase -= VMM_ALL_HOMER_OCC_MEMORY_SIZE; + // malloc space big enough for all of OCC + homerVirtAddrBase = (void *)malloc(1 * MEGABYTE); + homerPhysAddrBase = mm_virt_to_phys(homerVirtAddrBase); } - TRACFCOMP( g_fapiTd, "HOMER is at %.16X", homerPhysAddrBase ); +#endif + + if (i_useSRAM) + { + // OCC is going into L3 and SRAM so only need 1 prime and load + // into the Master Proc + TargetService & tS = targetService(); + Target * sysTarget = NULL; + tS.getTopLevelTarget( sysTarget ); + assert( sysTarget != NULL ); + Target* masterproc = NULL; + tS.masterProcChipTargetHandle( masterproc ); + + /******* SETUP AND LOAD **************/ + l_errl = primeAndLoadOcc (masterproc, + homerVirtAddrBase, + homerPhysAddrBase, + i_useSRAM); + if(l_errl) + { + o_failedOccTarget = masterproc; + TRACFCOMP( g_fapiImpTd, ERR_MRK + "loadnStartAllOccs:primeAndLoadOcc failed"); + free(homerVirtAddrBase); + break; + } - //Map entire homer region into virtual memory - homerVirtAddrBase = - mm_block_map(reinterpret_cast(homerPhysAddrBase), - VMM_HOMER_REGION_SIZE); + /********* START OCC *************/ + l_errl = HBOCC::startOCC (masterproc, NULL, o_failedOccTarget); -#endif + // it either started or errored; either way, free the memory + free(homerVirtAddrBase); + + if (l_errl) + { + TRACFCOMP( g_fapiImpTd, ERR_MRK"loadnStartAllOccs: startOCC failed"); + break; + } + } + else + { TargetHandleList procChips; getAllChips(procChips, TYPE_PROC, true); @@ -233,6 +319,7 @@ namespace HBOCC INFO_MRK"loadnStartAllOccs: %d procs found", procChips.size()); + TargetHandleList::iterator itr1 = procChips.begin(); //The OCC Procedures require processors within a DCM be //setup together. So, first checking if any proc has //DCM installed attribute set. If not, we can iterate @@ -241,9 +328,6 @@ namespace HBOCC //If DCM installed is set, we work under the assumption //that each nodeID is a DCM. So sort the list by NodeID //then call OCC Procedures on NodeID pairs. - - TargetHandleList::iterator itr1 = procChips.begin(); - if(0 == (*itr1)->getAttr()) { @@ -257,12 +341,13 @@ namespace HBOCC /******* SETUP AND LOAD **************/ l_errl = primeAndLoadOcc (*itr, homerVirtAddrBase, - homerPhysAddrBase); + homerPhysAddrBase, + i_useSRAM); if(l_errl) { o_failedOccTarget = *itr; TRACFCOMP( g_fapiImpTd, ERR_MRK - "loadnStartAllOccs:loadnStartOcc failed"); + "loadnStartAllOccs:primeAndLoadOcc failed"); break; } @@ -270,7 +355,7 @@ namespace HBOCC l_errl = HBOCC::startOCC (*itr, NULL, o_failedOccTarget); if (l_errl) { - TRACFCOMP( g_fapiImpTd, ERR_MRK"loadnStartAllOcc: start failed"); + TRACFCOMP( g_fapiImpTd, ERR_MRK"loadnStartAllOccs: startOCC failed"); break; } } @@ -326,7 +411,8 @@ namespace HBOCC /********** Setup and load targ0 ***********/ l_errl = primeAndLoadOcc (targ0, homerVirtAddrBase, - homerPhysAddrBase); + homerPhysAddrBase, + i_useSRAM); if(l_errl) { o_failedOccTarget = targ0; @@ -339,7 +425,8 @@ namespace HBOCC /*********** Setup and load targ1 **********/ l_errl = primeAndLoadOcc (targ1, homerVirtAddrBase, - homerPhysAddrBase); + homerPhysAddrBase, + i_useSRAM); if(l_errl) { o_failedOccTarget = targ1; @@ -363,7 +450,7 @@ namespace HBOCC break; } } - + } } while(0); errlHndl_t l_tmpErrl = NULL; @@ -441,16 +528,16 @@ namespace HBOCC * * @return errlHndl_t Error log if OCC load failed */ - errlHndl_t activateOCCs() + errlHndl_t activateOCCs(bool i_useSRAM) { - TRACUCOMP( g_fapiTd,ENTER_MRK"activateOCCs" ); + TRACUCOMP( g_fapiTd,ENTER_MRK"activateOCCs(%d)", i_useSRAM ); errlHndl_t l_errl = NULL; TARGETING::Target* l_failedOccTarget = NULL; #ifdef CONFIG_HTMGT bool occStartSuccess = true; #endif - l_errl = loadnStartAllOccs (l_failedOccTarget); + l_errl = loadnStartAllOccs (l_failedOccTarget, i_useSRAM); if (l_errl) { errlCommit (l_errl, HWPF_COMP_ID); @@ -467,7 +554,10 @@ namespace HBOCC #ifdef CONFIG_HTMGT // Report OCC status to HTMGT - HTMGT::processOccStartStatus(occStartSuccess,l_failedOccTarget); + if (!i_useSRAM) + { + HTMGT::processOccStartStatus(occStartSuccess,l_failedOccTarget); + } #endif TRACUCOMP( g_fapiTd,EXIT_MRK"activateOCC" ); return l_errl; diff --git a/src/usr/hwpf/hwp/occ/occ_common.C b/src/usr/hwpf/hwp/occ/occ_common.C index 983d84ea3..96ef4d7f3 100644 --- a/src/usr/hwpf/hwp/occ/occ_common.C +++ b/src/usr/hwpf/hwp/occ/occ_common.C @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -121,8 +122,101 @@ namespace HBOCC return l_errl; } +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + errlHndl_t loadOCCImageDuringIpl( TARGETING::Target* i_target, + void* i_occVirtAddr) + { + TRACUCOMP( g_fapiTd, + ENTER_MRK"loadOCCImageDuringIpl(%p)", + i_occVirtAddr); + + errlHndl_t l_errl = NULL; + size_t lidSize = 0; + do { + UtilLidMgr lidMgr(HBOCC::OCC_LIDID); + + l_errl = lidMgr.getLidSize(lidSize); + if(l_errl) + { + TRACFCOMP( g_fapiImpTd, + ERR_MRK"loadOCCImageDuringIpl: Error getting lid size. lidId=0x%.8x", + OCC_LIDID); + break; + } + + // get the full OCC LID and then copy them. + l_errl = lidMgr.getLid(i_occVirtAddr, lidSize); + if(l_errl) + { + TRACFCOMP( g_fapiImpTd, + ERR_MRK"loadOCCImageDuringIpl: Error getting lid. lidId=0x%.8x", + OCC_LIDID); + break; + } + + // OCC Boot Image is now at the start of that L3 region. + size_t l_length = 0; // length of this section + size_t l_startOffset = 0; // offset to start of the section + size_t l_offsetToLength = 0x48; // offset to length of the section + + char *l_tmpStart = reinterpret_cast(i_occVirtAddr) + + l_startOffset; + uint32_t *ptrToLength = (uint32_t *)(l_tmpStart + l_offsetToLength); + l_length = *ptrToLength; + + // OCC Main Application + l_startOffset = l_length; // after the Boot image + l_tmpStart = reinterpret_cast(i_occVirtAddr) + + l_startOffset; + ptrToLength = (uint32_t *)(l_tmpStart + l_offsetToLength); + l_length = *ptrToLength; + + // write the IPL flag and the nest FREQ for OCC. + // IPL_FLAG is a two byte field. OR a 1 into these two bytes. + // FREQ is the 4 byte nest frequency value that goes into + // the same field in the HOMER. + TARGETING::TargetService & tS = TARGETING::targetService(); + TARGETING::Target * sysTarget = NULL; + tS.getTopLevelTarget( sysTarget ); + assert( sysTarget != NULL ); + + uint16_t *ptrToIplFlag = + (uint16_t *)((char *)l_tmpStart + OCC_OFFSET_IPL_FLAG); + uint32_t *ptrToFreq = + (uint32_t *)((char *)l_tmpStart + OCC_OFFSET_FREQ); + *ptrToIplFlag |= 0x0001; + *ptrToFreq = sysTarget->getAttr(); + + ecmdDataBufferBase l_occAppData(l_length * 8 /* bits */); + uint32_t rc = l_occAppData.insert((uint32_t *)l_tmpStart, 0, + l_length * 8 /* bits */); + if (rc) + { + TRACFCOMP( g_fapiImpTd, + ERR_MRK"loadOCCImageDuringIpl: Error %d doing insert", + rc); + // create l_errl + break; + } + const uint32_t l_SramAddrApp = OCC_SRAM_ADDRESS; + l_errl = HBOCC::writeSRAM(i_target, l_SramAddrApp, l_occAppData); + if(l_errl) + { + TRACFCOMP( g_fapiImpTd, + ERR_MRK"loadOCCImageDuringIpl: Error in writeSRAM of app"); + break; + } + + }while(0); + + TRACUCOMP( g_fapiTd, + EXIT_MRK"loadOCCImageDuringIpl"); + return l_errl; + } +#endif + /** - * @brief Sets up OCC Host data + * @brief Sets up OCC Host data in Homer */ errlHndl_t loadHostDataToHomer( TARGETING::Target* i_proc, void* i_occHostDataVirtAddr) @@ -192,27 +286,124 @@ namespace HBOCC EXIT_MRK"loadHostDataToHomer"); return l_errl; - } + } // loadHostDataToHomer + +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS +#ifndef __HOSTBOOT_RUNTIME + /** + * @brief Sets up OCC Host data in SRAM + */ + errlHndl_t loadHostDataToSRAM( TARGETING::Target* i_proc, + const PRDF::HwInitialized_t i_curHw) + { + TRACUCOMP( g_fapiTd, + ENTER_MRK"loadHostDataToSRAM i_curHw=%d",i_curHw); + + errlHndl_t l_errl = NULL; + + //Treat virtual address as starting pointer + //for config struct + HBOCC::occHostConfigDataArea_t * config_data = + new HBOCC::occHostConfigDataArea_t(); + + // Get top level system target + TARGETING::TargetService & tS = TARGETING::targetService(); + TARGETING::Target * sysTarget = NULL; + tS.getTopLevelTarget( sysTarget ); + assert( sysTarget != NULL ); + + uint32_t nestFreq = sysTarget->getAttr(); + + config_data->version = HBOCC::OccHostDataVersion; + config_data->nestFrequency = nestFreq; + + // Figure out the interrupt type + if( INITSERVICE::spBaseServicesEnabled() ) + { + config_data->interruptType = USE_FSI2HOST_MAILBOX; + } + else + { + config_data->interruptType = USE_PSIHB_COMPLEX; + } + + config_data->firMaster = IS_FIR_MASTER; + l_errl = PRDF::writeHomerFirData( config_data->firdataConfig, + sizeof(config_data->firdataConfig), + i_curHw); + if (l_errl) + { + TRACFCOMP( g_fapiImpTd, + ERR_MRK"loadHostDataToSRAM: Error in writeHomerFirData"); + } + else + { + const uint32_t l_SramAddrFir = OCC_SRAM_FIR_DATA; + ecmdDataBufferBase l_occFirData(OCC_SRAM_FIR_LENGTH * 8 /* bits */); + /// copy config_data in here + uint32_t rc = l_occFirData.insert((uint32_t *)config_data, 0, + sizeof(*config_data) * 8 /* bits */); + if (rc) + { + TRACFCOMP( g_fapiImpTd, + ERR_MRK"loadHostDataToSRAM: Error %d doing insert", + rc); + /*@ + * @errortype + * @moduleid fapi::MOD_OCC_LOAD_HOST_DATA_TO_SRAM + * @reasoncode fapi::RC_ECMD_INSERT_FAILED + * @userdata1 Return Code + * @userdata2 0 + * @devdesc ecmd insert failed for l_occFirData + * @custdesc A problem occurred during the IPL + * of the system. + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_OCC_LOAD_HOST_DATA_TO_SRAM, + fapi::RC_ECMD_INSERT_FAILED, + rc, 0); + } + else + { + l_errl = HBOCC::writeSRAM(i_proc, l_SramAddrFir, l_occFirData); + if(l_errl) + { + TRACFCOMP( g_fapiImpTd, + ERR_MRK"loadHostDataToSRAM: Error in writeSRAM"); + } + } + } + + TRACUCOMP( g_fapiTd, + EXIT_MRK"loadHostDataToSRAM"); + + return l_errl; + } // loadHostDataToSRAM +#endif +#endif errlHndl_t loadOCC(TARGETING::Target* i_target, uint64_t i_occImgPaddr, - uint64_t i_occImgVaddr, - uint64_t i_commonPhysAddr) + uint64_t i_occImgVaddr, // dest + uint64_t i_commonPhysAddr, + bool i_useSRAM) { errlHndl_t l_errl = NULL; + TRACFCOMP( g_fapiTd, - ENTER_MRK"loadOCC" ); + ENTER_MRK"loadOCC(0x%08X, 0x%08X, 0x%08X, %d)", + i_occImgPaddr, i_occImgVaddr, i_commonPhysAddr, + i_useSRAM); do{ // Remember where we put things - if( i_target ) - { - // Subtract HOMER_OFFSET_TO_OCC_IMG to be technically - // correct though HOMER_OFFSET_TO_OCC_IMG happens to be zero - i_target->setAttr - (i_occImgPaddr - HOMER_OFFSET_TO_OCC_IMG); - i_target->setAttr - (i_occImgVaddr - HOMER_OFFSET_TO_OCC_IMG); - } + // Subtract HOMER_OFFSET_TO_OCC_IMG to be technically + // correct though HOMER_OFFSET_TO_OCC_IMG happens to be zero + i_target->setAttr + (i_occImgPaddr - HOMER_OFFSET_TO_OCC_IMG); + i_target->setAttr + (i_occImgVaddr - HOMER_OFFSET_TO_OCC_IMG); + // cast OUR type of target to a FAPI type of target. const fapi::Target l_fapiTarg(fapi::TARGET_TYPE_PROC_CHIP, (const_cast(i_target))); @@ -242,7 +433,6 @@ namespace HBOCC ERR_MRK"loadOCC: Bar0 config failed!" ); l_errl->collectTrace(FAPI_TRACE_NAME,256); l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256); - break; } @@ -264,7 +454,6 @@ namespace HBOCC ERR_MRK"loadOCC: Bar1 config failed!" ); l_errl->collectTrace(FAPI_TRACE_NAME,256); l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256); - break; } @@ -286,34 +475,60 @@ namespace HBOCC VMM_OCC_COMMON_SIZE_IN_MB, PBA_CMD_SCOPE_NODAL ); - if ( l_errl != NULL ) + if ( l_errl ) { TRACFCOMP( g_fapiImpTd, ERR_MRK"loadOCC: Bar3 config failed!" ); l_errl->collectTrace(FAPI_TRACE_NAME,256); l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256); - break; } +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + if (i_useSRAM) + { + void* occVirt = reinterpret_cast(i_occImgVaddr); + l_errl = loadOCCImageDuringIpl( i_target, occVirt ); + if( l_errl ) + { + TRACFCOMP(g_fapiImpTd, + ERR_MRK"loadOCC: loadOCCImageDuringIpl failed!"); + break; + } + } + else +#endif + { //============================== //Load the OCC HOMER image //============================== + +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + // clear (up to and including) the IPL Flag + const uint32_t l_SramAddrApp = OCC_SRAM_ADDRESS; + ecmdDataBufferBase l_occAppData((OCC_OFFSET_IPL_FLAG + 6) * 8 /* bits */); + l_errl = HBOCC::writeSRAM(i_target, l_SramAddrApp, l_occAppData); + if(l_errl) + { + TRACFCOMP( g_fapiImpTd, + ERR_MRK"loadOCC: Error in writeSRAM of 0"); + break; + } +#endif void* occVirt = reinterpret_cast(i_occImgVaddr); l_errl = loadOCCImageToHomer( occVirt ); - if( l_errl != NULL ) + if( l_errl ) { TRACFCOMP(g_fapiImpTd, ERR_MRK"loadOCC: loadOCCImageToHomer failed!"); break; } + } }while(0); TRACFCOMP( g_fapiTd, EXIT_MRK"loadOCC"); - return l_errl; - } /** @@ -434,6 +649,7 @@ namespace HBOCC EXIT_MRK"startOCC"); return l_errl; } + /** * @brief Stop OCC for specified DCM pair of processors. * If 2nd input is NULL, OCC will be setup on just -- cgit v1.2.1