[Skiboot] [PATCH v2] occ: hbrt: Change the OCC reset order
Shilpasri G Bhat
shilpa.bhat at linux.vnet.ibm.com
Fri Nov 13 00:11:32 AEDT 2015
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 at linux.vnet.ibm.com>
---
Changes from v1:
- Remove sorting of chipids.
- Separate the chipids to master and slave in hw/occ.c
core/hostservices.c | 40 ++++++++++++++++++++++++++++------------
hw/occ.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
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;
diff --git a/hw/occ.c b/hw/occ.c
index 0f2b037..7c4baf8 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -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 */
--
1.9.3
More information about the Skiboot
mailing list