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

Shilpasri G Bhat shilpa.bhat at linux.vnet.ibm.com
Tue Feb 16 00:44:01 AEDT 2016


Hi Cedric,

On 02/15/2016 06:24 PM, C├ędric Le Goater wrote:
> 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.
> 

No. I did not mean this opal call to replace the existing sensor OPAL interface.
It could be used to add new sensors after the system has booted.

Thanks and Regards,
Shilpa

>> 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