[Skiboot] [RESEND PATCH v2 2/4] Self save API integration

Pratik Sampat psampat at linux.ibm.com
Sun Jan 12 19:49:38 AEDT 2020


In thehttps://patchwork.ozlabs.org/  I can see that applying the patches have
failed. However, I can see that the patches are being applied to the
d75e82dbfbb9443efeb3f9a5921ac23605aab469 which is not the current up-stream 
master. I have tested these patches which apply on the master branch of 
https://github.com/open-power/skiboot


On 10/01/20 5:20 pm, Pratik Rajesh Sampat wrote:
> The commit makes the self save API available outside the firmware by defining
> an OPAL wrapper.
> This wrapper has a similar interface to that of self restore and expects the
> cpu pir, SPR number, minus the value of that SPR to be passed in its
> paramters and returns OPAL_SUCCESS on success.
>
> Signed-off-by: Pratik Rajesh Sampat <psampat at linux.ibm.com>
> ---
>   doc/opal-api/opal-slw-self-save-reg-176.rst | 33 ++++++++
>   hw/slw.c                                    | 89 +++++++++++++++++++++
>   include/opal-api.h                          |  3 +-
>   include/p9_stop_api.H                       | 17 ++++
>   include/skiboot.h                           |  3 +
>   5 files changed, 144 insertions(+), 1 deletion(-)
>   create mode 100644 doc/opal-api/opal-slw-self-save-reg-176.rst
>
> diff --git a/doc/opal-api/opal-slw-self-save-reg-176.rst b/doc/opal-api/opal-slw-self-save-reg-176.rst
> new file mode 100644
> index 00000000..6a4e1a5f
> --- /dev/null
> +++ b/doc/opal-api/opal-slw-self-save-reg-176.rst
> @@ -0,0 +1,33 @@
> +.. OPAL_SLW_SELF_SAVE_REG:
> +
> +OPAL_SLW_SELF_SAVE_REG
> +======================
> +
> +.. code-block:: c
> +
> +   #define OPAL_SLW_SELF_SAVE_REG			176
> +
> +   int64_t opal_slw_self_save_reg(uint64_t cpu_pir, uint64_t sprn);
> +
> +:ref:`OPAL_SLW_SELF_SAVE_REG` is used to inform low-level firmware to save
> +the current contents of the SPR before entering a state of loss and
> +also restore the content back on waking up from a deep stop state.
> +
> +Parameters
> +----------
> +
> +``uint64_t cpu_pir``
> +  This parameter specifies the pir of the cpu for which the call is being made.
> +``uint64_t sprn``
> +  This parameter specifies the spr number as mentioned in p9_stop_api.H for
> +  Power9 and p8_pore_table_gen_api.H for Power8.
> +
> +Returns
> +-------
> +
> +:ref:`OPAL_UNSUPPORTED`
> +  If spr restore is not supported by pore engine.
> +:ref:`OPAL_PARAMETER`
> +  Invalid handle for the pir/chip
> +:ref:`OPAL_SUCCESS`
> +  On success
> \ No newline at end of file
> diff --git a/hw/slw.c b/hw/slw.c
> index 566a1128..14dbce47 100644
> --- a/hw/slw.c
> +++ b/hw/slw.c
> @@ -35,6 +35,43 @@ static bool slw_current_le = false;
>   enum wakeup_engine_states wakeup_engine_state = WAKEUP_ENGINE_NOT_PRESENT;
>   bool has_deep_states = false;
>   
> +/**
> + * The struct and SPR list is partially consistent with libpore/p9_stop_api.c
> + */
> +/**
> + * @brief summarizes attributes associated with a SPR register.
> + */
> +typedef struct
> +{
> +    uint32_t iv_sprId;
> +    bool     iv_isThreadScope;
> +    uint32_t iv_saveMaskPos;
> +
> +} StopSprReg_t;
> +
> +/**
> + * @brief a true in the table below means register is of scope thread
> + * whereas a false meanse register is of scope core.
> + * The number is the bit position on a uint32_t mask
> + */
> +
> +static const StopSprReg_t g_sprRegister[] =
> +{
> +	{ P9_STOP_SPR_DAWR,      true,  1   },
> +	{ 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, 255 },
> +	{ P9_STOP_SPR_HID,       false, 21  },
> +	{ P9_STOP_SPR_HMEER,     false, 22  },
> +	{ P9_STOP_SPR_PMCR,      false, 23  },
> +	{ P9_STOP_SPR_PTCR,      false, 24  },
> +};
> +
> +static const uint32_t MAX_SPR_SUPPORTED	= ARRAY_SIZE(g_sprRegister);
> +
>   DEFINE_LOG_ENTRY(OPAL_RC_SLW_INIT, OPAL_PLATFORM_ERR_EVT, OPAL_SLW,
>   		 OPAL_PLATFORM_FIRMWARE, OPAL_PREDICTIVE_ERR_GENERAL,
>   		 OPAL_NA);
> @@ -1446,6 +1483,58 @@ int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val)
>   
>   opal_call(OPAL_SLW_SET_REG, opal_slw_set_reg, 3);
>   
> +int64_t opal_slw_self_save_reg(uint64_t cpu_pir, uint64_t sprn)
> +{
> +	struct cpu_thread * c = find_cpu_by_pir(cpu_pir);
> +	struct proc_chip * chip;
> +	int rc;
> +	int index;
> +	uint32_t save_reg_vector = 0;
> +
> +	if (!c) {
> +		prlog(PR_DEBUG, "SLW: Unknown thread with pir %x\n",
> +		      (u32) cpu_pir);
> +		return OPAL_PARAMETER;
> +	}
> +
> +	chip = get_chip(c->chip_id);
> +	if (!chip) {
> +		prlog(PR_DEBUG, "SLW: Unknown chip for thread with pir %x\n",
> +		      (u32) cpu_pir);
> +		return OPAL_PARAMETER;
> +	}
> +	if (proc_gen != proc_gen_p9 || !has_deep_states) {
> +		prlog(PR_DEBUG, "SLW: Does not support deep states\n");
> +		return OPAL_UNSUPPORTED;
> +	}
> +	if (wakeup_engine_state != WAKEUP_ENGINE_PRESENT) {
> +		log_simple_error(&e_info(OPAL_RC_SLW_REG),
> +			"SLW: wakeup_engine in bad state=%d chip=%x\n",
> +			wakeup_engine_state, chip->id);
> +		return OPAL_INTERNAL_ERROR;
> +	}
> +	for (index = 0; index < MAX_SPR_SUPPORTED; ++index) {
> +		if (sprn == (CpuReg_t) g_sprRegister[index].iv_sprId) {
> +			save_reg_vector = PPC_BIT32(
> +				g_sprRegister[index].iv_saveMaskPos);
> +			break;
> +		}
> +	}
> +	if (save_reg_vector == 0)
> +		return OPAL_INTERNAL_ERROR;
> +	rc = p9_stop_save_cpureg_control((void *) chip->homer_base,
> +						cpu_pir, save_reg_vector);
> +
> +	if (rc) {
> +		log_simple_error(&e_info(OPAL_RC_SLW_REG),
> +			"SLW: Failed to save vector %x for CPU %x\n",
> +			save_reg_vector, c->pir);
> +		return OPAL_INTERNAL_ERROR;
> +	}
> +	return OPAL_SUCCESS;
> +}
> +opal_call(OPAL_SLW_SELF_SAVE_REG, opal_slw_self_save_reg, 2);
> +
>   void slw_init(void)
>   {
>   	struct proc_chip *chip;
> diff --git a/include/opal-api.h b/include/opal-api.h
> index d92ecf54..af2c2476 100644
> --- a/include/opal-api.h
> +++ b/include/opal-api.h
> @@ -227,7 +227,8 @@
>   #define OPAL_SECVAR_ENQUEUE_UPDATE		178
>   #define OPAL_PHB_SET_OPTION			179
>   #define OPAL_PHB_GET_OPTION			180
> -#define OPAL_LAST				180
> +#define OPAL_SLW_SELF_SAVE_REG			181
> +#define OPAL_LAST				181
>   
>   #define QUIESCE_HOLD			1 /* Spin all calls at entry */
>   #define QUIESCE_REJECT			2 /* Fail all calls with OPAL_BUSY */
> diff --git a/include/p9_stop_api.H b/include/p9_stop_api.H
> index 9d3bc1e5..c304f70f 100644
> --- a/include/p9_stop_api.H
> +++ b/include/p9_stop_api.H
> @@ -34,6 +34,8 @@
>   ///
>   /// @file   p9_stop_api.H
>   /// @brief  describes STOP API which  create/manipulate STOP image.
> +///         This header need not be consistent, however is a subset of the
> +///         libpore/p9_stop_api.H counterpart
>   ///
>   // *HWP HW Owner    :  Greg Still <stillgs at us.ibm.com>
>   // *HWP FW Owner    :  Prem Shanker Jha <premjha2 at in.ibm.com>
> @@ -58,6 +60,7 @@ typedef enum
>       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_LDBAR   =    850,   // thread register
>       P9_STOP_SPR_PSSCR   =    855,   // thread register
>       P9_STOP_SPR_PMCR    =    884,   // core register
> @@ -230,6 +233,20 @@ 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 );
>   #ifdef __cplusplus
>   } // extern "C"
>   };  // namespace stopImageSection ends
> diff --git a/include/skiboot.h b/include/skiboot.h
> index e9d57dec..1ed8464e 100644
> --- a/include/skiboot.h
> +++ b/include/skiboot.h
> @@ -306,6 +306,9 @@ extern void nx_p9_rng_late_init(void);
>   /* SLW reinit function for switching core settings */
>   extern int64_t slw_reinit(uint64_t flags);
>   
> +/* Self save SPR before entering the stop state */
> +extern int64_t opal_slw_self_save_reg(uint64_t cpu_pir, uint64_t sprn);
> +
>   /* Patch SPR in SLW image */
>   extern int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val);
>   



More information about the Skiboot mailing list