[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