From c1da4a458459a9ab8a09421069d42f3154bd3792 Mon Sep 17 00:00:00 2001 From: spashabk-in Date: Mon, 16 Apr 2018 01:51:22 -0500 Subject: Handle hreset of SBE Figure out hreset from l1 loader, and if it is hreset avoid l2 loader and instead jump to kernel boot. In kernel boot - avoid contructor calls and any intialization RTC: 165477 Change-Id: Ia10c83dd7c15fb5115964cba315fbedfe10a636e Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/57246 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: RAJA DAS Reviewed-by: Sachin Gupta --- src/boot/loader_l1.S | 24 +++++++- src/build/utils/sbe_link.H | 2 + src/sbefw/core/sbecmdprocessor.C | 12 +++- src/sbefw/core/sbecmdreceiver.C | 3 - src/sbefw/core/sbeglobals.C | 2 + src/sbefw/core/sbeglobals.H | 3 + src/sbefw/core/sbemain.C | 118 +++++++++++++++++++++------------------ src/sbefw/core/sbeutil.C | 62 +++++++++++++++++++- src/sbefw/core/sbeutil.H | 12 ++++ 9 files changed, 178 insertions(+), 60 deletions(-) diff --git a/src/boot/loader_l1.S b/src/boot/loader_l1.S index 92259e3c..593b586d 100644 --- a/src/boot/loader_l1.S +++ b/src/boot/loader_l1.S @@ -5,7 +5,7 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -57,7 +57,14 @@ __l1Loader: li r1, 0x00 stvd d0, 0(r5) + # If hreset of SBE, jump directly to kernel, as all the pibmem contents + # are already populated + _liw %r3, 0x50008 + lvd d3,0(r3) + bb1wi r3,13,jump_to_kernel + bl _pibmemRepair + _liw %r3, SBE_LOADER_BASE_SECTION # Base Loader Section Location _liw %r4, SBE_LOADER_BASE_ORIGIN # dest _liw %r9, SBE_SEEPROM_BASE_ORIGIN @@ -107,4 +114,19 @@ copy_loop_init: blr +jump_to_kernel: + # setup IVPR before jumping to kernel + _liw %r8, SBE_BASE_ORIGIN + li r9,0 + _liw %r10, 0xC0000160 + stvd d8,0(r10) + ############################################################ + # SBE entry function is 4 byte number in image header + ############################################################ + + _liw %r3, SBE_SEEPROM_BASE_ORIGIN + SBE_KERNEL_ENTRY_HEADER_OFFSET + lwz r6, 0(r3) + mtlr r6 + blr + #include "pibmem_repair.S" diff --git a/src/build/utils/sbe_link.H b/src/build/utils/sbe_link.H index 876b4b18..b5638cb6 100644 --- a/src/build/utils/sbe_link.H +++ b/src/build/utils/sbe_link.H @@ -79,6 +79,8 @@ // Base Loader entry function offset in header #define SBE_LOADER_ENTRY_HEADER_OFFSET 20 +// PK boot offset in header +#define SBE_KERNEL_ENTRY_HEADER_OFFSET 28 /// The physical address offset where SBE-SEEPROM code is loaded /// diff --git a/src/sbefw/core/sbecmdprocessor.C b/src/sbefw/core/sbecmdprocessor.C index 9dda2164..32645255 100644 --- a/src/sbefw/core/sbecmdprocessor.C +++ b/src/sbefw/core/sbecmdprocessor.C @@ -258,9 +258,17 @@ void sbeSyncCommandProcessor_routine(void *i_pArg) // is ready now to receive data on its interfaces (void)SbeRegAccess::theSbeRegAccess().setSbeReady(); - // Check the destination bit at the start - if(true == SbeRegAccess::theSbeRegAccess().isDestBitRuntime()) + if (SBE_GLOBAL->isHreset) { + SBE::clearHresetBit(); + SBE_INFO(SBE_FUNC"Hreset, going back to the state before reset"); + (void)SbeRegAccess::theSbeRegAccess(). + updateSbeState( + (sbeState)SbeRegAccess::theSbeRegAccess().getSbeState()); + } + else if(true == SbeRegAccess::theSbeRegAccess().isDestBitRuntime()) + { + // Check the destination bit at the start SBE_INFO(SBE_FUNC"Destination bit tells us to go to runtime"); (void)SbeRegAccess::theSbeRegAccess(). updateSbeState(SBE_STATE_RUNTIME); diff --git a/src/sbefw/core/sbecmdreceiver.C b/src/sbefw/core/sbecmdreceiver.C index 430830e2..7ee8d602 100644 --- a/src/sbefw/core/sbecmdreceiver.C +++ b/src/sbefw/core/sbecmdreceiver.C @@ -58,9 +58,6 @@ void sbeCommandReceiver_routine(void *i_pArg) uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; sbeInterfaceSrc_t curInterface = SBE_INTERFACE_UNKNOWN; - // Set Current State to First State i.e. Unknown - (void)SbeRegAccess::theSbeRegAccess().updateSbeState(SBE_STATE_UNKNOWN); - do { // @TODO via RTC: 128944 diff --git a/src/sbefw/core/sbeglobals.C b/src/sbefw/core/sbeglobals.C index 90a80b72..c5f898b9 100644 --- a/src/sbefw/core/sbeglobals.C +++ b/src/sbefw/core/sbeglobals.C @@ -53,3 +53,5 @@ uint16_t SBEGlobalsSingleton::failedSecStatus = SBE_SEC_OPERATION_SUCCESSFUL; uint16_t SBEGlobalsSingleton::failedSeqId = 0; uint8_t SBEGlobalsSingleton::failedCmdClass = 0; uint8_t SBEGlobalsSingleton::failedCmd = 0; + +bool SBEGlobalsSingleton::isHreset = false; diff --git a/src/sbefw/core/sbeglobals.H b/src/sbefw/core/sbeglobals.H index 6284a57f..8ddb06be 100644 --- a/src/sbefw/core/sbeglobals.H +++ b/src/sbefw/core/sbeglobals.H @@ -96,6 +96,9 @@ class SBEGlobalsSingleton // SBE commit id static uint32_t fwCommitId; + // hreset flow + static bool isHreset; + // Secure memory window arrays static secureMemRegion_t mainMemRegions[MAX_MAIN_STORE_REGIONS]; static secureMemRegion_t occSramRegions[MAX_OCC_SRAM_REGIONS]; diff --git a/src/sbefw/core/sbemain.C b/src/sbefw/core/sbemain.C index e49fc029..bc84739b 100644 --- a/src/sbefw/core/sbemain.C +++ b/src/sbefw/core/sbemain.C @@ -5,7 +5,8 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ +/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ @@ -67,21 +68,29 @@ extern uint64_t _sbss_end __attribute__ ((section (".sbss"))); // false in future. void __eabi() { - // Initialise sbss section - uint64_t *startAddr = &_sbss_start; - while ( startAddr != &_sbss_end ) - { - *startAddr = 0; - startAddr++; - } - - // Call global constructors - void(**ctors)() = &ctor_start_address; - while( ctors != &ctor_end_address) + do { - (*ctors)(); - ctors++; - } + SBE_GLOBAL->isHreset = SBE::isHreset(); + if (SBE_GLOBAL->isHreset) + { + // skip constructors + break; + } + // Initialise sbss section + uint64_t *startAddr = &_sbss_start; + while ( startAddr != &_sbss_end ) + { + *startAddr = 0; + startAddr++; + } + // Call global constructors + void(**ctors)() = &ctor_start_address; + while( ctors != &ctor_end_address) + { + (*ctors)(); + ctors++; + } + } while (false); } } // end extern "C" @@ -289,47 +298,50 @@ uint32_t main(int argc, char **argv) break; } - // TODO via RTC 126146. - // Check if we should call plat_TargetsInit in some other thread. - // We may want to keep only PK init in main and can move - // plat init to some other thread. Only if this is required by more - // than one thread and there can be some race condition, we will - // keep it here before starting other threads. - fapi2::ReturnCode fapiRc = fapi2::plat_TargetsInit(); - if( fapiRc != fapi2::FAPI2_RC_SUCCESS ) - { - SBE_ERROR(SBE_FUNC"plat_TargetsInit failed"); - (void)SbeRegAccess::theSbeRegAccess(). - stateTransition(SBE_FAILURE_EVENT); - // Hard Reset SBE to recover - break; - } - - fapiRc = fapi2::plat_AttrInit(); - if(fapiRc != fapi2::FAPI2_RC_SUCCESS) + if (!SBE_GLOBAL->isHreset) { - SBE_ERROR(SBE_FUNC"plat_AttrInit failed"); - (void)SbeRegAccess::theSbeRegAccess(). - stateTransition(SBE_FAILURE_EVENT); - // Hard Reset SBE to recover - 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().stateTransition( - SBE_FAILURE_EVENT); - // Hard Reset SBE to recover - break; + // TODO via RTC 126146. + // Check if we should call plat_TargetsInit in some other thread. + // We may want to keep only PK init in main and can move + // plat init to some other thread. Only if this is required by more + // than one thread and there can be some race condition, we will + // keep it here before starting other threads. + fapi2::ReturnCode fapiRc = fapi2::plat_TargetsInit(); + if( fapiRc != fapi2::FAPI2_RC_SUCCESS ) + { + SBE_ERROR(SBE_FUNC"plat_TargetsInit failed"); + (void)SbeRegAccess::theSbeRegAccess(). + stateTransition(SBE_FAILURE_EVENT); + // Hard Reset SBE to recover + break; + } + + fapiRc = fapi2::plat_AttrInit(); + if(fapiRc != fapi2::FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC"plat_AttrInit failed"); + (void)SbeRegAccess::theSbeRegAccess(). + stateTransition(SBE_FAILURE_EVENT); + // Hard Reset SBE to recover + 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().stateTransition( + SBE_FAILURE_EVENT); + // Hard Reset SBE to recover + break; + } + if(SBE::isSimicsRunning()) + { + SBE_INFO("SBE is running on simics"); + } } - if(SBE::isSimicsRunning()) - { - SBE_INFO("SBE is running on simics"); - } // Start running the highest priority thread. // This function never returns pk_start_threads(); diff --git a/src/sbefw/core/sbeutil.C b/src/sbefw/core/sbeutil.C index bc53e7a4..c0b291e2 100644 --- a/src/sbefw/core/sbeutil.C +++ b/src/sbefw/core/sbeutil.C @@ -5,7 +5,8 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ +/* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ @@ -25,8 +26,17 @@ #include "fapi2.H" #include "sbetrace.H" #include "sbeglobals.H" + +#include "plat_hw_access.H" +#include "assert.h" + // Nest frequency array #include "p9_frequency_buckets.H" + +#define SBE_PERV_SB_CS_SCOM 0x00050008 +#define SBCS_VEC_1_CLEAR(sbcsreg) (sbcsreg & ~0x0004000000000000ull) +#define SBCS_VEC_1_GET(sbcsreg) (sbcsreg & 0x0004000000000000ull) + namespace SBE { bool isSimics() __attribute__((alias("__isSimicsRunning"))); @@ -58,5 +68,55 @@ namespace SBE pk_timebase_freq_set(SBE_GLOBAL->sbefreq); #undef SBE_FUNC } + + bool isHreset(void) + { + #define SBE_FUNC "IS_HRESET" + using namespace fapi2; + bool isHreset = false; + uint64_t sbcsreg = 0; + ReturnCode rc = FAPI2_RC_SUCCESS; + plat_target_handle_t tgtHndl; + rc = getscom_abs_wrap (&tgtHndl, + SBE_PERV_SB_CS_SCOM, + &sbcsreg); + if (rc != FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC" could not read sbcs register, halting."); + pk_halt(); + } + isHreset = SBCS_VEC_1_GET(sbcsreg); + SBE_INFO(SBE_FUNC" [%d]", isHreset); + return (isHreset); + #undef SBE_FUNC + } + + void clearHresetBit(void) + { + #define SBE_FUNC "CLEAR_HRESET_BIT" + using namespace fapi2; + // clear the hreset bit + uint64_t sbcsreg = 0; + plat_target_handle_t tgtHndl; + ReturnCode rc = getscom_abs_wrap (&tgtHndl, + SBE_PERV_SB_CS_SCOM, + &sbcsreg); + if (rc != FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC" could not read sbcs register, halting."); + pk_halt(); + } + + sbcsreg = SBCS_VEC_1_CLEAR(sbcsreg); + rc = putscom_abs_wrap (&tgtHndl, + SBE_PERV_SB_CS_SCOM, + sbcsreg); + if (rc != FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC" could not write sbcs register, halting."); + pk_halt(); + } + #undef SBE_FUNC + } } diff --git a/src/sbefw/core/sbeutil.H b/src/sbefw/core/sbeutil.H index 73850ff7..e32a8189 100644 --- a/src/sbefw/core/sbeutil.H +++ b/src/sbefw/core/sbeutil.H @@ -203,5 +203,17 @@ namespace SBE */ void updatePkFreq(); + /* @brief - Check if the boot is on HRESET of SBE + * + * @return - True if HRESET, false otherwise + */ + bool isHreset(void); + + /* @brief - Clear HRESET BIT + * + * @return - void + */ + void clearHresetBit(void); + } // namespace SBE #endif //SBE_UTIL_H -- cgit v1.2.1