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 /hw/occ.c | |
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>
Diffstat (limited to 'hw/occ.c')
-rw-r--r-- | hw/occ.c | 44 |
1 files changed, 44 insertions, 0 deletions
@@ -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; |