diff options
author | Santosh Puranik <santosh.puranik@in.ibm.com> | 2016-03-03 11:14:15 +0530 |
---|---|---|
committer | AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com> | 2016-04-06 09:50:39 -0400 |
commit | fe7353cd3d3658f507cf665f76d45d76f17d528d (patch) | |
tree | 4ba175fc9eb25a007cabe67291f00d787d1aa68e /sbe/sbefw | |
parent | b771932dc75e689aeea7236a08ac9b92e3ab6734 (diff) | |
download | talos-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.C | 142 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdiplcontrol.H | 14 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdprocessor.C | 27 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdreceiver.C | 3 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdsram.C | 23 | ||||
-rw-r--r-- | sbe/sbefw/sbefifo.H | 11 | ||||
-rw-r--r-- | sbe/sbefw/sbefwfiles.mk | 2 | ||||
-rw-r--r-- | sbe/sbefw/sbemain.C | 14 | ||||
-rw-r--r-- | sbe/sbefw/sberegaccess.C | 210 | ||||
-rw-r--r-- | sbe/sbefw/sberegaccess.H | 230 | ||||
-rw-r--r-- | sbe/sbefw/sbestates.H | 38 |
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 + |