summaryrefslogtreecommitdiffstats
path: root/src/sbefw/core/sbecmdmpipl.C
diff options
context:
space:
mode:
authorspashabk-in <shakeebbk@in.ibm.com>2017-11-27 04:43:18 -0600
committerSachin Gupta <sgupta2m@in.ibm.com>2018-01-03 00:22:11 -0500
commit819a606d9c583ccfa1ca7852a4bae42efb5da53e (patch)
tree9d9f0945dd4a7adc400ad9f941f0399396df203b /src/sbefw/core/sbecmdmpipl.C
parentb99e4a419eecff1dbc488324e11aa0a3e31aa368 (diff)
downloadtalos-sbe-819a606d9c583ccfa1ca7852a4bae42efb5da53e.tar.gz
talos-sbe-819a606d9c583ccfa1ca7852a4bae42efb5da53e.zip
[SBE-code-re-org][1] sbefw - core and app folders
Create a core and app folder inside sbefw Change-Id: I4ee04eb5d6623a2272a20f5dd8b02ef795757b2e Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/50185 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src/sbefw/core/sbecmdmpipl.C')
-rw-r--r--src/sbefw/core/sbecmdmpipl.C430
1 files changed, 430 insertions, 0 deletions
diff --git a/src/sbefw/core/sbecmdmpipl.C b/src/sbefw/core/sbecmdmpipl.C
new file mode 100644
index 00000000..3179382f
--- /dev/null
+++ b/src/sbefw/core/sbecmdmpipl.C
@@ -0,0 +1,430 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/core/sbecmdmpipl.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* */
+/* */
+/* 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 */
+/*
+ * @file: ppe/src/sbefw/sbecmdmpipl.C
+ *
+ * @brief This file contains the SBE MPIPL chipOps
+ *
+ */
+
+#include "sbefifo.H"
+#include "sbeSpMsg.H"
+#include "sbe_sp_intf.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbecmdmpipl.H"
+#include "sberegaccess.H"
+#include "sbefapiutil.H"
+#include "sbecmdiplcontrol.H"
+
+#include "p9_hcd_core_stopclocks.H"
+#include "p9_hcd_cache_stopclocks.H"
+#include "p9_stopclocks.H"
+#include "fapi2.H"
+
+using namespace fapi2;
+
+// Defines for stop clock
+#define SBE_IS_EX0(chipletId) \
+ (!(((chipletId - CORE_CHIPLET_OFFSET) & 0x0002) >> 1))
+
+/* @brief Bitmapped enumeration to identify the stop clock HWP call
+ */
+enum stopClockHWPType
+{
+ SC_NONE = 0x00,
+ SC_PROC = 0x01, // Call p9_stopclocks
+ SC_CACHE = 0x02, // Call p9_hcd_cache_stopclocks
+ SC_CORE = 0x04, // Call p9_hcd_core_stopclocks
+};
+
+#ifdef __SBEFW_SEEPROM__
+
+#ifdef SEEPROM_IMAGE
+ // Using function pointer to force long call.
+p9_hcd_cache_stopclocks_FP_t p9_hcd_cache_stopclocks_hwp = &p9_hcd_cache_stopclocks;
+p9_hcd_core_stopclocks_FP_t p9_hcd_core_stopclocks_hwp = &p9_hcd_core_stopclocks;
+p9_stopclocks_FP_t p9_stopclocks_hwp = &p9_stopclocks;
+#endif
+
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeEnterMpipl Sbe enter MPIPL function
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeEnterMpipl(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeEnterMpipl "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_fapiRc = FAPI2_RC_SUCCESS;
+ uint32_t len = 0;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ l_rc = sbeUpFifoDeq_mult (len, NULL);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ uint32_t l_minor = 1;
+ do
+ {
+ l_fapiRc = sbeExecuteIstep(SBE_ISTEP_MPIPL_START, l_minor);
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "Failed in Mpipl Start in ChipOp Mode "
+ "Minor: %d", l_minor);
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ // reset attribute. We do not want to reset register, so do not
+ // use setMpIplMode
+ uint8_t isMpipl = 0;
+ PLAT_ATTR_INIT(ATTR_IS_MPIPL, Target<TARGET_TYPE_SYSTEM>(),
+ isMpipl);
+ break;
+ }
+ ++l_minor;
+ }while(l_minor<=MPIPL_START_MAX_SUBSTEPS);
+
+ }while(0);
+
+ // Create the Response to caller
+ do
+ {
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ l_rc = sbeDsSendRespHdr( l_respHdr, &l_ffdc);
+ }while(0);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeContinueMpipl Sbe Continue MPIPL function
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeContinueMpipl(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeContinueMpipl "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+
+ ReturnCode l_fapiRc = FAPI2_RC_SUCCESS;
+ sbeResponseFfdc_t l_ffdc;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ l_rc = sbeUpFifoDeq_mult (len, NULL);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ sbeRole l_sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ?
+ SBE_ROLE_SLAVE : SBE_ROLE_MASTER;
+ // Run isteps
+ const uint8_t isteps[][3] = {
+ // Major Num, Minor Start, Minor End
+ {SBE_ISTEP_MPIPL_CONTINUE, ISTEP_MINOR_START, MPIPL_CONTINUE_MAX_SUBSTEPS},
+ {SBE_ISTEP4, ISTEP_MINOR_START, ISTEP4_MAX_SUBSTEPS},
+ {SBE_ISTEP5, ISTEP_MINOR_START, ISTEP5_MAX_SUBSTEPS}};
+ // Loop through isteps
+ for( auto istep : isteps)
+ {
+ // This is required here to skip the major istep 4/5 in slave
+ if((SBE_ROLE_SLAVE == l_sbeRole) &&
+ (istep[0] == SBE_ISTEP4 || istep[0] == SBE_ISTEP5))
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_RUNTIME_EVENT);
+ continue;
+ }
+ for(uint8_t l_minor = istep[1]; l_minor <= istep[2]; l_minor++)
+ {
+ l_fapiRc = sbeExecuteIstep(istep[0], l_minor);
+ if(l_fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "Failed in Mpipl continue in ChipOp "
+ "Mode Major [%d] Minor [%d]", istep[0], l_minor);
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ }
+ if(l_ffdc.getRc() != FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+ }
+ }while(0);
+
+ // reset attribute. We do not want to reset register, so do not
+ // use setMpIplMode
+ uint8_t isMpipl = 0;
+ PLAT_ATTR_INIT(ATTR_IS_MPIPL, Target<TARGET_TYPE_SYSTEM>(), isMpipl);
+ // Create the Response to caller
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ if(SBE_SEC_OPERATION_SUCCESSFUL == l_rc)
+ {
+ l_rc = sbeDsSendRespHdr( l_respHdr, &l_ffdc);
+ }
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+///////////////////////////////////////////////////////////////////////
+/* @brief Deduce the type of stop clock procedure to call based on
+ * target and chiplet id combination
+ *
+ * @param[in] i_targetType SBE chip-op target type
+ * @param[in] i_chipletId Chiplet id
+ *
+ * @return Bitmapped stopClockHWPType enum values
+ */
+///////////////////////////////////////////////////////////////////////
+static inline uint32_t getStopClockHWPType(uint32_t i_targetType,
+ uint32_t i_chipletId)
+{
+ uint32_t l_rc = SC_NONE;
+ TargetType l_fapiTarget = sbeGetFapiTargetType(
+ i_targetType,
+ i_chipletId);
+ if((l_fapiTarget == TARGET_TYPE_PROC_CHIP) ||
+ (l_fapiTarget == TARGET_TYPE_PERV) ||
+ ((i_targetType == TARGET_CORE) && (i_chipletId == SMT4_ALL_CORES))||
+ ((i_targetType == TARGET_EQ) && (i_chipletId == EQ_ALL_CHIPLETS)) ||
+ ((i_targetType == TARGET_EX) && (i_chipletId == EX_ALL_CHIPLETS)))
+ {
+ l_rc |= SC_PROC;
+ }
+ if((l_fapiTarget == TARGET_TYPE_CORE) ||
+ (l_fapiTarget == TARGET_TYPE_EX))
+ {
+ l_rc |= SC_CORE;
+ }
+ if((l_fapiTarget == TARGET_TYPE_EQ) ||
+ (l_fapiTarget == TARGET_TYPE_EX))
+ {
+ l_rc |= SC_CACHE;
+ }
+ return l_rc;
+}
+
+///////////////////////////////////////////////////////////////////////
+/* @brief Prepare Stop clock flags base on Target Type
+ *
+ * @param[in] i_targetType SBE chip-op target Type
+ *
+ * @return p9_stopclocks_flags
+ */
+///////////////////////////////////////////////////////////////////////
+static inline p9_stopclocks_flags getStopClocksFlags(uint32_t i_targetType)
+{
+ p9_stopclocks_flags l_flags;
+
+ if(i_targetType != TARGET_PROC_CHIP)
+ {
+ // Clear default flags - only in case the target is not PROC_CHIP
+ // Otherwise, for a PROC_CHIP target, we want to keep default flags
+ l_flags.clearAll();
+ }
+ if(i_targetType == TARGET_PERV)
+ {
+ // Keep only tp as true
+ l_flags.stop_tp_clks = true;
+ }
+ else if(i_targetType == TARGET_CORE)
+ {
+ // Keep only core flag as true
+ l_flags.stop_core_clks = true;
+ }
+ else if(i_targetType == TARGET_EQ)
+ {
+ // Keep only cache flag as true
+ l_flags.stop_cache_clks = true;
+ }
+ else if(i_targetType == TARGET_EX)
+ {
+ // Keep only cache and core as true
+ l_flags.stop_cache_clks = true;
+ l_flags.stop_core_clks = true;
+ }
+
+ return l_flags;
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeStopClocks Sbe Stop Clocks function
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeStopClocks(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeStopClocks"
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_fapiRc = FAPI2_RC_SUCCESS;
+ uint32_t l_len = 0;
+ sbeResponseFfdc_t l_ffdc;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+ sbeStopClocksReqMsgHdr_t l_reqMsg = {0};
+
+ do
+ {
+ // Get the TargetType and ChipletId from the command message
+ l_len = sizeof(sbeStopClocksReqMsgHdr_t)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len, (uint32_t *)&l_reqMsg); // EOT fetch
+ // If FIFO access failure
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ SBE_INFO(SBE_FUNC "TargetType 0x%04X ChipletId 0x%02X",
+ (uint16_t)l_reqMsg.targetType,
+ (uint8_t)l_reqMsg.chipletId);
+
+ fapi2::plat_target_handle_t l_tgtHndl;
+ // Keep these default values in sync with p9_stopclocks.H
+ p9hcd::P9_HCD_CLK_CTRL_CONSTANTS l_clk_regions
+ = p9hcd::CLK_REGION_ALL_BUT_PLL_REFR;
+ p9hcd::P9_HCD_EX_CTRL_CONSTANTS l_ex_select = p9hcd::BOTH_EX;
+
+ // Get the type of stopclocks procedure to call
+ // based on target and chiplet id
+ uint32_t l_hwpType = getStopClockHWPType(l_reqMsg.targetType,
+ l_reqMsg.chipletId);
+ if(l_hwpType == SC_NONE)
+ {
+ // Error in target and chiplet id combination
+ SBE_ERROR(SBE_FUNC "Invalid TargetType[0x%04X] ChipletId[0x%02X]",
+ (uint32_t)l_reqMsg.targetType,
+ (uint32_t)l_reqMsg.chipletId);
+ l_respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_INVALID_TARGET_TYPE_PASSED );
+ break;
+ }
+ // All Core/All Cache/All Ex & Perv & Proc are handled here
+ if(l_hwpType & SC_PROC)
+ {
+ SBE_DEBUG(SBE_FUNC " Calling p9_stopclocks");
+ p9_stopclocks_flags l_flags = getStopClocksFlags(
+ l_reqMsg.targetType);
+ if(l_reqMsg.targetType == TARGET_EX)
+ {
+ l_clk_regions = static_cast<p9hcd::P9_HCD_CLK_CTRL_CONSTANTS>
+ (p9hcd::CLK_REGION_EX0_REFR |
+ p9hcd::CLK_REGION_EX1_REFR);
+ }
+ l_flags.sync_stop_quad_clks = false;
+ SBE_EXEC_HWP(l_fapiRc, p9_stopclocks_hwp,
+ plat_getChipTarget(),
+ l_flags,
+ l_clk_regions,
+ l_ex_select);
+ }
+ // Specific CORE/EX
+ if(l_hwpType & SC_CORE)
+ {
+ SBE_DEBUG(SBE_FUNC " Calling p9_hcd_core_stopclocks");
+ sbeGetFapiTargetHandle(l_reqMsg.targetType,
+ l_reqMsg.chipletId,
+ l_tgtHndl);
+ if(l_reqMsg.targetType == TARGET_EX)
+ {
+ Target<TARGET_TYPE_EX> l_exTgt(l_tgtHndl);
+ for(auto &l_childCore :
+ l_exTgt.getChildren<TARGET_TYPE_CORE>())
+ {
+ SBE_EXEC_HWP(l_fapiRc,
+ p9_hcd_core_stopclocks_hwp,
+ l_childCore,
+ false);
+ }
+ }
+ else
+ {
+ SBE_EXEC_HWP(l_fapiRc, p9_hcd_core_stopclocks_hwp, l_tgtHndl, false);
+ }
+ }
+ // Specific EQ/EX
+ if(l_hwpType & SC_CACHE)
+ {
+ SBE_DEBUG(SBE_FUNC " Calling p9_hcd_cache_stopclocks");
+ if(l_reqMsg.targetType == TARGET_EX)
+ {
+ // Modify l_clk_regions based on chiplet Id
+ l_clk_regions = SBE_IS_EX0(l_reqMsg.chipletId) ?
+ p9hcd::CLK_REGION_EX0_REFR : p9hcd::CLK_REGION_EX1_REFR;
+ // Modify l_ex_select based on chiplet ID
+ l_ex_select = SBE_IS_EX0(l_reqMsg.chipletId) ?
+ p9hcd::EVEN_EX : p9hcd::ODD_EX;
+ Target<TARGET_TYPE_EX> l_ex_target(l_tgtHndl);
+ l_tgtHndl = l_ex_target.getParent<TARGET_TYPE_EQ>();
+ }
+ SBE_EXEC_HWP(l_fapiRc, p9_hcd_cache_stopclocks_hwp,
+ l_tgtHndl,
+ (p9hcd::P9_HCD_CLK_CTRL_CONSTANTS)l_clk_regions,
+ (p9hcd::P9_HCD_EX_CTRL_CONSTANTS)l_ex_select,
+ false);
+ }
+
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" Stopclocks failed for TargetType [0x%04X] "
+ "ChipletId [0x%02X]",
+ (uint16_t)l_reqMsg.targetType,
+ (uint8_t)l_reqMsg.chipletId);
+ l_respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ }while(0);
+
+ // Create the Response to caller
+ // If there was a FIFO error, will skip sending the response,
+ // instead give the control back to the command processor thread
+ if(SBE_SEC_OPERATION_SUCCESSFUL == l_rc)
+ {
+ l_rc = sbeDsSendRespHdr( l_respHdr, &l_ffdc);
+ }
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+#endif //__SBEFW_SEEPROM__
OpenPOWER on IntegriCloud