diff options
author | Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> | 2017-09-15 17:50:58 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-09-19 04:16:53 -0500 |
commit | 1eb77e6332d61b5f70a04dcedcbf6c32d25f5a9c (patch) | |
tree | 23e9e34181e44ed2816d06290723edb5cae523c3 /hw | |
parent | 3c79b3daa9f3439113690a0b3c6a127b7a425125 (diff) | |
download | skiboot-1eb77e6332d61b5f70a04dcedcbf6c32d25f5a9c.zip skiboot-1eb77e6332d61b5f70a04dcedcbf6c32d25f5a9c.tar.gz skiboot-1eb77e6332d61b5f70a04dcedcbf6c32d25f5a9c.tar.bz2 |
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 <akshay.adiga@linux.vnet.ibm.com>
Reviewed-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/slw.c | 60 |
1 files changed, 40 insertions, 20 deletions
@@ -30,6 +30,7 @@ #include <libfdt/libfdt.h> #include <opal-api.h> +#include <p9_stop_api.H> #include <p8_pore_table_gen_api.H> #include <sbe_xip_image.h> @@ -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; } |