@@ -756,9 +756,12 @@ static void slw_late_init_p9(struct proc_chip *chip)
/* Add device tree properties to determine self-save | restore */
void add_cpu_self_save_properties()
{
- int i;
+ int i, rc;
+ bool self_save_supported = true;
struct dt_node *self_restore, *self_save, *power_mgt;
bitmap_t *self_restore_map, *self_save_map;
+ uint64_t compVector = -1;
+ struct proc_chip *chip;
const uint64_t self_restore_regs[] = {
P8_SPR_HRMOR,
@@ -791,6 +794,21 @@ void add_cpu_self_save_properties()
self_save_map = zalloc(BITMAP_BYTES(SPR_BITMAP_LENGTH));
self_restore_map = zalloc(BITMAP_BYTES(SPR_BITMAP_LENGTH));
+ chip = next_chip(NULL);
+ assert(chip);
+ rc = proc_stop_api_discover_capability((void *) chip->homer_base,
+ &compVector);
+ if (rc == STOP_SAVE_ARG_INVALID_IMG) {
+ prlog(PR_DEBUG, "HOMER BASE INVALID\n");
+ goto bail;
+ } else if (rc == STOP_SAVE_API_IMG_INCOMPATIBLE) {
+ prlog(PR_DEBUG, "STOP API running incompatible versions\n");
+ if ((compVector & SELF_RESTORE_VER_MISMATCH) == 0) {
+ prlog(PR_DEBUG, "Self-save API unsupported\n");
+ self_save_supported = false;
+ }
+ }
+
for (i = 0; i < ARRAY_SIZE(self_save_regs); i++)
bitmap_set_bit(*self_save_map, self_save_regs[i]);
@@ -818,7 +836,7 @@ void add_cpu_self_save_properties()
prerror("OCC: Failed to create self save node");
goto bail;
}
- if (proc_gen == proc_gen_p9) {
+ if (proc_gen == proc_gen_p9 && self_save_supported) {
dt_add_property_string(self_save, "status", "enabled");
dt_add_property(self_save, "sprn-bitmask", *self_save_map,
@@ -110,6 +110,7 @@ typedef enum
STOP_SAVE_FAIL = 14, // for internal failure within firmware.
STOP_SAVE_SPR_ENTRY_MISSING = 15,
STOP_SAVE_SPR_BIT_POS_RESERVE = 16,
+ STOP_SAVE_API_IMG_INCOMPATIBLE = 18,
} StopReturnCode_t;
/**
@@ -164,6 +165,14 @@ typedef enum
} ScomSection_t;
+/**
+ * @brief versions pertaining relvant to STOP API.
+ */
+typedef enum
+{
+ STOP_API_VER = 0x00,
+ STOP_API_VER_CONTROL = 0x02,
+} VersionList_t;
/**
@@ -195,6 +204,14 @@ typedef enum
BIT_POS_USPRG1 = 30,
} SprBitPositionList_t;
+typedef enum
+{
+ SMF_SUPPORT_MISSING_IN_HOMER = 0x01,
+ SELF_SUPPORT_MISSING_FOR_LE_HYP = 0x02,
+ IPL_RUNTIME_CPU_SAVE_VER_MISMATCH = 0x04,
+ SELF_RESTORE_VER_MISMATCH = 0x08,
+} VersionIncompList_t;
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -247,6 +264,15 @@ StopReturnCode_t p9_stop_save_scom( void* const i_pImage,
StopReturnCode_t
p9_stop_save_cpureg_control( void* i_pImage, const uint64_t i_pir,
const uint32_t i_saveRegVector );
+
+/**
+ * @brief verifies if API is compatible of current HOMER image.
+ * @param[in] i_pImage points to the start of HOMER image of P9 chip.
+ * @param[out] o_inCompVector list of incompatibilities found.
+ * @return STOP_SAVE_SUCCESS if if API succeeds, error code otherwise.
+ */
+StopReturnCode_t proc_stop_api_discover_capability( void* const i_pImage, uint64_t* o_inCompVector );
+
#ifdef __cplusplus
} // extern "C"
}; // namespace stopImageSection ends
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -76,7 +76,8 @@ enum
SKIP_SPR_REST_INST = 0x4800001c, //b . +0x01c
MFLR_R30 = 0x7fc802a6,
SKIP_SPR_SELF_SAVE = 0x3bff0020, //addi r31 r31, 0x20
- MTLR_INST = 0x7fc803a6 //mtlr r30
+ MTLR_INST = 0x7fc803a6, //mtlr r30
+ BRANCH_BE_INST = 0x48000020,
};
#ifdef __cplusplus
@@ -444,6 +444,13 @@ HCD_CONST(CME_QUAD_PSTATE_SIZE, HALF_KB)
HCD_CONST(CME_REGION_SIZE, (64 * ONE_KB))
+
+// HOMER compatibility
+
+HCD_CONST(STOP_API_CPU_SAVE_VER, 0x02)
+HCD_CONST(SELF_SAVE_RESTORE_VER, 0x02)
+HCD_CONST(SMF_SUPPORT_SIGNATURE_OFFSET, 0x1300)
+HCD_CONST(SMF_SELF_SIGNATURE, (0x5f534d46))
// Debug
HCD_CONST(CPMR_TRACE_REGION_OFFSET, (512 * ONE_KB))
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -1828,6 +1828,64 @@ StopReturnCode_t proc_stop_init_self_save( void* const i_pImage, const uint32_t
return l_rc;
}
+StopReturnCode_t proc_stop_api_discover_capability( void* const i_pImage, uint64_t * o_inCompVector )
+{
+ StopReturnCode_t l_rc = STOP_SAVE_SUCCESS;
+ uint64_t l_incompVector = 0;
+ uint32_t l_tempWord = 0;
+ *o_inCompVector = 0;
+
+ do
+ {
+ if( !i_pImage )
+ {
+ l_rc = STOP_SAVE_ARG_INVALID_IMG;
+ break;
+ }
+
+ l_tempWord =
+ *(uint32_t*)((uint8_t*)i_pImage + CPMR_HOMER_OFFSET + SMF_SUPPORT_SIGNATURE_OFFSET);
+
+ if( l_tempWord != SWIZZLE_4_BYTE(SMF_SELF_SIGNATURE) )
+ {
+ l_incompVector |= SMF_SUPPORT_MISSING_IN_HOMER;
+ }
+
+ l_tempWord = *(uint32_t *)((uint8_t *)i_pImage + CPMR_HOMER_OFFSET + CPMR_HEADER_SIZE );
+
+ if( l_tempWord != SWIZZLE_4_BYTE(BRANCH_BE_INST) )
+ {
+ l_incompVector |= SELF_SUPPORT_MISSING_FOR_LE_HYP;
+ }
+
+ l_tempWord = *(uint8_t *)((uint8_t *)i_pImage + CPMR_HOMER_OFFSET + CPMR_SELF_RESTORE_VER_BYTE );
+
+ prlog(PR_EMERG, "SLW: self save ltemp: 0x%x\n", l_tempWord);
+ if( l_tempWord < SELF_SAVE_RESTORE_VER )
+ {
+ l_incompVector |= SELF_RESTORE_VER_MISMATCH;
+ }
+
+ l_tempWord = *(uint8_t *)((uint8_t *)i_pImage + CPMR_HOMER_OFFSET + CPMR_STOP_API_VER_BYTE );
+
+ if( l_tempWord < STOP_API_CPU_SAVE_VER )
+ {
+ l_incompVector |= IPL_RUNTIME_CPU_SAVE_VER_MISMATCH;
+ }
+
+ prlog(PR_EMERG, "SLW: Comp: 0x%llx\n", l_incompVector);
+ *o_inCompVector = l_incompVector;
+
+ if( l_incompVector )
+ {
+ l_rc = STOP_SAVE_API_IMG_INCOMPATIBLE;
+ }
+
+ }while(0);
+
+ return l_rc;
+}
+
#ifdef __cplusplus
} //namespace stopImageSection ends
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -114,6 +114,7 @@ typedef enum
STOP_SAVE_FAIL = 14, // for internal failure within firmware.
STOP_SAVE_SPR_ENTRY_MISSING = 15,
STOP_SAVE_SPR_BIT_POS_RESERVE = 16,
+ STOP_SAVE_API_IMG_INCOMPATIBLE = 18,
} StopReturnCode_t;
/**
@@ -198,6 +199,21 @@ typedef enum
BIT_POS_USPRG1 = 30,
} SprBitPositionList_t;
+/**
+ * @brief List of major incompatibilities between API version.
+ * @note STOP APIs assumes a specific HOMER layout, certain
+ * level of CME-SGPE hcode and certain version of self-save restore
+ * binary. A mismatch can break STOP function.
+ */
+
+typedef enum
+{
+ SMF_SUPPORT_MISSING_IN_HOMER = 0x01,
+ SELF_SUPPORT_MISSING_FOR_LE_HYP = 0x02,
+ IPL_RUNTIME_CPU_SAVE_VER_MISMATCH = 0x04,
+ SELF_RESTORE_VER_MISMATCH = 0x08,
+} VersionIncompList_t;
+
#ifdef __cplusplus
extern "C" {
@@ -341,6 +357,14 @@ StopReturnCode_t proc_stop_save_cpureg( void* const i_pImage,
*/
StopReturnCode_t proc_stop_init_self_save( void* const i_pImage, const uint32_t i_corePos );
+/**
+ * @brief verifies if API is compatible of current HOMER image.
+ * @param[in] i_pImage points to the start of HOMER image of P9 chip.
+ * @param[out] o_inCompVector list of incompatibilities found.
+ * @return STOP_SAVE_SUCCESS if if API succeeds, error code otherwise.
+ */
+StopReturnCode_t proc_stop_api_discover_capability( void* const i_pImage, uint64_t* o_inCompVector );
+
#ifdef __cplusplus
} // extern "C"
}; // namespace stopImageSection ends