summaryrefslogtreecommitdiffstats
path: root/sbe/sbefw
diff options
context:
space:
mode:
authorSantosh Puranik <santosh.puranik@in.ibm.com>2016-03-03 11:14:15 +0530
committerAMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>2016-04-06 09:50:39 -0400
commitfe7353cd3d3658f507cf665f76d45d76f17d528d (patch)
tree4ba175fc9eb25a007cabe67291f00d787d1aa68e /sbe/sbefw
parentb771932dc75e689aeea7236a08ac9b92e3ab6734 (diff)
downloadtalos-sbe-fe7353cd3d3658f507cf665f76d45d76f17d528d.tar.gz
talos-sbe-fe7353cd3d3658f507cf665f76d45d76f17d528d.zip
Continuous IPL support
Class for register access Beginnings of SBE states RTC: 120752 Change-Id: I6d5ceedd34dc311a352c3d9a638b8fc7f2bef291 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/21693 Tested-by: Jenkins Server Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com> Reviewed-by: AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>
Diffstat (limited to 'sbe/sbefw')
-rw-r--r--sbe/sbefw/sbecmdiplcontrol.C142
-rw-r--r--sbe/sbefw/sbecmdiplcontrol.H14
-rw-r--r--sbe/sbefw/sbecmdprocessor.C27
-rw-r--r--sbe/sbefw/sbecmdreceiver.C3
-rw-r--r--sbe/sbefw/sbecmdsram.C23
-rw-r--r--sbe/sbefw/sbefifo.H11
-rw-r--r--sbe/sbefw/sbefwfiles.mk2
-rw-r--r--sbe/sbefw/sbemain.C14
-rw-r--r--sbe/sbefw/sberegaccess.C210
-rw-r--r--sbe/sbefw/sberegaccess.H230
-rw-r--r--sbe/sbefw/sbestates.H38
11 files changed, 668 insertions, 46 deletions
diff --git a/sbe/sbefw/sbecmdiplcontrol.C b/sbe/sbefw/sbecmdiplcontrol.C
index 71e19a2c..d73a8ddc 100644
--- a/sbe/sbefw/sbecmdiplcontrol.C
+++ b/sbe/sbefw/sbecmdiplcontrol.C
@@ -11,6 +11,8 @@
#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)
@@ -59,7 +61,6 @@ 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);
@@ -87,6 +88,8 @@ 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);
//structure for mapping SBE wrapper and HWP functions
typedef struct
@@ -99,9 +102,12 @@ typedef struct
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
@@ -113,6 +119,17 @@ const uint32_t ISTEP2_MAX_SUBSTEPS = 15;
const uint32_t ISTEP3_MAX_SUBSTEPS = 20;
const uint32_t ISTEP4_MAX_SUBSTEPS = 31;
const uint32_t ISTEP5_MAX_SUBSTEPS = 2;
+static const uint8_t ISTEP_MINOR_START = 1;
+static const uint8_t SLAVE_LAST_MINOR_ISTEP = 18;
+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
@@ -154,8 +171,7 @@ static istepMap_t g_istep3PtrTbl[ ISTEP3_MAX_SUBSTEPS ] =
{ &istepWithProc, { .procHwp = &p9_sbe_scominit }},
{ &istepWithProc, { .procHwp = &p9_sbe_lpc_init }},
{ &istepWithProc, { .procHwp = &p9_sbe_fabricinit }},
- { &istepNoOp, NULL }, // TODO via RTC 120752
- // FW proc_sbe_check_master
+ { &istepCheckSbeMaster, NULL },
{ &istepWithProc, { .procHwp = &p9_sbe_mcs_setup }},
{ &istepSelectEx, NULL },
};
@@ -199,7 +215,7 @@ static istepMap_t g_istep4PtrTbl[ ISTEP4_MAX_SUBSTEPS ] =
static istepMap_t g_istep5PtrTbl[ ISTEP5_MAX_SUBSTEPS ]
{
{ &istepLoadBootLoader, NULL },
- { &istepWithCore, { .coreHwp = &p9_sbe_instruct_start }},
+ { &istepStartInstruction, { .coreHwp = &p9_sbe_instruct_start }},
};
// Functions
@@ -251,8 +267,8 @@ uint32_t sbeHandleIstep (uint8_t *i_pArg)
respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
ffdc.setRc(fapiRc);
+ break;
}
-
}while(0);
//loop 2
@@ -345,9 +361,14 @@ ReturnCode sbeExecuteIstep (const uint8_t i_major, const uint8_t i_minor)
break;
}
- // bits 16-23 major istep number, 24-31 minor istep number
- uint64_t l_iplState = (uint64_t)(i_major)<<40 | (uint64_t)(i_minor)<<32;
- SBE_UPDATE_SBE_MSG_REG (l_iplState);
+ (void)SbeRegAccess::theSbeRegAccess().updateSbeStep(i_major, i_minor);
+
+ // TODO: via RTC: 126146 - Should the state be set to DUMP even in istep
+ // mode failures? Revisit this when we implement state management.
+ if(rc != FAPI2_RC_SUCCESS)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().updateSbeState(SBE_STATE_DUMP);
+ }
return rc;
#undef SBE_FUNC
@@ -365,6 +386,17 @@ bool validateIstep (const uint8_t i_major, const uint8_t i_minor)
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.18 on a slave SBE
+ valid = false;
+ break;
+ }
+
switch( i_major )
{
case SBE_ISTEP2:
@@ -505,12 +537,38 @@ ReturnCode istepLoadBootLoader( sbeIstepHwp_t i_hwp)
P9XipHeader *hdr = getXipHdr();
P9XipSection *hbblSection = &(hdr->iv_section[P9_XIP_SECTION_SBE_HBBL]);
- ReturnCode rc = p9_sbe_load_bootloader( proc, exTgt, hbblSection->iv_size,
+ 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().updateSbeState(SBE_STATE_RUNTIME);
+ }
+ return rc;
+}
+
+//----------------------------------------------------------------------------
+ReturnCode istepCheckSbeMaster( sbeIstepHwp_t i_hwp)
+{
+ ReturnCode rc = FAPI2_RC_SUCCESS;
+ g_sbeRole = SbeRegAccess::theSbeRegAccess().isSbeSlave() ?
+ SBE_ROLE_SLAVE : SBE_ROLE_MASTER;
+ if(SBE_ROLE_SLAVE == g_sbeRole)
+ {
+ (void)SbeRegAccess::theSbeRegAccess().updateSbeState(SBE_STATE_RUNTIME);
+ }
+ return rc;
+}
+
+//----------------------------------------------------------------------------
ReturnCode istepNoOp( sbeIstepHwp_t i_hwp)
{
SBE_DEBUG("istepNoOp");
@@ -523,7 +581,69 @@ uint32_t sbeWaitForSbeIplDone (uint8_t *i_pArg)
{
uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
SBE_TRACE("sbeWaitForSbeIplDone");
-
-
return rc;
}
+
+//----------------------------------------------------------------------------
+void sbeDoContinuousIpl()
+{
+ #define SBE_FUNC "sbeDoContinuousIpl "
+ SBE_DEBUG(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().updateSbeState(SBE_STATE_IPLING);
+ 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_DEBUG(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.18 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;
+ #undef SBE_FUNC
+}
+
diff --git a/sbe/sbefw/sbecmdiplcontrol.H b/sbe/sbefw/sbecmdiplcontrol.H
index 9440889c..c3bf0b2d 100644
--- a/sbe/sbefw/sbecmdiplcontrol.H
+++ b/sbe/sbefw/sbecmdiplcontrol.H
@@ -10,6 +10,10 @@
#include <stdint.h>
+namespace fapi2
+{
+ class ReturnCode;
+}
/**
* @brief execute istep chipop (0xA101)
@@ -31,4 +35,14 @@ uint32_t sbeHandleIstep(uint8_t *i_pArg);
uint32_t sbeWaitForSbeIplDone (uint8_t *i_pArg);
+/**
+ * @brief Executes IPL steps in continuous mode.
+ *
+ * @par On the master SBE, this will run
+ * all steps from 2.2 to 5.2. On the slave SBE, it runs all steps from 2.2
+ * to 3.18.
+ * In case an error is encountered, the execution is aborted.
+ */
+void sbeDoContinuousIpl();
+
#endif // __SBEFW_SBECMDIPLCONTROL_H
diff --git a/sbe/sbefw/sbecmdprocessor.C b/sbe/sbefw/sbecmdprocessor.C
index 72796579..afeeebdb 100644
--- a/sbe/sbefw/sbecmdprocessor.C
+++ b/sbe/sbefw/sbecmdprocessor.C
@@ -17,6 +17,9 @@
#include "sbeerrorcodes.H"
#include "sbeHostUtils.H"
#include "sbeHostMsg.H"
+#include "sbecmdiplcontrol.H"
+#include "sberegaccess.H"
+#include "sbestates.H"
/////////////////////////////////////////////////////////////////////
@@ -55,7 +58,7 @@ void sbeHandlePsuResponse (const uint32_t i_rc)
break;
}
break;
-
+
case SBE_SEC_OS_FAILURE:
// Set primary and secondary status
g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE, i_rc);
@@ -71,7 +74,7 @@ void sbeHandlePsuResponse (const uint32_t i_rc)
break;
}
break;
-
+
case SBE_SEC_OPERATION_SUCCESSFUL:
// Services code successfully executed the chipOp.
SBE_INFO(SBE_FUNC"PSU ChipOp Done");
@@ -210,6 +213,26 @@ void sbeSyncCommandProcessor_routine(void *i_pArg)
uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
uint16_t l_primStatus = SBE_PRI_OPERATION_SUCCESSFUL;
+ // Check the destination bit
+ if(true == SbeRegAccess::theSbeRegAccess().isDestBitRuntime())
+ {
+ SBE_DEBUG(SBE_FUNC"Destination bit tells us to go to runtime");
+ (void)SbeRegAccess::theSbeRegAccess().
+ updateSbeState(SBE_STATE_RUNTIME);
+ }
+
+ else if(true == SbeRegAccess::theSbeRegAccess().isIstepMode())
+ {
+ SBE_DEBUG(SBE_FUNC"Continuous IPL mode not set, will wait for "
+ "commands...");
+ (void)SbeRegAccess::theSbeRegAccess().
+ updateSbeState(SBE_STATE_ISTEP);
+ }
+ else
+ {
+ sbeDoContinuousIpl();
+ }
+
// Wait for new command processing
int l_rcPk = pk_semaphore_pend (
&g_sbeSemCmdProcess, PK_WAIT_FOREVER);
diff --git a/sbe/sbefw/sbecmdreceiver.C b/sbe/sbefw/sbecmdreceiver.C
index 93af6005..415e23c6 100644
--- a/sbe/sbefw/sbecmdreceiver.C
+++ b/sbe/sbefw/sbecmdreceiver.C
@@ -16,6 +16,7 @@
#include "sbeerrorcodes.H"
#include "sbeHostMsg.H"
#include "sbeHostUtils.H"
+#include "sberegaccess.H"
sbeFifoCmdReqBuf_t g_sbeFifoCmdHdr;
sbeCmdRespHdr_t g_sbeCmdRespHdr;
@@ -32,7 +33,7 @@ void sbeCommandReceiver_routine(void *i_pArg)
// Update SBE msgg reg to indicate that control loop
// is ready now to receive data on its interfaces
- SBE_UPDATE_SBE_MSG_REG(SBE_STATE_PK_READY);
+ (void)SbeRegAccess::theSbeRegAccess().setSbeReady();
do
{
diff --git a/sbe/sbefw/sbecmdsram.C b/sbe/sbefw/sbecmdsram.C
index 8a3065a1..09ff5535 100644
--- a/sbe/sbefw/sbecmdsram.C
+++ b/sbe/sbefw/sbecmdsram.C
@@ -10,6 +10,7 @@
#include "sbe_sp_intf.H"
#include "sbetrace.H"
#include "sbeFifoMsgUtils.H"
+#include "sberegaccess.H"
#include "fapi2.H"
#include "p9_pm_ocb_init.H"
@@ -54,26 +55,6 @@ uint32_t sbeOccSramAccess_Wrap(const bool i_isGetFlag)
do
{
- // Do a SCOM on Register PERV_SCRATCH_REGISTER_3_SCOM for Bit3
- // to know if Fsp is attached
- // This can be a attribute read or to refer a global value.
- // TODO - RTC:120752
- uint64_t l_scratchReg3data = 0;
- bool l_isFspAttached = false;
- l_rc = getscom_abs(PERV_SCRATCH_REGISTER_3_SCOM, &l_scratchReg3data);
- if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
- {
- SBE_ERROR(SBE_FUNC "getscom_abs failed for "
- "PERV_SCRATCH_REGISTER_3_SCOM l_rc [0x%08X]", l_rc);
- break;
- }
-
- // Fetch the Bit3
- if(l_scratchReg3data & SBE_FWCTRLFLG3_FSP_ATTACHED)
- {
- l_isFspAttached = true;
- }
-
// Get the Req Struct Size Data from upstream Fifo
uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t);
l_rc = sbeUpFifoDeq_mult (l_len2dequeue,
@@ -105,7 +86,7 @@ uint32_t sbeOccSramAccess_Wrap(const bool i_isGetFlag)
switch(l_req.mode)
{
case NORMAL_MODE:
- if(!l_isFspAttached)
+ if(false == SbeRegAccess::theSbeRegAccess().isFspSystem())
{
l_chan = p9ocb::OCB_CHAN2;
}
diff --git a/sbe/sbefw/sbefifo.H b/sbe/sbefw/sbefifo.H
index 702ded36..7c53994d 100644
--- a/sbe/sbefw/sbefifo.H
+++ b/sbe/sbefw/sbefifo.H
@@ -122,17 +122,6 @@ typedef struct
uint32_t reserved;
} sbeDownFifoStatusReg_t;
-// @TODO via RTC 142985: move to a better file with final fix
-// Do a R-M-W to retain un-related bits
-/**
- * @brief Update SBE Messaging Register with the SBE states
- */
-const uint32_t SBE_SCOM_MESSAGE_REGISTER = 0x50009;
-const uint64_t SBE_STATE_PK_READY = 0x8000000000000000ull;
-
-#define SBE_UPDATE_SBE_MSG_REG(value) \
- putscom_abs(SBE_SCOM_MESSAGE_REGISTER, (value));
-
/*****************************************************************/
/** Upstream FIFO access utilities **/
/*****************************************************************/
diff --git a/sbe/sbefw/sbefwfiles.mk b/sbe/sbefw/sbefwfiles.mk
index 00b79328..95d4bdf9 100644
--- a/sbe/sbefw/sbefwfiles.mk
+++ b/sbe/sbefw/sbefwfiles.mk
@@ -13,6 +13,8 @@ SBEFW-CPP-SOURCES += sbecmdmemaccess.C
SBEFW-CPP-SOURCES += sbeHostUtils.C
SBEFW-CPP-SOURCES += sbecmdcntrldmt.C
SBEFW-CPP-SOURCES += sbecmdsram.C
+SBEFW-CPP-SOURCES += sberegaccess.C
+
SBEFW-C-SOURCES =
SBEFW-S-SOURCES =
diff --git a/sbe/sbefw/sbemain.C b/sbe/sbefw/sbemain.C
index 041dc0fe..2f8f43f7 100644
--- a/sbe/sbefw/sbemain.C
+++ b/sbe/sbefw/sbemain.C
@@ -15,6 +15,8 @@
#include "sbeexeintf.H"
#include "sbetrace.H"
+#include "sberegaccess.H"
+#include "sbestates.H"
#include "fapi2.H" // For target init
// TODO via RTC 142365
@@ -299,6 +301,18 @@ uint32_t main(int argc, char **argv)
// enable FSP to get FFDC for this failure.
break;
}
+
+ if(SbeRegAccess::theSbeRegAccess().init())
+ {
+ SBE_ERROR(SBE_FUNC"Failed to initialize SbeRegAccess");
+ // init failure could mean the below will fail too, but attempt it
+ // anyway
+ (void)SbeRegAccess::theSbeRegAccess().updateSbeState(SBE_STATE_DUMP);
+ // TODO: via RTC 126146 : Decide if we should really break here or
+ // continue in the failed state.
+ break;
+ }
+
// Start running the highest priority thread.
// This function never returns
pk_start_threads();
diff --git a/sbe/sbefw/sberegaccess.C b/sbe/sbefw/sberegaccess.C
new file mode 100644
index 00000000..be5bdb2a
--- /dev/null
+++ b/sbe/sbefw/sberegaccess.C
@@ -0,0 +1,210 @@
+/*
+ * @file: ppe/sbe/sbefw/sberegaccess.C
+ *
+ * @brief This file contains interfaces to get/set FW flags either in the
+ * scratch registers and/or the FW attributes.
+ */
+
+#include "sberegaccess.H"
+#include "sbetrace.H"
+#include "fapi2.H"
+#include <ppe42_scom.h>
+
+using namespace fapi2;
+
+/**
+ * @brief Initizlize the class
+ *
+ * @return An RC indicating success/failure
+ */
+uint32_t SbeRegAccess::init()
+{
+ #define SBE_FUNC "SbeRegAccess::SbeRegAccess "
+ static bool l_initDone = false;
+ uint32_t l_rc = 0;
+ uint64_t l_mbx8 = 0;
+ do
+ {
+ if(l_initDone)
+ {
+ break;
+ }
+ Target<TARGET_TYPE_PROC_CHIP> l_chip = plat_getChipTarget();
+ // Read SBE messaging register into iv_messagingReg
+ l_rc = getscom_abs(SBE_MESSAGING_REGISTER_ADDR, &iv_messagingReg);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading sbe messaging reg., RC: 0x%08X. ",
+ l_rc);
+ break;
+ }
+ // Read Mailbox register 8 to check if the mailbox registers 3 and 6 are
+ // valid
+ l_rc = getscom_abs(SBE_MBX8_REGISTER_ADDR, &l_mbx8);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading mailbox reg 7, RC: 0x%08X. ",
+ l_rc);
+ break;
+ }
+ if(l_mbx8 & SBE_MBX8_MBX3_VALID_MASK)
+ {
+ // Read MBX3
+ l_rc = getscom_abs(SBE_MBX3_REGISTER_ADDR, &iv_mbx3);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading mailbox reg 3, RC: 0x%08X. ",
+ l_rc);
+ break;
+ }
+ }
+ else
+ {
+ // Need to read the values off the attributes
+ // TODO: via RTC 150291 : Needs to be changed when all FW control
+ // attributes are to be combined into one
+ uint8_t l_attr = 0;
+ FAPI_ATTR_GET(ATTR_ISTEP_MODE, l_chip, l_attr);
+ iv_istepMode = l_attr;
+ FAPI_ATTR_GET(ATTR_SBE_RUNTIME_MODE, l_chip, l_attr);
+ iv_sbeDestRuntime = l_attr;
+ FAPI_ATTR_GET(ATTR_IS_SP_MODE, l_chip, l_attr);
+ iv_fspAttached = l_attr;
+ FAPI_ATTR_GET(ATTR_SBE_FFDC_ENABLE, l_chip, l_attr);
+ iv_collectFFDC = l_attr;
+ FAPI_ATTR_GET(ATTR_SBE_INTERNAL_FFDC_ENABLE, l_chip, l_attr);
+ iv_sendFFDC = l_attr;
+ }
+ if(l_mbx8 & SBE_MBX8_MBX6_VALID_MASK)
+ {
+ // Read MBX6
+ l_rc = getscom_abs(SBE_MBX6_REGISTER_ADDR, &iv_mbx6);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed reading mailbox reg 6, RC: 0x%08X. "
+ l_rc);
+ break;
+ }
+ }
+ // TODO via RTC:150291 Need to get the exact attribute name that
+ // provides the master/slave role
+ } while(false);
+ SBE_DEBUG(SBE_FUNC"Read mailbox registers: mbx8: 0x%08X, mbx3: 0x%08X, "
+ "mbx6: 0x%08X", (uint32_t)(l_mbx8 >> 32),
+ (uint32_t)(iv_mbx3 >> 32), (uint32_t)(iv_mbx6 >> 32));
+ l_initDone = true;
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/**
+ * @brief Update the SBE states into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the state
+ * bits are preserved. The current state of the register is set to
+ * i_state, whereas the old current state is copied to previous state
+ *
+ * @param [in] i_state The current SBE state
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::updateSbeState(const sbeState &i_state)
+{
+ #define SBE_FUNC "SbeRegAccess::updateSbeState "
+ uint32_t l_rc = 0;
+
+ iv_prevState = iv_currState;
+ iv_currState = i_state;
+ l_rc = putscom_abs(SBE_MESSAGING_REGISTER_ADDR, iv_messagingReg);
+ if(PCB_ERROR_NONE != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to update state to messaging "
+ "register. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/**
+ * @brief Update the SBE IPL steps into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the IPL
+ * steps are retianed
+ *
+ * @param [in] i_major IPL major step number
+ * @param [in] i_minor IPL minor step number
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::updateSbeStep(const uint8_t i_major,
+ const uint8_t i_minor)
+{
+ #define SBE_FUNC "SbeRegAccess::updateSbeStep "
+ uint32_t l_rc = 0;
+
+ iv_majorStep = i_major;
+ iv_minorStep = i_minor;
+
+ l_rc = putscom_abs(SBE_MESSAGING_REGISTER_ADDR, iv_messagingReg);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to update SBE step to messaging "
+ "register. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+/**
+ * @brief Set the SBE ready bit into the SBE messaging register
+ * (meaning that SBE control loop is initialized) The function does a
+ * read-modify-write, so any bits other than the SBE ready bit remain
+ * unchanged.
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::setSbeReady()
+{
+ #define SBE_FUNC "SbeRegAccess::setSbeReady "
+ uint32_t l_rc = 0;
+
+ iv_sbeBooted = true;
+ l_rc = putscom_abs(SBE_MESSAGING_REGISTER_ADDR, iv_messagingReg);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to update SBE ready state to "
+ "messaging register. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+
+/**
+ * @brief Set the MPIPL mode bit into the mailbox scratch reg. 3
+ * The function does a read-modify-write, so any bits other than the
+ * SBE ready bit remain unchanged.
+ *
+ * @param i_set [in] Whether to set or clear the MPIPL flag
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+uint32_t SbeRegAccess::setMpIplMode(const bool i_set)
+{
+ #define SBE_FUNC "SbeRegAccess::setMpIplMode"
+ uint32_t l_rc = 0;
+ uint8_t l_set = i_set;
+ iv_mpiplMode = i_set;
+ FAPI_ATTR_SET(ATTR_IS_MPIPL, Target<TARGET_TYPE_SYSTEM>(), l_set);
+ l_rc = putscom_abs(SBE_MBX3_REGISTER_ADDR, iv_mbx3);
+ if(l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"Failed to set/clear MPIPL flag in "
+ "mbx reg. 3. RC: 0x%08X", l_rc);
+ }
+ return l_rc;
+ #undef SBE_FUNC
+}
+
diff --git a/sbe/sbefw/sberegaccess.H b/sbe/sbefw/sberegaccess.H
new file mode 100644
index 00000000..5f0005d1
--- /dev/null
+++ b/sbe/sbefw/sberegaccess.H
@@ -0,0 +1,230 @@
+/*
+ * @file: ppe/sbe/sbefw/sberegaccess.H
+ *
+ * @brief This file contains interfaces to get/set FW flags either in the
+ * scratch registers and/or the FW attributes.
+ */
+
+#ifndef __SBEFW_SBEREGACCESS_H
+#define __SBEFW_SBEREGACCESS_H
+
+#include <stdint.h>
+#include "sbestates.H"
+
+/**
+ * @brief Utility singleton that SBEFW can use to read write various scratch
+ * registers/FW attributes
+ * TODO: via RTC ??????: Need to change the read of scratch registers to FAPI
+ * attribute accesses once we have the attributes defined in the HWP code.
+ */
+class SbeRegAccess
+{
+ public:
+ // Disable copy construction and assignment operators
+ SbeRegAccess(const SbeRegAccess&) = delete;
+ SbeRegAccess& operator=(const SbeRegAccess&) = delete;
+
+ /**
+ * @brief Returns the instance of this class
+ *
+ * @return A reference to SbeRegAccess
+ *
+ */
+ static SbeRegAccess& theSbeRegAccess()
+ {
+ static SbeRegAccess iv_instance;
+ return iv_instance;
+ }
+
+ /**
+ * @brief Initializes the class for use
+ *
+ * @return An RC indicating success/failure
+ *
+ */
+ uint32_t init();
+
+ /**
+ * @brief Update the SBE states into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the state
+ * bits are preserved. The current state of the register is set to
+ * i_state, whereas the old current state is copied to previous state
+ *
+ * @param [in] i_state The current SBE state
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t updateSbeState(const sbeState &i_state);
+
+ /**
+ * @brief Update the SBE IPL steps into the SBE messaging register. The
+ * function does a read-modify-write, so any bits other than the IPL
+ * steps are retianed
+ *
+ * @param [in] i_major IPL major step number
+ * @param [in] i_minor IPL minor step number
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t updateSbeStep(const uint8_t i_major, const uint8_t i_minor);
+
+ /**
+ * @brief Set the SBE ready bit into the SBE messaging register
+ * (meaning that SBE control loop is initialized) The function does a
+ * read-modify-write, so any bits other than the SBE ready bit remain
+ * unchanged.
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t setSbeReady();
+
+ /**
+ * @brief Set the MPIPL mode bit into the mailbox scratch reg. 3
+ * The function does a read-modify-write, so any bits other than the
+ * SBE ready bit remain unchanged. It also updates the attribute
+ * ATTR_MPIPL
+ *
+ * @param i_set [in] true == set, false == clear
+ *
+ * @return RC indicating success/failure.
+ *
+ */
+ uint32_t setMpIplMode(const bool i_set);
+
+ /**
+ * @brief Check if we are on an FSP attached
+ *
+ * @return true if FSP attached system, false otherwise
+ *
+ */
+ inline bool isFspSystem() const
+ {
+ return iv_fspAttached;
+ }
+
+ /**
+ * @brief Check if we are in ISTEP IPL mode
+ *
+ * @return true if in istep mode, false otherwise
+ *
+ */
+ inline bool isIstepMode() const
+ {
+ return iv_istepMode;
+ }
+
+ /**
+ * @brief Check if SBE should directly go to runtime state
+ *
+ * @return true if SBE should go directly to runtime state,
+ * false otherwise
+ *
+ */
+ inline bool isDestBitRuntime() const
+ {
+ return iv_sbeDestRuntime;
+ }
+
+ /**
+ * @brief Check if SBE should collect FFDC
+ *
+ * @return true if in istep mode, false otherwise
+ *
+ */
+ inline bool isCollectFFDCSet() const
+ {
+ return iv_collectFFDC;
+ }
+
+ /**
+ * @brief Check if SBE should send internal FFDC for any chip op
+ * failures as a part of the response
+ *
+ * @return true if in istep mode, false otherwise
+ *
+ */
+ inline bool isSendInternalFFDCSet() const
+ {
+ return iv_sendFFDC;
+ }
+
+ /**
+ * @brief Check if SBE is slave/master
+ *
+ * @return true if SBE is slave, false if master
+ *
+ */
+ inline bool isSbeSlave() const
+ {
+ return iv_isSlave;
+ }
+
+ private:
+
+ /**
+ * @brief Constructor
+ */
+ SbeRegAccess() : iv_mbx3(0), iv_mbx6(0), iv_messagingReg(0)
+ {}
+
+ union
+ {
+ struct
+ {
+ uint64_t iv_istepMode : 1;
+ uint64_t iv_sbeDestRuntime : 1;
+ uint64_t iv_mpiplMode : 1;
+ uint64_t iv_fspAttached : 1;
+ uint64_t iv_collectFFDC : 1;
+ uint64_t iv_sendFFDC : 1;
+ uint64_t iv_mbx3DontCare : 26;
+ uint64_t iv_mbx3Unused : 32;
+ };
+ uint64_t iv_mbx3;
+ };
+
+ union
+ {
+ struct
+ {
+ uint64_t iv_mbx6DontCare : 24;
+ uint64_t iv_isSlave : 1;
+ uint64_t iv_mbx6DontCare2 : 7;
+ uint64_t iv_mbx6Unused : 32;
+ };
+ uint64_t iv_mbx6;
+ };
+
+ union
+ {
+ struct
+ {
+ uint64_t iv_sbeBooted : 1;
+ uint64_t iv_reserved1 : 3;
+ uint64_t iv_prevState : 4;
+ uint64_t iv_currState : 4;
+ uint64_t iv_majorStep : 4;
+ uint64_t iv_minorStep : 8;
+ uint64_t iv_reserved2 : 8;
+ uint64_t iv_unused : 32;
+ };
+ uint64_t iv_messagingReg;
+ };
+
+ // Scom address definitions for mailbox scratch registers, note that the
+ // mailbox numbering starts at 0
+ static const uint32_t SBE_MESSAGING_REGISTER_ADDR = 0x50009;
+ static const uint32_t SBE_MBX3_REGISTER_ADDR = 0x5003A;
+ static const uint32_t SBE_MBX6_REGISTER_ADDR = 0x5003D;
+ static const uint32_t SBE_MBX8_REGISTER_ADDR = 0x5003F;
+
+ // Bit masks defining bits in the above registers that the SBE is
+ // interested in
+ static const uint64_t SBE_MBX8_MBX3_VALID_MASK = 0x2000000000000000ULL;
+ static const uint64_t SBE_MBX8_MBX6_VALID_MASK = 0x0400000000000000ULL;
+};
+#endif //__SBEFW_SBEREGACCESS_H
+
diff --git a/sbe/sbefw/sbestates.H b/sbe/sbefw/sbestates.H
new file mode 100644
index 00000000..4c01c218
--- /dev/null
+++ b/sbe/sbefw/sbestates.H
@@ -0,0 +1,38 @@
+/*
+ * @file: ppe/sbe/sbefw/sbestates.H
+ *
+ * @brief This file contains interfaces pertaining to SBE state/role management
+ *
+ */
+
+#ifndef __SBEFW_SBESTATES_H
+#define __SBEFW_SBESTATES_H
+
+/**
+ * @brief An enumeration of all SBE states
+ *
+ */
+enum sbeState
+{
+ SBE_STATE_UNKNOWN = 0, // Unkown, initial state
+ SBE_STATE_FFDC = 1, // Waiting for FFDC collection after a reset
+ SBE_STATE_IPLING = 2, // IPL'ing - autonomous mode (transient)
+ SBE_STATE_ISTEP = 3, // ISTEP - Running IPL by steps (transient)
+ SBE_STATE_RUNTIME = 4, // SBE Runtime
+ SBE_STATE_DUMP = 5, // Dumping (transient?)
+ SBE_STATE_MPIPL = 6, // MPIPL (transient)
+ SBE_STATE_FAILURE = 7, // Internal SBE failure
+ SBE_STATE_ABORT = 8, // SBE was asked to to abort - need reset to get out
+ SBE_STATE_QUIESCE = 0xF, // Final state - needs SBE reset to get out
+};
+
+enum sbeRole
+{
+ SBE_ROLE_MASTER = 0,
+ SBE_ROLE_SLAVE = 1
+};
+
+extern sbeRole g_sbeRole;
+
+#endif //__SBEFW_SBESTATES_H
+
OpenPOWER on IntegriCloud