diff mbox series

STOP API: API conditionally supports 255 SCOM restore entries for each quad.

Message ID 20180711124228.10300-1-akshay.adiga@linux.vnet.ibm.com
State Accepted
Headers show
Series STOP API: API conditionally supports 255 SCOM restore entries for each quad. | expand

Commit Message

Akshay Adiga July 11, 2018, 12:42 p.m. UTC
From: Prem Shanker Jha <premjha2@in.ibm.com>

This is first of the series of commits intended for incorporating
new mechanisms for SCOM restore. STOP API looks for a specific
version in QPMR header of HOMER. If version is greater than 2, it allows
 - 255 SCOM Restore entries per quad
 - doesn't divide quad restore region in to L2, L3 and EQ sub-region
If version is less than or equal to 2, API provideis legacy
functionality.
Key_Cronus_Test=PM_REGRESS

RTC: 188827
Change-Id: Iac6ee94619302f745fee0c77acc168eaba04c3da
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56385
Tested-by: Cronus HW CI <cronushw-ci+hostboot@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+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://ralgit01.raleigh.ibm.com/gerrit1/56390
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
---
 libpore/p9_hcd_memmap_base.H  |   6 +-
 libpore/p9_stop_api.C         | 197 ++++++++++++++++++----------------
 libpore/p9_stop_data_struct.H |  22 +++-
 libpore/p9_stop_util.C        |  19 ++--
 4 files changed, 136 insertions(+), 108 deletions(-)

Comments

Stewart Smith July 17, 2018, 6:15 a.m. UTC | #1
Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> writes:
> From: Prem Shanker Jha <premjha2@in.ibm.com>
>
> This is first of the series of commits intended for incorporating
> new mechanisms for SCOM restore. STOP API looks for a specific
> version in QPMR header of HOMER. If version is greater than 2, it allows
>  - 255 SCOM Restore entries per quad
>  - doesn't divide quad restore region in to L2, L3 and EQ sub-region
> If version is less than or equal to 2, API provideis legacy
> functionality.
> Key_Cronus_Test=PM_REGRESS

This patch appears to break things, we get these new OPAL errors:

[   81.249303719,3] IMC: IMC event_mask stopapi ret = 12, scoms = 20010aa8 (core id = 0)
[   81.249405452,3] IMC: SCOM entries are full
[  106.228080041,3] IMC: IMC event_mask stopapi ret = 12, scoms = 20010aa8 (core id = 0)
[  106.228183131,3] IMC: SCOM entries are full

Is this a bug with the STOP API changes or have we just been silently
dropping this and having bugs in IMC?
Akshay Adiga July 18, 2018, 8:30 a.m. UTC | #2
On Tue, Jul 17, 2018 at 04:15:52PM +1000, Stewart Smith wrote:
> Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> writes:
> > From: Prem Shanker Jha <premjha2@in.ibm.com>
> >
> > This is first of the series of commits intended for incorporating
> > new mechanisms for SCOM restore. STOP API looks for a specific
> > version in QPMR header of HOMER. If version is greater than 2, it allows
> >  - 255 SCOM Restore entries per quad
> >  - doesn't divide quad restore region in to L2, L3 and EQ sub-region
> > If version is less than or equal to 2, API provideis legacy
> > functionality.
> > Key_Cronus_Test=PM_REGRESS
> 
> This patch appears to break things, we get these new OPAL errors:
> 
> [   81.249303719,3] IMC: IMC event_mask stopapi ret = 12, scoms = 20010aa8 (core id = 0)
> [   81.249405452,3] IMC: SCOM entries are full
> [  106.228080041,3] IMC: IMC event_mask stopapi ret = 12, scoms = 20010aa8 (core id = 0)
> [  106.228183131,3] IMC: SCOM entries are full
> 
> Is this a bug with the STOP API changes or have we just been silently
> dropping this and having bugs in IMC?

We have not been failing silently, This patch made it fail.

The patch expected a newer hostboot/firmware and was not able to handle
current firmware level. The following patch fixes it. 

diff --git a/libpore/p9_stop_api.C b/libpore/p9_stop_api.C
index df1188c5..3b39b0cf 100644
--- a/libpore/p9_stop_api.C
+++ b/libpore/p9_stop_api.C
@@ -836,6 +836,10 @@ StopReturnCode_t p9_stop_save_scom( void* const
i_pImage,
                 *(uint32_t*)((uint8_t*)i_pImage + CPMR_HOMER_OFFSET +
CPMR_MAX_SCOM_REST_PER_CORE_BYTE);
             pScomEntry              =   CORE_ID_SCOM_START(i_pImage,
chipletId )
                                         cacheEntry              =
false;
+               if( !l_maxScomRestoreEntry )
+               {
+                  l_maxScomRestoreEntry   = 15;
+               }
         }
         else
         {

This hunk is provided by Prem specifically for OPAL so that we can merge
these changes, the stop-api library will merge it a later point of time.
> 
> -- 
> Stewart Smith
> OPAL Architect, IBM.
Stewart Smith July 19, 2018, 7:54 a.m. UTC | #3
Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> writes:

> On Tue, Jul 17, 2018 at 04:15:52PM +1000, Stewart Smith wrote:
>> Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> writes:
>> > From: Prem Shanker Jha <premjha2@in.ibm.com>
>> >
>> > This is first of the series of commits intended for incorporating
>> > new mechanisms for SCOM restore. STOP API looks for a specific
>> > version in QPMR header of HOMER. If version is greater than 2, it allows
>> >  - 255 SCOM Restore entries per quad
>> >  - doesn't divide quad restore region in to L2, L3 and EQ sub-region
>> > If version is less than or equal to 2, API provideis legacy
>> > functionality.
>> > Key_Cronus_Test=PM_REGRESS
>> 
>> This patch appears to break things, we get these new OPAL errors:
>> 
>> [   81.249303719,3] IMC: IMC event_mask stopapi ret = 12, scoms = 20010aa8 (core id = 0)
>> [   81.249405452,3] IMC: SCOM entries are full
>> [  106.228080041,3] IMC: IMC event_mask stopapi ret = 12, scoms = 20010aa8 (core id = 0)
>> [  106.228183131,3] IMC: SCOM entries are full
>> 
>> Is this a bug with the STOP API changes or have we just been silently
>> dropping this and having bugs in IMC?
>
> We have not been failing silently, This patch made it fail.
>
> The patch expected a newer hostboot/firmware and was not able to handle
> current firmware level. The following patch fixes it. 
>
> diff --git a/libpore/p9_stop_api.C b/libpore/p9_stop_api.C
> index df1188c5..3b39b0cf 100644
> --- a/libpore/p9_stop_api.C
> +++ b/libpore/p9_stop_api.C
> @@ -836,6 +836,10 @@ StopReturnCode_t p9_stop_save_scom( void* const
> i_pImage,
>                  *(uint32_t*)((uint8_t*)i_pImage + CPMR_HOMER_OFFSET +
> CPMR_MAX_SCOM_REST_PER_CORE_BYTE);
>              pScomEntry              =   CORE_ID_SCOM_START(i_pImage,
> chipletId )
>                                          cacheEntry              =
> false;
> +               if( !l_maxScomRestoreEntry )
> +               {
> +                  l_maxScomRestoreEntry   = 15;
> +               }
>          }
>          else
>          {
>
> This hunk is provided by Prem specifically for OPAL so that we can merge
> these changes, the stop-api library will merge it a later point of
> time.

Okay, I'm okay with taking this with that extra hunk that defaults back
to what the original was (rather than assuming 0).

So, (with that hunk), merged to master as of 1a4aa1cb03498de236989ab8be797f0e84011fd8
diff mbox series

Patch

diff --git a/libpore/p9_hcd_memmap_base.H b/libpore/p9_hcd_memmap_base.H
index 70738418..e579eea9 100644
--- a/libpore/p9_hcd_memmap_base.H
+++ b/libpore/p9_hcd_memmap_base.H
@@ -5,7 +5,7 @@ 
 /*                                                                        */
 /* OpenPOWER HostBoot Project                                             */
 /*                                                                        */
-/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
+/* Contributors Listed Below - COPYRIGHT 2015,2018                        */
 /* [+] International Business Machines Corp.                              */
 /*                                                                        */
 /*                                                                        */
@@ -171,6 +171,7 @@  HCD_CONST(QPMR_STOP_FFDC_OFFSET_BYTE,           0x58)
 HCD_CONST(QPMR_STOP_FFDC_LENGTH_BYTE,           0x5C)
 HCD_CONST(QPMR_SGPE_BOOT_PROG_CODE,             0x60)
 HCD_CONST(QPMR_SGPE_IMAGE_SIZE,                 0x64)
+HCD_CONST(QPMR_QUAD_MAX_SCOM_ENTRY_BYTE,        0x68)
 
 /// SGPE Boot
 
@@ -284,7 +285,7 @@  HCD_CONST(QUAD_SCOM_RESTORE_SIZE_PER_QUAD,
           (SCOM_RESTORE_ENTRY_SIZE* QUAD_SCOM_RESTORE_REGS_PER_QUAD))
 
 HCD_CONST(QUAD_SCOM_RESTORE_SIZE_TOTAL,         (6 * ONE_KB)) //rounded to 6KB
-
+HCD_CONST(LEGACY_SCOM_RESTORE_VER,              0x02)
 //---------------------------------------------------------------------------------------
 
 /// CPMR Header
@@ -309,6 +310,7 @@  HCD_CONST(CPMR_CORE_SCOM_RESTORE_OFFSET_BYTE,   0x40)
 HCD_CONST(CPMR_CORE_SCOM_RESTORE_LENGTH_BYTE,   0x44)
 HCD_CONST(CPMR_SELF_RESTORE_OFFSET_BYTE,        0x48)
 HCD_CONST(CPMR_SELF_RESTORE_LENGTH_BYTE,        0x4C)
+HCD_CONST(CPMR_MAX_SCOM_REST_PER_CORE_BYTE,     0x50)
 
 /// Self Restore
 
diff --git a/libpore/p9_stop_api.C b/libpore/p9_stop_api.C
index 5c0f2e5e..df1188c5 100644
--- a/libpore/p9_stop_api.C
+++ b/libpore/p9_stop_api.C
@@ -5,7 +5,7 @@ 
 /*                                                                        */
 /* OpenPOWER HostBoot Project                                             */
 /*                                                                        */
-/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
+/* Contributors Listed Below - COPYRIGHT 2015,2018                        */
 /* [+] International Business Machines Corp.                              */
 /*                                                                        */
 /*                                                                        */
@@ -32,13 +32,14 @@ 
 // *HWP Team        :  PM
 // *HWP Level       :  2
 // *HWP Consumed by :  HB:HYP
-
+#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"
-#include <stdio.h>
 
 #ifdef __FAPI_2_
     #include <fapi2.H>
@@ -67,8 +68,7 @@  const StopSprReg_t g_sprRegister[] =
     { P9_STOP_SPR_DAWR,      true  },
 };
 
-const uint32_t MAX_SPR_SUPPORTED =
-    sizeof ( g_sprRegister ) / sizeof( StopSprReg_t );
+const uint32_t MAX_SPR_SUPPORTED =  10;
 
 //-----------------------------------------------------------------------------
 
@@ -83,7 +83,7 @@  const uint32_t MAX_SPR_SUPPORTED =
  * @note    for register of scope core, function shall force io_threadId to
  *          zero.
  */
-static StopReturnCode_t validateSprImageInputs( void*   const i_pImage,
+STATIC StopReturnCode_t validateSprImageInputs( void*   const i_pImage,
         const CpuReg_t i_regId,
         const uint32_t  i_coreId,
         uint32_t*     i_pThreadId,
@@ -179,7 +179,7 @@  static StopReturnCode_t validateSprImageInputs( void*   const i_pImage,
  * @param[in]   i_data  16 bit immediate data
  * @return  returns 32 bit number representing ori instruction.
  */
-static uint32_t getOriInstruction( const uint16_t i_Rs, const uint16_t i_Ra,
+STATIC uint32_t getOriInstruction( const uint16_t i_Rs, const uint16_t i_Ra,
                                    const uint16_t i_data )
 {
     uint32_t oriInstOpcode = 0;
@@ -197,7 +197,7 @@  static uint32_t getOriInstruction( const uint16_t i_Rs, const uint16_t i_Ra,
 /**
  * @brief generates 32 bit key used for SPR lookup in core section.
  */
-static uint32_t genKeyForSprLookup( const CpuReg_t i_regId )
+STATIC uint32_t genKeyForSprLookup( const CpuReg_t i_regId )
 {
     return getOriInstruction( 0, 0, (uint16_t) i_regId );
 }
@@ -211,7 +211,7 @@  static uint32_t genKeyForSprLookup( const CpuReg_t i_regId )
  * @param[in] i_Rb source register number for xor operation
  * @return returns 32 bit number representing xor  immediate instruction.
  */
-static uint32_t getXorInstruction( const uint16_t i_Ra, const uint16_t i_Rs,
+STATIC uint32_t getXorInstruction( const uint16_t i_Ra, const uint16_t i_Rs,
                                    const uint16_t i_Rb )
 {
     uint32_t xorRegInstOpcode;
@@ -233,7 +233,7 @@  static uint32_t getXorInstruction( const uint16_t i_Ra, const uint16_t i_Rs,
  * @param[in] i_data    16 bit immediate data
  * @return returns 32 bit number representing oris  immediate instruction.
  */
-static uint32_t getOrisInstruction( const uint16_t i_Rs, const uint16_t i_Ra,
+STATIC uint32_t getOrisInstruction( const uint16_t i_Rs, const uint16_t i_Ra,
                                     const uint16_t i_data )
 {
     uint32_t orisInstOpcode;
@@ -253,7 +253,7 @@  static uint32_t getOrisInstruction( const uint16_t i_Rs, const uint16_t i_Ra,
  * @param[in] i_Spr represents spr where data is to be moved.
  * @return returns 32 bit number representing mtspr instruction.
  */
-static uint32_t getMtsprInstruction( const uint16_t i_Rs, const uint16_t i_Spr )
+STATIC uint32_t getMtsprInstruction( const uint16_t i_Rs, const uint16_t i_Spr )
 {
     uint32_t mtsprInstOpcode = 0;
     uint32_t temp = (( i_Spr & 0x03FF ) << 11);
@@ -275,7 +275,7 @@  static uint32_t getMtsprInstruction( const uint16_t i_Rs, const uint16_t i_Spr )
  * @param[in] i_me      bit position up to which mask should be 1.
  * @return returns 32 bit number representing rldicr instruction.
  */
-static uint32_t getRldicrInstruction( const uint16_t i_Ra, const uint16_t i_Rs,
+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;
@@ -294,24 +294,24 @@  static uint32_t getRldicrInstruction( const uint16_t i_Ra, const uint16_t i_Rs,
  * @brief looks up entry for given SPR in given thread/core section.
  * @param[in]   i_pThreadSectLoc    start of given thread section or core section.
  * @param[in]   i_lookUpKey         search key for lookup of given SPR entry.
- * @param[in]   i_isCoreReg         true if register is of scope core, false
+ * @param[in]   i_isThreadReg       true if register is of scope thread, false
  *                                  otherwise.
  * @param[in|out] io_pSprEntryLoc   Input:  NULL
  *                                  Output: location of given entry or end of table.
  * @return      STOP_SAVE_SUCCESS if entry is found, STOP_SAVE_FAIL in case of
  *              an error.
  */
-static StopReturnCode_t lookUpSprInImage( uint32_t* i_pThreadSectLoc,
+STATIC StopReturnCode_t lookUpSprInImage( uint32_t* i_pThreadSectLoc,
         const uint32_t i_lookUpKey,
-        const bool i_isCoreReg,
+        const bool i_isThreadReg,
         void** io_pSprEntryLoc )
 {
-    StopReturnCode_t l_rc = STOP_SAVE_FAIL;
-    uint32_t temp = i_isCoreReg ? (uint32_t)(CORE_RESTORE_CORE_AREA_SIZE) :
-                    (uint32_t)(CORE_RESTORE_THREAD_AREA_SIZE);
-    uint32_t* i_threadSectEnd = i_pThreadSectLoc + temp;
-    uint32_t bctr_inst = SWIZZLE_4_BYTE(BLR_INST);
-    *io_pSprEntryLoc = NULL;
+    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 );
+    *io_pSprEntryLoc            =   NULL;
 
     do
     {
@@ -352,16 +352,16 @@  static StopReturnCode_t lookUpSprInImage( uint32_t* i_pThreadSectLoc,
  * @param[in] i_regData     data needs to be written to SPR entry.
  * @return    STOP_SAVE_SUCCESS if update works, STOP_SAVE_FAIL otherwise.
  */
-static StopReturnCode_t updateSprEntryInImage( uint32_t* i_pSprEntryLocation,
+STATIC StopReturnCode_t updateSprEntryInImage( uint32_t* i_pSprEntryLocation,
         const CpuReg_t i_regId,
         const uint64_t i_regData )
 {
     StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
-    uint32_t tempInst = 0;
-    uint64_t tempRegData = 0;
-    bool newEntry  = true;
-    uint16_t regRs = 0; //to use R0 for SPR restore insruction generation
-    uint16_t regRa = 0;
+    uint32_t tempInst       =   0;
+    uint64_t tempRegData    =   0;
+    bool newEntry           =   true;
+    uint16_t regRs          =   0; //to use R0 for SPR restore insruction generation
+    uint16_t regRa          =   0;
 
     do
     {
@@ -469,12 +469,14 @@  StopReturnCode_t p9_stop_save_cpureg(  void* const i_pImage,
 
     do
     {
-        uint32_t threadId = 0;
-        uint32_t coreId   = 0;
-        uint32_t lookUpKey = 0;
+        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;
+        void* pThreadLocation   = NULL;
+        bool threadScopeReg     = false;
+
+        MY_INF(">> p9_stop_save_cpureg" );
 
         l_rc = getCoreAndThread( i_pImage, i_pir, &coreId, &threadId );
 
@@ -556,6 +558,7 @@  StopReturnCode_t p9_stop_save_cpureg(  void* const i_pImage,
     }
     while(0);
 
+    MY_INF("<< p9_stop_save_cpureg" );
     return l_rc;
 }
 
@@ -572,7 +575,7 @@  StopReturnCode_t p9_stop_save_cpureg(  void* const i_pImage,
  * @note        Function does not validate that the given SCOM address really
  *              belongs to the given section.
  */
-static StopReturnCode_t validateScomImageInputs( void* const i_pImage,
+STATIC StopReturnCode_t validateScomImageInputs( void* const i_pImage,
         const uint32_t i_scomAddress,
         const uint8_t i_chipletId,
         const ScomOperation_t i_operation,
@@ -665,7 +668,7 @@  static StopReturnCode_t validateScomImageInputs( void* const i_pImage,
  * @return      STOP_SAVE_SUCCESS if existing entry is updated, STOP_SAVE_FAIL
  *              otherwise.
  */
-static StopReturnCode_t editScomEntry( uint32_t i_scomAddr, uint64_t i_scomData,
+STATIC StopReturnCode_t editScomEntry( uint32_t i_scomAddr, uint64_t i_scomData,
                                        ScomEntry_t* i_pEntryLocation,
                                        uint32_t i_operation )
 {
@@ -695,16 +698,16 @@  static StopReturnCode_t editScomEntry( uint32_t i_scomAddr, uint64_t i_scomData,
             case P9_STOP_SCOM_NOOP:
                 {
                     uint32_t nopInst = getOriInstruction( 0, 0, 0 );
-                    i_pEntryLocation->scomEntryHeader = SWIZZLE_4_BYTE(SCOM_ENTRY_START);
-                    i_pEntryLocation->scomEntryData = nopInst;
-                    i_pEntryLocation->scomEntryAddress = nopInst;
+                    i_pEntryLocation->scomEntryHeader   =   SWIZZLE_4_BYTE(SCOM_ENTRY_START);
+                    i_pEntryLocation->scomEntryData     =   nopInst;
+                    i_pEntryLocation->scomEntryAddress  =   nopInst;
                 }
                 break;
 
             case P9_STOP_SCOM_APPEND:
-                i_pEntryLocation->scomEntryHeader = SWIZZLE_4_BYTE(SCOM_ENTRY_START);
-                i_pEntryLocation->scomEntryData = i_scomData;
-                i_pEntryLocation->scomEntryAddress = i_scomAddr;
+                i_pEntryLocation->scomEntryHeader       =   SWIZZLE_4_BYTE(SCOM_ENTRY_START);
+                i_pEntryLocation->scomEntryData         =   i_scomData;
+                i_pEntryLocation->scomEntryAddress      =   i_scomAddr;
                 break;
         }
 
@@ -726,7 +729,7 @@  static StopReturnCode_t editScomEntry( uint32_t i_scomAddr, uint64_t i_scomData,
  *              place of NOP, at the end of table or as first entry of the cache
  *              sub-section(L2, L3 or EQ ).
  */
-static StopReturnCode_t updateScomEntry( uint32_t i_scomAddr, uint64_t i_scomData,
+STATIC StopReturnCode_t updateScomEntry( uint32_t i_scomAddr, uint64_t i_scomData,
         ScomEntry_t* i_scomEntry   )
 {
     StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
@@ -740,9 +743,9 @@  static StopReturnCode_t updateScomEntry( uint32_t i_scomAddr, uint64_t i_scomDat
             break;
         }
 
-        i_scomEntry->scomEntryHeader = SWIZZLE_4_BYTE(SCOM_ENTRY_START); // done for now
-        i_scomEntry->scomEntryAddress = i_scomAddr;
-        i_scomEntry->scomEntryData = i_scomData;
+        i_scomEntry->scomEntryHeader    =   SWIZZLE_4_BYTE(SCOM_ENTRY_START); // done for now
+        i_scomEntry->scomEntryAddress   =   i_scomAddr;
+        i_scomEntry->scomEntryData      =   i_scomData;
 
     }
     while(0);
@@ -754,31 +757,20 @@  static StopReturnCode_t updateScomEntry( uint32_t i_scomAddr, uint64_t i_scomDat
 /**
  * @brief populates SCOM restore entry header with version and layout info.
  * @param[in]   i_scomEntry     points to SCOM restore entry
- * @param[in]   i_section       section of SCOM restore area
  * @param[in]   i_imageVer      SGPE image version
+ * @param[in]   i_maxScomEntry  max SCOM entries supported
  */
 
-static void updateEntryHeader( ScomEntry_t* i_scomEntry ,
-                               const ScomSection_t i_section,
-                               uint32_t i_imageVer )
+STATIC void updateEntryHeader( ScomEntry_t* i_scomEntry ,
+                               uint32_t i_imageVer,
+                               uint32_t i_maxScomEntry )
 {
     uint32_t l_temp = 0;
-    uint32_t l_entryLimit = 0;
 
     if( i_imageVer >= STOP_API_VER_CONTROL )
     {
-        if( P9_STOP_SECTION_CORE_SCOM == i_section )
-        {
-            l_entryLimit = MAX_CORE_SCOM_ENTRIES;
-        }
-        else
-        {
-            l_entryLimit = MAX_EQ_SCOM_ENTRIES + MAX_L2_SCOM_ENTRIES +
-                           MAX_L3_SCOM_ENTRIES;
-        }
-
+        l_temp = ( 0x000000ff & i_maxScomEntry );
         l_temp |= ( STOP_API_VER  & 0x7 ) << 28;
-        l_temp |= ( 0x000000ff & l_entryLimit );
         i_scomEntry->scomEntryHeader = SWIZZLE_4_BYTE(l_temp);
 
         MY_INF("SCOM Restore Header 0x%08x", l_temp );
@@ -794,41 +786,41 @@  StopReturnCode_t p9_stop_save_scom( void* const   i_pImage,
                                     const ScomSection_t i_section )
 {
     StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
-    StopCacheSection_t* pStopCacheScomStart = NULL;
-    ScomEntry_t* pScomEntry = NULL;
-    uint32_t entryLimit = 0;
-    uint8_t chipletId = 0;
-
-    uint32_t nopInst;
-    ScomEntry_t* pEntryLocation = NULL;
-    ScomEntry_t* pNopLocation = NULL;
-    ScomEntry_t* pEditScomHeader = NULL;
-    ScomEntry_t* pTableEndLocationtable = NULL;
+    uint32_t entryLimit =   0;
+    uint8_t chipletId   =   0;
+    uint32_t nopInst    =   0;
+    uint32_t index      =   0;
+    uint32_t imageVer   =   0;
+    uint32_t entrySwzHeader = 0;
+    uint32_t l_maxScomRestoreEntry = 0;
+    ScomEntry_t* pScomEntry      =  NULL;
+    ScomEntry_t* pEntryLocation  =  NULL;
+    ScomEntry_t* pNopLocation    =  NULL;
+    ScomEntry_t* pEditScomHeader =  NULL;
+    StopCacheSection_t* pStopCacheScomStart =   NULL;
+    ScomEntry_t* pTableEndLocationtable     =   NULL;
     uint32_t swizzleAddr;
     uint64_t swizzleData;
     uint32_t swizzleAttn;
-    uint32_t entrySwzHeader = 0;
-    uint32_t index = 0;
-    uint32_t swizzleBlr = SWIZZLE_4_BYTE(BLR_INST);
+    uint32_t swizzleBlr     =   SWIZZLE_4_BYTE(BLR_INST);
+    bool     cacheEntry     =   true;
+
+    MY_INF(">> p9_stop_save_scom");
 
     //Reads SGPE image version info from QPMR Header in HOMER
     //For backward compatibility, for base version of SGPE Hcode,
     //STOP API retains default behavior but adds version specific
     //details in each entry in later versions.
+    imageVer       =  *(uint32_t*)((uint8_t*)i_pImage + QPMR_HOMER_OFFSET + QPMR_BUILD_VER_BYTE);
+    imageVer       =  SWIZZLE_4_BYTE(imageVer);
 
-    uint32_t imageVer =  *(uint32_t*)((uint8_t*)i_pImage + QPMR_HOMER_OFFSET + QPMR_BUILD_VER_BYTE);
-    imageVer = SWIZZLE_4_BYTE(imageVer);
 
     do
     {
-        chipletId = i_scomAddress >> 24;
-        chipletId = chipletId & 0x3F;
+        chipletId   =   i_scomAddress >> 24;
+        chipletId   =   chipletId & 0x3F;
 
-        l_rc = validateScomImageInputs( i_pImage,
-                                        i_scomAddress,
-                                        chipletId,
-                                        i_operation,
-                                        i_section );
+        l_rc        =   validateScomImageInputs( i_pImage, i_scomAddress, chipletId, i_operation, i_section );
 
         if( l_rc )
         {
@@ -840,12 +832,15 @@  StopReturnCode_t p9_stop_save_scom( void* const   i_pImage,
         {
             // chiplet is core. So, let us find the start address of SCOM area
             // pertaining to a core in STOP image.
-            pScomEntry = CORE_ID_SCOM_START(i_pImage,
-                                            chipletId )
-                         entryLimit = MAX_CORE_SCOM_ENTRIES;
+            l_maxScomRestoreEntry   =
+                *(uint32_t*)((uint8_t*)i_pImage + CPMR_HOMER_OFFSET + CPMR_MAX_SCOM_REST_PER_CORE_BYTE);
+            pScomEntry              =   CORE_ID_SCOM_START(i_pImage, chipletId )
+                                        cacheEntry              =   false;
         }
         else
         {
+            l_maxScomRestoreEntry   =
+                *(uint32_t*)((uint8_t*)i_pImage + QPMR_HOMER_OFFSET + QPMR_QUAD_MAX_SCOM_ENTRY_BYTE);
             // chiplet is a cache. let us find start address of cache section
             // associated with given chiplet. A cache section associated with
             // given chiplet is split in to L2, L3 and EQ area.
@@ -853,6 +848,8 @@  StopReturnCode_t p9_stop_save_scom( void* const   i_pImage,
                                                     chipletId);
         }
 
+        l_maxScomRestoreEntry   =   SWIZZLE_4_BYTE(l_maxScomRestoreEntry);
+
         if(( !pStopCacheScomStart ) && ( !pScomEntry) )
         {
             //Error invalid pointer to SCOM entry in cache or core section
@@ -885,6 +882,8 @@  StopReturnCode_t p9_stop_save_scom( void* const   i_pImage,
                 //Handling for core and cache segment is different for scom
                 //entries. It is because scom entries are organized differently
                 //in core and cache segment.
+
+                entryLimit  =   l_maxScomRestoreEntry;
                 break;
 
             default:
@@ -892,6 +891,15 @@  StopReturnCode_t p9_stop_save_scom( void* const   i_pImage,
                 break;
         }
 
+        if(( imageVer > LEGACY_SCOM_RESTORE_VER ) && ( cacheEntry ) )
+        {
+            //STOP API migrated to newer algorithm for creation of entries
+            pScomEntry  =   CACHE_SCOM_ADDR(i_pImage,
+                                            chipletId,
+                                            l_maxScomRestoreEntry )
+                            entryLimit  =   l_maxScomRestoreEntry;
+        }
+
         if(( !pScomEntry ) || ( l_rc ) )
         {
             // Error Invalid pointer to cache entry
@@ -901,13 +909,13 @@  StopReturnCode_t p9_stop_save_scom( void* const   i_pImage,
             break;
         }
 
-        nopInst = getOriInstruction( 0, 0, 0 );
-        pEntryLocation = NULL;
-        pNopLocation = NULL;
-        pTableEndLocationtable = NULL;
-        swizzleAddr = SWIZZLE_4_BYTE(i_scomAddress);
-        swizzleData = SWIZZLE_8_BYTE(i_scomData);
-        swizzleAttn = SWIZZLE_4_BYTE(ATTN_OPCODE);
+        nopInst                 =   getOriInstruction( 0, 0, 0 );
+        pEntryLocation          =   NULL;
+        pNopLocation            =   NULL;
+        pTableEndLocationtable  =   NULL;
+        swizzleAddr             =   SWIZZLE_4_BYTE(i_scomAddress);
+        swizzleData             =   SWIZZLE_8_BYTE(i_scomData);
+        swizzleAttn             =   SWIZZLE_4_BYTE(ATTN_OPCODE);
 
         for( index = 0; index < entryLimit; ++index )
         {
@@ -1027,7 +1035,7 @@  StopReturnCode_t p9_stop_save_scom( void* const   i_pImage,
             case P9_STOP_SCOM_OR_APPEND:
             case P9_STOP_SCOM_AND_APPEND:
                 {
-                    uint32_t tempOperation = P9_STOP_SCOM_APPEND;
+                    uint32_t tempOperation  = P9_STOP_SCOM_APPEND;
                     ScomEntry_t* editAppend = NULL;
 
                     if( NULL == pEntryLocation )
@@ -1074,9 +1082,10 @@  StopReturnCode_t p9_stop_save_scom( void* const   i_pImage,
     {
         //Update SCOM Restore entry with version and memory layout
         //info
-        updateEntryHeader( pEditScomHeader, i_section, imageVer );
+        updateEntryHeader( pEditScomHeader, imageVer, l_maxScomRestoreEntry );
     }
 
+    MY_INF("<< p9_stop_save_scom");
     return l_rc;
 }
 
diff --git a/libpore/p9_stop_data_struct.H b/libpore/p9_stop_data_struct.H
index d1b50546..940f4057 100644
--- a/libpore/p9_stop_data_struct.H
+++ b/libpore/p9_stop_data_struct.H
@@ -5,7 +5,7 @@ 
 /*                                                                        */
 /* OpenPOWER HostBoot Project                                             */
 /*                                                                        */
-/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
+/* Contributors Listed Below - COPYRIGHT 2015,2018                        */
 /* [+] International Business Machines Corp.                              */
 /*                                                                        */
 /*                                                                        */
@@ -35,10 +35,6 @@ 
 #ifndef __STOP_DATA_STRUCT_
 #define __STOP_DATA_STRUCT_
 
-#if !(defined  _AIX) && !(defined __SKIBOOT__)
-    #include <endian.h>
-#endif
-
 #include "p9_hcd_memmap_base.H"
 
 #ifdef __SKIBOOT__
@@ -49,6 +45,15 @@ 
     #include <fapi2.H>
 #endif
 
+#ifdef PPC_HYP
+
+    #define STATIC
+
+#else
+
+    #define STATIC static
+
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -140,6 +145,13 @@  enum
 ((StopCacheSection_t *)(((uint8_t *)(io_image)) + QUAD_SCOM_RESTORE_HOMER_OFFSET +\
                         ((i_chipletId - CACHE_CHIPLET_ID_MIN) * \
                          QUAD_SCOM_RESTORE_SIZE_PER_QUAD)));
+
+#define CACHE_SCOM_ADDR(io_image,\
+                        i_chipletId,\
+                        i_maxScomEntry)\
+((ScomEntry_t *)(((uint8_t *)(io_image)) + QUAD_SCOM_RESTORE_HOMER_OFFSET +\
+                 ((i_chipletId - CACHE_CHIPLET_ID_MIN) * \
+                  ((i_maxScomEntry + 1) * 16 ))));
 #ifdef __cplusplus
 }  // extern "C"
 
diff --git a/libpore/p9_stop_util.C b/libpore/p9_stop_util.C
index c351b58a..979455a2 100644
--- a/libpore/p9_stop_util.C
+++ b/libpore/p9_stop_util.C
@@ -5,7 +5,7 @@ 
 /*                                                                        */
 /* OpenPOWER HostBoot Project                                             */
 /*                                                                        */
-/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
+/* Contributors Listed Below - COPYRIGHT 2015,2018                        */
 /* [+] International Business Machines Corp.                              */
 /*                                                                        */
 /*                                                                        */
@@ -32,6 +32,9 @@ 
 // *HWP Team        :  PM
 // *HWP Level       :  2
 // *HWP Consumed by :  HB:HYP
+#ifdef PPC_HYP
+    #include <HvPlicModule.H>
+#endif
 
 #include "p9_stop_api.H"
 #include "p9_stop_util.H"
@@ -42,22 +45,24 @@  namespace stopImageSection
 {
 #endif
 
+//-----------------------------------------------------------------------
+
 /**
  * @brief   Returns proc chip's fuse mode status.
  * @param   i_pImage    points to start of chip's HOMER image.
  * @param   o_fusedMode  points to fuse mode information.
  * @return  STOP_SAVE_SUCCESS if functions succeeds, error code otherwise.
  */
-static StopReturnCode_t  isFusedMode( void* const i_pImage, bool* o_fusedMode )
+STATIC StopReturnCode_t  isFusedMode( void* const i_pImage, bool* o_fusedMode )
 {
-    uint64_t cpmrCheckWord;
-    StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
+    StopReturnCode_t l_rc   =   STOP_SAVE_SUCCESS;
+    uint64_t cpmrCheckWord  =   0;
     *o_fusedMode = false;
 
     do
     {
-        HomerSection_t* pHomerDesc = ( HomerSection_t* ) i_pImage;
-        HomerImgDesc_t* pHomer =  (HomerImgDesc_t*)( pHomerDesc->interrruptHandler );
+        HomerSection_t* pHomerDesc  =   ( HomerSection_t* ) i_pImage;
+        HomerImgDesc_t* pHomer      =   (HomerImgDesc_t*)( pHomerDesc->interrruptHandler );
 
         if( !i_pImage )
         {
@@ -90,7 +95,7 @@  static StopReturnCode_t  isFusedMode( void* const i_pImage, bool* o_fusedMode )
         }
 
         MY_ERR("Unexpected value 0x%08x for fused mode. Bad or corrupt "
-               "HOMER location", pHomer->fuseModeStatus );
+               "HOMER location", pHomer->fusedModeStatus );
         l_rc = STOP_SAVE_INVALID_FUSED_CORE_STATUS ;
 
     }