[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