diff options
author | Prem Shanker Jha <premjha2@in.ibm.com> | 2018-05-15 10:39:08 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-09-14 16:13:01 -0500 |
commit | 09ab06ca2d5640622c0d39ee34520b10db3a9072 (patch) | |
tree | 164e2a7910fb443994a1c3a523b927a88a4860a3 /src/import | |
parent | 7bb1f127506943f90e153c7013fa026b42959069 (diff) | |
download | talos-hostboot-09ab06ca2d5640622c0d39ee34520b10db3a9072.tar.gz talos-hostboot-09ab06ca2d5640622c0d39ee34520b10db3a9072.zip |
UV Support : Augmented STOP API and self restore for enabling ultravisor.
HW-Image-Coreq: yes
HW-Image-Prereq: Ia9ae0d284398af375f1562efff152a6a12a6eb9a
Change-Id: I1f7ca865640dfc0a08aef783fd3595d2f249a672
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/58843
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com>
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
Reviewed-by: AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/59321
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import')
12 files changed, 1155 insertions, 142 deletions
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H b/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H index a3e66b4f1..9cbb6ff19 100644 --- a/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H +++ b/src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H @@ -311,6 +311,7 @@ HCD_CONST(CPMR_ATTN_WORD1_BYTE, 0x04) HCD_CONST(CPMR_MAGIC_NUMBER_BYTE, 0x08) HCD_CONST(CPMR_BUILD_DATE_BYTE, 0x10) HCD_CONST(CPMR_BUILD_VER_BYTE, 0x14) +HCD_CONST(CPMR_URMOR_FIX_BYTE, 0x1E) HCD_CONST(CPMR_CME_HCODE_OFFSET_BYTE, 0x20) HCD_CONST(CPMR_CME_HCODE_LENGTH_BYTE, 0x24) HCD_CONST(CPMR_CORE_COMMON_RING_OFFSET_BYTE, 0x28) @@ -329,21 +330,30 @@ HCD_CONST(CPMR_MAX_SCOM_REST_PER_CORE_BYTE, 0x50) HCD_CONST(SELF_RESTORE_CPMR_OFFSET, CPMR_HEADER_SIZE) HCD_CONST(SELF_RESTORE_INT_SIZE, (8 * ONE_KB)) -HCD_CONST(THREAD_LAUNCHER_SIZE, 256) +HCD_CONST(THREAD_LAUNCHER_SIZE, 1024) HCD_CONST(SELF_RESTORE_CODE_SIZE, (SELF_RESTORE_INT_SIZE + THREAD_LAUNCHER_SIZE)) -HCD_CONST(CORE_RESTORE_THREAD_AREA_SIZE, (ONE_KB)) -HCD_CONST(CORE_RESTORE_CORE_AREA_SIZE, (ONE_KB)) +HCD_CONST(CORE_RESTORE_THREAD_AREA_SIZE, HALF_KB) +HCD_CONST(SELF_SAVE_THREAD_AREA_SIZE, 256) +HCD_CONST(CORE_RESTORE_CORE_AREA_SIZE, HALF_KB) +HCD_CONST(CORE_SAVE_CORE_AREA_SIZE, HALF_KB) + +//self save-restore size per thread HCD_CONST(CORE_RESTORE_SIZE_PER_THREAD, - (CORE_RESTORE_THREAD_AREA_SIZE + CORE_RESTORE_CORE_AREA_SIZE)) + (CORE_RESTORE_THREAD_AREA_SIZE + SELF_SAVE_THREAD_AREA_SIZE)) +//self save-restore size per core +HCD_CONST(SELF_RESTORE_SIZE_PER_CORE, + (CORE_RESTORE_SIZE_PER_THREAD + CORE_RESTORE_CORE_AREA_SIZE + + CORE_SAVE_CORE_AREA_SIZE)) +//size of self restore region for entire chip HCD_CONST(SELF_RESTORE_CORE_REGS_SIZE, - (CORE_RESTORE_SIZE_PER_THREAD* - MAX_THREADS_PER_CORE* MAX_CORES_PER_CHIP)) - + (SELF_RESTORE_SIZE_PER_CORE* MAX_CORES_PER_CHIP)) +//total self restore region including thread launcher code size HCD_CONST(SELF_RESTORE_SIZE_TOTAL, (SELF_RESTORE_CODE_SIZE + SELF_RESTORE_CORE_REGS_SIZE)) +HCD_CONST( EC_LEVEL_URMOR_FIX, 0x23 ) /// Core Scom diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H b/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H index 0e3d59a29..e3d3e388e 100644 --- a/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H +++ b/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H @@ -135,7 +135,8 @@ HCD_HDR_ATTN ( attnOpcodes, 2); HCD_HDR_UINT64( magic_number, CPMR_MAGIC_NUMBER); HCD_HDR_UINT32( cpmrbuildDate, 0); HCD_HDR_UINT32( cpmrVersion, 0); -HCD_HDR_UINT8_VEC (cpmrReserveFlags, 7, 0); +HCD_HDR_UINT8_VEC (cpmrReserveFlags, 6, 0); +HCD_HDR_UINT8 ( urmorFix, 0); HCD_HDR_UINT8 ( fusedModeStatus, 0); HCD_HDR_UINT32( cmeImgOffset, 0); HCD_HDR_UINT32( cmeImgLength, 0); diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C b/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C index fa0340fac..057896741 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C +++ b/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C @@ -141,6 +141,17 @@ enum }; /** + * @brief models a CPU register restoration area in STOP section of homer image. + */ +typedef struct +{ + uint8_t iv_threadRestoreArea[MAX_THREADS_PER_CORE][CORE_RESTORE_THREAD_AREA_SIZE]; + uint8_t iv_threadSaveArea[MAX_THREADS_PER_CORE][SELF_SAVE_THREAD_AREA_SIZE]; + uint8_t iv_coreRestoreArea[CORE_RESTORE_CORE_AREA_SIZE]; + uint8_t iv_coreSaveArea[CORE_SAVE_CORE_AREA_SIZE]; +} SprRestoreRegion_t; + +/** * @brief struct used to manipulate scan ring in HOMER. */ struct RingBufData @@ -677,6 +688,101 @@ fapi_try_exit: //------------------------------------------------------------------------------ +fapi2::ReturnCode initSelfRestoreRegion( Homerlayout_t* i_pChipHomer ) +{ + FAPI_INF(">> initSelfRestoreRegion"); + uint32_t l_fillBlr = SWIZZLE_4_BYTE(SELF_RESTORE_BLR_INST); + uint32_t l_fillAttn = SWIZZLE_4_BYTE(CORE_RESTORE_PAD_OPCODE); + uint32_t l_byteCnt = 0; + uint32_t * l_pSelfRestLoc = + (uint32_t *)&i_pChipHomer->cpmrRegion.selfRestoreRegion.coreSelfRestore[0]; + + SprRestoreRegion_t * l_pSaveRestore = + (SprRestoreRegion_t *)&i_pChipHomer->cpmrRegion.selfRestoreRegion.coreSelfRestore[0]; + + while( l_byteCnt < SELF_RESTORE_CORE_REGS_SIZE ) + { + memcpy( l_pSelfRestLoc, &l_fillAttn, sizeof( uint32_t ) ); + l_byteCnt += 4; + l_pSelfRestLoc++; + } + + //Initialize Core SPR and Thread SPR start boundary with BLR instruction. + + FAPI_INF( " Size of SprRestoreRegion_t 0x%08x", sizeof( SprRestoreRegion_t ) ); + for( uint8_t l_coreId = 0; l_coreId < MAX_CORES_PER_CHIP; l_coreId++ ) + { + memcpy( (uint32_t *)&l_pSaveRestore->iv_coreRestoreArea[0], &l_fillBlr, sizeof(uint32_t) ); + + for( uint8_t l_threadId = 0; l_threadId < MAX_THREADS_PER_CORE; l_threadId++ ) + { + memcpy( &l_pSaveRestore->iv_threadRestoreArea[l_threadId][0], + &l_fillBlr, + sizeof(uint32_t) ); + + if( 0 == l_threadId ) + { + memcpy( &l_pSaveRestore->iv_coreRestoreArea[0], + &l_fillBlr, + sizeof(uint32_t) ); + } + } + + l_pSaveRestore++; + } + + FAPI_INF("<< initSelfRestoreRegion"); + + return fapi2::FAPI2_RC_SUCCESS; +} + +//------------------------------------------------------------------------------ + +fapi2::ReturnCode initSelfSaveRestoreEntries( Homerlayout_t* i_pChipHomer, + P9FuncModel & i_procFuncModel ) +{ + FAPI_DBG(">> initSelfSaveRestoreEntries" ); + StopReturnCode_t l_retCode; + uint32_t l_corePos = 0; + + for( l_corePos = 0; l_corePos < MAX_CORES_PER_CHIP; l_corePos++ ) + { + if( !i_procFuncModel.isCoreFunctional( l_corePos ) ) + { + continue; + } + + FAPI_INF( "Core Pos 0x%02d", l_corePos ); + l_retCode = p9_stop_init_cpureg( (void *)i_pChipHomer, l_corePos ); + + FAPI_ASSERT( ( STOP_SAVE_SUCCESS == l_retCode ), + fapi2::SELF_RESTORE_INIT_FAILED() + .set_HOMER_PTR( i_pChipHomer ) + .set_CORE_POS( l_corePos ) + .set_FAILURE_CODE( l_retCode ) + .set_EC_LEVEL( i_procFuncModel.getChipLevel() ) + .set_CHIP_TYPE( i_procFuncModel.getChipName() ), + "Failed To Initialize The Self-Restore Region 0x%08x", l_retCode ); + + l_retCode = p9_stop_init_self_save( (void *)i_pChipHomer, l_corePos ); + + FAPI_ASSERT( ( STOP_SAVE_SUCCESS == l_retCode ), + fapi2::SELF_SAVE_INIT_FAILED() + .set_HOMER_PTR( i_pChipHomer ) + .set_CORE_POS( l_corePos ) + .set_FAILURE_CODE( l_retCode ) + .set_EC_LEVEL( i_procFuncModel.getChipLevel() ) + .set_CHIP_TYPE( i_procFuncModel.getChipName() ), + "Failed To Initialize The Self-Save Region 0x%08x", (uint32_t)l_retCode ); + } + + fapi_try_exit: + FAPI_DBG("<< initSelfSaveRestoreEntries" ); + return fapi2::current_err; +} + +//------------------------------------------------------------------------------ + uint32_t getXipImageSectn( uint8_t * i_srcPtr, uint8_t i_secId, uint8_t i_ecLevel, P9XipSection& o_ppeSection ) { @@ -1277,8 +1383,9 @@ void updateCpmrCmeRegion( Homerlayout_t* i_pChipHomer ) * @brief updates various CPMR fields which are associated with self restore code. * @param[in] i_pChipHomer points to start of P9 HOMER. * @param[in] i_fuseState core fuse status + * @param[in] i_urmorFix true if URMOR correction is needed else false. */ -void updateCpmrHeaderSR( Homerlayout_t* i_pChipHomer, uint8_t i_fusedState ) +void updateCpmrHeaderSR( Homerlayout_t* i_pChipHomer, uint8_t i_fusedState, uint8_t i_urmorFix ) { FAPI_INF(">> updateCpmrHeaderSR"); cpmrHeader_t* pCpmrHdr = @@ -1290,6 +1397,11 @@ void updateCpmrHeaderSR( Homerlayout_t* i_pChipHomer, uint8_t i_fusedState ) uint32_t(NONFUSED_CORE_MODE); pCmeHdr->g_cme_mode_flags = SWIZZLE_4_BYTE(i_fusedState ? 1 : 0); + if( i_urmorFix ) + { + pCpmrHdr->urmorFix = 0x01; + } + FAPI_INF("CPMR SR"); FAPI_INF("Fuse Mode : 0x%08X", pCpmrHdr->fusedModeStatus ); FAPI_INF("CME Image Flag : 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_mode_flags)); @@ -1297,6 +1409,7 @@ void updateCpmrHeaderSR( Homerlayout_t* i_pChipHomer, uint8_t i_fusedState ) SWIZZLE_4_BYTE(pCpmrHdr->cmeImgOffset) * 32, SWIZZLE_4_BYTE(pCpmrHdr->cmeImgOffset)); FAPI_DBG("CME Image Size : 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->cmeImgLength)); + FAPI_DBG("URMOR WorkAround Needed : %s", pCpmrHdr->urmorFix ? "Yes" : "No" ); FAPI_INF("<< updateCpmrHeaderSR"); } @@ -1546,10 +1659,7 @@ fapi2::ReturnCode buildCoreRestoreImage( void* const i_pImageIn, fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; //Let us find XIP Header for Core Self Restore Image P9XipSection ppeSection; - uint8_t* pSelfRestImg = NULL; - uint32_t wordCnt = 0; - uint32_t l_fillBlr = SWIZZLE_4_BYTE(SELF_RESTORE_BLR_INST); - uint32_t l_fillAttn = SWIZZLE_4_BYTE(CORE_RESTORE_PAD_OPCODE); + uint8_t* pSelfRestImg = NULL; rcTemp = p9_xip_get_section( i_pImageIn, P9_XIP_SECTION_HW_RESTORE, &ppeSection ); @@ -1609,32 +1719,15 @@ fapi2::ReturnCode buildCoreRestoreImage( void* const i_pImageIn, //Padding SPR restore area with ATTN Opcode FAPI_INF("Padding CPMR Core Restore portion with Attn opcodes"); - while( wordCnt < SELF_RESTORE_CORE_REGS_SIZE ) - { - uint32_t l_fillPattern = 0; + FAPI_TRY( initSelfRestoreRegion( i_pChipHomer ), + "Failed To Initialize The Self-Restore Region" ); - if( ( 0 == wordCnt ) || ( 0 == ( wordCnt % CORE_RESTORE_SIZE_PER_THREAD ) )) - { - l_fillPattern = l_fillBlr; - } - else - { - l_fillPattern = l_fillAttn; - } + FAPI_TRY( initSelfSaveRestoreEntries( i_pChipHomer, i_procFuncModel ), + "Failed To Initialize The Self-Save Region" ); - //Lab Need: First instruction in thread SPR restore region should be a blr instruction. - //This helps in a specific lab scenario. If Self Restore region is populated only for - //select number of threads, other threads will not hit attention during the self restore - //sequence. Instead, execution will hit a blr and control should return to thread launcher - //region. - - memcpy( (uint32_t*)&i_pChipHomer->cpmrRegion.selfRestoreRegion.coreSelfRestore[wordCnt], - &l_fillPattern, - sizeof( uint32_t )); - wordCnt += 4; - } } - updateCpmrHeaderSR( i_pChipHomer, i_fusedState ); + + updateCpmrHeaderSR( i_pChipHomer, i_fusedState, i_procFuncModel.hasUrmorBug() ); if( i_imgType.coreScomBuild ) { @@ -4378,6 +4471,145 @@ void customizeMagicWord( Homerlayout_t* i_pHomer ) //--------------------------------------------------------------------------- +/** + * @brief returns PIR value for a given core and thread. + * @param[in] i_corePos core position + * @param[in] i_threadPos thread position + * @param[in] i_fuseMode fuse status of core. + * @return PIR value + */ +uint64_t getPirValue( uint32_t i_corePos, uint32_t i_threadPos, uint8_t i_fuseMode ) +{ + uint64_t l_pir = 0; + uint8_t l_tempPir = 0; + l_tempPir = 0; + l_tempPir = (i_corePos / MAX_CORES_PER_QUAD ) << MAX_CORES_PER_QUAD; + i_corePos = i_corePos % MAX_CORES_PER_QUAD; + + switch( i_corePos ) + { + case 0: + break; + + case 1: + if( i_fuseMode ) + { + l_tempPir |= FUSED_CORE_BIT3; + } + else + { + l_tempPir |= FUSED_CORE_BIT1; + } + + break; + + case 2: + l_tempPir |= FUSED_CORE_BIT0; + break; + + case 3: + if( i_fuseMode ) + { + l_tempPir |= ( FUSED_CORE_BIT0 | FUSED_CORE_BIT3 ); + } + else + { + l_tempPir |= (FUSED_CORE_BIT0 | FUSED_CORE_BIT1 ); + } + + break; + } + + switch( i_threadPos ) + { + case 0: + break; + + case 1: + if( i_fuseMode ) + { + l_tempPir |= FUSED_CORE_BIT2; + } + else + { + l_tempPir |= FUSED_CORE_BIT3; + } + + break; + + case 2: + if( i_fuseMode ) + { + l_tempPir |= FUSED_CORE_BIT1; + } + else + { + l_tempPir |= FUSED_CORE_BIT2; + } + + break; + + case 3: + if( i_fuseMode ) + { + l_tempPir |= ( FUSED_CORE_BIT1 | FUSED_CORE_BIT2 ); + } + else + { + l_tempPir |= ( FUSED_CORE_BIT2 | FUSED_CORE_BIT3); + } + + break; + } + + l_pir = l_tempPir; + + return l_pir; +} + +//--------------------------------------------------------------------------- + +/** + * @brief creates URMOR restore value in HOMER. + * @param[in] i_pHomerImage points to P9 chip's HOMER. + * @param[in] i_fuseMode fuse status of core + * @param[in] i_chipFuncModel describes config details of the P9 chip + * @return PIR value + */ +fapi2::ReturnCode addUrmorRestore( void * const i_pHomerImage, + uint8_t i_fuseMode, + P9FuncModel & i_chipFuncModel ) +{ + #ifdef __URMOR_TEST + + // to verify UV and HV exit in Cronus environment. + uint64_t l_pir = 0; + StopReturnCode_t l_rc; + + for( uint8_t l_corePos = 0; l_corePos < MAX_CORES_PER_CHIP; l_corePos++ ) + { + if( i_chipFuncModel.isCoreFunctional( l_corePos ) ) + { + l_pir = getPirValue( l_corePos, 0, i_fuseMode ); + l_rc = stopImageSection::p9_stop_save_cpureg( i_pHomerImage, + P9_STOP_SPR_URMOR, + 0x00, + l_pir ); + FAPI_ASSERT( ( !l_rc ), + fapi2::URMOR_RESTORE_ENTRY_FAILED() + .set_PIR( l_pir ) + .set_STOP_API_RC( l_rc ), + "Failed To Create URMOR Restore Entry" ); + } + } + +fapi_try_exit: + #endif + return fapi2::current_err; +} + +//--------------------------------------------------------------------------- + fapi2::ReturnCode p9_hcode_image_build( CONST_FAPI2_PROC& i_procTgt, void* const i_pImageIn, void* i_pHomerImage, @@ -4602,6 +4834,9 @@ fapi2::ReturnCode p9_hcode_image_build( CONST_FAPI2_PROC& i_procTgt, //customize magic word based on endianess customizeMagicWord( pChipHomer ); + FAPI_TRY( addUrmorRestore( i_pHomerImage, fuseModeState, l_chipFuncModel ), + "Failed to create URMOR restore entry" ); + fapi_try_exit: FAPI_IMP("<< p9_hcode_image_build" ); return fapi2::current_err; diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.C b/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.C index 4431c8e01..67b1d1d8c 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.C +++ b/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -776,7 +776,8 @@ P9FuncModel::P9FuncModel( ): iv_funcExes(0), iv_funcQuads(0), iv_ddLevel(0), - iv_chipName(0) + iv_chipName(0), + iv_urmorBug(0) { } //------------------------------------------------------------------------- @@ -801,11 +802,12 @@ P9FuncModel::P9FuncModel( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP >& i_ FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, i_procTgt, iv_ddLevel); FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_procTgt, iv_chipName); + FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW403111, i_procTgt, iv_urmorBug); FAPI_DBG("functional core : 0x%08x Ex : 0x%08x quad 0x%08x" - "EC : 0x%02x ChipName : 0x%02x", + "EC : 0x%02x ChipName : 0x%02x URMOR Bug 0x%02x", iv_funcCores, iv_funcExes, iv_funcQuads, iv_ddLevel, - iv_chipName ); + iv_chipName, iv_urmorBug ); } //--------------------------------------------------------------------------- @@ -842,8 +844,18 @@ uint8_t P9FuncModel::getChipLevel() const return iv_ddLevel; } +//------------------------------------------------------------------------- uint8_t P9FuncModel::getChipName() const { return iv_chipName; } + +//------------------------------------------------------------------------- +uint8_t P9FuncModel::hasUrmorBug() const +{ + return iv_urmorBug; +} + +//------------------------------------------------------------------------- + } diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.H b/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.H index d6e079efd..074b9f9f9 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.H +++ b/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -321,6 +321,11 @@ class P9FuncModel uint8_t getChipName() const; /** + * returns true if URMOR has a hw bug else false. + */ + uint8_t hasUrmorBug() const; + + /** * @brief constructor */ P9FuncModel( ); @@ -332,8 +337,9 @@ class P9FuncModel uint16_t iv_funcExes; uint8_t iv_funcQuads; uint8_t iv_ddLevel; - uint8_t iv_chipName; - uint8_t iv_reserve[3]; + uint8_t iv_chipName; + uint8_t iv_urmorBug; + uint8_t iv_reserve[2]; }; }// namesapce p9_hcodeImageBuild ends diff --git a/src/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H b/src/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H index e5689ae82..dd4358a82 100755 --- a/src/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H +++ b/src/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ +/* Contributors Listed Below - COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -50,21 +50,32 @@ namespace stopImageSection */ enum { - ORI_OPCODE = 24, - RFI_OPCODE = 19, - RFI_CONST = 50, - ORIS_OPCODE = 25, - OPCODE_31 = 31, - XOR_CONST = 316, - RLDICR_OPCODE = 30, - RLDICR_CONST = 1, - MTSPR_CONST1 = 467, - MTMSRD_CONST1 = 178, - MR_R0_TO_R10 = 0x7c0a0378, //mr r10, r0 - MR_R0_TO_R21 = 0x7c150378, //mr r21, r0 - BLR_INST = 0x4e800020, - MTSPR_BASE_OPCODE = 0x7c0003a6, - ATTN_OPCODE = 0x00000200, + ORI_OPCODE = 24, + RFI_OPCODE = 19, + RFI_CONST = 50, + MFMSR_CONST = 83, + ORIS_OPCODE = 25, + OPCODE_31 = 31, + XOR_CONST = 316, + RLDICR_OPCODE = 30, + RLDICR_CONST = 1, + MTSPR_CONST1 = 467, + MTMSRD_CONST1 = 178, + MR_R0_TO_R10 = 0x7c0a0378, //mr r10, r0 + MR_R0_TO_R21 = 0x7c150378, //mr r21, r0 + MR_R0_TO_R9 = 0x7c090378, //mr r9, r0 + URMOR_CORRECTION = 0x7d397ba6, + MFSPR_CONST = 339, + BLR_INST = 0x4e800020, + MTSPR_BASE_OPCODE = 0x7c0003a6, + ATTN_OPCODE = 0x00000200, + OPCODE_18 = 18, + SELF_SAVE_FUNC_ADD = 0x2300, + SELF_SAVE_OFFSET = 0x180, + SKIP_SPR_REST_INST = 0x4800001c, //b . +0x01c + MFLR_R30 = 0x7fc802a6, + SKIP_SPR_SELF_SAVE = 0x3bff0020, //addi r31 r31, 0x20 + MTLR_INST = 0x7fc803a6 //mtlr r30 }; #ifdef __cplusplus diff --git a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C index 03d9ff99d..0cc6aa0c9 100755 --- a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C +++ b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C @@ -37,16 +37,12 @@ #ifdef PPC_HYP #include <HvPlicModule.H> #endif + #include "p9_stop_api.H" #include "p9_cpu_reg_restore_instruction.H" #include "p9_stop_data_struct.H" #include <string.h> #include "p9_stop_util.H" - -#ifdef __FAPI_2_ - #include <fapi2.H> -#endif - #ifdef __cplusplus extern "C" { @@ -58,25 +54,81 @@ namespace stopImageSection const StopSprReg_t g_sprRegister[] = { - { P9_STOP_SPR_HSPRG0, true }, - { P9_STOP_SPR_HRMOR, false }, - { P9_STOP_SPR_LPCR, true }, - { P9_STOP_SPR_HMEER, false }, - { P9_STOP_SPR_LDBAR, true }, - { P9_STOP_SPR_PSSCR, true }, - { P9_STOP_SPR_PMCR, false }, - { P9_STOP_SPR_HID, false }, - { P9_STOP_SPR_MSR, true }, - { P9_STOP_SPR_DAWR, true }, + { P9_STOP_SPR_CIABR, true, 0 }, + { P9_STOP_SPR_DAWR, true, 1 }, + { P9_STOP_SPR_DAWRX, true, 2 }, + { P9_STOP_SPR_HSPRG0, true, 3 }, + { P9_STOP_SPR_LDBAR, true, 4, }, + { P9_STOP_SPR_LPCR, true, 5 }, + { P9_STOP_SPR_PSSCR, true, 6 }, + { P9_STOP_SPR_MSR, true, 7 }, + { P9_STOP_SPR_HRMOR, false, 20 }, + { P9_STOP_SPR_HID, false, 21 }, + { P9_STOP_SPR_HMEER, false, 22 }, + { P9_STOP_SPR_PMCR, false, 23 }, + { P9_STOP_SPR_PTCR, false, 24 }, + { P9_STOP_SPR_SMFCTRL, true, 28 }, + { P9_STOP_SPR_USPRG0, true, 29 }, + { P9_STOP_SPR_USPRG1, true, 30 }, + { P9_STOP_SPR_URMOR, false, 31 }, }; -const uint32_t MAX_SPR_SUPPORTED = 10; +const uint32_t MAX_SPR_SUPPORTED = 17; const uint32_t LEGACY_CORE_SCOM_SUPPORTED = 15; const uint32_t LEGACY_QUAD_SCOM_SUPPORTED = 63; //----------------------------------------------------------------------------- /** + * @brief vaildated input arguments passed to p9_stop_save_cpureg_control. + * @param[in] i_pImage point to start of HOMER + * @param[in] i_coreId id of the core + * @param[in] i_threadId id of the thread + * @param[in] i_saveMaskVector SPR save bit mask vector + * @return STOP_SAVE_SUCCESS if function succeeds, error code otherwise. + */ +STATIC StopReturnCode_t validateArgumentSaveRegMask( void* const i_pImage, + uint32_t const i_coreId, + uint32_t const i_threadId, + uint64_t i_saveMaskVector ) +{ + StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; + + do + { + if( !i_pImage ) + { + l_rc = STOP_SAVE_ARG_INVALID_IMG; + break; + } + + if( i_coreId > MAX_CORE_ID_SUPPORTED ) + { + l_rc = STOP_SAVE_ARG_INVALID_CORE; + break; + } + + if( i_threadId > MAX_THREAD_ID_SUPPORTED ) + { + l_rc = STOP_SAVE_ARG_INVALID_THREAD; + break; + } + + if( ( 0 == i_saveMaskVector ) || ( BAD_SAVE_MASK & i_saveMaskVector ) ) + { + l_rc = STOP_SAVE_ARG_INVALID_REG; + break; + } + + } + while(0); + + return l_rc; +} + +//----------------------------------------------------------------------------- + +/** * @brief validates input arguments provided by STOP API caller. * @param[in] i_pImage pointer to beginning of chip's HOMER image. * @param[in] i_regId SPR register id @@ -141,11 +193,11 @@ STATIC StopReturnCode_t validateSprImageInputs( void* const i_pImage, for( index = 0; index < MAX_SPR_SUPPORTED; ++index ) { - if( i_regId == (CpuReg_t )g_sprRegister[index].sprId ) + if( i_regId == (CpuReg_t )g_sprRegister[index].iv_sprId ) { // given register is in the list of register supported sprSupported = true; - *i_pThreadLevelReg = g_sprRegister[index].isThreadScope; + *i_pThreadLevelReg = g_sprRegister[index].iv_isThreadScope; *i_pThreadId = *i_pThreadLevelReg ? *i_pThreadId : 0; break; } @@ -272,6 +324,20 @@ STATIC uint32_t getMtsprInstruction( const uint16_t i_Rs, const uint16_t i_Spr ) //----------------------------------------------------------------------------- /** + * @brief generates instruction for mfmsr + * @param[in] i_Rt target register for SPR content. + * @return returns 32 bit number representing mfmsr instruction. + */ +STATIC uint32_t getMfmsrInstruction( const uint16_t i_Rt ) +{ + uint32_t mfmsrInstOpcode = ((OPCODE_31 << 26) | (i_Rt << 21) | (MFMSR_CONST)); + + return SWIZZLE_4_BYTE(mfmsrInstOpcode); +} + +//----------------------------------------------------------------------------- + +/** * @brief generates rldicr instruction. * @param[in] i_Rs source register number * @param[in] i_Ra destination register number @@ -283,7 +349,6 @@ STATIC uint32_t getRldicrInstruction( const uint16_t i_Ra, const uint16_t i_Rs, const uint16_t i_sh, uint16_t i_me ) { uint32_t rldicrInstOpcode = 0; - rldicrInstOpcode = 0; rldicrInstOpcode = ((RLDICR_OPCODE << 26 ) | ( i_Rs << 21 ) | ( i_Ra << 16 )); rldicrInstOpcode |= ( ( i_sh & 0x001F ) << 11 ) | (RLDICR_CONST << 2 ); rldicrInstOpcode |= (( i_sh & 0x0020 ) >> 4); @@ -294,6 +359,24 @@ STATIC uint32_t getRldicrInstruction( const uint16_t i_Ra, const uint16_t i_Rs, //----------------------------------------------------------------------------- +STATIC uint32_t getMfsprInstruction( const uint16_t i_Rt, const uint16_t i_sprNum ) +{ + uint32_t mfsprInstOpcode = 0; + mfsprInstOpcode = (( OPCODE_31 << 26 ) | ( i_Rt << 21 ) | ( i_sprNum << 11 ) | ( MFSPR_CONST << 1 )); + return SWIZZLE_4_BYTE(mfsprInstOpcode); +} + +//----------------------------------------------------------------------------- + +STATIC uint32_t getBranchLinkRegInstruction( ) +{ + uint32_t branchConstInstOpcode = 0; + branchConstInstOpcode = (( OPCODE_18 << 26 ) | ( SELF_SAVE_FUNC_ADD ) | 0x03 ); + + return SWIZZLE_4_BYTE(branchConstInstOpcode); +} +//----------------------------------------------------------------------------- + /** * @brief looks up entry for given SPR in given thread/core section. * @param[in] i_pThreadSectLoc start of given thread section or core section. @@ -311,16 +394,18 @@ STATIC StopReturnCode_t lookUpSprInImage( uint32_t* i_pThreadSectLoc, void** io_pSprEntryLoc ) { StopReturnCode_t l_rc = STOP_SAVE_FAIL; - uint32_t bctr_inst = SWIZZLE_4_BYTE(BLR_INST); uint32_t temp = i_isThreadReg ? (uint32_t)(CORE_RESTORE_THREAD_AREA_SIZE) : (uint32_t)(CORE_RESTORE_CORE_AREA_SIZE); + uint32_t* i_threadSectEnd = i_pThreadSectLoc + ( temp >> 2 ); + uint32_t bctr_inst = SWIZZLE_4_BYTE(BLR_INST); *io_pSprEntryLoc = NULL; do { if( !i_pThreadSectLoc ) { + MY_ERR( "Bad SPR Start Location" ); break; } @@ -333,6 +418,7 @@ STATIC StopReturnCode_t lookUpSprInImage( uint32_t* i_pThreadSectLoc, if( ( temp == i_lookUpKey ) || ( temp == bctr_inst ) ) { + MY_INF( "Found 0x%08x", temp ); *io_pSprEntryLoc = i_pThreadSectLoc; l_rc = STOP_SAVE_SUCCESS; break; @@ -340,7 +426,6 @@ STATIC StopReturnCode_t lookUpSprInImage( uint32_t* i_pThreadSectLoc, i_pThreadSectLoc = i_pThreadSectLoc + SIZE_PER_SPR_RESTORE_INST; } - } while(0); @@ -358,7 +443,9 @@ STATIC StopReturnCode_t lookUpSprInImage( uint32_t* i_pThreadSectLoc, */ STATIC StopReturnCode_t updateSprEntryInImage( uint32_t* i_pSprEntryLocation, const CpuReg_t i_regId, - const uint64_t i_regData ) + const uint64_t i_regData, + const SprEntryUpdateMode i_mode + ) { StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; uint32_t tempInst = 0; @@ -387,9 +474,19 @@ STATIC StopReturnCode_t updateSprEntryInImage( uint32_t* i_pSprEntryLocation, *i_pSprEntryLocation = tempInst; i_pSprEntryLocation += SIZE_PER_SPR_RESTORE_INST; - //clear R0 i.e. "xor ra, rs, rb" - tempInst = getXorInstruction( regRs, regRs, regRs ); - *i_pSprEntryLocation = tempInst; + if( INIT_SPR_REGION == i_mode ) + { + //adding inst 'b . + 0x1C' + *i_pSprEntryLocation = SWIZZLE_4_BYTE(SKIP_SPR_REST_INST); + } + else + { + //clear R0 i.e. "xor ra, rs, rb" + tempInst = getXorInstruction( regRs, regRs, regRs ); + *i_pSprEntryLocation = tempInst; + } + + i_pSprEntryLocation += SIZE_PER_SPR_RESTORE_INST; tempRegData = i_regData >> 48; @@ -432,15 +529,20 @@ STATIC StopReturnCode_t updateSprEntryInImage( uint32_t* i_pSprEntryLocation, //in. Instruction below moves contents of MSR Value (in R0 ) to R21. tempInst = SWIZZLE_4_BYTE( MR_R0_TO_R21 ); } - else if (P9_STOP_SPR_HRMOR == i_regId ) + else if ( P9_STOP_SPR_HRMOR == i_regId ) { - //Case HRMOR, move contents of R0 to a placeholder GPR (R10) - //Thread Launcher expects HRMOR value in R10 + //Case URMOR, move contents of R0 to a placeholder GPR (R10) + //Thread Launcher expects URMOR value in R10 tempInst = SWIZZLE_4_BYTE( MR_R0_TO_R10 ); } + else if( P9_STOP_SPR_URMOR == i_regId ) + { + tempInst = SWIZZLE_4_BYTE( MR_R0_TO_R9 ); + } else { // Case other SPRs, move contents of R0 to SPR + // For a UV system, even HRMOR is treated like any other SPR. tempInst = getMtsprInstruction( 0, (uint16_t)i_regId ); } @@ -463,6 +565,70 @@ STATIC StopReturnCode_t updateSprEntryInImage( uint32_t* i_pSprEntryLocation, //----------------------------------------------------------------------------- +STATIC StopReturnCode_t initSelfSaveEntry( void* const i_pImage, uint16_t i_sprNum ) +{ + StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; + uint32_t* i_pSprSave = (uint32_t*)i_pImage; + + //ori r0, r0, 0x00nn + *i_pSprSave = getOriInstruction( 0, 0, i_sprNum ); + + i_pSprSave++; + + //addi r31, r31, 0x20 + *i_pSprSave = SWIZZLE_4_BYTE(SKIP_SPR_SELF_SAVE); + i_pSprSave++; + + //nop + *i_pSprSave = getOriInstruction( 0, 0, 0 );; + i_pSprSave++; + + //mtlr, r30 + *i_pSprSave = SWIZZLE_4_BYTE( MTLR_INST ); + i_pSprSave++; + + //blr + *i_pSprSave = SWIZZLE_4_BYTE(BLR_INST); + i_pSprSave++; + + + return l_rc; +} + +//----------------------------------------------------------------------------- + +STATIC StopReturnCode_t getSprRegIndexAdjustment( const uint32_t i_saveMaskPos, uint32_t* i_sprAdjIndex ) +{ + StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; + + do + { + if( (( i_saveMaskPos >= SPR_BIT_POS_8 ) && ( i_saveMaskPos <= SPR_BIT_POS_19 )) || + (( i_saveMaskPos >= SPR_BIT_POS_25 ) && ( i_saveMaskPos <= SPR_BIT_POS_27 )) ) + { + l_rc = STOP_SAVE_SPR_BIT_POS_RESERVE; + break; + } + + if( (i_saveMaskPos > SPR_BIT_POS_19) && (i_saveMaskPos < SPR_BIT_POS_25 ) ) + { + *i_sprAdjIndex = 12; + } + else if( i_saveMaskPos > SPR_BIT_POS_27 ) + { + *i_sprAdjIndex = 15; + } + else + { + *i_sprAdjIndex = 0; + } + + } + while(0); + + return l_rc; +} +//----------------------------------------------------------------------------- StopReturnCode_t p9_stop_save_cpureg( void* const i_pImage, const CpuReg_t i_regId, const uint64_t i_regData, @@ -473,12 +639,14 @@ StopReturnCode_t p9_stop_save_cpureg( void* const i_pImage, do { - uint32_t threadId = 0; - uint32_t coreId = 0; - uint32_t lookUpKey = 0; - void* pSprEntryLocation = NULL; // an offset w.r.t. to start of image - void* pThreadLocation = NULL; - bool threadScopeReg = false; + uint32_t threadId = 0; + uint32_t coreId = 0; + uint32_t lookUpKey = 0; + void* pSprEntryLocation = NULL; // an offset w.r.t. to start of image + void* pThreadLocation = NULL; + bool threadScopeReg = false; + uint8_t l_urmorFix = false; + uint64_t l_sprValue = 0; MY_INF(">> p9_stop_save_cpureg" ); @@ -510,17 +678,19 @@ StopReturnCode_t p9_stop_save_cpureg( void* const i_pImage, break; } + l_urmorFix = *(uint8_t*)((uint8_t*)i_pImage + CPMR_HOMER_OFFSET + CPMR_URMOR_FIX_BYTE); + chipHomer = ( HomerSection_t*)i_pImage; if( threadScopeReg ) { pThreadLocation = - &(chipHomer->coreThreadRestore[coreId][threadId].threadArea[0]); + &(chipHomer->iv_coreThreadRestore[coreId].iv_threadRestoreArea[threadId][0]); } else { pThreadLocation = - &(chipHomer->coreThreadRestore[coreId][threadId].coreArea[0]); + &(chipHomer->iv_coreThreadRestore[coreId].iv_coreRestoreArea[0]); } if( ( SWIZZLE_4_BYTE(BLR_INST) == *(uint32_t*)pThreadLocation ) || @@ -548,9 +718,19 @@ StopReturnCode_t p9_stop_save_cpureg( void* const i_pImage, break; } + if( ( P9_STOP_SPR_URMOR == i_regId ) && ( l_urmorFix ) ) + { + l_sprValue = i_regData - URMOR_CORRECTION; + } + else + { + l_sprValue = i_regData; + } + l_rc = updateSprEntryInImage( (uint32_t*) pSprEntryLocation, i_regId, - i_regData ); + l_sprValue, + UPDATE_SPR_ENTRY ); if( l_rc ) { @@ -1108,6 +1288,409 @@ StopReturnCode_t p9_stop_save_scom( void* const i_pImage, return l_rc; } +//----------------------------------------------------------------------------- + +/** + * @brief searches a self save entry of an SPR in self-save segment. + * @param[in] i_sprBitPos bit position associated with SPR in save mask vector. + * @param[in] l_pSprSaveStart start location of SPR save segment + * @param[in] i_searchLength length of SPR save segment + * @param[in] i_pSaveSprLoc start location of save entry for a given SPR. + * @return STOP_SAVE_SUCCESS if look up succeeds, error code otherwise. + */ +StopReturnCode_t lookUpSelfSaveSpr( uint32_t i_sprBitPos, uint32_t* l_pSprSaveStart, + uint32_t i_searchLength, uint32_t** i_pSaveSprLoc ) +{ + int32_t l_saveWordLength = (int32_t)(i_searchLength >> 2); + uint32_t l_oriInst = getOriInstruction( 0, 0, i_sprBitPos ); + StopReturnCode_t l_rc = STOP_SAVE_FAIL; + + while( l_saveWordLength > 0 ) + { + if( l_oriInst == *l_pSprSaveStart ) + { + *i_pSaveSprLoc = l_pSprSaveStart; + l_rc = STOP_SAVE_SUCCESS; + break; + } + + l_pSprSaveStart++; + l_saveWordLength--; + } + + return l_rc; +} + +//----------------------------------------------------------------------------- + +/** + * @brief searches a self save entry of an SPR in self-save segment. + * @param[in] i_pSaveReg start of editable location of a SPR save entry. + * @param[in] i_sprNum Id of the SPR for which entry needs to be edited. + * @return STOP_SAVE_SUCCESS if look up succeeds, error code otherwise. + */ +StopReturnCode_t updateSelfSaveEntry( uint32_t* i_pSaveReg, uint16_t i_sprNum ) +{ + StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; + + do + { + if( !i_pSaveReg ) + { + l_rc = STOP_SAVE_FAIL; + MY_ERR( "Failed to update self save area for SPR 0x%04x", i_sprNum ); + break; + } + + if( P9_STOP_SPR_MSR == i_sprNum ) + { + getMfmsrInstruction( 1 ); + *i_pSaveReg = getMfmsrInstruction( 1 ); + } + else + { + *i_pSaveReg = getMfsprInstruction( 1, i_sprNum ); + } + + i_pSaveReg++; + + *i_pSaveReg = getBranchLinkRegInstruction( ); + } + while(0); + + return l_rc; +} + +//----------------------------------------------------------------------------- + +StopReturnCode_t p9_stop_save_cpureg_control( void* i_pImage, + const uint64_t i_pir, + const uint32_t i_saveRegVector ) +{ + StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; + uint32_t l_coreId = 0; + uint32_t l_threadId = 0; + uint32_t l_sprPos = 0; + uint32_t l_sprIndex = 0; + uint32_t l_lookupLength = 0; + uint32_t l_lookUpKey = 0; + uint32_t* l_pSaveStart = NULL; + uint32_t* l_pRestoreStart = NULL; + uint32_t* l_pSprSave = NULL; + void* l_pTempLoc = NULL; + HomerSection_t* l_pHomer = NULL; + + do + { + l_rc = getCoreAndThread( i_pImage, i_pir, &l_coreId, &l_threadId ); + + if( l_rc ) + { + MY_ERR( "Error in getting core no 0x%08x and thread no 0x%08x from PIR 0x%016lx", + l_coreId, l_threadId, i_pir ); + break; + } + + l_rc = validateArgumentSaveRegMask( i_pImage, l_coreId, l_threadId, i_saveRegVector ); + + if( l_rc ) + { + MY_ERR( "Invalid argument rc 0x%08x", (uint32_t) l_rc ); + break; + } + + l_pHomer = (HomerSection_t*)i_pImage; + + for( l_sprIndex = 0; l_sprIndex < MAX_SPR_SUPPORTED; l_sprIndex++ ) + { + l_sprPos = g_sprRegister[l_sprIndex].iv_saveMaskPos; + + //Check if a given SPR needs to be self-saved each time on STOP entry + + if( i_saveRegVector & ( TEST_BIT_PATTERN >> l_sprPos ) ) + { + + if( g_sprRegister[l_sprIndex].iv_isThreadScope ) + { + l_lookupLength = SELF_SAVE_THREAD_AREA_SIZE; + l_pSaveStart = + (uint32_t*)&l_pHomer->iv_coreThreadRestore[l_coreId].iv_threadSaveArea[l_threadId][0]; + l_pRestoreStart = + (uint32_t*)&l_pHomer->iv_coreThreadRestore[l_coreId].iv_threadRestoreArea[l_threadId][0]; + } + else + { + l_lookupLength = CORE_SAVE_CORE_AREA_SIZE; + l_pSaveStart = (uint32_t*)&l_pHomer->iv_coreThreadRestore[l_coreId].iv_coreSaveArea[0]; + l_pRestoreStart = (uint32_t*)&l_pHomer->iv_coreThreadRestore[l_coreId].iv_coreRestoreArea[0]; + } + + // an SPR restore section for given core already exists + l_lookUpKey = genKeyForSprLookup( ( CpuReg_t )g_sprRegister[l_sprIndex].iv_sprId ); + + l_rc = lookUpSprInImage( (uint32_t*)l_pRestoreStart, l_lookUpKey, + g_sprRegister[l_sprIndex].iv_isThreadScope, &l_pTempLoc ); + + if( l_rc ) + { + //SPR specified in the save mask but there is no restore entry present in the memory + //Self-Save instruction will edit it during STOP entry to make it a valid entry + + l_rc = p9_stop_save_cpureg( i_pImage, + (CpuReg_t)g_sprRegister[l_sprIndex].iv_sprId, + 0x00, //creates a dummy entry + i_pir ); + } + + //Find if SPR-Save eye catcher exist in self-save segment of SPR restore region. + l_rc = lookUpSelfSaveSpr( l_sprPos, l_pSaveStart, l_lookupLength, &l_pSprSave ); + + if( l_rc ) + { + MY_INF( "Failed to find SPR No %02d save entry", l_sprPos ); + l_rc = STOP_SAVE_SPR_ENTRY_MISSING; + break; + } + + l_pSprSave++; //point to next instruction location + + //update specific instructions of self save region to enable saving for SPR + l_rc = updateSelfSaveEntry( l_pSprSave, g_sprRegister[l_sprIndex].iv_sprId ); + + }// end if( i_saveRegVector..) + }// end for + } + while(0); + + return l_rc; +} + +//----------------------------------------------------------------------------------------------------- + +StopReturnCode_t p9_stop_init_cpureg( void* const i_pImage, const uint32_t i_corePos ) +{ + StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; + uint32_t* l_pRestoreStart = NULL; + void* l_pTempLoc = NULL; + HomerSection_t* l_pHomer = NULL; + uint32_t l_threadPos = 0; + uint32_t l_lookUpKey = 0; + uint32_t l_sprIndex = 0; + + MY_INF( ">> p9_stop_init_cpureg" ); + + do + { + if( !i_pImage ) + { + l_rc = STOP_SAVE_ARG_INVALID_IMG; + break; + } + + if( i_corePos > MAX_CORE_ID_SUPPORTED ) + { + l_rc = STOP_SAVE_ARG_INVALID_CORE; + break; + } + + l_pHomer = ( HomerSection_t*) i_pImage; + + for( l_sprIndex = 0; l_sprIndex < MAX_SPR_SUPPORTED; l_sprIndex++ ) + { + //Check if a given SPR needs to be self-saved each time on STOP entry + + l_lookUpKey = genKeyForSprLookup( ( CpuReg_t )g_sprRegister[l_sprIndex].iv_sprId ); + + if( g_sprRegister[l_sprIndex].iv_isThreadScope ) + { + for( l_threadPos = 0; l_threadPos < MAX_THREADS_PER_CORE; l_threadPos++ ) + { + l_pRestoreStart = + (uint32_t*)&l_pHomer->iv_coreThreadRestore[i_corePos].iv_threadRestoreArea[l_threadPos][0]; + + l_rc = lookUpSprInImage( (uint32_t*)l_pRestoreStart, l_lookUpKey, + g_sprRegister[l_sprIndex].iv_isThreadScope, + &l_pTempLoc ); + + if( l_rc ) + { + MY_ERR( "Thread SPR lookup failed in p9_stop_init_cpureg SPR %d Core %d Thread %d Index %d", + g_sprRegister[l_sprIndex].iv_sprId, i_corePos, l_threadPos, l_sprIndex ); + break; + } + + l_rc = updateSprEntryInImage( (uint32_t*) l_pTempLoc, + ( CpuReg_t )g_sprRegister[l_sprIndex].iv_sprId, + 0x00, + INIT_SPR_REGION ); + + if( l_rc ) + { + MY_ERR( "Thread SPR region init failed. Core %d SPR Id %d", + i_corePos, g_sprRegister[l_sprIndex].iv_sprId ); + break; + } + + }//end for thread + + if( l_rc ) + { + break; + } + + }//end if SPR threadscope + else + { + l_pRestoreStart = (uint32_t*)&l_pHomer->iv_coreThreadRestore[i_corePos].iv_coreRestoreArea[0]; + + l_rc = lookUpSprInImage( (uint32_t*)l_pRestoreStart, l_lookUpKey, + g_sprRegister[l_sprIndex].iv_isThreadScope, + &l_pTempLoc ); + + if( l_rc ) + { + MY_ERR( "Core SPR lookup failed in p9_stop_init_cpureg" ); + break; + } + + l_rc = updateSprEntryInImage( (uint32_t*) l_pTempLoc, + ( CpuReg_t )g_sprRegister[l_sprIndex].iv_sprId, + 0x00, + INIT_SPR_REGION ); + + if( l_rc ) + { + MY_ERR( "Core SPR region init failed. Core %d SPR Id %d SPR Index %d", + i_corePos, g_sprRegister[l_sprIndex].iv_sprId, l_sprIndex ); + break; + } + + }// end else + + }// end for l_sprIndex + + } + while(0); + + MY_INF( "<< p9_stop_init_cpureg" ); + return l_rc; +} + +//----------------------------------------------------------------------------------------------------- + +StopReturnCode_t p9_stop_init_self_save( void* const i_pImage, const uint32_t i_corePos ) +{ + StopReturnCode_t l_rc = STOP_SAVE_SUCCESS; + uint32_t* l_pSaveStart = NULL; + HomerSection_t* l_pHomer = NULL; + uint32_t l_threadPos = 0; + uint32_t l_sprBitPos = 0; + uint32_t l_sprIndexAdj = 0; + MY_INF( ">> p9_stop_init_self_save" ); + + do + { + if( !i_pImage ) + { + l_rc = STOP_SAVE_ARG_INVALID_IMG; + break; + } + + if( i_corePos > MAX_CORE_ID_SUPPORTED ) + { + l_rc = STOP_SAVE_ARG_INVALID_CORE; + break; + } + + l_pHomer = ( HomerSection_t*) i_pImage; + + for( l_threadPos = 0; l_threadPos < MAX_THREADS_PER_CORE; l_threadPos++ ) + { + l_pSaveStart = + (uint32_t*)&l_pHomer->iv_coreThreadRestore[i_corePos].iv_threadSaveArea[l_threadPos][0]; + + //Adding instruction 'mflr r30' + *l_pSaveStart = SWIZZLE_4_BYTE(MFLR_R30); + l_pSaveStart++; + + for( l_sprBitPos = 0; l_sprBitPos <= MAX_SPR_BIT_POS; l_sprBitPos++ ) + { + l_rc = getSprRegIndexAdjustment( l_sprBitPos, &l_sprIndexAdj ); + + if( STOP_SAVE_SPR_BIT_POS_RESERVE == l_rc ) + { + //Failed to find SPR index adjustment + continue; + } + + if( !g_sprRegister[l_sprBitPos - l_sprIndexAdj].iv_isThreadScope ) + { + continue; + } + + + l_rc = initSelfSaveEntry( l_pSaveStart, g_sprRegister[l_sprBitPos - l_sprIndexAdj].iv_saveMaskPos ); + + if( l_rc ) + { + MY_ERR( "Failed to init thread self-save region for core %d thread %d", + i_corePos, l_threadPos ); + break; + } + + l_pSaveStart++; + l_pSaveStart++; + l_pSaveStart++; + } + + }// for thread = 0; + + if( l_rc ) + { + //breakout if saw an error while init of thread SPR region + break; + } + + l_pSaveStart = + (uint32_t*)&l_pHomer->iv_coreThreadRestore[i_corePos].iv_coreSaveArea[0]; + + *l_pSaveStart = SWIZZLE_4_BYTE(MFLR_R30); + l_pSaveStart++; + + for( l_sprBitPos = 0; l_sprBitPos <= MAX_SPR_BIT_POS; l_sprBitPos++ ) + { + l_rc = getSprRegIndexAdjustment( l_sprBitPos, &l_sprIndexAdj ); + + if( STOP_SAVE_SPR_BIT_POS_RESERVE == l_rc ) + { + //Failed to find SPR index adjustment + continue; + } + + if( g_sprRegister[l_sprBitPos - l_sprIndexAdj].iv_isThreadScope ) + { + continue; + } + + l_rc = initSelfSaveEntry( l_pSaveStart, g_sprRegister[l_sprBitPos - l_sprIndexAdj].iv_saveMaskPos ); + + if( l_rc ) + { + MY_ERR( "Failed to init core self-save region for core %d thread %d", + i_corePos, l_threadPos ); + break; + } + + l_pSaveStart++; + l_pSaveStart++; + l_pSaveStart++; + } + } + while(0); + + MY_INF( "<< p9_stop_init_self_save" ); + return l_rc; +} #ifdef __cplusplus } //namespace stopImageSection ends diff --git a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H index 6416771d1..17caedb3c 100755 --- a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H +++ b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ +/* Contributors Listed Below - COPYRIGHT 2015,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -54,10 +54,17 @@ namespace stopImageSection typedef enum { P9_STOP_SPR_DAWR = 180, // thread register + P9_STOP_SPR_CIABR = 187, // thread register + P9_STOP_SPR_DAWRX = 188, // thread register P9_STOP_SPR_HSPRG0 = 304, // thread register P9_STOP_SPR_HRMOR = 313, // core register P9_STOP_SPR_LPCR = 318, // thread register P9_STOP_SPR_HMEER = 337, // core register + P9_STOP_SPR_PTCR = 464, // core register + P9_STOP_SPR_USPRG0 = 496, // thread register + P9_STOP_SPR_USPRG1 = 497, // thread register + P9_STOP_SPR_URMOR = 505, // core register + P9_STOP_SPR_SMFCTRL = 511, // thread register P9_STOP_SPR_LDBAR = 850, // thread register P9_STOP_SPR_PSSCR = 855, // thread register P9_STOP_SPR_PMCR = 884, // core register @@ -70,21 +77,23 @@ typedef enum */ typedef enum { - STOP_SAVE_SUCCESS = 0, - STOP_SAVE_ARG_INVALID_IMG = 1, - STOP_SAVE_ARG_INVALID_REG = 2, - STOP_SAVE_ARG_INVALID_THREAD = 3, - STOP_SAVE_ARG_INVALID_MODE = 4, - STOP_SAVE_ARG_INVALID_CORE = 5, - STOP_SAVE_SPR_ENTRY_NOT_FOUND = 6, - STOP_SAVE_SPR_ENTRY_UPDATE_FAILED = 7, - STOP_SAVE_SCOM_INVALID_OPERATION = 8, - STOP_SAVE_SCOM_INVALID_SECTION = 9, - STOP_SAVE_SCOM_INVALID_ADDRESS = 10, - STOP_SAVE_SCOM_INVALID_CHIPLET = 11, - STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED = 12, - STOP_SAVE_INVALID_FUSED_CORE_STATUS = 13, - STOP_SAVE_FAIL = 14, // for internal failure within firmware. + STOP_SAVE_SUCCESS = 0, + STOP_SAVE_ARG_INVALID_IMG = 1, + STOP_SAVE_ARG_INVALID_REG = 2, + STOP_SAVE_ARG_INVALID_THREAD = 3, + STOP_SAVE_ARG_INVALID_MODE = 4, + STOP_SAVE_ARG_INVALID_CORE = 5, + STOP_SAVE_SPR_ENTRY_NOT_FOUND = 6, + STOP_SAVE_SPR_ENTRY_UPDATE_FAILED = 7, + STOP_SAVE_SCOM_INVALID_OPERATION = 8, + STOP_SAVE_SCOM_INVALID_SECTION = 9, + STOP_SAVE_SCOM_INVALID_ADDRESS = 10, + STOP_SAVE_SCOM_INVALID_CHIPLET = 11, + STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED = 12, + STOP_SAVE_INVALID_FUSED_CORE_STATUS = 13, + STOP_SAVE_FAIL = 14, // for internal failure within firmware. + STOP_SAVE_SPR_ENTRY_MISSING = 15, + STOP_SAVE_SPR_BIT_POS_RESERVE = 16, } StopReturnCode_t; /** @@ -92,16 +101,16 @@ typedef enum */ typedef enum { - P9_STOP_SCOM_OP_MIN = 0, - P9_STOP_SCOM_APPEND = 1, - P9_STOP_SCOM_REPLACE = 2, - P9_STOP_SCOM_OR = 3, - P9_STOP_SCOM_AND = 4, - P9_STOP_SCOM_NOOP = 5, - P9_STOP_SCOM_RESET = 6, - P9_STOP_SCOM_OR_APPEND = 7, - P9_STOP_SCOM_AND_APPEND = 8, - P9_STOP_SCOM_OP_MAX = 9 + P9_STOP_SCOM_OP_MIN = 0, + P9_STOP_SCOM_APPEND = 1, + P9_STOP_SCOM_REPLACE = 2, + P9_STOP_SCOM_OR = 3, + P9_STOP_SCOM_AND = 4, + P9_STOP_SCOM_NOOP = 5, + P9_STOP_SCOM_RESET = 6, + P9_STOP_SCOM_OR_APPEND = 7, + P9_STOP_SCOM_AND_APPEND = 8, + P9_STOP_SCOM_OP_MAX = 9 } ScomOperation_t; /** @@ -109,12 +118,12 @@ typedef enum */ typedef enum { - P9_STOP_SECTION_MIN = 0, - P9_STOP_SECTION_CORE_SCOM = 1, - P9_STOP_SECTION_EQ_SCOM = 2, - P9_STOP_SECTION_L2 = 3, - P9_STOP_SECTION_L3 = 4, - P9_STOP_SECTION_MAX = 5 + P9_STOP_SECTION_MIN = 0, + P9_STOP_SECTION_CORE_SCOM = 1, + P9_STOP_SECTION_EQ_SCOM = 2, + P9_STOP_SECTION_L2 = 3, + P9_STOP_SECTION_L3 = 4, + P9_STOP_SECTION_MAX = 5 } ScomSection_t; /** @@ -126,6 +135,31 @@ typedef enum STOP_API_VER_CONTROL = 0x02, } VersionList_t; +/** + * @brief Summarizes bit position allocated to SPRs in save bit mask vector. + */ +typedef enum +{ + BIT_POS_CIABR = 0, + BIT_POS_DAWR = 1, + BIT_POS_DAWRX = 2, + BIT_POS_HSPRG0 = 3, + BIT_POS_LDBAR = 4, + BIT_POS_LPCR = 5, + BIT_POS_PSSCR = 6, + BIT_POS_MSR = 7, + BIT_POS_HRMOR = 20, + BIT_POS_HID = 21, + BIT_POS_HMEER = 22, + BIT_POS_PMCR = 23, + BIT_POS_PTCR = 24, + BIT_POS_SMFCTRL = 28, + BIT_POS_USPRG0 = 29, + BIT_POS_USPRG1 = 30, + BIT_POS_URMOR = 31, +} SprBitPositionList_t; + + #ifdef __cplusplus extern "C" { #endif @@ -143,6 +177,18 @@ StopReturnCode_t p9_stop_save_cpureg( void* const i_pImage, const CpuReg_t i_regId, const uint64_t i_regData, const uint64_t i_pir ); +/** + * @brief Updates STOP image entry associated with CPU register. + * @param[in] i_pImage start address of homer image associated with processor. + * @param[in] i_corePos physical core's relative position within processor chip. + * @return STOP_SAVE_SUCCESS SUCCESS if image is initialized successfully, error + * code otherwise. + * @note API is intended only for use case of HOMER build. There is no explicit + * effort to support any other use case. + * + */ + +StopReturnCode_t p9_stop_init_cpureg( void* const i_pImage, const uint32_t i_corePos ); /** * @brief Updates scom image entry associated with given core or cache in @@ -164,6 +210,32 @@ StopReturnCode_t p9_stop_save_scom( void* const i_pImage, const ScomOperation_t i_operation, const ScomSection_t i_section ); +/** + * @brief Facilitates self save and restore of a list of SPRs of a thread. + * @param[in] i_pImage points to the start of HOMER image of P9 chip. + * @param[in] i_pir PIR associated with thread + * @param[in] i_saveRegVector bit vector representing SPRs that needs to be restored. + * @return STOP_SAVE_SUCCESS if API succeeds, error code otherwise. + * @note SPR save vector is a bit vector. For each SPR supported, + * there is an associated bit position in the bit vector.Refer + * to definition of SprBitPositionList_t to determine bit position + * associated with a particular SPR. + */ +StopReturnCode_t +p9_stop_save_cpureg_control( void* i_pImage, const uint64_t i_pir, + const uint32_t i_saveRegVector ); + +/** + * @brief initializes self-save region with specific instruction. + * @param[in] i_pImage start address of homer image of P9 chip. + * @param[in] i_corePos physical core's relative position within processor chip. + * @return STOP_SAVE_SUCCESS SUCCESS if self-save is initialized successfully, + * error code otherwise. + * @note API is intended only for use case of HOMER build. There is no explicit + * effort to support any other use case. + */ +StopReturnCode_t p9_stop_init_self_save( void* const i_pImage, const uint32_t i_corePos ); + #ifdef __cplusplus } // extern "C" }; // namespace stopImageSection ends diff --git a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_data_struct.H b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_data_struct.H index 940f4057f..ff8e85200 100755 --- a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_data_struct.H +++ b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_data_struct.H @@ -63,8 +63,21 @@ namespace stopImageSection enum { - MAX_SPR_RESTORE_INST = 0x08, - SIZE_PER_SPR_RESTORE_INST = ((4 * sizeof(uint8_t)) / sizeof(uint32_t)), + MAX_SPR_RESTORE_INST = 0x08, + SIZE_PER_SPR_RESTORE_INST = ((4 * sizeof(uint8_t)) / sizeof(uint32_t)), + MAX_THREAD_LEVEL_SPRS = 11, + MAX_CORE_LEVEL_SPRS = 6, + MAX_SPR_BIT_POS = 31, + SPR_BIT_POS_8 = 8, + SPR_BIT_POS_19 = 19, + SPR_BIT_POS_25 = 25, + SPR_BIT_POS_27 = 27, +}; + +enum SprEntryUpdateMode +{ + INIT_SPR_REGION = 0x01, + UPDATE_SPR_ENTRY = 0x02, }; typedef struct @@ -79,8 +92,10 @@ typedef struct */ typedef struct { - uint8_t threadArea[CORE_RESTORE_THREAD_AREA_SIZE]; - uint8_t coreArea[CORE_RESTORE_CORE_AREA_SIZE]; + uint8_t iv_threadRestoreArea[MAX_THREADS_PER_CORE][CORE_RESTORE_THREAD_AREA_SIZE]; + uint8_t iv_threadSaveArea[MAX_THREADS_PER_CORE][SELF_SAVE_THREAD_AREA_SIZE]; + uint8_t iv_coreRestoreArea[CORE_RESTORE_CORE_AREA_SIZE]; + uint8_t iv_coreSaveArea[CORE_SAVE_CORE_AREA_SIZE]; } SprRestoreArea_t; /** @@ -90,10 +105,10 @@ typedef struct */ typedef struct { - uint8_t occ_host_sgpe_area[ TWO_MB ]; // CPU restore area starts at an offset of 2MB from chip HOMER - uint8_t interrruptHandler[SELF_RESTORE_INT_SIZE]; - uint8_t threadLauncher[THREAD_LAUNCHER_SIZE]; - SprRestoreArea_t coreThreadRestore[MAX_CORES_PER_CHIP][MAX_THREADS_PER_CORE]; + uint8_t iv_occ_host_sgpe_area[ TWO_MB ]; // CPU restore area starts at an offset of 2MB from chip HOMER + uint8_t iv_interrruptHandler[SELF_RESTORE_INT_SIZE]; + uint8_t iv_threadLauncher[THREAD_LAUNCHER_SIZE]; + SprRestoreArea_t iv_coreThreadRestore[MAX_CORES_PER_CHIP]; uint8_t reserve[(ONE_KB * ONE_KB) - SELF_RESTORE_SIZE_TOTAL]; } HomerSection_t; @@ -116,14 +131,19 @@ typedef struct */ typedef struct { - uint32_t sprId; - bool isThreadScope; + uint32_t iv_sprId; + bool iv_isThreadScope; + uint32_t iv_saveMaskPos; + } StopSprReg_t; enum { - SIZE_SCOM_ENTRY = sizeof( ScomEntry_t ), - SCOM_ENTRY_START = 0xDEADDEAD, + SIZE_SCOM_ENTRY = sizeof( ScomEntry_t ), + SCOM_ENTRY_START = 0xDEADDEAD, + BAD_SAVE_MASK = 0x007FF000, + MAX_SPR_INDEX = 31, + TEST_BIT_PATTERN = 0x80000000, }; #ifdef __FAPI_2_ diff --git a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_util.C b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_util.C index 979455a2c..950198849 100755 --- a/src/import/chips/p9/procedures/utils/stopreg/p9_stop_util.C +++ b/src/import/chips/p9/procedures/utils/stopreg/p9_stop_util.C @@ -62,7 +62,7 @@ STATIC StopReturnCode_t isFusedMode( void* const i_pImage, bool* o_fusedMode ) do { HomerSection_t* pHomerDesc = ( HomerSection_t* ) i_pImage; - HomerImgDesc_t* pHomer = (HomerImgDesc_t*)( pHomerDesc->interrruptHandler ); + HomerImgDesc_t* pHomer = (HomerImgDesc_t*)( pHomerDesc->iv_interrruptHandler ); if( !i_pImage ) { @@ -177,6 +177,7 @@ StopReturnCode_t getCoreAndThread( void* const i_pImage, const uint64_t i_pir, } } + MY_INF("Core Type %s", fusedMode ? "Fused" : "Un-Fused" ); //quad field is not affected by fuse mode *o_pCoreId += 4 * (( coreThreadInfo & 0x70 ) >> 4 ); diff --git a/src/import/chips/p9/procedures/xml/attribute_info/chip_ec_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/chip_ec_attributes.xml index b371d5f96..1d07abe1d 100644 --- a/src/import/chips/p9/procedures/xml/attribute_info/chip_ec_attributes.xml +++ b/src/import/chips/p9/procedures/xml/attribute_info/chip_ec_attributes.xml @@ -7858,4 +7858,28 @@ </chipEcFeature> </attribute> <!-- ******************************************************************** --> + <attribute> + <id>ATTR_CHIP_EC_FEATURE_HW403111</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description> + mtspr URMOR, rX will add the PPC instruction text to the Rx value + </description> + <chipEcFeature> + <chip> + <name>ENUM_ATTR_NAME_NIMBUS</name> + <ec> + <value>0x22</value> + <test>LESS_THAN_OR_EQUAL</test> + </ec> + </chip> + <chip> + <name>ENUM_ATTR_NAME_CUMULUS</name> + <ec> + <value>0x13</value> + <test>LESS_THAN_OR_EQUAL</test> + </ec> + </chip> + </chipEcFeature> + </attribute> + <!-- ******************************************************************** --> </attributes> diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_hcode_image_build_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_hcode_image_build_errors.xml index 52f4d111a..850bfcd78 100755 --- a/src/import/chips/p9/procedures/xml/error_info/p9_hcode_image_build_errors.xml +++ b/src/import/chips/p9/procedures/xml/error_info/p9_hcode_image_build_errors.xml @@ -686,7 +686,6 @@ <priority>HIGH</priority> </callout> </hwpError> - <!-- *********************************************************************** --> <hwpError> <rc>RC_P9_PGPE_AUX_TASK_BIN_SIZE_ERROR</rc> @@ -702,4 +701,43 @@ </callout> </hwpError> <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SELF_RESTORE_INIT_FAILED</rc> + <description>hcode image build procedure failed to initialize self-restore region.</description> + <ffdc>HOMER_PTR</ffdc> + <ffdc>CORE_POS</ffdc> + <ffdc>FAILURE_CODE</ffdc> + <ffdc>EC_LEVEL</ffdc> + <ffdc>CHIP_TYPE</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SELF_SAVE_INIT_FAILED</rc> + <description>hcode image build procedure failed to initialize self-save region.</description> + <ffdc>HOMER_PTR</ffdc> + <ffdc>CORE_POS</ffdc> + <ffdc>FAILURE_CODE</ffdc> + <ffdc>EC_LEVEL</ffdc> + <ffdc>CHIP_TYPE</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_URMOR_RESTORE_ENTRY_FAILED</rc> + <description>hcode image build procedure failed to create URMOR restor entry</description> + <ffdc>PIR</ffdc> + <ffdc>STOP_API_RC</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> </hwpErrors> |