hw/homer: Enable HOMER region reservation for POWER9

Submitted by Vaidyanathan Srinivasan on Feb. 26, 2017, 3:37 p.m.

Details

Message ID 20170226153700.31230-1-svaidy@linux.vnet.ibm.com
State New
Headers show

Commit Message

Vaidyanathan Srinivasan Feb. 26, 2017, 3:37 p.m.
PBA BARs map various regions in HOMER memory used by
STOP engines and OCC.
Skip PBA BARs that have incomplete initialization and
reserve the regions that are available in the system.

Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
---
 hw/homer.c | 49 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/hw/homer.c b/hw/homer.c
index 84eb536..9ea1188 100644
--- a/hw/homer.c
+++ b/hw/homer.c
@@ -22,22 +22,39 @@ 
 #include <mem_region.h>
 #include <hostservices.h>
 
-#define PBA_BAR0	0x2013f00
-#define PBA_BARMASK0	0x2013f04
+#define P8_PBA_BAR0	0x2013f00
+#define P8_PBA_BARMASK0	0x2013f04
+
+#define P9_PBA_BAR0	0x5012B00
+#define P9_PBA_BARMASK0	0x5012B04
+
+#define PBA_MASK_ALL_BITS 0x000001FFFFF00000ULL /* Bits 23:43 */
 
 static bool read_pba_bar(struct proc_chip *chip, unsigned int bar_no,
 			 uint64_t *base, uint64_t *size)
 {
 	uint64_t bar, mask;
+	uint64_t pba_bar, pba_mask;
 	int rc;
 
-	rc = xscom_read(chip->id, PBA_BAR0 + bar_no, &bar);
+	if (proc_gen == proc_gen_p8) {
+		pba_bar = P8_PBA_BAR0;
+		pba_mask = P8_PBA_BARMASK0;
+	} else if (proc_gen == proc_gen_p9) {
+		pba_bar = P9_PBA_BAR0;
+		pba_mask = P9_PBA_BARMASK0;
+	} else {
+		prerror("HOMER:read_pba_bar() Unknown processor, cannot find PBA BARs\n");
+		return false;
+	}
+
+	rc = xscom_read(chip->id, pba_bar + bar_no, &bar);
 	if (rc) {
 		prerror("SLW: Error %d reading PBA BAR%d on chip %d\n",
 			rc, bar_no, chip->id);
 		return false;
 	}
-	rc = xscom_read(chip->id, PBA_BARMASK0 + bar_no, &mask);
+	rc = xscom_read(chip->id, pba_mask + bar_no, &mask);
 	if (rc) {
 		prerror("SLW: Error %d reading PBA BAR MASK%d on chip %d\n",
 			rc, bar_no, chip->id);
@@ -46,6 +63,16 @@  static bool read_pba_bar(struct proc_chip *chip, unsigned int bar_no,
 	prlog(PR_DEBUG, "  PBA BAR%d : 0x%016llx\n", bar_no, bar);
 	prlog(PR_DEBUG, "  PBA MASK%d: 0x%016llx\n", bar_no, mask);
 
+	if (mask == PBA_MASK_ALL_BITS) {
+		/*
+		 * This could happen if all HOMER users are not enabled
+		 * during early system bringup. Skip using the PBA BAR.
+		 */
+		mask = 0;
+		bar = 0;
+		prerror("  PBA MASK%d uninitalized skipping BAR\n", bar_no);
+	}
+
 	*base = bar & 0x0ffffffffffffffful;
 	*size = (mask | 0xfffff) + 1;
 
@@ -120,7 +147,9 @@  void homer_init(void)
 {
 	struct proc_chip *chip;
 
-	if (proc_gen != proc_gen_p8 || chip_quirk(QUIRK_NO_PBA))
+	if ((proc_gen != proc_gen_p8 &&
+		proc_gen != proc_gen_p9) ||
+		chip_quirk(QUIRK_NO_PBA))
 		return;
 
 	/*
@@ -140,6 +169,7 @@  void homer_init(void)
 	 */
 
 	chip = next_chip(NULL);
+	/* Both HOMER images and OCC areas are setup */
 	if (chip->homer_base && chip->occ_common_base) {
 		/* Reserve OCC common area from BAR */
 		if (!mem_range_is_reserved(chip->occ_common_base,
@@ -150,6 +180,15 @@  void homer_init(void)
 						chip->occ_common_base,
 						chip->occ_common_size);
 		}
+	} else if (chip->homer_base) {
+		/*
+		 * HOMER is setup but not OCC!! Do not allocate HOMER
+		 * regions.  This case is possible during early system bringup
+		 * where OCC images are not yet operational.
+		 */
+
+		prlog(PR_WARNING,
+			"HOMER base is setup, but not OCC common area!\n");
 	} else {
 		/* Allocate memory for HOMER and OCC common area */
 		host_services_occ_base_setup();