From 1eb77e6332d61b5f70a04dcedcbf6c32d25f5a9c Mon Sep 17 00:00:00 2001 From: Akshay Adiga Date: Fri, 15 Sep 2017 17:50:58 +0530 Subject: [PATCH] SLW: Add opal_slw_set_reg support for power9 This OPAL call is made from Linux to OPAL to configure values in various SPRs after wakeup from a deep idle state. Signed-off-by: Akshay Adiga Reviewed-by: Vaidyanathan Srinivasan Signed-off-by: Stewart Smith --- hw/slw.c | 60 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/hw/slw.c b/hw/slw.c index d8829a6b5de5..a1ed7ba2186f 100644 --- a/hw/slw.c +++ b/hw/slw.c @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -1402,41 +1403,60 @@ int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val) struct cpu_thread *c = find_cpu_by_pir(cpu_pir); struct proc_chip *chip; - void *image; int rc; - int i; - int spr_is_supported = 0; assert(c); chip = get_chip(c->chip_id); assert(chip); - image = (void *) chip->slw_base; - /* Check of the SPR is supported by libpore */ - for ( i=0; i < SLW_SPR_REGS_SIZE ; i++) { - if (sprn == SLW_SPR_REGS[i].value) { - spr_is_supported = 1; - break; + if (proc_gen == proc_gen_p9) { + if (!chip->homer_base) { + log_simple_error(&e_info(OPAL_RC_SLW_REG), + "SLW: HOMER base not set %x\n", + chip->id); + return OPAL_INTERNAL_ERROR; } - } - if (!spr_is_supported) { - log_simple_error(&e_info(OPAL_RC_SLW_REG), + rc = p9_stop_save_cpureg((void *)chip->homer_base, + sprn, val, cpu_pir); + + } else if (proc_gen == proc_gen_p8) { + int spr_is_supported = 0; + void *image; + int i; + + /* Check of the SPR is supported by libpore */ + for (i = 0; i < SLW_SPR_REGS_SIZE ; i++) { + if (sprn == SLW_SPR_REGS[i].value) { + spr_is_supported = 1; + break; + } + } + if (!spr_is_supported) { + log_simple_error(&e_info(OPAL_RC_SLW_REG), "SLW: Trying to set unsupported spr for CPU %x\n", - c->pir); + c->pir); + return OPAL_UNSUPPORTED; + } + image = (void *)chip->slw_base; + rc = p8_pore_gen_cpureg_fixed(image, P8_SLW_MODEBUILD_SRAM, + sprn, val, + cpu_get_core_index(c), + cpu_get_thread_index(c)); + } else { + log_simple_error(&e_info(OPAL_RC_SLW_REG), + "SLW: proc_gen not supported\n"); return OPAL_UNSUPPORTED; - } - rc = p8_pore_gen_cpureg_fixed(image, P8_SLW_MODEBUILD_SRAM, sprn, - val, cpu_get_core_index(c), - cpu_get_thread_index(c)); + } if (rc) { log_simple_error(&e_info(OPAL_RC_SLW_REG), - "SLW: Failed to set spr for CPU %x\n", - c->pir); + "SLW: Failed to set spr %llx for CPU %x, RC=0x%x\n", + sprn, c->pir, rc); return OPAL_INTERNAL_ERROR; } - + prlog(PR_DEBUG, "SLW: restore spr:0x%llx on c:0x%x with 0x%llx\n", + sprn, c->pir, val); return OPAL_SUCCESS; }