summaryrefslogtreecommitdiffstats
path: root/src/import/chips
diff options
context:
space:
mode:
authorPrem Shanker Jha <premjha2@in.ibm.com>2018-05-15 10:39:08 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-09-14 16:13:01 -0500
commit09ab06ca2d5640622c0d39ee34520b10db3a9072 (patch)
tree164e2a7910fb443994a1c3a523b927a88a4860a3 /src/import/chips
parent7bb1f127506943f90e153c7013fa026b42959069 (diff)
downloadtalos-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/chips')
-rw-r--r--src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_base.H24
-rw-r--r--src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H3
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C291
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.C20
-rw-r--r--src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.H12
-rwxr-xr-xsrc/import/chips/p9/procedures/utils/stopreg/p9_cpu_reg_restore_instruction.H43
-rwxr-xr-xsrc/import/chips/p9/procedures/utils/stopreg/p9_stop_api.C657
-rwxr-xr-xsrc/import/chips/p9/procedures/utils/stopreg/p9_stop_api.H136
-rwxr-xr-xsrc/import/chips/p9/procedures/utils/stopreg/p9_stop_data_struct.H44
-rwxr-xr-xsrc/import/chips/p9/procedures/utils/stopreg/p9_stop_util.C3
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/chip_ec_attributes.xml24
-rwxr-xr-xsrc/import/chips/p9/procedures/xml/error_info/p9_hcode_image_build_errors.xml40
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>
OpenPOWER on IntegriCloud