diff options
author | Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> | 2015-11-12 18:41:32 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-11-13 15:57:13 +1100 |
commit | a804c1b2c13f0f16fb6999c3d2340fa6bd2865d3 (patch) | |
tree | dca05d627e2a7c1d022952f580348e4fd03795c2 | |
parent | ad1aa4b81a1add6a3ac2e100dcc73aa0ed33d611 (diff) | |
download | skiboot-a804c1b2c13f0f16fb6999c3d2340fa6bd2865d3.zip skiboot-a804c1b2c13f0f16fb6999c3d2340fa6bd2865d3.tar.gz skiboot-a804c1b2c13f0f16fb6999c3d2340fa6bd2865d3.tar.bz2 |
occ: hbrt: Change the OCC reset order
Modify the OCC reset order such that master OCC is reset after the
slave OCCs are reset. In Tuleta/Alpine systems 'proc0' will always be
the master OCC, which has to be stopped last when FSP sends OCC_RESET
command to Opal.
This fixes BZ 119718, SW289036
Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | core/hostservices.c | 40 | ||||
-rw-r--r-- | hw/occ.c | 44 | ||||
-rw-r--r-- | include/hostservices.h | 3 |
3 files changed, 75 insertions, 12 deletions
diff --git a/core/hostservices.c b/core/hostservices.c index 815654d..672b57f 100644 --- a/core/hostservices.c +++ b/core/hostservices.c @@ -826,9 +826,8 @@ int host_services_occ_start(void) int host_services_occ_stop(void) { - struct proc_chip *chip; - int i, rc = 0, nr_chips=0; - uint64_t chipids[MAX_CHIPS]; + int i, rc = 0, nr_slaves = 0, nr_masters = 0; + uint64_t *master_chipids = NULL, *slave_chipids = NULL; prlog(PR_INFO, "HBRT: OCC Stop requested\n"); @@ -837,22 +836,39 @@ int host_services_occ_stop(void) return -ENOENT; } - for_each_chip(chip) { - chipids[nr_chips++] = chip->id; - } + rc = find_master_and_slave_occ(&master_chipids, &slave_chipids, + &nr_masters, &nr_slaves); + if (rc) + goto out; - for (i = 0; i < nr_chips; i++) + for (i = 0; i < nr_slaves; i++) prlog(PR_TRACE, "HBRT: Calling stopOCC() for %04llx ", - chipids[i]); + slave_chipids[i]); + + if (!nr_slaves) + goto master; + + /* Lets STOP all the slave OCC */ + rc = hservice_runtime->stopOCCs(slave_chipids, nr_slaves); + prlog(PR_DEBUG, "HBRT: stopOCCs() slave rc = %d\n", rc); + +master: + for (i = 0; i < nr_masters; i++) + prlog(PR_TRACE, "HBRT: Calling stopOCC() for %04llx ", + master_chipids[i]); + + /* Lets STOP all the master OCC */ + rc = hservice_runtime->stopOCCs(master_chipids, nr_masters); - /* Lets STOP all OCC */ - rc = hservice_runtime->stopOCCs(chipids, nr_chips); hservice_mark(); - prlog(PR_DEBUG, "HBRT: stopOCCs() rc = %d\n", rc); + prlog(PR_DEBUG, "HBRT: stopOCCs() master rc = %d\n", rc); + +out: + free(master_chipids); + free(slave_chipids); return rc; } - void host_services_occ_base_setup(void) { struct proc_chip *chip; @@ -454,6 +454,50 @@ struct occ_load_req { }; static LIST_HEAD(occ_load_req_list); +int find_master_and_slave_occ(uint64_t **master, uint64_t **slave, + int *nr_masters, int *nr_slaves) +{ + struct proc_chip *chip; + int nr_chips = 0, i; + uint64_t chipids[MAX_CHIPS]; + + for_each_chip(chip) { + chipids[nr_chips++] = chip->id; + } + + chip = next_chip(NULL); + /* + * Proc0 is the master OCC for Tuleta/Alpine boxes. + * Hostboot expects the pair of chips for MURANO, so pass the sibling + * chip id along with proc0 to hostboot. + */ + *nr_masters = (chip->type == PROC_CHIP_P8_MURANO) ? 2 : 1; + *master = (uint64_t *)malloc(*nr_masters * sizeof(uint64_t)); + + if (!master) { + printf("OCC: master array alloc failure\n"); + return -ENOMEM; + } + + if (nr_chips - *nr_masters > 0) { + *nr_slaves = nr_chips - *nr_masters; + *slave = (uint64_t *)malloc(*nr_slaves * sizeof(uint64_t)); + if (!slave) { + printf("OCC: slave array alloc failure\n"); + return -ENOMEM; + } + } + + for (i = 0; i < nr_chips; i++) { + if (i < *nr_masters) { + *(*master + i) = chipids[i]; + continue; + } + *(*slave + i - *nr_masters) = chipids[i]; + } + return 0; +} + static void occ_queue_load(u8 scope, u32 dbob_id, u32 seq_id) { struct occ_load_req *occ_req; diff --git a/include/hostservices.h b/include/hostservices.h index e85abc3..d6bb3e3 100644 --- a/include/hostservices.h +++ b/include/hostservices.h @@ -36,4 +36,7 @@ void host_services_occ_base_setup(void); #define HOMER_IMAGE_SIZE 0x400000 /* 4MB per-chip */ #define OCC_COMMON_SIZE 0x800000 /* 8MB */ +int find_master_and_slave_occ(uint64_t **master, uint64_t **slave, + int *nr_masters, int *nr_slaves); + #endif /* __HOSTSERVICES_H */ |