diff options
-rw-r--r-- | src/include/runtime/interface.h | 5 | ||||
-rw-r--r-- | src/include/usr/isteps/pm/pm_common_ext.H | 25 | ||||
-rw-r--r-- | src/include/usr/runtime/runtime_reasoncodes.H | 5 | ||||
-rw-r--r-- | src/include/usr/scom/scomif.H | 49 | ||||
-rw-r--r-- | src/usr/isteps/pm/runtime/makefile | 5 | ||||
-rw-r--r-- | src/usr/isteps/pm/runtime/rt_pm.C | 129 | ||||
-rw-r--r-- | src/usr/scom/scomtrans.C | 148 | ||||
-rw-r--r-- | src/usr/scom/scomtrans.H | 22 | ||||
-rw-r--r-- | src/usr/scom/test/scomtest.H | 14 |
9 files changed, 298 insertions, 104 deletions
diff --git a/src/include/runtime/interface.h b/src/include/runtime/interface.h index f5eb2cba1..316bd2d03 100644 --- a/src/include/runtime/interface.h +++ b/src/include/runtime/interface.h @@ -407,7 +407,8 @@ typedef struct hostInterfaces * @pre HBRT is responsible for enabling special wakeup on the * associated core(s) before calling this interface * - * @param i_homer start address of the homer image + * @param i_chipId processor chip ID + plus ID type, always proc (0x0) * @param i_section runtime section to update * (passthru to pore_gen_scom) * @param i_operation type of operation to perform @@ -419,7 +420,7 @@ typedef struct hostInterfaces * Any value other than 0 on failure. * @platform FSP, OpenPOWER */ - int (*hcode_scom_update)( uint64_t i_homer, + int (*hcode_scom_update)( uint64_t i_chipId, uint32_t i_section, uint32_t i_operation, uint64_t i_scomAddr, diff --git a/src/include/usr/isteps/pm/pm_common_ext.H b/src/include/usr/isteps/pm/pm_common_ext.H index c503ada82..0d024ac43 100644 --- a/src/include/usr/isteps/pm/pm_common_ext.H +++ b/src/include/usr/isteps/pm/pm_common_ext.H @@ -31,13 +31,15 @@ namespace HBPM { /** * @brief Enumeration of the load PM complex mode - * LOAD == i_mode + * LOAD * - Call pm_reset first * - Load OCC lid, write OCC config data, build Pstate * Parameter Blocks, and load Hcode reference image lid - * RELOAD == i_mode + * RELOAD * - Reload OCC lid, rewrite OCC config data, build Pstate * Parameter Blocks, and rebuild Hcode + * UNKNOWN + * - Unknown PM load type, do not load OCC/HCODE */ enum loadPmMode { @@ -88,6 +90,25 @@ namespace HBPM */ errlHndl_t getRingOvd(void*& io_overrideImg); +#if __HOSTBOOT_RUNTIME + /** + * @brief Modify the SCOM restore section of the HCODE image with the + * given register data + * @param i_section Runtime section to update + * (passthru to pore_gen_scom) + * @param i_operation Type of operation to perform + * (passthru to pore_gen_scom) + * @param i_target Target owning the scom address + * @param i_rel_scom_addr Fully qualified scom address + * @param i_scom_data Data for operation + * @return errlHndl_t + */ + errlHndl_t hcode_update( uint32_t i_section, + uint32_t i_operation, + TARGETING::Target* i_target, + uint64_t i_rel_scom_addr, + uint64_t i_scom_data ); +#endif } //namespace HBPM ends #endif diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H index afff1c07b..469d2a6b2 100644 --- a/src/include/usr/runtime/runtime_reasoncodes.H +++ b/src/include/usr/runtime/runtime_reasoncodes.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -56,6 +56,7 @@ namespace RUNTIME MOD_POPULATE_RTDATABYNODE = 0x14, /**< populate_hbruntime.C */ MOD_PM_RT_LOAD_PM_COMPLEX = 0x15, /**< rt_pm.C */ + MOD_PM_RT_HCODE_UPDATE = 0x16, /**< rt_pm.C */ }; enum RuntimeReasonCode @@ -90,6 +91,8 @@ namespace RUNTIME RT_NO_PROC_TARGET = RUNTIME_COMP_ID | 0x1B, RC_UNMAP_FAIL = RUNTIME_COMP_ID | 0x1C, RC_PM_RT_UNKNOWN_MODE = RUNTIME_COMP_ID | 0x1D, + RC_PM_RT_INTERFACE_ERR = RUNTIME_COMP_ID | 0x1E, + RC_PM_RT_HCODE_UPDATE_ERR = RUNTIME_COMP_ID | 0x1F, }; enum UserDetailsTypes diff --git a/src/include/usr/scom/scomif.H b/src/include/usr/scom/scomif.H new file mode 100644 index 000000000..4bba1112b --- /dev/null +++ b/src/include/usr/scom/scomif.H @@ -0,0 +1,49 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/scom/scomif.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __SCOMIF_H +#define __SCOMIF_H + +namespace SCOM +{ + +/** + * @brief This function translates a relative scom address + * to an absolute scom address + * + * @param[in] i_target SCom target + * @param[in|out] io_addr SCom address + * @param[out] o_needsWakeup Enable SW before scom + * @param[in] i_opMode Defaults to 0 (Standard) + * @return errlHndl_t + */ +errlHndl_t scomTranslate(TARGETING::Target * &i_target, + uint64_t & io_addr, + bool & o_needsWakeup, + uint64_t i_opMode = 0); + + +}; // end namespace SCOM + +#endif // end __SCOMIF_H diff --git a/src/usr/isteps/pm/runtime/makefile b/src/usr/isteps/pm/runtime/makefile index 1f0e90b2e..fa1aca5ae 100644 --- a/src/usr/isteps/pm/runtime/makefile +++ b/src/usr/isteps/pm/runtime/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2016 +# Contributors Listed Below - COPYRIGHT 2016,2017 # [+] International Business Machines Corp. # # @@ -26,10 +26,13 @@ HOSTBOOT_RUNTIME = 1 ROOTPATH = ../../../../.. + VPATH += ../ MODULE = pm_rt +EXTRAINCDIR += ${ROOTPATH}/src/usr/scom/runtime + ## Objects unique to HBRT OBJS += rt_pm.o diff --git a/src/usr/isteps/pm/runtime/rt_pm.C b/src/usr/isteps/pm/runtime/rt_pm.C index 5d17836d4..3619a2315 100644 --- a/src/usr/isteps/pm/runtime/rt_pm.C +++ b/src/usr/isteps/pm/runtime/rt_pm.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -44,6 +44,9 @@ #include <targeting/common/utilFilter.H> #include <targeting/common/targetservice.H> +#include <scom/scomif.H> +#include "handleSpecialWakeup.H" + using namespace TARGETING; using namespace RUNTIME; @@ -287,6 +290,130 @@ namespace RTPM return rc; } + + /** + * @brief HCODE update operation + */ + errlHndl_t hcode_update( uint32_t i_section, + uint32_t i_operation, + Target* i_target, + uint64_t i_rel_scom_addr, + uint64_t i_scom_data ) + { + errlHndl_t l_err = NULL; + int rc = 0; + + do { + if( g_hostInterfaces == NULL || + g_hostInterfaces->hcode_scom_update == NULL ) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"hcode_update: " + "Hypervisor hcode_scom_update interface not linked"); + /*@ + * @errortype + * @moduleid MOD_PM_RT_HCODE_UPDATE + * @reasoncode RC_PM_RT_INTERFACE_ERR + * @userdata1[0:31] Target HUID + * @userdata1[32:63] SCOM restore section + * @userdata2 SCOM address + * @devdesc HCODE scom update runtime interface not linked. + */ + l_err= new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, + MOD_PM_RT_HCODE_UPDATE, + RC_PM_RT_INTERFACE_ERR, + TWO_UINT32_TO_UINT64( + TARGETING::get_huid(i_target), + i_section), + i_rel_scom_addr); + break; + } + + // Enable special wakeup + l_err = handleSpecialWakeup(i_target,true); + if(l_err) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"hcode_update: " + "handleSpecialWakeup enable ERROR" ); + break; + } + + // Get the Proc Chip Id + const TARGETING::Target * l_pChipTarget = + getParentChip(const_cast<TARGETING::Target *>(i_target)); + RT_TARG::rtChipId_t l_chipId = 0; + + l_err = RT_TARG::getRtTarget(l_pChipTarget, l_chipId); + if(l_err) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"hcode_update: getRtTarget ERROR" ); + break; + } + + // Translate the scom address + uint64_t l_scomAddr = i_rel_scom_addr; + bool l_needsWakeup = false; // Ignored - SW already enabled + + l_err = SCOM::scomTranslate(i_target, + l_scomAddr, + l_needsWakeup); + if(l_err) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"hcode_update: scomTranslate ERROR" ); + break; + } + + rc = g_hostInterfaces->hcode_scom_update(l_chipId, + i_section, + i_operation, + l_scomAddr, + i_scom_data); + if(rc) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"hcode_update: " + "HCODE scom update failed. " + "rc 0x%X target 0x%llX chipId 0x%llX section 0x%X " + "operation 0x%X scomAddr 0x%llX scomData 0x%llX", + rc, get_huid(i_target), l_chipId, i_section, + i_operation, l_scomAddr, i_scom_data); + + // convert rc to error log + /*@ + * @errortype + * @moduleid MOD_PM_RT_HCODE_UPDATE + * @reasoncode RC_PM_RT_HCODE_UPDATE_ERR + * @userdata1 Hypervisor return code + * @userdata2 SCOM address + * @devdesc HCODE SCOM update error + */ + l_err=new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, + MOD_PM_RT_HCODE_UPDATE, + RC_PM_RT_HCODE_UPDATE_ERR, + rc, + l_scomAddr); + break; + } + + // Disable special wakeup + l_err = handleSpecialWakeup(i_target,false); + if(l_err) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"hcode_update: " + "handleSpecialWakeup disable ERROR" ); + break; + } + + } while (0); + + return l_err; + } + + //------------------------------------------------------------------------ struct registerPm diff --git a/src/usr/scom/scomtrans.C b/src/usr/scom/scomtrans.C index 2c8bcc6e7..089b74ec2 100644 --- a/src/usr/scom/scomtrans.C +++ b/src/usr/scom/scomtrans.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -47,6 +47,7 @@ #include <errl/errlmanager.H> #include "scom.H" #include "scomtrans.H" +#include <scom/scomif.H> #include <scom/scomreasoncodes.H> #include <errl/errludtarget.H> #include <initservice/initserviceif.H> @@ -177,67 +178,96 @@ errlHndl_t startScomProcess(DeviceFW::OperationType i_opType, va_list i_args) { errlHndl_t l_err = NULL; - TARGETING::Target* l_target_SW = NULL; - //will hold the value of parent chip for indirect scom - TARGETING::Target* l_parentChip = - const_cast<TARGETING::Target *>(TARGETING::getParentChip(i_target)); - uint64_t l_addr = va_arg(i_args,uint64_t); - //if opMode is not specified as an argument va_arg will return NULL which is 0 - uint64_t l_opMode = va_arg(i_args,uint64_t); + do { + //will hold the value of parent chip for indirect scom + TARGETING::Target* l_parentChip = const_cast<TARGETING::Target *> + (TARGETING::getParentChip(i_target)); + uint64_t l_addr = va_arg(i_args,uint64_t); + // if opMode is not specified as an argument + // va_arg will return NULL which=0 + uint64_t l_opMode = va_arg(i_args,uint64_t); + bool l_needsWakeup = false; + + l_err = scomTranslate(i_target, + l_addr, + l_needsWakeup, + l_opMode); + if(l_err) + { + break; + } - l_err = scomTranslate(i_target, l_addr, l_target_SW, l_opMode); +#if __HOSTBOOT_RUNTIME + if(l_needsWakeup) + { + TRACDCOMP(g_trac_scom,"Special wakeup required, starting now.."); + g_wakeupInProgress = true; + l_err = handleSpecialWakeup(i_target,true); + if(l_err) + { + TRACFCOMP(g_trac_scom, "startScomProcess: " + "handleSpecialWakeup enable ERROR"); + + //capture the target data in the elog + ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target") + .addToLog(l_err); + l_err->collectTrace(SCOM_COMP_NAME,1024); + break; + } + + g_wakeupInProgress = false; + } +#endif - if (l_err == NULL) - { // call the routine that will do the indirect scom // and then call the correct device driver. l_err = SCOM::checkIndirectAndDoScom(i_opType, - l_parentChip, - io_buffer, - io_buflen, - i_accessType, - l_addr); - } - - // @todo RTC:124196 need to move this to a more general location so that - // the disable occurs after the HBRT is complete. + l_parentChip, + io_buffer, + io_buflen, + i_accessType, + l_addr); + + // @todo RTC:124196 need to move this to a more general location so that + // the disable occurs after the HBRT is complete. #if __HOSTBOOT_RUNTIME - if(!(l_opMode & fapi2::DO_NOT_DO_WAKEUP) && - (l_target_SW != NULL) && - !g_wakeupInProgress) - { - g_wakeupInProgress = true; - errlHndl_t l_errSW = NULL; + if(l_needsWakeup && !g_wakeupInProgress) + { + g_wakeupInProgress = true; + errlHndl_t l_errSW = NULL; - l_errSW = handleSpecialWakeup(l_target_SW,false); + l_errSW = handleSpecialWakeup(i_target,false); - if(l_err != NULL && l_errSW) - { - TRACFCOMP(g_trac_scom,"Disable p9_cpu_special_wakeup ERROR"); + if(l_err != NULL && l_errSW) + { + TRACFCOMP(g_trac_scom, "startScomProcess: " + "handleSpecialWakeup disable ERROR"); - // capture the target data in the elog - ERRORLOG::ErrlUserDetailsTarget(l_target_SW).addToLog(l_errSW); - errlCommit(l_errSW,RUNTIME_COMP_ID); - } - else if(l_errSW) - { - l_err = l_errSW; + // capture the target data in the elog + ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_errSW); + errlCommit(l_errSW,RUNTIME_COMP_ID); + } + else if(l_errSW) + { + l_err = l_errSW; + } + g_wakeupInProgress = false; } - g_wakeupInProgress = false; - } #endif + } while (0); + return l_err; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// errlHndl_t scomTranslate(TARGETING::Target * &i_target, - uint64_t & io_addr, - TARGETING::Target * io_target_SW, - uint64_t i_opMode) + uint64_t & io_addr, + bool & o_needsWakeup, + uint64_t i_opMode) { errlHndl_t l_err = NULL; @@ -247,10 +277,10 @@ errlHndl_t scomTranslate(TARGETING::Target * &i_target, //Need to support centaur still @TODO RTC: 139953 l_err = p9_translation(i_target, - l_type, - io_addr, - io_target_SW, - i_opMode); + l_type, + io_addr, + o_needsWakeup, + i_opMode); return l_err; } @@ -260,7 +290,7 @@ errlHndl_t scomTranslate(TARGETING::Target * &i_target, errlHndl_t p9_translation (TARGETING::Target * &i_target, TARGETING::TYPE i_type, uint64_t &io_addr, - TARGETING::Target * io_target_SW, + bool & o_needsWakeup, uint64_t i_opMode) { errlHndl_t l_err = NULL; @@ -317,35 +347,15 @@ errlHndl_t p9_translation (TARGETING::Target * &i_target, !(i_opMode & fapi2::DO_NOT_DO_WAKEUP) ) { TRACDCOMP(g_trac_scom,"Determining if Special Wakeup is needed.."); - bool l_needsWakeup = true; + o_needsWakeup = true; for(uint16_t i = 0; i < l_scomPairings.size(); i++) { if( l_scomPairings[i].chipUnitType == PU_PERV_CHIPUNIT) { - l_needsWakeup = false; + o_needsWakeup = false; break; } } - if(l_needsWakeup) - { - TRACDCOMP(g_trac_scom,"Special wakeup required, starting now.."); - g_wakeupInProgress = true; - - l_err = handleSpecialWakeup(i_target,true); - if(l_err) - { - TRACFCOMP(g_trac_scom, - "Enable handleSpecialWakeup ERROR"); - - //capture the target data in the elog - ERRORLOG::ErrlUserDetailsTarget(i_target,"SCOM Target") - .addToLog(l_err); - l_err->collectTrace(SCOM_COMP_NAME,1024); - break; - } - io_target_SW = i_target; - g_wakeupInProgress = false; - } } #endif diff --git a/src/usr/scom/scomtrans.H b/src/usr/scom/scomtrans.H index 4e63b9453..5b1d8e90b 100644 --- a/src/usr/scom/scomtrans.H +++ b/src/usr/scom/scomtrans.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -61,36 +61,20 @@ errlHndl_t startScomProcess(DeviceFW::OperationType i_opType, va_list i_args); /** - * @brief Performs a SCom Translation of the scom address - * This function performs the translation and gets the - * correct target. - * - * @param[in] i_target SCom target - * @param[in|out] io_addr SCom address - * @param[in|out] io_target_SW target for SW - * @param[in] i_opMode Defaults to 0 (Standard) - * @return errlHndl_t - */ -errlHndl_t scomTranslate(TARGETING::Target * &i_target, - uint64_t & io_addr, - TARGETING::Target * io_target_SW, - uint64_t i_opMode = 0); - -/** * @brief This function translates a scom address using the * the interface that the HW team provided. * * @param[in] i_target SCom target is passed in * @param[in] i_type Type of the target * @param[in|out] io_addr Address to be translated - * @param[in|out] io_target_SW SW target for HBRT + * @param[out] o_needsWakeup Enable SW before scom * @param[in] i_opMode Defaults to 0 (Standard) * @return errlHndl_t */ errlHndl_t p9_translation (TARGETING::Target * &i_target, TARGETING::TYPE i_type, uint64_t &io_addr, - TARGETING::Target * io_target_SW, + bool & o_needsWakeup, uint64_t i_opMode = 0); /** diff --git a/src/usr/scom/test/scomtest.H b/src/usr/scom/test/scomtest.H index edfa21260..1358a5f4a 100644 --- a/src/usr/scom/test/scomtest.H +++ b/src/usr/scom/test/scomtest.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2016 */ +/* Contributors Listed Below - COPYRIGHT 2011,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -38,19 +38,14 @@ #include <fsi/fsiif.H> #include <targeting/common/util.H> #include <targeting/common/utilFilter.H> +#include <scom/scomif.H> #include <devicefw/driverif.H> extern trace_desc_t* g_trac_scom; -namespace SCOM -{ -extern errlHndl_t scomTranslate(TARGETING::Target* &i_target, - uint64_t &io_addr, - TARGETING::Target* io_target_SW, - uint64_t i_opMode = 0); -} + class ScomTest: public CxxTest::TestSuite { public: @@ -1108,9 +1103,10 @@ public: { total++; uint64_t tempAddr = test_data[i].initAddr; + bool needsWakeup = false; l_err = SCOM::scomTranslate(test_data[i].target, tempAddr, - NULL); + needsWakeup); if( l_err && !test_data[i].expectError) { |