diff options
author | Marty Gloff <mgloff@us.ibm.com> | 2016-05-03 11:40:06 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-06-06 13:05:51 -0400 |
commit | 7851bd428df9a7868d5931377124bcbc7b928829 (patch) | |
tree | 4352e03ceabaa169679d2b1791e2b89851f2c40c /src/usr | |
parent | 63c066b4613672bd1bb7d3dad3db5ac810e702b0 (diff) | |
download | talos-hostboot-7851bd428df9a7868d5931377124bcbc7b928829.tar.gz talos-hostboot-7851bd428df9a7868d5931377124bcbc7b928829.zip |
Implement PM complex calls in HBRT, no HWPs - Initial Infrastructure
Create src/usr/isteps/pm directory and runtime subdirectory.
Add rt_pm.C with functions to support runtime interfaces.
Add pm_common files with funtions to support runtime functions.
Create and update appropriate makefiles.
Change-Id: Ibdbd8890c7f134e5f687708e292543f8ce6f5d89
RTC: 148935
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/24020
Tested-by: Jenkins Server
Tested-by: FSP CI Jenkins
Reviewed-by: Corey V. Swenson <cswenson@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/isteps/makefile | 1 | ||||
-rw-r--r-- | src/usr/isteps/pm/makefile | 37 | ||||
-rw-r--r-- | src/usr/isteps/pm/pm.mk | 59 | ||||
-rw-r--r-- | src/usr/isteps/pm/pm_common.C | 563 | ||||
-rw-r--r-- | src/usr/isteps/pm/pm_common.H | 168 | ||||
-rw-r--r-- | src/usr/isteps/pm/runtime/makefile | 39 | ||||
-rw-r--r-- | src/usr/isteps/pm/runtime/rt_pm.C | 389 |
7 files changed, 1256 insertions, 0 deletions
diff --git a/src/usr/isteps/makefile b/src/usr/isteps/makefile index 4448caa3a..1c665231b 100644 --- a/src/usr/isteps/makefile +++ b/src/usr/isteps/makefile @@ -38,6 +38,7 @@ SUBDIRS+=istep15.d SUBDIRS+=istep16.d SUBDIRS+=istep20.d SUBDIRS+=istep21.d +SUBDIRS+=pm.d OBJS += hwpisteperror.o OBJS += hwpistepud.o diff --git a/src/usr/isteps/pm/makefile b/src/usr/isteps/pm/makefile new file mode 100644 index 000000000..dd45303f5 --- /dev/null +++ b/src/usr/isteps/pm/makefile @@ -0,0 +1,37 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/isteps/pm/makefile $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2016 +# [+] 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 +ROOTPATH = ../../../.. + +MODULE = pm + +SUBDIRS+=runtime.d + +## Objects unique to HB IPL +OBJS += + +## Objects common to HB IPL and HBRT +include pm.mk + +include ${ROOTPATH}/config.mk diff --git a/src/usr/isteps/pm/pm.mk b/src/usr/isteps/pm/pm.mk new file mode 100644 index 000000000..dd184fed1 --- /dev/null +++ b/src/usr/isteps/pm/pm.mk @@ -0,0 +1,59 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/isteps/pm/pm.mk $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2016 +# [+] 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 + +## support for fapi2 +EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include/ +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/ + +## pointer to common HWP files +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/xip/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/lib/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/utils/stopreg/ + +HWP_PATH += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/pm +EXTRAINCDIR += ${HWP_PATH} +HWP_XIP_PATH += ${ROOTPATH}/src/import/chips/p9/xip +EXTRAINCDIR += ${HWP_XIP_PATH} + +## pointer to already consumed procedures. + +## NOTE: add the base istep dir here. +EXTRAINCDIR += ${ROOTPATH}/src/usr/isteps/ + +#common PM Complex functions between ipl and runtime +OBJS += pm_common.o + +## NOTE: add a new directory onto the vpaths when you add a new HWP +VPATH += ${HWP_PATH} ${HWP_XIP_PATH} + +include ${ROOTPATH}/procedure.rules.mk +include $(HWP_PATH)/p9_hcode_image_build.mk +include $(HWP_PATH)/p9_pm_pba_bar_config.mk +include $(HWP_PATH)/p9_pm_init.mk +include ${HWP_XIP_PATH}/p9_xip_image.mk + +include ${ROOTPATH}/config.mk diff --git a/src/usr/isteps/pm/pm_common.C b/src/usr/isteps/pm/pm_common.C new file mode 100644 index 000000000..654f82be1 --- /dev/null +++ b/src/usr/isteps/pm/pm_common.C @@ -0,0 +1,563 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/pm/pm_common.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] 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 */ + +#include <stdint.h> + +#include <pm/pm_common.H> + +#include <initservice/taskargs.H> +#include <errl/errlentry.H> + +#include <sys/misc.h> + +// targeting support +#include <targeting/common/commontargeting.H> +#include <targeting/common/utilFilter.H> +#include <targeting/common/targetservice.H> +#include <targeting/common/util.H> + +// fapi support +#include <fapi2.H> +#include <fapi2/plat_hwp_invoker.H> + +//PNOR Resource Provider +#include <pnor/pnorif.H> + +#include <initservice/isteps_trace.H> +#include <isteps/istep_reasoncodes.H> + +#include <vfs/vfs.H> +#include <util/utillidmgr.H> +#include <initservice/initserviceif.H> + +#include <runtime/interface.h> + +// Procedures +#include <p9_pm_pba_bar_config.H> +#include <p9_pm_init.H> +#include <p9_hcode_image_build.H> + +#include <p9_hcode_image_defines.H> + +#include <arch/ppc.H> + +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + #include <diag/prdf/prdfWriteHomerFirData.H> +#endif + +// Easy macro replace for unit testing +//#define TRACUCOMP(args...) TRACFCOMP(args) +#define TRACUCOMP(args...) + +using namespace TARGETING; +using namespace p9_hcodeImageBuild; + +namespace HBPM +{ + /** + * @brief Build new Pstate Parameter Block for PGPE and CME + */ + errlHndl_t pstateParameterBuild( TARGETING::Target* i_target, + void* i_homer) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ENTER_MRK"pstateParameterBuild(%p)", + i_homer); + + errlHndl_t l_errl = NULL; + + // cast OUR type of target to a FAPI type of target. + // figure out homer offsets + const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> + l_fapiTarg(i_target); + + do + { + // p9_pstate_parameter_build.C +/* FAPI_INVOKE_HWP( l_errl, + p9_pstate_parameter_build, + l_fapiTarg, + i_homer ); @TODO RTC:153885 */ + + if (l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"pstateParameterBuild: " + "p9_pstate_parameter_build failed!" ); + l_errl->collectTrace(FAPI_TRACE_NAME,256); + l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256); + l_errl->collectTrace("ISTEPS_TRACE",256); + + break; + } + + } while(0); + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + EXIT_MRK"pstateParameterBuild: RC=0x%X, PLID=0x%lX", + ERRL_GETRC_SAFE(l_errl), ERRL_GETPLID_SAFE(l_errl) ); + return l_errl; + } // pstateParameterBuild + + /** + * @brief Sets up OCC Host data in Homer + */ + errlHndl_t loadHostDataToHomer( TARGETING::Target* i_proc, + void* i_occHostDataVirtAddr) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ENTER_MRK"loadHostDataToHomer(%p)", + i_occHostDataVirtAddr); + + errlHndl_t l_errl = NULL; + + //Treat virtual address as starting pointer + //for config struct + HBPM::occHostConfigDataArea_t * config_data = + reinterpret_cast<HBPM::occHostConfigDataArea_t *> + (i_occHostDataVirtAddr); + + // 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<ATTR_FREQ_PB>(); + + config_data->version = HBPM::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; + } + +#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS + // Figure out the FIR master + TARGETING::Target* masterproc = NULL; + tS.masterProcChipTargetHandle( masterproc ); + if( masterproc == i_proc ) + { + config_data->firMaster = IS_FIR_MASTER; + + // TODO: RTC 124683 The ability to write the HOMER data + // is currently not available at runtime. +#ifndef __HOSTBOOT_RUNTIME + l_errl = PRDF::writeHomerFirData( config_data->firdataConfig, + sizeof(config_data->firdataConfig) ); +#endif + + } + else + { + config_data->firMaster = NOT_FIR_MASTER; + } + +#else + config_data->firMaster = 0; +#endif + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + EXIT_MRK"loadHostDataToHomer: RC=0x%X, PLID=0x%lX", + ERRL_GETRC_SAFE(l_errl), ERRL_GETPLID_SAFE(l_errl) ); + + return l_errl; + } // loadHostDataToHomer + + /** + * @brief Sets up Hcode in Homer + */ + errlHndl_t loadHcode( TARGETING::Target* i_target, + void* i_pImageOut, + uint32_t i_mode ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ENTER_MRK"loadHcode(0x%08X, %p, %d)", + i_target->getAttr<ATTR_HUID>(), + i_pImageOut, + i_mode); + + errlHndl_t l_errl = NULL; + + // cast OUR type of target to a FAPI type of target. + // figure out homer offsets + const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> + l_fapiTarg(i_target); +/* @TODO RTC: 148935 start */ + void *l_pImageIn = NULL; + + do + { + // @TODO RTC: 148935 Only get LID once from pnor/fsp + size_t lidSize = 0; + uint32_t lidId = (i_target->getAttr<ATTR_MODEL>() == MODEL_NIMBUS) + ? HBPM::NIMBUS_HCODE_LIDID + : HBPM::CUMULUS_HCODE_LIDID; + UtilLidMgr lidMgr(lidId); + + l_errl = lidMgr.getLidSize(lidSize); + if(l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"loadHcode: " + "Error getting lid size. lidId=0x%.8x", + lidId); + break; + } + + // allocate memory for Hcode + l_pImageIn = static_cast<void*>(malloc(lidSize)); + + l_errl = lidMgr.getLid(l_pImageIn, lidSize); + if(l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"loadHcode: " + "Error getting lid. lidId=0x%.8x", + lidId); + break; + } + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "loadHcode: HCODE addr = 0x%p ", + l_pImageIn); + + ImageType_t l_imgType; + void *l_buffer = (void*)malloc(HW_IMG_RING_SIZE); + + FAPI_INVOKE_HWP( l_errl, + p9_hcode_image_build, + l_fapiTarg, + l_pImageIn, + i_pImageOut, + (HBRT_PM_LOAD == i_mode) + ? PHASE_IPL : PHASE_REBUILD, + l_imgType, + l_buffer ); + + if (l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"loadHcode: p9_hcode_image_build failed!" ); + l_errl->collectTrace(FAPI_TRACE_NAME,256); + l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256); + l_errl->collectTrace("ISTEPS_TRACE",256); + + break; + } + + // Log some info about Homer + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "pImageOut=%p",i_pImageOut); + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "lidSize=%d",lidSize); + + // Log some info from the headers + Homerlayout_t* pChipHomer = (Homerlayout_t*)i_pImageOut; + + // SGPE Region with QPMR Header + SgpeLayout_t* pSgpeLayout = + (SgpeLayout_t*)(&(pChipHomer->sgpeRegion)); + QpmrHeaderLayout_t* pQpmrHeaderLayout = + (QpmrHeaderLayout_t*)(&(pSgpeLayout->qpmrHeader)); + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "QPMR -- Date:%d, Version:%d", + pQpmrHeaderLayout->buildDate, + pQpmrHeaderLayout->buildVersion); + + SgpeImageHeader_t* pSgpeImageHeader = + (SgpeImageHeader_t*)(&(pSgpeLayout->imgHeader)); + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "SGPE -- Location: %p, Date:%d, Version:%d", + pSgpeLayout, + pSgpeImageHeader->buildDate, + pSgpeImageHeader->buildVer); + + // CME Region + CmeRegionLayout_t* pCmeLayout = + (CmeRegionLayout_t*)(&(pChipHomer->cmeRegion)); + CmeImageHeader_t* pCmeImageHeader = + (CmeImageHeader_t*)(&(pCmeLayout->imgHeader)); + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "CME -- Location: %p, Date:%d, Version:%d", + pCmeLayout, + pCmeImageHeader->buildDate, + pCmeImageHeader->buildVer); + + // PGPE Region + PgpeLayout_t* pPgpeLayout = + (PgpeLayout_t*)(&(pChipHomer->pgpeRegion)); + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "PGPE -- Location: %p", + pPgpeLayout); + } while(0); +/* end @TODO RTC: 148935 */ + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + EXIT_MRK"loadHcode: RC=0x%X, PLID=0x%lX", + ERRL_GETRC_SAFE(l_errl), ERRL_GETPLID_SAFE(l_errl) ); + + return l_errl; + } // loadHcode + + /** + * @brief Execute procedures and steps required to setup for loading + * the OCC image in a specified processor + */ + errlHndl_t loadOCCSetup(TARGETING::Target* i_target, + uint64_t i_occImgPaddr, + uint64_t i_occImgVaddr, // dest + uint64_t i_commonPhysAddr) + { + errlHndl_t l_errl = NULL; + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ENTER_MRK"loadOCCSetup(0x%08X, 0x%08X, 0x%08X)", + i_occImgPaddr, i_occImgVaddr, i_commonPhysAddr); + do{ + // cast OUR type of target to a FAPI type of target. + const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> + l_fapiTarg(i_target); + char l_fapiTargString[50]; // @TODO RTC: 148935 Find constant for 50 + toString(l_fapiTarg, l_fapiTargString, sizeof(l_fapiTargString)); + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "loadOCCSetup: FapiTarget: %s",l_fapiTargString); + + //============================== + //Setup for OCC Load + //============================== + + // BAR0 is the Entire HOMER (start of HOMER contains OCC base Image) + // Bar size is in MB, obtained value of 4MB from Greg Still + TRACUCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + INFO_MRK"loadOCCSetup: OCC Address: 0x%.8X, size=0x%.8X", + i_occImgPaddr, VMM_HOMER_INSTANCE_SIZE_IN_MB); + // @TODO RTC: 148935 Find/Define size constant in HWP dir +/* @TODO RTC: 148935 start */ + FAPI_INVOKE_HWP( l_errl, + p9_pm_pba_bar_config, + l_fapiTarg, + 0, + i_occImgPaddr, + VMM_HOMER_INSTANCE_SIZE_IN_MB, // @TODO RTC: 148935 + // Find/Define constant in HWP directory for size + p9pba::LOCAL_NODAL, + 0xFF ); + + if (l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"loadOCCSetup: Bar0 config failed!" ); + l_errl->collectTrace(FAPI_TRACE_NAME,256); + l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256); + l_errl->collectTrace("ISTEPS_TRACE",256); + break; + } +/* end @TODO RTC: 148935 */ + // BAR2 is the OCC Common Area + // Bar size is in MB + TARGETING::Target* sys = NULL; + TARGETING::targetService().getTopLevelTarget(sys); + sys->setAttr<ATTR_OCC_COMMON_AREA_PHYS_ADDR>(i_commonPhysAddr); + + TRACUCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + INFO_MRK"loadOCCSetup: " + "OCC Common Addr: 0x%.8X,size=0x%.8X", + i_commonPhysAddr,VMM_OCC_COMMON_SIZE_IN_MB); + // @TODO RTC: 148935 Find/Define size constant in HWP dir +/* @TODO RTC: 148935 start */ + FAPI_INVOKE_HWP( l_errl, + p9_pm_pba_bar_config, + l_fapiTarg, + 2, + i_commonPhysAddr, + VMM_OCC_COMMON_SIZE_IN_MB, // @TODO RTC: 148935 + // Find/Define constant in HWP directory for size + p9pba::LOCAL_NODAL, + 0xFF ); + + if (l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"loadOCCSetup: Bar2 config failed!" ); + l_errl->collectTrace(FAPI_TRACE_NAME,256); + l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256); + l_errl->collectTrace("ISTEPS_TRACE",256); + break; + } +/* end @TODO RTC: 148935 */ + }while(0); + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + EXIT_MRK"loadOCCSetup: RC=0x%X, PLID=0x%lX", + ERRL_GETRC_SAFE(l_errl), ERRL_GETPLID_SAFE(l_errl) ); + return l_errl; + } + + + /** + * @brief Execute procedures and steps required to load + * OCC image in a specified processor + */ + errlHndl_t loadOCCImageToHomer(TARGETING::Target* i_target, + uint64_t i_occImgPaddr, + uint64_t i_occImgVaddr) // dest + { + errlHndl_t l_errl = NULL; + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ENTER_MRK"loadOCCImageToHomer(0x%08X, 0x%08X)", + i_occImgPaddr, i_occImgVaddr); + do{ + void* occVirt = reinterpret_cast<void *>(i_occImgVaddr); + + // @TODO RTC: 148935 Only get LID once from pnor/fsp + size_t lidSize = 0; + UtilLidMgr lidMgr(HBPM::OCC_LIDID); + + l_errl = lidMgr.getLidSize(lidSize); + if(l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"loadOCCImageToHomer: " + "Error getting lid size. lidId=0x%.8x", + OCC_LIDID); + break; + } + + l_errl = lidMgr.getLid(occVirt, lidSize); + if(l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"loadOCCImageToHomer: " + "Error getting lid. lidId=0x%.8x", + OCC_LIDID); + break; + } + }while(0); + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + EXIT_MRK"loadOCCImageToHomer: RC=0x%X, PLID=0x%lX", + ERRL_GETRC_SAFE(l_errl), ERRL_GETPLID_SAFE(l_errl) ); + return l_errl; + } // loadOCCImageToHomer + + + /** + * @brief Start PM Complex. + */ + errlHndl_t startPMComplex (Target* i_target) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ENTER_MRK"startPMComplex"); + errlHndl_t l_errl = NULL; + + // cast OUR type of target to a FAPI type of target. + // figure out homer offsets + const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> + l_fapiTarg(i_target); +/* @TODO RTC: 148935 start */ + do { + // Init path + // p9_pm_init.C enum: PM_INIT + FAPI_INVOKE_HWP( l_errl, + p9_pm_init, + l_fapiTarg, + p9pm::PM_INIT ); + + if ( l_errl != NULL ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"startPMComplex: p9_pm_init, init failed!" ); + l_errl->collectTrace(FAPI_TRACE_NAME,256); + l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256); + l_errl->collectTrace("ISTEPS_TRACE",256); + + break; + } + + } while (0); +/* end @TODO RTC: 148935 */ + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + EXIT_MRK"startPMComplex: RC=0x%X, PLID=0x%lX", + ERRL_GETRC_SAFE(l_errl), ERRL_GETPLID_SAFE(l_errl) ); + return l_errl; + } + + + /** + * @brief Reset PM Complex. + */ + errlHndl_t resetPMComplex(TARGETING::Target * i_target) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ENTER_MRK"resetPMComplex"); + errlHndl_t l_errl = NULL; + + // cast OUR type of target to a FAPI type of target. + // figure out homer offsets + const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> + l_fapiTarg(i_target); +/* @TODO RTC: 148935 start */ + do + { + // Reset path + // p9_pm_init.C enum: PM_RESET + FAPI_INVOKE_HWP( l_errl, + p9_pm_init, + l_fapiTarg, + p9pm::PM_RESET ); + + if (l_errl) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"resetPMComplex:p9_pm_init, reset failed!" ); + l_errl->collectTrace(FAPI_TRACE_NAME,256); + l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256); + l_errl->collectTrace("ISTEPS_TRACE",256); + + break; + } + + } while(0); +/* end @TODO RTC: 148935 */ + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + EXIT_MRK"resetPMComplex: RC=0x%X, PLID=0x%lX", + ERRL_GETRC_SAFE(l_errl), ERRL_GETPLID_SAFE(l_errl) ); + return l_errl; + } + +} // end HBPM namespace + diff --git a/src/usr/isteps/pm/pm_common.H b/src/usr/isteps/pm/pm_common.H new file mode 100644 index 000000000..692bea0ad --- /dev/null +++ b/src/usr/isteps/pm/pm_common.H @@ -0,0 +1,168 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/pm/pm_common.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] 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 PM_COMMON_H +#define PM_COMMON_H + +#include <limits.h> +#include <errl/errlentry.H> +#include <diag/prdf/prdfWriteHomerFirData.H> + +namespace HBPM +{ + /* + * @brief Host config data consumed by OCC + */ + struct occHostConfigDataArea_t + { + uint32_t version; + + //For computation of timebase frequency + uint32_t nestFrequency; + + // For determining the interrupt type to Host + // 0x00000000 = Use FSI2HOST Mailbox + // 0x00000001 = Use OCC interrupt line through PSIHB complex + uint32_t interruptType; + + // For informing OCC if it is the FIR master: + // 0x00000000 = Default + // 0x00000001 = FIR Master + uint32_t firMaster; + + // FIR collection configuration data needed by FIR Master + // OCC in the event of a checkstop + uint8_t firdataConfig[3072]; + }; + + enum + { + OccHostDataVersion = 0x00000090, + + OCC_LIDID = 0x81e00430, // @TODO RTC: 148935 Where to define? + OCC_IBSCOM_RANGE_IN_MB = MEGABYTE, + + // Interrupt Types + USE_FSI2HOST_MAILBOX = 0x00000000, + USE_PSIHB_COMPLEX = 0x00000001, + + // FIR Master + NOT_FIR_MASTER = 0x00000000, + IS_FIR_MASTER = 0x00000001, + + // Hcode Reference Image LIDs + NIMBUS_HCODE_LIDID = 0x81e00602, // @TODO RTC: 148935 Where to define? + CUMULUS_HCODE_LIDID = 0x81e00603, // @TODO RTC: 148935 Where to define? + }; + + /** + * @brief Build new Pstate Parameter Block for PGPE and CME + * + * @param[in] i_target: Target processor + * @param[in] i_homer: Virtual address of current proc's HOMER + * + * @return errlHndl_t Error log Pstate Parameter Block build failed + */ + errlHndl_t pstateParameterBuild( TARGETING::Target* i_target, + void* i_homer); + +/** + * @brief Sets up OCC Host data in Homer + * + * @param[in] i_proc: target processor to load + * @param[in] i_occHostDataVirtAddr Virtual + * address of current + * proc's Host data area. + * + * @return errlHndl_t Error log Host data setup failed + */ + errlHndl_t loadHostDataToHomer(TARGETING::Target* i_proc, + void* i_occHostDataVirtAddr); + + /** + * @brief Sets up Hcode in Homer + * + * @param[in] i_target: Target processor + * @param[in] i_pImageOut: Pointer to HOMER image buffer + * @param[in] i_mode Selects initial load vs concurrent reloads + * @return errlHndl_t Error log if loadHcode failed + */ + errlHndl_t loadHcode( TARGETING::Target* i_target, + void* i_pImageOut, + uint32_t i_mode ); + + /** + * @brief Execute procedures and steps required to setup for loading + * the OCC image in a specified processor + * + * @param[in] i_target: Target processor + * @param[in] i_occImgPaddr: Physical address of current + * proc's OCC image in the homer + * @param[in] i_occImgVaddr: Virtual address of current + * proc's OCC image in the homer + * @param[in] i_commonPhysAddr: Physical address of common + * OCC region + * @return errlHndl_t Error log if loadOCCSetup failed + */ + errlHndl_t loadOCCSetup(TARGETING::Target* i_target, + uint64_t i_occImgPaddr, + uint64_t i_occImgVaddr, + uint64_t i_commonPhysAddr); + + /** + * @brief Execute procedures and steps required to load + * OCC image in a specified processor + * + * @param[in] i_target: Target processor + * @param[in] i_occImgPaddr: Physical address of current + * proc's OCC image in the homer + * @param[in] i_occImgVaddr: Virtual address of current + * proc's OCC image in the homer + * @return errlHndl_t Error log if loadOCCImageToHomer failed + */ + errlHndl_t loadOCCImageToHomer(TARGETING::Target* i_target, + uint64_t i_occImgPaddr, + uint64_t i_occImgVaddr); + + /** + * @brief Start PM Complex. + * + * @param[in] i_target: target of processor + * + * @return errlHndl_t Error log of startPMComplex failed + */ + errlHndl_t startPMComplex (TARGETING::Target* i_target); + + /** + * @brief Reset PM Complex. + * + * @param[in] i_target: target of processor + * + * @return errlHndl_t Error log of resetPMComplex failed + */ + errlHndl_t resetPMComplex(TARGETING::Target * i_target); + +} //namespace HBPM ends + +#endif diff --git a/src/usr/isteps/pm/runtime/makefile b/src/usr/isteps/pm/runtime/makefile new file mode 100644 index 000000000..1f0e90b2e --- /dev/null +++ b/src/usr/isteps/pm/runtime/makefile @@ -0,0 +1,39 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/isteps/pm/runtime/makefile $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2016 +# [+] 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 + +HOSTBOOT_RUNTIME = 1 + +ROOTPATH = ../../../../.. +VPATH += ../ + +MODULE = pm_rt + +## Objects unique to HBRT +OBJS += rt_pm.o + +## Objects common to HBRT and HB IPL +include ../pm.mk + +include ${ROOTPATH}/config.mk diff --git a/src/usr/isteps/pm/runtime/rt_pm.C b/src/usr/isteps/pm/runtime/rt_pm.C new file mode 100644 index 000000000..46aefe865 --- /dev/null +++ b/src/usr/isteps/pm/runtime/rt_pm.C @@ -0,0 +1,389 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/pm/runtime/rt_pm.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] 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 */ + +#include <stdint.h> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <errno.h> +#include <sys/misc.h> +#include <trace/interface.H> +#include <util/utillidmgr.H> + +#include <pm/pm_common.H> + +#include <runtime/interface.h> +#include <runtime/rt_targeting.H> + +#include <initservice/isteps_trace.H> + +// targeting support +#include <targeting/common/utilFilter.H> +#include <targeting/common/targetservice.H> + +using namespace TARGETING; + +namespace ISTEPS_TRACE +{ + // declare storage for isteps_trace! + trace_desc_t * g_trac_isteps_trace = NULL; + TRAC_INIT(&ISTEPS_TRACE::g_trac_isteps_trace, "ISTEPS_TRACE", 2*KILOBYTE); +} + +namespace RTPM +{ + /** + * @brief Process error log created while running a PM Complex function + * @param[in] i_err Error handle + * @param[in/out] io_rc Return code + */ + void pm_complex_error( errlHndl_t i_err, + int &io_rc ) + { + errlCommit( i_err, RUNTIME_COMP_ID ); + + if(io_rc == 0) + { + io_rc = -1; + } + + return; + } + + + // @TODO RTC: 148935 Defer creation of publicly accessible version for + // HTMGT to consume that also handles the non-runtime case + /** + * @brief Convert HOMER physical address space to a vitual address + * @param[in] i_proc_target Processsor target + * @param[in] i_phys_addr Physical address + * @return NULL on error, else virtual address + */ + void *convertHomerPhysToVirt( TARGETING::Target* i_proc_target, + uint64_t i_phys_addr) + { + int rc = 0; + + void *l_virt_addr = reinterpret_cast <void*> + (i_proc_target->getAttr<ATTR_HOMER_VIRT_ADDR>()); + + if((i_proc_target->getAttr<ATTR_HOMER_PHYS_ADDR>() != i_phys_addr) || + (NULL == l_virt_addr)) + { + if(NULL != l_virt_addr) + { + rc = g_hostInterfaces->unmap_phys_mem(l_virt_addr); + if(rc) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"convertHomerPhysToVirt: " + "unmap_phys_mem failed, rc=0x%0X", + rc); + + l_virt_addr = NULL; + } + } + + l_virt_addr = g_hostInterfaces->map_phys_mem(i_phys_addr, + 4*MEGABYTE); + + // Update the attributes for the current values + i_proc_target->setAttr<ATTR_HOMER_PHYS_ADDR>(i_phys_addr); + i_proc_target->setAttr<ATTR_HOMER_VIRT_ADDR>( + reinterpret_cast<uint64_t>(l_virt_addr)); + } + + return l_virt_addr; + } + + + /** + * @brief Load OCC/HCODE images into mainstore + */ + int load_pm_complex( uint64_t i_chip, + uint64_t i_homer_addr, + uint64_t i_occ_common_addr, + uint32_t i_mode ) + { + // LOAD == i_mode + // - HBRT loads OCC lid, writes OCC config data, builds Pstate + // Parameter Blocks, and loads Hcode reference image lid + // RELOAD == i_mode + // - HBRT reloads OCC lid, rewrites OCC config data, builds Pstate + // Parameter Blocks, and rebuilds Hcode + + Target* proc_target = NULL; + errlHndl_t err = NULL; + int rc = 0; + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "load_pm_complex: homer addr=%016llx. " + "occ common addr=%016lx. RtProcChip=%llx. mode=%d", + i_homer_addr, + i_occ_common_addr, + i_chip, + i_mode); +/* @TODO RTC: 148935 */ + do + { + // Utility to convert i_chip to Target + err = RT_TARG::getHbTarget(i_chip, proc_target); + if(err) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"load_pm_complex: " + "convert Chip to Target failed!" ); + rc = EINVAL; + break; + } + else + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "load_pm_complex: " + "proc Target HUID=0x%08X", + proc_target->getAttr<ATTR_HUID>()); + } + + void* occVirt = convertHomerPhysToVirt(proc_target, + i_homer_addr); + if(NULL == occVirt) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"load_pm_complex: " + "converting physical address to virtual failed!"); + break; + } + + uint64_t l_homer_addr_va = + reinterpret_cast <uint64_t>(occVirt); + + err = HBPM::loadOCCSetup(proc_target, + i_homer_addr, + l_homer_addr_va, + i_occ_common_addr); + if(err) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"load_pm_complex: " + "setting up OCC load failed!" ); + break; + } + + err = HBPM::loadOCCImageToHomer(proc_target, + i_homer_addr, + l_homer_addr_va); + if(err) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"load_pm_complex: " + "loading OCC failed!" ); + break; + } + + void* occHostVirt = reinterpret_cast <void *>(l_homer_addr_va + + HOMER_OFFSET_TO_OCC_HOST_DATA); + + err = HBPM::loadHostDataToHomer(proc_target, + occHostVirt); + if(err) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"load_pm_complex: " + "loading Host Data Area failed!" ); + break; + } + + // @TODO RTC:153885 verify parameters on call + err = HBPM::pstateParameterBuild(proc_target, + occVirt); + if(err) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"load_pm_complex: " + "building Pstate Parameter Block failed!"); + break; + } + + err = HBPM::loadHcode(proc_target, + occVirt, + i_mode); + if(err) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"load_pm_complex: " + "loadHcode, %s failed!", + (HBRT_PM_LOAD == i_mode) ? "LOAD" : "RELOAD"); + break; + } + } while(0); +/* @TODO RTC: 148935 */ + if (err) + { + pm_complex_error(err, + rc); + } + + return rc; + } + + + /** + * @brief Start OCC/HCODE on the specified chip + */ + int start_pm_complex( uint64_t i_chip ) + { + // HBRT executes p9_pm_init(INIT) + + Target* proc_target = NULL; + errlHndl_t err = NULL; + int rc = 0; + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "start_pm_complex: RtProcChip %llx", i_chip); + + // Run Sheldon's simics command file @TODO RTC: 148935 + /* MAGIC_INSTRUCTION(MAGIC_RUN_COMMAND_FILE); @TODO RTC: 148935 */ + +/* @TODO RTC: 148935 start */ + do + { + // Utility to convert i_chip to Target + err = RT_TARG::getHbTarget(i_chip, proc_target); + if( err ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"start_pm_complex: " + "convert Chip to Target failed!" ); + rc = EINVAL; + break; + } + else + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "start_pm_complex: " + "proc Target HUID=0x%08X", + proc_target->getAttr<ATTR_HUID>()); + } + + err = HBPM::startPMComplex(proc_target); + if( err ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"start_pm_complex: " + "starting OCC failed!" ); + break; + } + } while(0); +/* end @TODO RTC: 148935 */ + if ( err ) + { + pm_complex_error(err, + rc); + } + + return rc; + } + + + /** + * @brief Reset OCC/HCODE on the specified chip + */ + int reset_pm_complex( uint64_t i_chip ) + { + // HBRT executes p9_pm_init(RESET) + + Target* proc_target = NULL; + errlHndl_t err = NULL; + int rc = 0; + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "reset_pm_complex: RtProcChip %llx", i_chip); +/* @TODO RTC: 148935 start */ + do + { + // Utility to convert i_chip to Target + err = RT_TARG::getHbTarget(i_chip, proc_target); + if( err ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"reset_pm_complex: " + "convert Chip to Target failed!" ); + rc = EINVAL; + break; + } + else + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "reset_pm_complex: " + "proc Target HUID=0x%08X", + proc_target->getAttr<ATTR_HUID>()); + } + + err = HBPM::resetPMComplex(proc_target); + if( err ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK"reset_pm_complex: " + "stopping OCC failed!" ); + break; + } + } while(0); +/* end @TODO RTC: 148935 */ + if ( err ) + { + pm_complex_error(err, + rc); + } + + return rc; + } + + //------------------------------------------------------------------------ + + struct registerPm + { + registerPm() + { + runtimeInterfaces_t * rt_intf = getRuntimeInterfaces(); + rt_intf->load_pm_complex = &load_pm_complex; + rt_intf->start_pm_complex = &start_pm_complex; + rt_intf->reset_pm_complex = &reset_pm_complex; + + // If we already loaded OCC during the IPL we need to fix up + // the virtual address because we're now not using virtual + // memory + + TargetHandleList procChips; + getAllChips(procChips, TYPE_PROC, true); + for (TargetHandleList::iterator itr = procChips.begin(); + itr != procChips.end(); + ++itr) + { + (*itr)->setAttr<ATTR_HOMER_VIRT_ADDR>(0); + } + } + }; + + registerPm g_registerPm; +}; |