summaryrefslogtreecommitdiffstats
path: root/src/sbefw/core/sbecmdiplcontrol.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbefw/core/sbecmdiplcontrol.C')
-rw-r--r--src/sbefw/core/sbecmdiplcontrol.C1715
1 files changed, 1715 insertions, 0 deletions
diff --git a/src/sbefw/core/sbecmdiplcontrol.C b/src/sbefw/core/sbecmdiplcontrol.C
new file mode 100644
index 00000000..ae811c4c
--- /dev/null
+++ b/src/sbefw/core/sbecmdiplcontrol.C
@@ -0,0 +1,1715 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/core/sbecmdiplcontrol.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,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/sbe/sbefw/sbecmdiplcontrol.C
+ *
+ * @brief This file contains the SBE istep chipOps
+ *
+ */
+
+#include "sbecmdiplcontrol.H"
+#include "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeFifoMsgUtils.H"
+#include "assert.h"
+#include "sberegaccess.H"
+#include "sbestates.H"
+#include "sbecmdcntrldmt.H"
+#include "sbeglobals.H"
+// TODO Workaround
+#include "plat_target_parms.H"
+
+#include "fapi2.H"
+#include "p9_misc_scom_addresses_fld.H"
+#include "p9_perv_scom_addresses_fld.H"
+#include "p9n2_quad_scom_addresses.H"
+// Pervasive HWP Header Files ( istep 2)
+#include <p9_sbe_attr_setup.H>
+#include <p9_sbe_tp_chiplet_init1.H>
+#include <p9_sbe_tp_gptr_time_initf.H>
+#include <p9_sbe_npll_initf.H>
+#include <p9_sbe_npll_setup.H>
+#include <p9_sbe_tp_switch_gears.H>
+#include <p9_sbe_clock_test2.H>
+#include <p9_sbe_tp_chiplet_reset.H>
+#include <p9_sbe_tp_repr_initf.H>
+#include <p9_sbe_tp_chiplet_init2.H>
+#include <p9_sbe_tp_arrayinit.H>
+#include <p9_sbe_tp_initf.H>
+#include <p9_sbe_tp_chiplet_init3.H>
+
+// Pervasive HWP Header Files ( istep 3)
+#include <p9_sbe_chiplet_reset.H>
+#include <p9_sbe_gptr_time_initf.H>
+#include <p9_sbe_chiplet_init.H>
+#include <p9_sbe_chiplet_pll_initf.H>
+#include <p9_sbe_chiplet_pll_setup.H>
+#include <p9_sbe_repr_initf.H>
+#include <p9_sbe_arrayinit.H>
+#include <p9_sbe_tp_enable_ridi.H>
+#include <p9_sbe_setup_boot_freq.H>
+#include <p9_sbe_nest_initf.H>
+#include <p9_sbe_nest_startclocks.H>
+#include <p9_sbe_io_initf.H>
+#include <p9_sbe_nest_enable_ridi.H>
+#include <p9_sbe_startclock_chiplets.H>
+#include <p9_sbe_scominit.H>
+#include <p9_sbe_lpc_init.H>
+#include <p9_sbe_fabricinit.H>
+#include <p9_sbe_mcs_setup.H>
+#include <p9_sbe_select_ex.H>
+// Cache HWP header file
+#include <p9_hcd_cache.H>
+#include <p9_hcd_cache_dcc_skewadjust_setup.H>
+#include <p9_hcd_cache_chiplet_l3_dcc_setup.H>
+#include <p9_hcd_cache_dpll_initf.H>
+// Core HWP header file
+#include <p9_hcd_core.H>
+
+// istep 5 hwp header files
+#include "p9_sbe_instruct_start.H"
+#include "p9_sbe_load_bootloader.H"
+
+// istep mpipl header files
+#include "p9_block_wakeup_intr.H"
+#include "p9_query_core_access_state.H"
+#include "p9_sbe_check_quiesce.H"
+#include "p9_l2_flush.H"
+#include "p9_l3_flush.H"
+#include "p9_sbe_sequence_drtm.H"
+#include "p9_thread_control.H"
+#include "sbecmdcntlinst.H"
+#include "p9_quad_power_off.H"
+#include "p9_hcd_cache_stopclocks.H"
+#include "p9_stopclocks.H"
+#include "p9_suspend_powman.H"
+#include "p9_suspend_io.H"
+
+#include "sbeXipUtils.H" // For getting hbbl offset
+#include "sbeutil.H" // For getting SBE_TO_NEST_FREQ_FACTOR
+
+#include "p9_fbc_utils.H"
+#include "sbeSecureMemRegionManager.H"
+// Forward declaration
+using namespace fapi2;
+
+bool validateIstep (uint8_t i_major, uint8_t i_minor);
+
+//typedefs
+typedef ReturnCode (*sbeIstepHwpProc_t)
+ (const Target<TARGET_TYPE_PROC_CHIP> & i_target);
+
+typedef ReturnCode (*sbeIstepHwpTpSwitchGears_t)
+ (const Target<TARGET_TYPE_PROC_CHIP> & i_target);
+
+typedef ReturnCode (*sbeIstepHwpEq_t)
+ (const Target<TARGET_TYPE_EQ> & i_target);
+
+typedef ReturnCode (*sbeIstepHwpCore_t)
+ (const Target<TARGET_TYPE_CORE> & i_target);
+
+typedef ReturnCode (*sbeIstepHwpExL2Flush_t)
+ (const Target<TARGET_TYPE_EX> & i_target,
+ const p9core::purgeData_t & i_purgeData);
+
+typedef ReturnCode (*sbeIstepHwpExL3Flush_t)
+ (const Target<TARGET_TYPE_EX> & i_target,
+ const uint32_t i_purgeType,
+ const uint32_t i_purgeAddr);
+
+typedef ReturnCode (*sbeIstepHwpCoreBlockIntr_t)
+ (const Target<TARGET_TYPE_CORE> & i_target,
+ const p9pmblockwkup::OP_TYPE i_oper);
+
+typedef ReturnCode (*sbeIstepHwpCoreScomState_t)
+ (const Target<TARGET_TYPE_CORE> & i_target,
+ bool & o_isScom,
+ bool & o_isScan);
+
+typedef ReturnCode (*sbeIstepHwpSequenceDrtm_t)
+ (const Target<TARGET_TYPE_PROC_CHIP> & i_target,
+ uint8_t & o_status);
+
+typedef ReturnCode (*sbeIstepHwpQuadPoweroff_t)
+ (const Target<TARGET_TYPE_EQ> & i_target,
+ uint64_t * o_ring_save_data);
+
+typedef ReturnCode (*sbeIstepHwpCacheInitf_t)
+ (const Target<TARGET_TYPE_EQ> & i_target,
+ const uint64_t * i_ring_save_data);
+
+typedef union
+{
+ sbeIstepHwpProc_t procHwp;
+ sbeIstepHwpEq_t eqHwp;
+ sbeIstepHwpCore_t coreHwp;
+ sbeIstepHwpExL2Flush_t exL2Hwp;
+ sbeIstepHwpExL3Flush_t exL3Hwp;
+ sbeIstepHwpCoreBlockIntr_t coreBlockIntrHwp;
+ sbeIstepHwpCoreScomState_t coreScomStateHwp;
+ sbeIstepHwpSequenceDrtm_t procSequenceDrtm;
+ sbeIstepHwpQuadPoweroff_t quadPoweroffHwp;
+ sbeIstepHwpCacheInitf_t cacheInitfHwp;
+}sbeIstepHwp_t;
+
+// Wrapper function for HWP IPl functions
+typedef ReturnCode (*sbeIstep_t)( sbeIstepHwp_t );
+
+// Wrapper function which will call HWP.
+ReturnCode istepWithProc( sbeIstepHwp_t i_hwp );
+ReturnCode istepHwpTpSwitchGears( sbeIstepHwp_t i_hwp);
+ReturnCode istepAttrSetup( sbeIstepHwp_t i_hwp );
+ReturnCode istepNoOp( sbeIstepHwp_t i_hwp );
+ReturnCode istepWithEq( sbeIstepHwp_t i_hwp);
+ReturnCode istepWithCore( sbeIstepHwp_t i_hwp);
+ReturnCode istepSelectEx( sbeIstepHwp_t i_hwp);
+ReturnCode istepLoadBootLoader( sbeIstepHwp_t i_hwp);
+ReturnCode istepCheckSbeMaster( sbeIstepHwp_t i_hwp);
+ReturnCode istepStartInstruction( sbeIstepHwp_t i_hwp);
+ReturnCode istepWithCoreConditional( sbeIstepHwp_t i_hwp);
+ReturnCode istepWithEqConditional( sbeIstepHwp_t i_hwp);
+ReturnCode istepNestFreq( sbeIstepHwp_t i_hwp);
+ReturnCode istepLpcInit( sbeIstepHwp_t i_hwp);
+ReturnCode istepCacheInitf( sbeIstepHwp_t i_hwp );
+
+//MPIPL Specific
+ReturnCode istepWithCoreSetBlock( sbeIstepHwp_t i_hwp );
+ReturnCode istepWithCoreState( sbeIstepHwp_t i_hwp );
+ReturnCode istepMpiplRstClrTpmBits( sbeIstepHwp_t i_hwp );
+ReturnCode istepWithProcQuiesceLQASet( sbeIstepHwp_t i_hwp );
+ReturnCode istepWithExL2Flush( sbeIstepHwp_t i_hwp );
+ReturnCode istepWithExL3Flush( sbeIstepHwp_t i_hwp );
+ReturnCode istepStartMpipl( sbeIstepHwp_t i_hwp );
+ReturnCode istepWithProcSequenceDrtm( sbeIstepHwp_t i_hwp );
+ReturnCode istepMpiplSetFunctionalState( sbeIstepHwp_t i_hwp );
+ReturnCode istepMpiplQuadPoweroff( sbeIstepHwp_t i_hwp );
+ReturnCode istepStopClockMpipl( sbeIstepHwp_t i_hwp );
+
+// Utility function to do TPM reset
+ReturnCode performTpmReset();
+
+//Utility function to update PHB functional State
+ReturnCode updatePhbFunctionalState( void );
+
+//Utility function to clear crest error latch
+ReturnCode resetCrespErrLatch( void );
+
+#ifdef SEEPROM_IMAGE
+
+//Utility function to mask special attention
+inline ReturnCode maskSpecialAttn( const Target<TARGET_TYPE_CORE>& i_target );
+// Using function pointer to force long call.
+extern p9_stopclocks_FP_t p9_stopclocks_hwp;
+extern p9_thread_control_FP_t threadCntlhwp;
+#ifndef __SBEFW_SEEPROM__
+p9_suspend_io_FP_t p9_suspend_io_hwp = &p9_suspend_io;
+p9_sbe_select_ex_FP_t p9_sbe_select_ex_hwp = &p9_sbe_select_ex;
+#endif
+#ifdef __SBEFW_SEEPROM__
+extern p9_suspend_io_FP_t p9_suspend_io_hwp;
+extern p9_sbe_select_ex_FP_t p9_sbe_select_ex_hwp;
+#endif
+
+#endif
+
+//structure for mapping SBE wrapper and HWP functions
+typedef struct
+{
+ sbeIstep_t istepWrapper;
+ sbeIstepHwp_t istepHwp;
+}istepMap_t;
+
+
+// constants
+static const uint32_t SBE_ROLE_MASK = 0x00000002;
+static const uint32_t SBE_SYSTEM_QUIESCE_TIMEOUT_LOOP = 20000;
+
+static const uint64_t SBE_LQA_DELAY_HW_US = 1000000ULL; // 1ms
+static const uint64_t SBE_LQA_DELAY_SIM_CYCLES = 0x1ULL;
+
+static const uint32_t PEC_PHB_IOVALID_BIT_SHIFT = 59;
+static const uint64_t PEC_PHB_IOVALID_BIT_MASK = 0x1ULL;
+
+// Bit-33 used to checkstop the system, Since this is directly getting inserted
+// will have to use bit (63-33) = 30th bit
+static const uint64_t N3_FIR_SYSTEM_CHECKSTOP_BIT = 30; // 63-33 = 30
+
+#ifndef __SBEFW_SEEPROM__
+sbeRole g_sbeRole = SBE_ROLE_MASTER;
+
+uint64_t G_ring_save[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+// Globals
+// TODO: via RTC 123602 This global needs to move to a class that will store the
+// SBE FFDC.
+fapi2::ReturnCode g_iplFailRc = FAPI2_RC_SUCCESS;
+#endif
+
+#ifdef __SBEFW_SEEPROM__
+extern sbeRole g_sbeRole;
+extern uint64_t G_ring_save[8];
+extern fapi2::ReturnCode g_iplFailRc;
+#endif
+
+
+#ifndef __SBEFW_SEEPROM__
+static istepMap_t g_istepMpiplStartPtrTbl[MPIPL_START_MAX_SUBSTEPS] =
+ {
+#ifdef SEEPROM_IMAGE
+ // Place holder for StartMpipl, State Change, PHB State Update,
+ // Clear CRESP error latch register.
+ // Set MPIPL mode in Sratch Reg 3
+ { &istepStartMpipl, NULL },
+ // Call suspend powerman
+ { &istepWithProc, { .procHwp = &p9_suspend_powman }},
+ // Find all the child cores within proc and call hwp to know the
+ // scom state and call instruction control. Also mask spl attention
+ // from core.
+ { &istepWithCoreState, { .coreScomStateHwp = &p9_query_core_access_state }},
+ // Reset the TPM and clear the TPM deconfig bit, it's not a
+ // procedure but local SBE function
+ { &istepMpiplRstClrTpmBits, NULL },
+ // quiesce state for all units on the powerbus on its chip
+ { &istepWithProcQuiesceLQASet, { .procHwp = &p9_sbe_check_quiesce }},
+ // L2 cache flush via purge engine on each EX
+ { &istepWithExL2Flush, { .exL2Hwp = &p9_l2_flush }},
+ // L3 cache flush via purge engine on each EX
+ { &istepWithExL3Flush, { .exL3Hwp = &p9_l3_flush }},
+ // Check on Quiescing of all Chips in a System by Local SBE
+ { &istepWithProcSequenceDrtm, { .procSequenceDrtm = &p9_sbe_sequence_drtm }},
+#endif
+ };
+
+static istepMap_t g_istepMpiplContinuePtrTbl[MPIPL_CONTINUE_MAX_SUBSTEPS] =
+ {
+#ifdef SEEPROM_IMAGE
+ // Setup EC/EQ guard records
+ { &istepMpiplSetFunctionalState, NULL},
+ { &istepNoOp, NULL }, // Witherspoon only (mpipl_dump_reg)
+ { &istepNoOp, NULL }, // Witherspoon only (mpipl_query_quad_access_state)
+ { &istepNoOp, NULL }, // Witherspoon only (mpipl_hcd_core_stopclocks)
+ { &istepNoOp, NULL }, // Witherspoon only (mpipl_hcd_cache_stopclocks)
+ // p9_quad_power_off
+ { istepMpiplQuadPoweroff, { .quadPoweroffHwp = &p9_quad_power_off} },
+ // No-op
+ { &istepNoOp, NULL},
+#endif
+ };
+
+static istepMap_t g_istepStopClockPtrTbl[ISTEP_STOPCLOCK_MAX_SUBSTEPS] =
+ {
+#ifdef SEEPROM_IMAGE
+ // Stop Clock Mpipl
+ { &istepStopClockMpipl, NULL},
+#endif
+ };
+
+// File static data
+static istepMap_t g_istep2PtrTbl[ ISTEP2_MAX_SUBSTEPS ] =
+ {
+#ifdef SEEPROM_IMAGE
+ { NULL, NULL },
+ { &istepAttrSetup, { .procHwp = &p9_sbe_attr_setup }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_init1 }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_gptr_time_initf }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_npll_initf }},
+ { &istepNestFreq, { .procHwp = &p9_sbe_npll_setup }},
+ { &istepHwpTpSwitchGears, { .procHwp = &p9_sbe_tp_switch_gears }},
+ { &istepWithProc, { .procHwp = &p9_sbe_clock_test2 }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_reset }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_repr_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_init2 }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_arrayinit }},
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_initf }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_chiplet_init3 }},
+#endif
+ };
+
+static istepMap_t g_istep3PtrTbl[ ISTEP3_MAX_SUBSTEPS ] =
+ {
+#ifdef SEEPROM_IMAGE
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_reset }},
+ { &istepWithProc, { .procHwp = &p9_sbe_gptr_time_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_pll_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_pll_setup }},
+ { &istepWithProc, { .procHwp = &p9_sbe_repr_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_chiplet_init }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_arrayinit }},
+ { &istepNoOp, NULL }, // DFT only
+ { &istepWithProc, { .procHwp = &p9_sbe_tp_enable_ridi }},
+ { &istepWithProc, { .procHwp = &p9_sbe_setup_boot_freq }},
+ { &istepWithProc, { .procHwp = &p9_sbe_nest_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_nest_startclocks }},
+ { &istepWithProc, { .procHwp = &p9_sbe_nest_enable_ridi }},
+ { &istepWithProc, { .procHwp = &p9_sbe_io_initf }},
+ { &istepWithProc, { .procHwp = &p9_sbe_startclock_chiplets }},
+ { &istepWithProc, { .procHwp = &p9_sbe_scominit }},
+ { &istepLpcInit, { .procHwp = &p9_sbe_lpc_init }},
+ { &istepWithProc, { .procHwp = &p9_sbe_fabricinit }},
+ { &istepCheckSbeMaster, NULL },
+ { &istepWithProc, { .procHwp = &p9_sbe_mcs_setup }},
+ { &istepSelectEx, NULL },
+#endif
+ };
+static istepMap_t g_istep4PtrTbl[ ISTEP4_MAX_SUBSTEPS ] =
+ {
+#ifdef SEEPROM_IMAGE
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_poweron} },
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_chiplet_reset } },
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_chiplet_l3_dcc_setup }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_gptr_time_initf }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_dpll_initf }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_dpll_setup }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_dcc_skewadjust_setup }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_chiplet_init }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_repair_initf }},
+ { &istepWithEq, { .eqHwp = &p9_hcd_cache_arrayinit }},
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepCacheInitf, { .cacheInitfHwp = &p9_hcd_cache_initf }},
+ { &istepWithEqConditional, { .eqHwp = &p9_hcd_cache_startclocks }},
+ { &istepWithEqConditional, { .eqHwp = &p9_hcd_cache_scominit }},
+ { &istepWithEqConditional, { .eqHwp = &p9_hcd_cache_scomcust }},
+ { &istepNoOp, NULL }, // Runtime only
+ { &istepNoOp, NULL }, // Runtime only
+ { &istepNoOp, NULL }, // stub for SBE
+ { &istepNoOp, NULL }, // stub for SBE
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_poweron }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_chiplet_reset }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_gptr_time_initf }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_chiplet_init }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_repair_initf }},
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_arrayinit }},
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepNoOp, NULL }, // DFT Only
+ { &istepWithCore, { .coreHwp = &p9_hcd_core_initf }},
+ { &istepWithCoreConditional,
+ { .coreHwp = &p9_hcd_core_startclocks }},
+ { &istepWithCoreConditional, { .coreHwp = &p9_hcd_core_scominit }},
+ { &istepWithCoreConditional, { .coreHwp = &p9_hcd_core_scomcust }},
+ { &istepNoOp, NULL },
+ { &istepNoOp, NULL },
+#endif
+ };
+
+// TODO via RTC 135345
+// Add the support for istep 5 HWP
+static istepMap_t g_istep5PtrTbl[ ISTEP5_MAX_SUBSTEPS ]
+ {
+#ifdef SEEPROM_IMAGE
+ { &istepLoadBootLoader, NULL },
+ { &istepStartInstruction, { .coreHwp = &p9_sbe_instruct_start }},
+#endif
+ };
+#endif //#ifndef __SBEFW_SEEPROM__
+
+
+// Functions
+#ifndef __SBEFW_SEEPROM__
+//----------------------------------------------------------------------------
+uint32_t sbeHandleIstep (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeHandleIstep "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ ReturnCode fapiRc = FAPI2_RC_SUCCESS;
+ uint32_t len = 0;
+ sbeIstepReqMsg_t req;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t ffdc;
+
+ // NOTE: In this function we will have two loops
+ // First loop will deque data and prepare the response
+ // Second response will enque the data on DS FIFO
+ //loop 1
+ do
+ {
+ len = sizeof( req )/sizeof(uint32_t);
+ rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&req);
+ if (rc != SBE_SEC_OPERATION_SUCCESSFUL) //FIFO access issue
+ {
+ SBE_ERROR(SBE_FUNC"FIFO dequeue failed, rc[0x%X]", rc);
+ break;
+ }
+
+ if( false == validateIstep( req.major, req.minor ) )
+ {
+ SBE_ERROR(SBE_FUNC" Invalid Istep. major:0x%08x"
+ " minor:0x%08x",
+ (uint32_t)req.major, (uint32_t)req.minor);
+ // @TODO via RTC 132295.
+ // Need to change code asper better error handling.
+ respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ break;
+ }
+
+ fapiRc = sbeExecuteIstep( req.major, req.minor );
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" sbeExecuteIstep() Failed. major:0x%08x"
+ " minor:0x%08x",
+ (uint32_t)req.major,
+ (uint32_t)req.minor);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+
+ }while(0);
+
+ //loop 2
+ do
+ {
+ // FIFO error
+ if ( rc )
+ {
+ break;
+ }
+
+ rc = sbeDsSendRespHdr(respHdr, &ffdc);
+ }while(0);
+
+ if( rc )
+ {
+ SBE_ERROR( SBE_FUNC"Failed. rc[0x%X]", rc);
+ }
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+// @note This is the responsibilty of caller to verify major/minor
+// number before calling this function
+
+// @TODO via RTC 129077.
+// This function should check for system checkstop as well.
+ReturnCode sbeExecuteIstep (const uint8_t i_major, const uint8_t i_minor)
+{
+ #define SBE_FUNC "sbeExecuteIstep "
+ SBE_INFO(SBE_FUNC"Major number:0x%x minor number:0x%x",
+ i_major, i_minor );
+
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ switch( i_major )
+ {
+ case SBE_ISTEP2:
+ rc = (g_istep2PtrTbl[i_minor-1].istepWrapper)(
+ g_istep2PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP3:
+ rc = (g_istep3PtrTbl[i_minor-1].istepWrapper)(
+ g_istep3PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP4:
+ rc = (g_istep4PtrTbl[i_minor-1].istepWrapper)(
+ g_istep4PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP5:
+ rc = (g_istep5PtrTbl[i_minor-1].istepWrapper)(
+ g_istep5PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP_MPIPL_START:
+ rc = (g_istepMpiplStartPtrTbl[i_minor-1].istepWrapper)(
+ g_istepMpiplStartPtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP_MPIPL_CONTINUE:
+ rc = (g_istepMpiplContinuePtrTbl[i_minor-1].istepWrapper)(
+ g_istepMpiplContinuePtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP_STOPCLOCK:
+ rc = (g_istepStopClockPtrTbl[i_minor-1].istepWrapper)(
+ g_istepStopClockPtrTbl[i_minor-1].istepHwp);
+ break;
+
+ // We should never reach here as before calling this validation has
+ // been done.
+ default:
+ assert(0);
+ break;
+ }
+
+ (void)SbeRegAccess::theSbeRegAccess().updateSbeStep(i_major, i_minor);
+
+ if(rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR( SBE_FUNC" FAPI RC:0x%08X", rc);
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_DUMP_FAILURE_EVENT);
+ }
+
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+bool validateIstep (const uint8_t i_major, const uint8_t i_minor)
+{
+ bool valid = true;
+ do
+ {
+ if( 0 == i_minor )
+ {
+ valid = false;
+ break;
+ }
+
+ switch( i_major )
+ {
+ case SBE_ISTEP2:
+ // istep 2.1 loads image to PIBMEM
+ // So SBE control loop can not execute istep 2.1.
+ if(( i_minor > ISTEP2_MAX_SUBSTEPS ) || ( i_minor == 1) )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP3:
+ if( (i_minor > ISTEP3_MAX_SUBSTEPS ) ||
+ ((SBE_ROLE_SLAVE == g_sbeRole) &&
+ (i_minor > SLAVE_LAST_MINOR_ISTEP)) )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP4:
+ if( (i_minor > ISTEP4_MAX_SUBSTEPS ) ||
+ (SBE_ROLE_SLAVE == g_sbeRole) )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP5:
+ if( (i_minor > ISTEP5_MAX_SUBSTEPS ) ||
+ (SBE_ROLE_SLAVE == g_sbeRole) )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP_MPIPL_START:
+ if( i_minor > MPIPL_START_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP_MPIPL_CONTINUE:
+ if( i_minor > MPIPL_CONTINUE_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP_STOPCLOCK:
+ if( i_minor > ISTEP_STOPCLOCK_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ default:
+ valid = false;
+ break;
+ }
+ } while(0);
+
+ return valid;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode performAttrSetup( )
+{
+ #define SBE_FUNC "performAttrSetup "
+ SBE_ENTER("performAttrSetup ");
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ SBE_EXEC_HWP(rc, p9_sbe_attr_setup, proc)
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ break;
+ }
+ // Apply the gard records
+ rc = plat_ApplyGards();
+
+ //Getting CBS_CS register value
+ fapi2::buffer<uint64_t> tempReg = 0;
+ plat_target_handle_t hndl;
+ rc = getscom_abs_wrap(&hndl,
+ PERV_CBS_CS_SCOM, tempReg.pointer());
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ break;
+ }
+ SBE_GLOBAL->sbeFWSecurityEnabled =
+ tempReg.getBit<PERV_CBS_CS_SECURE_ACCESS_BIT>();
+ }while(0);
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepAttrSetup( sbeIstepHwp_t i_hwp)
+{
+ return performAttrSetup();
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithProc( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ assert( NULL != i_hwp.procHwp );
+ SBE_EXEC_HWP(rc, i_hwp.procHwp,proc)
+ return rc;
+}
+//----------------------------------------------------------------------------
+
+ReturnCode istepHwpTpSwitchGears( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ assert( NULL != i_hwp.procHwp );
+ SBE_EXEC_HWP(rc, i_hwp.procHwp,proc)
+
+ // backup i2c mode register
+ uint32_t reg_address = PU_MODE_REGISTER_B;
+ PPE_LVD( reg_address, SBE_GLOBAL->i2cModeRegister);
+
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepNestFreq( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepNestFreq "
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ assert( NULL != i_hwp.procHwp );
+ do
+ {
+ SBE_EXEC_HWP(rc, i_hwp.procHwp,proc)
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ break;
+ }
+ // Update PK frequency
+ SBE::updatePkFreq();
+ }while(0);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+
+ReturnCode istepSelectEx( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ // TODO via RTC 135345
+ // Once multicast targets are supported, we may need to pass
+ // p9selectex::ALL as input.
+ SBE_EXEC_HWP(rc, p9_sbe_select_ex_hwp, proc, p9selectex::SINGLE)
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepWithEq( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ // TODO via RTC 135345
+ // Curently we are passing Hard code eq target. Finally it is
+ // going to be a multicast target. Once multicast support is
+ // present, use the right target.
+ fapi2::Target<fapi2::TARGET_TYPE_EQ > eqTgt;
+ // Put this in scope so that vector can be freed up before calling hwp.
+ {
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ auto eqList = proc.getChildren<fapi2::TARGET_TYPE_EQ>();
+ // As it is workaround lets assume there will always be atleast one
+ // functional eq. No need to validate.
+ eqTgt = eqList[0];
+ }
+
+ assert( NULL != i_hwp.eqHwp );
+ SBE_EXEC_HWP(rc, i_hwp.eqHwp, eqTgt )
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepCacheInitf (sbeIstepHwp_t i_hwp )
+{
+ #define SBE_FUNC "istepCacheInitf"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+
+ // TODO via RTC 135345
+ fapi2::Target<fapi2::TARGET_TYPE_EQ > eqTgt;
+ // Put this in scope so that vector can be freed up before calling hwp.
+ {
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ auto eqList = proc.getChildren<fapi2::TARGET_TYPE_EQ>();
+ // As it is workaround lets assume there will always be atleast one
+ // functional eq. No need to validate.
+ eqTgt = eqList[0];
+ }
+
+ SBE_EXEC_HWP(l_rc, i_hwp.cacheInitfHwp, eqTgt, G_ring_save)
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepWithCore( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepWithCore"
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+
+ // Get master Ex
+ uint8_t exId = 0;
+ uint8_t fuseMode = 0;
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ FAPI_ATTR_GET(fapi2::ATTR_MASTER_EX,proc,exId);
+ FAPI_ATTR_GET(ATTR_FUSED_CORE_MODE, Target<TARGET_TYPE_SYSTEM>(), fuseMode);
+ fapi2::Target<fapi2::TARGET_TYPE_EX >
+ exTgt(plat_getTargetHandleByInstance<fapi2::TARGET_TYPE_EX>(exId));
+ assert( NULL != i_hwp.coreHwp );
+
+ for (auto &coreTgt : exTgt.getChildren<fapi2::TARGET_TYPE_CORE>())
+ {
+ // Core0 is assumed to be the master core
+ SBE_EXEC_HWP(rc, i_hwp.coreHwp, coreTgt)
+ if(rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC " istepWithCore failed, RC=[0x%08X]", rc);
+ break;
+ }
+ // Only continue in case of istep4 && fuse core mode
+ if(!( (fuseMode) &&
+ (SbeRegAccess::theSbeRegAccess().getSbeMajorIstepNumber() ==
+ SBE_ISTEP4) ) )
+ {
+ break;
+ }
+ }
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithEqConditional( sbeIstepHwp_t i_hwp)
+{
+ SBE_ENTER("istepWithEqCondtional");
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM > sysTgt;
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ uint8_t iplPhase = ENUM_ATTR_SYSTEM_IPL_PHASE_HB_IPL;
+ FAPI_ATTR_GET(ATTR_SYSTEM_IPL_PHASE, sysTgt, iplPhase);
+ if( ENUM_ATTR_SYSTEM_IPL_PHASE_CACHE_CONTAINED == iplPhase )
+ {
+ break;
+ }
+ rc = istepWithEq(i_hwp);
+ }while(0);
+ SBE_EXIT("istepWithEqCondtional");
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithCoreConditional( sbeIstepHwp_t i_hwp)
+{
+ SBE_ENTER("istepWithCoreCondtional");
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM > sysTgt;
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ uint8_t iplPhase = ENUM_ATTR_SYSTEM_IPL_PHASE_HB_IPL;
+ FAPI_ATTR_GET(ATTR_SYSTEM_IPL_PHASE, sysTgt, iplPhase);
+ if( ENUM_ATTR_SYSTEM_IPL_PHASE_CACHE_CONTAINED == iplPhase )
+ {
+ break;
+ }
+ rc = istepWithCore(i_hwp);
+ }while(0);
+ SBE_EXIT("istepWithCoreCondtional");
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+constexpr uint32_t HB_MEM_WINDOW_SIZE = 32*1024*1024; //32 MB
+ReturnCode istepLoadBootLoader( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ // Get master Ex
+ uint8_t exId = 0;
+ Target< TARGET_TYPE_SYSTEM > sysTgt;
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ FAPI_ATTR_GET(fapi2::ATTR_MASTER_EX,proc,exId);
+ fapi2::Target<fapi2::TARGET_TYPE_EX >
+ exTgt(plat_getTargetHandleByInstance<fapi2::TARGET_TYPE_EX>(exId));
+ // Get hbbl section
+ P9XipHeader *hdr = getXipHdr();
+ P9XipSection *hbblSection = &(hdr->iv_section[P9_XIP_SECTION_SBE_HBBL]);
+
+ uint64_t drawer_base_address_nm0, drawer_base_address_nm1;
+ uint64_t drawer_base_address_m;
+ uint64_t drawer_base_address_mmio;
+ uint64_t l_hostboot_hrmor_offset;
+ do
+ {
+ // Update the ATTR_SBE_ADDR_KEY_STASH_ADDR before calling the bootloader,
+ // since it is going to access these data from inside.
+ uint64_t addr = SBE_GLOBAL->sbeKeyAddrPair.fetchStashAddrAttribute();
+ PLAT_ATTR_INIT(fapi2::ATTR_SBE_ADDR_KEY_STASH_ADDR, sysTgt, addr);
+ SBE_EXEC_HWP(rc, p9_sbe_load_bootloader, proc, exTgt, hbblSection->iv_size,
+ getSectionAddr(hbblSection))
+ if(rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(" p9_sbe_load_bootloader failed");
+ break;
+ }
+
+ // Open HB Dump memory Region
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
+ FAPI_ATTR_GET(fapi2::ATTR_HOSTBOOT_HRMOR_OFFSET,
+ FAPI_SYSTEM,
+ l_hostboot_hrmor_offset);
+ rc = p9_fbc_utils_get_chip_base_address_no_aliases(
+ proc,
+ ABS_FBC_GRP_ID_ONLY,
+ drawer_base_address_nm0,
+ drawer_base_address_nm1,
+ drawer_base_address_m,
+ drawer_base_address_mmio);
+ if(rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(" p9_fbc_utils_get_chip_base_address failed");
+ break;
+ }
+ drawer_base_address_nm0 += l_hostboot_hrmor_offset;
+ SBE_INFO("istep 5.1 HB Dump mem Region [0x%08X%08X]",
+ SBE::higher32BWord(drawer_base_address_nm0),
+ SBE::lower32BWord(drawer_base_address_nm0));
+ mainStoreSecMemRegionManager.add(drawer_base_address_nm0,
+ HB_MEM_WINDOW_SIZE,
+ static_cast<uint8_t>(memRegionMode::READ));
+
+ } while(0);
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepStartInstruction( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ rc = istepWithCore(i_hwp);
+ if(rc == FAPI2_RC_SUCCESS)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_RUNTIME_EVENT);
+ }
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepCheckSbeMaster( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepCheckSbeMaster "
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ rc = performTpmReset();
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" performTpmReset failed");
+ break;
+ }
+ g_sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ?
+ SBE_ROLE_SLAVE : SBE_ROLE_MASTER;
+ SBE_INFO(SBE_FUNC"g_sbeRole [%x]", g_sbeRole);
+ if(SBE_ROLE_SLAVE == g_sbeRole)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_RUNTIME_EVENT);
+ }
+ }while(0);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepNoOp( sbeIstepHwp_t i_hwp)
+{
+ SBE_INFO("istepNoOp");
+ return FAPI2_RC_SUCCESS ;
+}
+
+//----------------------------------------------------------------------------
+void sbeDoContinuousIpl()
+{
+ #define SBE_FUNC "sbeDoContinuousIpl "
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ // An array that holds the max number of minor steps per major step
+ const uint8_t l_minorSteps[] =
+ {
+ ISTEP2_MAX_SUBSTEPS,
+ ISTEP3_MAX_SUBSTEPS,
+ ISTEP4_MAX_SUBSTEPS,
+ ISTEP5_MAX_SUBSTEPS
+ };
+
+ // Where does each minor istep start from?
+ const uint8_t l_minorStartStep[] =
+ {
+ ISTEP2_MINOR_START,
+ ISTEP_MINOR_START,
+ ISTEP_MINOR_START,
+ ISTEP_MINOR_START
+ };
+
+ // Set SBE state as IPLing
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_PLCK_EVENT);
+ bool l_done = false;
+ // Run isteps
+ for(uint8_t l_major = SBE_ISTEP_FIRST;
+ (l_major <= SBE_ISTEP_LAST_MASTER) &&
+ (false == l_done);
+ ++l_major)
+ {
+ for(uint8_t l_minor = l_minorStartStep[l_major - SBE_ISTEP_FIRST];
+ l_minor <= l_minorSteps[l_major - SBE_ISTEP_FIRST];
+ ++l_minor)
+ {
+ l_rc = sbeExecuteIstep(l_major, l_minor);
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC"Failed istep execution in plck mode: "
+ "Major: %d, Minor: %d", l_major, l_minor);
+ l_done = true;
+ (void)SbeRegAccess::theSbeRegAccess().updateAsyncFFDCBit(
+ true);
+ break;
+ }
+ // Check if we are at step 3.20 on the slave SBE
+ if(((SBE_ISTEP_LAST_SLAVE == l_major) &&
+ (SLAVE_LAST_MINOR_ISTEP == l_minor)) &&
+ (SBE_ROLE_SLAVE == g_sbeRole))
+ {
+ l_done = true;
+ break;
+ }
+ }
+ }
+ } while(false);
+ // Store l_rc in a global variable that will be a part of the SBE FFDC
+ g_iplFailRc = l_rc;
+ SBE_EXIT(SBE_FUNC);
+ #undef SBE_FUNC
+}
+#endif // #ifndef __SBEFW_SEEPROM__
+
+// MPIPL Specific
+#ifdef __SBEFW_SEEPROM__
+//----------------------------------------------------------------------------
+ReturnCode istepWithCoreSetBlock( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepWithCoreSetBlock"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+ Target<TARGET_TYPE_PROC_CHIP > l_procTgt = plat_getChipTarget();
+ for (auto l_coreTgt : l_procTgt.getChildren<fapi2::TARGET_TYPE_CORE>())
+ {
+ SBE_EXEC_HWP(l_rc, i_hwp.coreBlockIntrHwp, l_coreTgt, p9pmblockwkup::SET)
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC " p9_block_wakeup_intr failed, RC=[0x%08X]",
+ l_rc);
+ break;
+ }
+ }
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepWithCoreState( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepWithCoreState"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+ Target<TARGET_TYPE_PROC_CHIP > l_procTgt = plat_getChipTarget();
+ for (auto l_coreTgt : l_procTgt.getChildren<fapi2::TARGET_TYPE_CORE>())
+ {
+ bool l_isScanEnable = false;
+ bool l_isCoreScomEnabled = false;
+ SBE_EXEC_HWP(l_rc, i_hwp.coreScomStateHwp, l_coreTgt,
+ l_isCoreScomEnabled, l_isScanEnable)
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC " p9_query_core_access_state failed, "
+ "RC=[0x%08X]", l_rc);
+ break;
+ }
+ if(l_isCoreScomEnabled) //true
+ {
+ uint8_t l_thread = SMT4_THREAD0;
+ fapi2::buffer<uint64_t> l_data64;
+ uint64_t l_state;
+ bool l_warnCheck = true;
+ do
+ {
+ // Call instruction control stop
+ // TODO RTC 164425 - Can we pass in 1111 i.e. all threads at the
+ // same time instead of individual threads
+ SBE_EXEC_HWP(l_rc, threadCntlhwp, l_coreTgt,
+ (SINGLE_THREAD_BIT_MASK >> l_thread),
+ PTC_CMD_STOP, l_warnCheck,l_data64, l_state)
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "p9_thread_control stop Failed for "
+ "Core Thread RC[0x%08X]", l_rc);
+ break;
+ }
+ }while(++l_thread < SMT4_THREAD_MAX);
+
+ l_rc = maskSpecialAttn(l_coreTgt);
+ if( l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "maskSpecialAttn failed");
+ break;
+ }
+ }
+ }
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepMpiplRstClrTpmBits( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepMpiplRstClrTpmBits"
+ SBE_ENTER(SBE_FUNC);
+
+ ReturnCode l_rc = performTpmReset();
+ if( l_rc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" performTpmReset failed");
+ }
+
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepWithExL2Flush( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepWithExL2Flush"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+
+ Target<TARGET_TYPE_PROC_CHIP > l_procTgt = plat_getChipTarget();
+ for (auto l_exTgt : l_procTgt.getChildren<fapi2::TARGET_TYPE_EX>())
+ {
+ p9core::purgeData_t l_purgeData;
+ // TODO RTC 164425 need to check if L2 is Scomable
+ // This will come from the HWP team.
+ SBE_EXEC_HWP(l_rc, i_hwp.exL2Hwp, l_exTgt, l_purgeData)
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC " p9_l2_flush failed, RC=[0x%08X]", l_rc);
+ break;
+ }
+ }
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepWithExL3Flush( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepWithExL3Flush"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+
+ Target<TARGET_TYPE_PROC_CHIP > l_procTgt = plat_getChipTarget();
+ for (auto l_exTgt : l_procTgt.getChildren<fapi2::TARGET_TYPE_EX>())
+ {
+ // TODO RTC 164425 need to check if L3 is Scomable
+ // This will come from the HWP team.
+ SBE_EXEC_HWP(l_rc, i_hwp.exL3Hwp, l_exTgt, L3_FULL_PURGE, 0x0)
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC " p9_l3_flush failed, RC=[0x%08X]", l_rc);
+ break;
+ }
+ }
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepWithProcSequenceDrtm( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepWithProcSequenceDrtm"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+ Target<TARGET_TYPE_PROC_CHIP > l_procTgt = plat_getChipTarget();
+
+ uint8_t l_status = 0;
+ size_t l_timeOut = SBE_SYSTEM_QUIESCE_TIMEOUT_LOOP;
+ while(l_timeOut)
+ {
+ SBE_EXEC_HWP(l_rc, i_hwp.procSequenceDrtm, l_procTgt, l_status)
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "p9_sbe_sequence_drtm failed, RC=[0x%08X]",l_rc);
+ break;
+ }
+ if(l_status)
+ {
+ SBE_INFO(SBE_FUNC "p9_sbe_sequence_drtm LQA SBE System Quiesce done");
+ break;
+ }
+ else
+ {
+ l_timeOut--;
+ // delay prior to repeating the above
+ FAPI_TRY(fapi2::delay(SBE_LQA_DELAY_HW_US, SBE_LQA_DELAY_SIM_CYCLES),
+ "Error from delay");
+ }
+ }
+ // Checkstop system if SBE system quiesce not set after the loop
+ if(!l_status || l_rc)
+ {
+ SBE_ERROR(SBE_FUNC "p9_sbe_sequence_drtm LQA SBE System Quiesce failed,"
+ "Either System Quiesce Achieved not true or procedure "
+ "failed RC=[0x%08X]",l_rc);
+ // check stop the system
+ // TODO RTC 164425 this needs to be replicated on any MPIPL Hwp failure
+ Target<TARGET_TYPE_PROC_CHIP > l_proc = plat_getChipTarget();
+ l_rc = putscom_abs_wrap(&l_proc, PERV_N3_LOCAL_FIR_OR,
+ ((uint64_t)1 << N3_FIR_SYSTEM_CHECKSTOP_BIT));
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ // Scom failed
+ SBE_ERROR(SBE_FUNC "PutScom failed for REG PERV_N3_LOCAL_FIR");
+ // TODO - Store the response in Async Response
+ // RTC:149074
+ }
+ }
+fapi_try_exit:
+ if(fapi2::current_err)
+ {
+ l_rc = fapi2::current_err;
+ }
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepStartMpipl( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepStartMpipl"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_ENTER_MPIPL_EVENT);
+ // Set MPIPL mode bit in Scratch Reg 3
+ (void)SbeRegAccess::theSbeRegAccess().setMpIplMode(true);
+ // Close all non-secure memory regions
+ mainStoreSecMemRegionManager.closeAllRegions();
+
+ do
+ {
+ rc = updatePhbFunctionalState();
+ if(rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "updatePhbFunctionalState failed");
+ break;
+ }
+ rc = resetCrespErrLatch();
+ if(rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "resetCrespErrLatch failed");
+ break;
+ }
+
+ }while(0);
+
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepMpiplQuadPoweroff( sbeIstepHwp_t i_hwp)
+{
+ #define SBE_FUNC "istepMpiplQuadPoweroff"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+ if(g_sbeRole == SBE_ROLE_MASTER)
+ {
+ Target<TARGET_TYPE_PROC_CHIP > l_proc = plat_getChipTarget();
+ // Fetch the MASTER_CORE attribute
+ uint8_t l_coreId = 0;
+ FAPI_ATTR_GET(fapi2::ATTR_MASTER_CORE, l_proc, l_coreId);
+ // Construct the Master Core Target
+ fapi2::Target<fapi2::TARGET_TYPE_CORE > l_core(
+ plat_getTargetHandleByChipletNumber<fapi2::TARGET_TYPE_CORE>(
+ l_coreId + CORE_CHIPLET_OFFSET));
+ fapi2::Target<fapi2::TARGET_TYPE_EQ> l_quad =
+ l_core.getParent<fapi2::TARGET_TYPE_EQ>();
+ SBE_EXEC_HWP(l_rc, i_hwp.quadPoweroffHwp, l_quad, G_ring_save)
+ }
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepWithProcQuiesceLQASet( sbeIstepHwp_t i_hwp )
+{
+ #define SBE_FUNC "istepWithProcQuiesceLQASet"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ l_rc = istepWithProc(i_hwp);
+ if(l_rc == FAPI2_RC_SUCCESS)
+ {
+ //set the LQA Bit
+ // TODO RTC 164425 - Create another istep for Setting LQA bit after
+ // L2/L3 flush istep
+ Target<TARGET_TYPE_PROC_CHIP > l_proc = plat_getChipTarget();
+ uint64_t l_data = 0x1000000000000000ULL; //Set bit3
+ l_rc = putscom_abs_wrap(&l_proc, PU_SECURITY_SWITCH_REGISTER_SCOM, l_data);
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "PutScom failed for PU_SECURITY_SWITCH_REGISTER_SCOM");
+ break;
+ }
+ l_data = 0;
+ l_rc = getscom_abs_wrap (&l_proc, PU_SECURITY_SWITCH_REGISTER_SCOM, &l_data);
+ if(l_rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "GetScom failed for PU_SECURITY_SWITCH_REGISTER_SCOM");
+ break;
+ }
+ SBE_INFO(SBE_FUNC "PU_SECURITY_SWITCH_REGISTER_SCOM Data [0x%08X][%08X]",
+ (uint32_t)((l_data >> 32) & 0xFFFFFFFF), (uint32_t)(l_data & 0xFFFFFFFF));
+ }
+ }while(0);
+ SBE_EXIT(SBE_FUNC);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepMpiplSetFunctionalState( sbeIstepHwp_t i_hwp )
+{
+ #define SBE_FUNC "istepMpiplSetFunctionalState"
+ SBE_ENTER(SBE_FUNC);
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ // Read the EQ and EC gard attributes from the chip target
+ fapi2::buffer<uint64_t> l_scratchReg1 = 0;
+ uint64_t l_scratchReg8 = 0;
+ static const uint64_t SCRATCH8_SCRATCH1REG_VALID_BIT =
+ 0x8000000000000000ULL;
+ fapi2::buffer<uint8_t> l_eqMask = 0;
+ fapi2::buffer<uint32_t> l_ecMask = 0;
+ plat_target_handle_t l_hndl;
+
+ // Set MPIPL mode bit in Scratch Reg 3
+ (void)SbeRegAccess::theSbeRegAccess().setMpIplMode(true);
+
+ rc = getscom_abs_wrap (&l_hndl,
+ PERV_SCRATCH_REGISTER_8_SCOM,
+ &l_scratchReg8);
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" Failed to read Scratch RegR8");
+ break;
+ }
+ if(l_scratchReg8 & SCRATCH8_SCRATCH1REG_VALID_BIT)
+ {
+ rc = getscom_abs_wrap (&l_hndl,
+ PERV_SCRATCH_REGISTER_1_SCOM,
+ &l_scratchReg1());
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" Failed to read Scratch Reg1");
+ break;
+ }
+
+ l_scratchReg1.extract<0, 6>(l_eqMask);
+ l_scratchReg1.extract<8, 24>(l_ecMask);
+ SBE_INFO(SBE_FUNC" Setting ATTR_EQ_GARD [0x%08X] "
+ "ATTR_EC_GARD [0x%08X]",
+ l_eqMask, l_ecMask);
+
+ PLAT_ATTR_INIT(fapi2::ATTR_EQ_GARD, proc, l_eqMask);
+ PLAT_ATTR_INIT(fapi2::ATTR_EC_GARD, proc, l_ecMask);
+
+ // Apply the gard records
+ rc = plat_ApplyGards();
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" Failed to to apply gard records");
+ break;
+ }
+
+ // TODO via RTC 135345
+ // Once multicast targets are supported, we may need to pass
+ // p9selectex::ALL as input.
+ SBE_EXEC_HWP(rc, p9_sbe_select_ex_hwp, proc, p9selectex::SINGLE)
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" Failed hwp p9_sbe_select_ex_hwp");
+ break;
+ }
+ }
+ else
+ {
+ SBE_ERROR(SBE_FUNC " Scratch Reg 1 is invalid,"
+ "not applying gard records");
+ }
+ }while(0);
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepStopClockMpipl( sbeIstepHwp_t i_hwp )
+{
+ #define SBE_FUNC "istepStopClockMpipl"
+ SBE_ENTER(SBE_FUNC);
+ uint32_t l_fapiRc = FAPI2_RC_SUCCESS;
+ p9_stopclocks_flags l_flags; // Default Flag Values
+ Target<TARGET_TYPE_PROC_CHIP > l_procTgt = plat_getChipTarget();
+ 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;
+
+ l_flags.clearAll();
+ l_flags.stop_core_clks = true;
+ l_flags.stop_cache_clks = true;
+
+ SBE_EXEC_HWP(l_fapiRc,
+ p9_stopclocks_hwp,
+ l_procTgt,
+ l_flags,
+ l_clk_regions,
+ l_ex_select);
+
+ SBE_EXIT(SBE_FUNC);
+ return l_fapiRc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+inline ReturnCode maskSpecialAttn( const Target<TARGET_TYPE_CORE>& i_target )
+{
+#define SBE_FUNC "maskSpecialAttn "
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ uint64_t maskData = 0;
+ const uint64_t ecMask = 0xffc0000000000000;
+ rc = getscom_abs_wrap (&i_target, P9N2_EX_SPA_MASK, &maskData );
+ if( rc )
+ {
+ SBE_ERROR(SBE_FUNC" Failed to read P9N2_EX_SPA_MASK");
+ break;
+ }
+ maskData = maskData | ecMask;
+ rc = putscom_abs_wrap (&i_target, P9N2_EX_SPA_MASK, maskData );
+ if( rc )
+ {
+ SBE_ERROR(SBE_FUNC" Failed to write P9N2_EX_SPA_MASK");
+ break;
+ }
+ }while(0);
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+#undef SBE_FUNC
+}
+#endif //#ifdef __SBEFW_SEEPROM__
+
+#ifndef __SBEFW_SEEPROM__
+//----------------------------------------------------------------------------
+ReturnCode performTpmReset()
+{
+ #define SBE_FUNC "performTpmReset "
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ constexpr uint64_t tpmBitMask = 0x0008000000000000ULL;
+ plat_target_handle_t tgtHndl;
+ uint64_t regData = 0;
+ rc = getscom_abs_wrap (&tgtHndl,
+ PU_PRV_MISC_PPE,
+ &regData);
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" Failed to read SBE internal reg for TPM reset");
+ break;
+ }
+
+ // To do TPM reset, first we should set bit 12 of PU_PRV_MISC_PPE
+ // and then clear it up.
+ regData = regData | tpmBitMask;
+ rc = putscom_abs_wrap(&tgtHndl, PU_PRV_MISC_PPE, regData);
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" Failed to set TPM mask");
+ break;
+ }
+
+ regData = regData & ( ~tpmBitMask);
+ rc = putscom_abs_wrap(&tgtHndl, PU_PRV_MISC_PPE, regData);
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" Failed to clear TPM mask");
+ break;
+ }
+
+ }while(0);
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepLpcInit( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ assert( NULL != i_hwp.procHwp );
+ if( !(SbeRegAccess::theSbeRegAccess().isSbeSlave()) )
+ {
+ SBE_EXEC_HWP(rc, i_hwp.procHwp,proc);
+ }
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+ReturnCode updatePhbFunctionalState( void )
+{
+ #define SBE_FUNC "updatePhbFunctionalState"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ const uint64_t pci_cplt_conf1[3] = {PEC_0_CPLT_CONF1, PEC_1_CPLT_CONF1, PEC_2_CPLT_CONF1};
+ // TODO workaround
+ extern std::vector<fapi2::plat_target_handle_t> G_vec_targets;
+ Target<TARGET_TYPE_PROC_CHIP > procTgt = plat_getChipTarget();
+ auto phbTgt_vec = procTgt.getChildren<fapi2::TARGET_TYPE_PHB>();
+
+ for (auto &phbTgt : phbTgt_vec)
+ {
+ //Get the PHB id
+ uint8_t phb_id = 0;
+ uint8_t pci_id = 0;
+ uint8_t phbPerPciCnt = 0;
+ uint64_t data = 0;
+
+ FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, phbTgt, phb_id);
+ if(phb_id == 1 || phb_id == 2)
+ {
+ pci_id = 1;
+ phbPerPciCnt = phb_id - 1; // To rotate per phb cnt within PCI from 0 to 1
+ }
+ else if(phb_id > 2)
+ {
+ pci_id = 2;
+ phbPerPciCnt = phb_id - 3; // To rotate per phb cnt within PCI from 0 to 1
+ }
+ rc = getscom_abs_wrap (&procTgt, pci_cplt_conf1[pci_id], &data);
+ if(rc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC" Failed to read Pec[%d] Chiplet Config1 register",pci_id);
+ break;
+ }
+ // Fetch bit4 from D000009 for PHB0
+ // Fetch bit4/5 from E000009 for PHB1/2
+ // Fetch bit4/5/6 from F000009 for PHB3/4/5
+ if( !((data >> (PEC_PHB_IOVALID_BIT_SHIFT - phbPerPciCnt)) & PEC_PHB_IOVALID_BIT_MASK) )
+ {
+ SBE_INFO(SBE_FUNC "PHB[%d] setting up as Non-Functional", phb_id);
+ static_cast<plat_target_handle_t&>(phbTgt.operator ()()).setFunctional(false);
+ G_vec_targets.at(PHB_TARGET_OFFSET+ phb_id) = (fapi2::plat_target_handle_t)(phbTgt.get());
+ }
+ }
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+#undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+ReturnCode resetCrespErrLatch( void )
+{
+ #define SBE_FUNC "resetCrespErrLatch"
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ static const uint64_t BIT_63_MASK = 0x01;
+ do
+ {
+ Target<TARGET_TYPE_PROC_CHIP > procTgt = plat_getChipTarget();
+ uint64_t data;
+ rc = getscom_abs_wrap (&procTgt, PU_PB_CENT_SM0_PB_CENT_MODE,
+ &data);
+ if( rc )
+ {
+ break;
+ }
+ data = data | BIT_63_MASK;
+ rc = putscom_abs_wrap (&procTgt, PU_PB_CENT_SM0_PB_CENT_MODE,
+ data);
+ if( rc )
+ {
+ break;
+ }
+ data = data &(~BIT_63_MASK);
+ rc = putscom_abs_wrap (&procTgt, PU_PB_CENT_SM0_PB_CENT_MODE,
+ data);
+ if( rc )
+ {
+ break;
+ }
+ }while(0);
+ if( rc )
+ {
+ SBE_ERROR(SBE_FUNC" Failed to reset Cresp error latch");
+ }
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+#undef SBE_FUNC
+}
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeHandleSuspendIO Sbe suspend IO function
+//
+// @return RC from the underlying FIFO utility
+///////////////////////////////////////////////////////////////////////
+uint32_t sbeHandleSuspendIO(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeHandleSuspendIO "
+ SBE_ENTER(SBE_FUNC);
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ ReturnCode fapiRc = FAPI2_RC_SUCCESS;
+ uint32_t len = 0;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t ffdc;
+ Target<TARGET_TYPE_PROC_CHIP > procTgt = plat_getChipTarget();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ rc = sbeUpFifoDeq_mult (len, NULL);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(rc);
+
+ // Update the PHB functional State before suspend io procedure
+ fapiRc = updatePhbFunctionalState();
+ if(fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "updatePhbFunctionalState failed");
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+
+ SBE_EXEC_HWP(fapiRc, p9_suspend_io_hwp, procTgt, false);
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC "p9_suspend_io hwp failed");
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ break;
+ }
+ }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(rc);
+ rc = sbeDsSendRespHdr( respHdr, &ffdc);
+ }while(0);
+
+ SBE_EXIT(SBE_FUNC);
+ return rc;
+ #undef SBE_FUNC
+}
+#endif //#ifndef __SBEFW_SEEPROM__
+
OpenPOWER on IntegriCloud