[Skiboot] [RFC PATCH 2/2] occ : Add opal call to support runtime update

C├ędric Le Goater clg at fr.ibm.com
Mon Feb 15 23:54:02 AEDT 2016


Hello Shilpasri,

On 02/15/2016 05:13 AM, Shilpasri G Bhat wrote:
> This patch adds a generic opal call to retrieve updated information.
> One such data is pstate table. OCC can provide new frequencies
> to the host which needs to be parsed and passed to linux for cpufreq
> to consume it. This call can be extended to support reading sensors,
> frequency throttle stats later in the future.

So you don't plan to use the existing sensor OPAL interface ? 

C.
 
> Signed-off-by: Shilpasri G Bhat <shilpa.bhat at linux.vnet.ibm.com>
> ---
>  core/opal.c        | 19 ++++++++++++
>  hw/occ.c           | 87 +++++++++++++++++++++++++++++++++++++++++++-----------
>  include/opal-api.h | 10 ++++++-
>  3 files changed, 98 insertions(+), 18 deletions(-)
> 
> diff --git a/core/opal.c b/core/opal.c
> index b6411f0..70ad574 100644
> --- a/core/opal.c
> +++ b/core/opal.c
> @@ -403,3 +403,22 @@ static int64_t opal_sync_host_reboot(void)
>  		return OPAL_BUSY_EVENT;
>  }
>  opal_call(OPAL_SYNC_HOST_REBOOT, opal_sync_host_reboot, 0);
> +
> +/* Opal call to get runtime updates */
> +static int opal_get_dynamic_update(enum opal_update_type type, void *buffer,
> +				   uint64_t len)
> +{
> +	if (type > OPAL_UPDATE_TYPE_MAX) {
> +		prerror("Unsupported dynamic update type %d\n", type);
> +		return OPAL_PARAMETER;
> +	}
> +
> +	switch (type) {
> +	case OPAL_UPDATE_TYPE_PSTATES:
> +		return opal_get_dynamic_pstate_update(buffer, len);
> +	default:
> +		prerror("Unsupported dynamic update type %d\n", type);
> +		return OPAL_PARAMETER;
> +	}
> +}
> +opal_call(OPAL_GET_DYNAMIC_UPDATE, opal_get_dynamic_update, 3);
> diff --git a/hw/occ.c b/hw/occ.c
> index 93dd7ce..301d2e4 100644
> --- a/hw/occ.c
> +++ b/hw/occ.c
> @@ -27,6 +27,7 @@
>  #include <opal-api.h>
>  #include <opal-msg.h>
>  #include <timer.h>
> +#include <libfdt/libfdt.h>
>  
>  /* OCC Communication Area for PStates */
>  
> @@ -140,14 +141,23 @@ static bool wait_for_all_occ_init(void)
>  	return true;
>  }
>  
> +/* Return nominal pstate to set in each core */
> +static s8 get_nominal_pstate(void)
> +{
> +	struct proc_chip *chip;
> +	struct occ_pstate_table *occ_data;
> +
> +	chip = next_chip(NULL);
> +	occ_data = chip_occ_data(chip);
> +	return occ_data->pstate_nom;
> +}
> +
>  /* Add device tree properties to describe pstates states */
> -/* Retrun nominal pstate to set in each core */
> -static bool add_cpu_pstate_properties(s8 *pstate_nom)
> +static bool add_cpu_pstate_properties(struct dt_node *power_mgt)
>  {
>  	struct proc_chip *chip;
>  	uint64_t occ_data_area;
>  	struct occ_pstate_table *occ_data;
> -	struct dt_node *power_mgt;
>  	u8 nr_pstates, nr_cores = 0;
>  	s8 pmax;
>  	/* Arrays for device tree */
> @@ -197,12 +207,6 @@ static bool add_cpu_pstate_properties(s8 *pstate_nom)
>  		return false;
>  	}
>  
> -	power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
> -	if (!power_mgt) {
> -		prerror("OCC: dt node /ibm,opal/power-mgt not found\n");
> -		return false;
> -	}
> -
>  	rc = false;
>  
>  	/* Setup arrays for device-tree */
> @@ -267,9 +271,6 @@ static bool add_cpu_pstate_properties(s8 *pstate_nom)
>  		free(dt_core_max);
>  	}
>  
> -	/* Return pstate to set for each core */
> -	*pstate_nom = occ_data->pstate_nom;
> -
>  	for_each_chip(chip) {
>  		struct dt_node *occ_node;
>  
> @@ -461,6 +462,7 @@ done:
>  /* Called after OCC init on P8 */
>  void occ_pstates_init(void)
>  {
> +	struct dt_node *power_mgt;
>  	struct proc_chip *chip;
>  	struct cpu_thread *c;
>  	s8 pstate_nom;
> @@ -484,16 +486,21 @@ void occ_pstates_init(void)
>  		return;
>  	}
>  
> -	/*
> -	 * Check boundary conditions and add device tree nodes
> -	 * and return nominal pstate to set for the core
> -	 */
> -	if (!add_cpu_pstate_properties(&pstate_nom)) {
> +	power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
> +	if (!power_mgt) {
> +		prerror("OCC: dt node /ibm,opal/power-mgt not found\n");
> +		return;
> +	}
> +
> +	/* Check boundary conditions and add device tree nodes */
> +	if (!add_cpu_pstate_properties(power_mgt)) {
>  		log_simple_error(&e_info(OPAL_RC_OCC_PSTATE_INIT),
>  			"Skiping core cpufreq init due to OCC error\n");
>  		return;
>  	}
>  
> +	/* Get nominal pstate to set for the core */
> +	pstate_nom = get_nominal_pstate();
>  	/* Setup host based pstates and set nominal frequency */
>  	for_each_chip(chip) {
>  		for_each_available_core_in_chip(c, chip->id) {
> @@ -929,4 +936,50 @@ void occ_fsp_init(void)
>  		fsp_register_client(&fsp_occ_client, FSP_MCLASS_OCC);
>  }
>  
> +int opal_get_dynamic_pstate_update(void *buff, uint64_t len)
> +{
> +	struct dt_node *new_dt_root, *power_mgt;
> +	void *fdt;
> +	int ret;
> +
> +	if (len > DEVICE_TREE_MAX_SIZE) {
> +		prerror("OCC: Invalid DT size %lld\n", len);
> +		return OPAL_PARAMETER;
> +	}
> +
> +	last_phandle = 0;
> +	new_dt_root = dt_new_root("");
> +	if (!new_dt_root) {
> +		prerror("OCC: Cannote create new_dt_root\n");
> +		return OPAL_NO_MEM;
> +	}
>  
> +	power_mgt = dt_new(new_dt_root, "power-mgt");
> +	if (!power_mgt) {
> +		prerror("OCC: Cannot create dt node /power-mgt\n");
> +		ret = OPAL_NO_MEM;
> +		goto free_dt_root;
> +	}
> +
> +	if (!add_cpu_pstate_properties(power_mgt)) {
> +		prerror("OCC: Pstates reinitialization failed\n");
> +		ret = OPAL_INTERNAL_ERROR;
> +		goto free_dt_root;
> +	}
> +
> +	fdt = create_dtb(new_dt_root);
> +	if (!fdt) {
> +		prerror("OCC: DTB creation failed\n");
> +		ret = OPAL_INTERNAL_ERROR;
> +		goto free_dt_root;
> +	}
> +
> +	ret = fdt_open_into(fdt, buff, fdt_totalsize(fdt));
> +	if (ret)
> +		prerror("fdt_move failed %d\n", ret);
> +
> +	free(fdt);
> +free_dt_root:
> +	dt_free(new_dt_root);
> +	return ret;
> +}
> diff --git a/include/opal-api.h b/include/opal-api.h
> index 369aa93..2727fa6 100644
> --- a/include/opal-api.h
> +++ b/include/opal-api.h
> @@ -163,7 +163,8 @@
>  #define OPAL_LEDS_SET_INDICATOR			115
>  #define OPAL_CEC_REBOOT2			116
>  #define OPAL_CONSOLE_FLUSH			117
> -#define OPAL_LAST				117
> +#define OPAL_GET_DYNAMIC_UPDATE			118
> +#define OPAL_LAST				118
>  
>  /* Device tree flags */
>  
> @@ -980,6 +981,13 @@ enum {
>  	OPAL_REBOOT_PLATFORM_ERROR,
>  };
>  
> +enum opal_update_type {
> +	OPAL_UPDATE_TYPE_PSTATES,
> +	OPAL_UPDATE_TYPE_MAX
> +};
> +
> +extern int opal_get_dynamic_pstate_update(void *buff, uint64_t len);
> +
>  #endif /* __ASSEMBLY__ */
>  
>  #endif /* __OPAL_API_H */
> 



More information about the Skiboot mailing list