summaryrefslogtreecommitdiffstats
path: root/src/sbefw/sbecmdiplcontrol.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbefw/sbecmdiplcontrol.C')
-rw-r--r--src/sbefw/sbecmdiplcontrol.C830
1 files changed, 830 insertions, 0 deletions
diff --git a/src/sbefw/sbecmdiplcontrol.C b/src/sbefw/sbecmdiplcontrol.C
new file mode 100644
index 00000000..0819a864
--- /dev/null
+++ b/src/sbefw/sbecmdiplcontrol.C
@@ -0,0 +1,830 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/sbecmdiplcontrol.C $ */
+/* */
+/* OpenPOWER sbe Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* */
+/* */
+/* 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 "fapi2.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"
+
+#include "sbeXipUtils.H" // For getting hbbl offset
+// Forward declaration
+using namespace fapi2;
+ReturnCode sbeExecuteIstep (uint8_t i_major, uint8_t i_minor);
+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 (*sbeIstepHwpEq_t)
+ (const Target<TARGET_TYPE_EQ> & i_target);
+
+typedef ReturnCode (*sbeIstepHwpCore_t)
+ (const Target<TARGET_TYPE_CORE> & i_target);
+
+typedef union
+{
+ sbeIstepHwpProc_t procHwp;
+ sbeIstepHwpEq_t eqHwp;
+ sbeIstepHwpCore_t coreHwp;
+}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 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);
+
+// Using function pointer to force long call.
+p9_sbe_select_ex_FP_t p9_sbe_select_ex_hwp = &p9_sbe_select_ex;
+
+//structure for mapping SBE wrapper and HWP functions
+typedef struct
+{
+ sbeIstep_t istepWrapper;
+ sbeIstepHwp_t istepHwp;
+}istepMap_t;
+
+// Major isteps which are supported
+typedef enum
+{
+ SBE_ISTEP2 = 2,
+ SBE_ISTEP_FIRST = SBE_ISTEP2,
+ SBE_ISTEP3 = 3,
+ SBE_ISTEP_LAST_SLAVE = SBE_ISTEP3,
+ SBE_ISTEP4 = 4,
+ SBE_ISTEP5 = 5,
+ SBE_ISTEP_LAST_MASTER = SBE_ISTEP5,
+}sbe_supported_steps_t;
+
+// constants
+const uint32_t ISTEP2_MAX_SUBSTEPS = 17;
+const uint32_t ISTEP3_MAX_SUBSTEPS = 22;
+const uint32_t ISTEP4_MAX_SUBSTEPS = 34;
+const uint32_t ISTEP5_MAX_SUBSTEPS = 2;
+static const uint8_t ISTEP_MINOR_START = 1;
+static const uint8_t SLAVE_LAST_MINOR_ISTEP = 20;
+static const uint8_t ISTEP2_MINOR_START = 2;
+static const uint32_t SBE_ROLE_MASK = 0x00000002;
+
+// 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;
+
+sbeRole g_sbeRole = SBE_ROLE_MASTER;
+
+// File static data
+
+static istepMap_t g_istep2PtrTbl[ ISTEP2_MAX_SUBSTEPS ] =
+ {
+ { 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 }},
+ { &istepWithProc, { .procHwp = &p9_sbe_npll_setup }},
+ { &istepWithProc, { .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 }},
+ };
+
+static istepMap_t g_istep3PtrTbl[ ISTEP3_MAX_SUBSTEPS ] =
+ {
+ { &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 }},
+ { &istepWithProc, { .procHwp = &p9_sbe_lpc_init }},
+ { &istepWithProc, { .procHwp = &p9_sbe_fabricinit }},
+ { &istepCheckSbeMaster, NULL },
+ { &istepWithProc, { .procHwp = &p9_sbe_mcs_setup }},
+ { &istepSelectEx, NULL },
+ };
+static istepMap_t g_istep4PtrTbl[ ISTEP4_MAX_SUBSTEPS ] =
+ {
+ { &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
+ { &istepWithEq, { .eqHwp = &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 },
+ };
+
+// TODO via RTC 135345
+// Add the support for istep 5 HWP
+static istepMap_t g_istep5PtrTbl[ ISTEP5_MAX_SUBSTEPS ]
+ {
+ { &istepLoadBootLoader, NULL },
+ { &istepStartInstruction, { .coreHwp = &p9_sbe_instruct_start }},
+ };
+
+// Functions
+//----------------------------------------------------------------------------
+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", req.major, 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", req.major, 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;
+
+ // 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)
+ {
+ // If IPLing State
+ uint64_t l_state = SbeRegAccess::theSbeRegAccess().getSbeState();
+ if(l_state == SBE_STATE_IPLING)
+ {
+ (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;
+ }
+
+ if((SBE_ROLE_SLAVE == g_sbeRole) &&
+ ((SBE_ISTEP_LAST_SLAVE < i_major) ||
+ ((SBE_ISTEP_LAST_SLAVE == i_major) &&
+ (SLAVE_LAST_MINOR_ISTEP < i_minor)
+ )))
+ {
+ // Cannot run beyond 3.20 on a slave SBE
+ 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 ) { valid = false; } ;
+ break;
+
+ case SBE_ISTEP4:
+ if( i_minor > ISTEP4_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP5:
+ if( i_minor > ISTEP5_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ default:
+ valid= false;
+ break;
+ }
+ } while(0);
+
+ return valid;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepAttrSetup( sbeIstepHwp_t i_hwp)
+{
+ SBE_ENTER("istepAttrSetup");
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ do
+ {
+ assert( NULL != i_hwp.procHwp );
+ rc = i_hwp.procHwp(proc);
+ if( rc != FAPI2_RC_SUCCESS )
+ {
+ break;
+ }
+ // Apply the gard records
+ rc = plat_ApplyGards();
+ }while(0);
+ SBE_EXIT("istepAttrSetup");
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithProc( sbeIstepHwp_t i_hwp)
+{
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ assert( NULL != i_hwp.procHwp );
+ return i_hwp.procHwp(proc);
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepSelectEx( sbeIstepHwp_t i_hwp)
+{
+ 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.
+ return p9_sbe_select_ex_hwp(proc, p9selectex::SINGLE);
+}
+
+//----------------------------------------------------------------------------
+
+
+ReturnCode istepWithEq( sbeIstepHwp_t i_hwp)
+{
+ // 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 );
+ return i_hwp.eqHwp( eqTgt );
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepWithCore( sbeIstepHwp_t i_hwp)
+{
+ // TODO via RTC 135345
+ // Curently we are passing Hard code core target. Finally it is
+ // going to be a multicast target. Once multicast support is
+ // present, use the right target.
+ fapi2::Target<fapi2::TARGET_TYPE_CORE > coreTgt;
+ // Put this in scope so that vector can be freed up before calling hwp.
+ {
+ Target<TARGET_TYPE_PROC_CHIP > proc = plat_getChipTarget();
+ auto coreList = proc.getChildren<fapi2::TARGET_TYPE_CORE>();
+ // As it is workaround lets assume there will always be atleast one
+ // functional ec. No need to validate.
+ coreTgt = coreList[0];
+ }
+ assert( NULL != i_hwp.coreHwp );
+ return i_hwp.coreHwp( coreTgt );
+}
+
+//----------------------------------------------------------------------------
+
+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;
+}
+
+//----------------------------------------------------------------------------
+
+ReturnCode istepLoadBootLoader( sbeIstepHwp_t i_hwp)
+{
+ // Get master Ex
+ uint8_t exId = 0;
+ 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]);
+
+ ReturnCode rc = p9_sbe_load_bootloader( proc, exTgt, hbblSection->iv_size,
+ getSectionAddr(hbblSection) );
+ 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)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ g_sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ?
+ SBE_ROLE_SLAVE : SBE_ROLE_MASTER;
+ SBE_INFO("stepCheckSbeMaster g_sbeRole [%x]", g_sbeRole);
+ if(SBE_ROLE_SLAVE == g_sbeRole)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_RUNTIME_EVENT);
+ }
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepNoOp( sbeIstepHwp_t i_hwp)
+{
+ SBE_INFO("istepNoOp");
+ return FAPI2_RC_SUCCESS ;
+}
+
+// Only allowed in PLCK Mode, since FFDC State mode is set only in PLCK
+//----------------------------------------------------------------------------
+uint32_t sbeContinueBoot (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeContinueBoot "
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ rc = sbeUpFifoDeq_mult (len, NULL);
+ if(rc != SBE_SEC_OPERATION_SUCCESSFUL)
+ {
+ // let command processor routine handle the RC
+ break;
+ }
+
+ uint32_t distance = 1;
+ len = sizeof(respHdr)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &respHdr);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+
+ len = sizeof(distance)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, &distance);
+ if (rc)
+ {
+ break;
+ }
+ rc = sbeDownFifoSignalEot();
+ if (rc)
+ {
+ break;
+ }
+
+ // Expecting this to be in PLCK Mode and not in Istep mode
+ if(SbeRegAccess::theSbeRegAccess().isDestBitRuntime())
+ {
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_CONTINUE_BOOT_RUNTIME_EVENT);
+ // Nothing to do here.
+ }
+ else
+ {
+ SBE_INFO(SBE_FUNC"Continuous IPL Mode set... IPLing");
+ (void)SbeRegAccess::theSbeRegAccess().stateTransition(
+ SBE_CONTINUE_BOOT_PLCK_EVENT);
+ sbeDoContinuousIpl();
+ }
+ }while(0);
+
+ SBE_DEBUG(SBE_FUNC "RC = 0x%08X", rc);
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+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;
+ 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
+}
+
+// TODO - RTC 133367
+//----------------------------------------------------------------------------
+uint32_t sbeEnterMpipl(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeEnterMpipl "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ l_rc = sbeUpFifoDeq_mult (len, NULL);
+ if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL )
+ {
+ // Let command processor routine to handle the RC
+ break;
+ }
+
+ sbeResponseFfdc_t l_ffdc;
+ l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc);
+
+ // set state to MPIPL Wait
+ (void)SbeRegAccess::theSbeRegAccess().
+ stateTransition(SBE_ENTER_MPIPL_EVENT);
+
+ //TODO RTC-123696 MPIPL Related procedure/steps
+ }while(0);
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+// TODO - RTC 133367
+//----------------------------------------------------------------------------
+uint32_t sbeContinueMpipl(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeContinueMpipl "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t len = 0;
+ sbeRespGenHdr_t l_respHdr;
+ l_respHdr.init();
+
+ do
+ {
+ // Dequeue the EOT entry as no more data is expected.
+ l_rc = sbeUpFifoDeq_mult (len, NULL);
+ if ( l_rc != SBE_SEC_OPERATION_SUCCESSFUL )
+ {
+ // Let command processor routine to handle the RC
+ break;
+ }
+
+ sbeResponseFfdc_t l_ffdc;
+ l_rc = sbeDsSendRespHdr( l_respHdr, l_ffdc);
+
+ //TODO RTC-134278 Continue MPIPL Related procedure/steps
+
+ // TODO - Once continue steps are over, it will trigger the
+ // istep5.2 and transition to runtime will happen
+
+ }while(0);
+
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
OpenPOWER on IntegriCloud