[V2] homer : Enable HOMER region reservation for POWER9

Submitted by Shilpasri G Bhat on March 8, 2017, 3:28 a.m.

Details

Message ID 1488943702-5674-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com
State Accepted
Headers show

Commit Message

Shilpasri G Bhat March 8, 2017, 3:28 a.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>
Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
---
Changes from V1:
- Define all the P9 BAR componenets
 hw/homer.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 74 insertions(+), 8 deletions(-)

Comments

Vaidyanathan Srinivasan March 8, 2017, 4:19 a.m.
* Shilpa Bhat <shilpa.bhat@linux.vnet.ibm.com> [2017-03-08 08:58:22]:

> 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>
> Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
> ---
> Changes from V1:
> - Define all the P9 BAR componenets
>  hw/homer.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 74 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/homer.c b/hw/homer.c
> index 84eb536..1e2298b 100644
> --- a/hw/homer.c
> +++ b/hw/homer.c
> @@ -22,8 +22,30 @@
>  #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 */
> +
> +enum P8_BAR {
> +	P8_BAR_HOMER = 0,
> +	P8_BAR_CENTAUR = 1,
> +	P8_BAR_SLW = 2,
> +	P8_BAR_OCC_COMMON = 3,
> +};
> +
> +enum P9_BAR {
> +	P9_BAR_HOMER = 0,
> +	P9_BAR_CENTAUR = 1,
> +	P9_BAR_OCC_COMMON = 2,
> +	P9_BAR_SBE = 3,
> +};
> +
> +u64 pba_bar0, pba_barmask0;
> +u8 bar_homer, bar_slw, bar_occ_common;

P8 vs P9 have different PBA BAR assignments that is captured here.

> 
>  static bool read_pba_bar(struct proc_chip *chip, unsigned int bar_no,
>  			 uint64_t *base, uint64_t *size)
> @@ -31,13 +53,13 @@ static bool read_pba_bar(struct proc_chip *chip, unsigned int bar_no,
>  	uint64_t bar, mask;
>  	int rc;
> 
> -	rc = xscom_read(chip->id, PBA_BAR0 + bar_no, &bar);
> +	rc = xscom_read(chip->id, pba_bar0 + 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_barmask0 + 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 +68,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;

This can happen in development firmware (hostboot/occ) where all
components are not yet production ready.  Skiboot can still survive
and use the pieces that is working.
 
> @@ -60,6 +92,7 @@ static void homer_init_chip(struct proc_chip *chip)
>  	/*
>  	 * PBA BARs assigned by HB:
>  	 *
> +	 * P8:
>  	 *   0 : Entire HOMER
>  	 *   1 : OCC to Centaur path (we don't care)
>  	 *   2 : SLW image
> @@ -68,8 +101,15 @@ static void homer_init_chip(struct proc_chip *chip)
>  	 * We need to reserve the memory covered by BAR 0 and BAR 3, however
>  	 * on earlier HBs, BAR0 isn't set so we need BAR 2 instead in that
>  	 * case to cover SLW (OCC not running).
> +	 *
> +	 * P9:
> +	 *   0 : Entire HOMER
> +	 *   1 : OCC to Centaur path (Cumulus only)
> +	 *   2 : OCC Common area
> +	 *   3 : SBE communication
> +	 *
>  	 */
> -	if (read_pba_bar(chip, 0, &hbase, &hsize)) {
> +	if (read_pba_bar(chip, bar_homer, &hbase, &hsize)) {
>  		prlog(PR_DEBUG, "  HOMER Image at 0x%llx size %lldMB\n",
>  		      hbase, hsize / 0x100000);
> 
> @@ -87,7 +127,8 @@ static void homer_init_chip(struct proc_chip *chip)
>  	 * We always read the SLW BAR since we need to grab info about the
>  	 * SLW image in the struct proc_chip for use by the slw.c code
>  	 */
> -	if (read_pba_bar(chip, 2, &sbase, &ssize)) {
> +	if (proc_gen == proc_gen_p8 &&
> +	    read_pba_bar(chip, bar_slw, &sbase, &ssize)) {
>  		prlog(PR_DEBUG, "  SLW Image at 0x%llx size %lldMB\n",
>  		      sbase, ssize / 0x100000);
> 
> @@ -108,7 +149,7 @@ static void homer_init_chip(struct proc_chip *chip)
>  		chip->slw_image_size = ssize; /* will be adjusted later */
>  	}
> 
> -	if (read_pba_bar(chip, 3, &obase, &osize)) {
> +	if (read_pba_bar(chip, bar_occ_common, &obase, &osize)) {
>  		prlog(PR_DEBUG, "  OCC Common Area at 0x%llx size %lldMB\n",
>  		      obase, osize / 0x100000);
>  		chip->occ_common_base = obase;
> @@ -120,9 +161,27 @@ void homer_init(void)
>  {
>  	struct proc_chip *chip;
> 
> -	if (proc_gen != proc_gen_p8 || chip_quirk(QUIRK_NO_PBA))
> +	if (chip_quirk(QUIRK_NO_PBA))
>  		return;
> 
> +	switch (proc_gen) {
> +	case proc_gen_p8:
> +		pba_bar0 = P8_PBA_BAR0;
> +		pba_barmask0 = P8_PBA_BARMASK0;
> +		bar_homer = P8_BAR_HOMER;
> +		bar_slw = P8_BAR_SLW;
> +		bar_occ_common = P8_BAR_OCC_COMMON;
> +		break;
> +	case proc_gen_p9:
> +		pba_bar0 = P9_PBA_BAR0;
> +		pba_barmask0 = P9_PBA_BARMASK0;
> +		bar_homer = P9_BAR_HOMER;
> +		bar_occ_common = P9_BAR_OCC_COMMON;
> +		break;
> +	default:
> +		return;
> +	};
> +
>  	/*
>  	 * XXX This is temporary, on P8 we look for any configured
>  	 * SLW/OCC BAR and reserve the memory. Eventually, this will be
> @@ -140,6 +199,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 +210,12 @@ 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.
> +		 */
>  	} else {
>  		/* Allocate memory for HOMER and OCC common area */
>  		host_services_occ_base_setup();

--Vaidy
Stewart Smith March 23, 2017, 5:43 a.m.
Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> writes:
> 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>
> Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
> ---
> Changes from V1:
> - Define all the P9 BAR componenets
>  hw/homer.c | 82
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------

Thanks, merged to master as of fc74d779c2187545f46a5d71bdbbdab9c546a74a

Patch hide | download patch | download mbox

diff --git a/hw/homer.c b/hw/homer.c
index 84eb536..1e2298b 100644
--- a/hw/homer.c
+++ b/hw/homer.c
@@ -22,8 +22,30 @@ 
 #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 */
+
+enum P8_BAR {
+	P8_BAR_HOMER = 0,
+	P8_BAR_CENTAUR = 1,
+	P8_BAR_SLW = 2,
+	P8_BAR_OCC_COMMON = 3,
+};
+
+enum P9_BAR {
+	P9_BAR_HOMER = 0,
+	P9_BAR_CENTAUR = 1,
+	P9_BAR_OCC_COMMON = 2,
+	P9_BAR_SBE = 3,
+};
+
+u64 pba_bar0, pba_barmask0;
+u8 bar_homer, bar_slw, bar_occ_common;
 
 static bool read_pba_bar(struct proc_chip *chip, unsigned int bar_no,
 			 uint64_t *base, uint64_t *size)
@@ -31,13 +53,13 @@  static bool read_pba_bar(struct proc_chip *chip, unsigned int bar_no,
 	uint64_t bar, mask;
 	int rc;
 
-	rc = xscom_read(chip->id, PBA_BAR0 + bar_no, &bar);
+	rc = xscom_read(chip->id, pba_bar0 + 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_barmask0 + 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 +68,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;
 
@@ -60,6 +92,7 @@  static void homer_init_chip(struct proc_chip *chip)
 	/*
 	 * PBA BARs assigned by HB:
 	 *
+	 * P8:
 	 *   0 : Entire HOMER
 	 *   1 : OCC to Centaur path (we don't care)
 	 *   2 : SLW image
@@ -68,8 +101,15 @@  static void homer_init_chip(struct proc_chip *chip)
 	 * We need to reserve the memory covered by BAR 0 and BAR 3, however
 	 * on earlier HBs, BAR0 isn't set so we need BAR 2 instead in that
 	 * case to cover SLW (OCC not running).
+	 *
+	 * P9:
+	 *   0 : Entire HOMER
+	 *   1 : OCC to Centaur path (Cumulus only)
+	 *   2 : OCC Common area
+	 *   3 : SBE communication
+	 *
 	 */
-	if (read_pba_bar(chip, 0, &hbase, &hsize)) {
+	if (read_pba_bar(chip, bar_homer, &hbase, &hsize)) {
 		prlog(PR_DEBUG, "  HOMER Image at 0x%llx size %lldMB\n",
 		      hbase, hsize / 0x100000);
 
@@ -87,7 +127,8 @@  static void homer_init_chip(struct proc_chip *chip)
 	 * We always read the SLW BAR since we need to grab info about the
 	 * SLW image in the struct proc_chip for use by the slw.c code
 	 */
-	if (read_pba_bar(chip, 2, &sbase, &ssize)) {
+	if (proc_gen == proc_gen_p8 &&
+	    read_pba_bar(chip, bar_slw, &sbase, &ssize)) {
 		prlog(PR_DEBUG, "  SLW Image at 0x%llx size %lldMB\n",
 		      sbase, ssize / 0x100000);
 
@@ -108,7 +149,7 @@  static void homer_init_chip(struct proc_chip *chip)
 		chip->slw_image_size = ssize; /* will be adjusted later */
 	}
 
-	if (read_pba_bar(chip, 3, &obase, &osize)) {
+	if (read_pba_bar(chip, bar_occ_common, &obase, &osize)) {
 		prlog(PR_DEBUG, "  OCC Common Area at 0x%llx size %lldMB\n",
 		      obase, osize / 0x100000);
 		chip->occ_common_base = obase;
@@ -120,9 +161,27 @@  void homer_init(void)
 {
 	struct proc_chip *chip;
 
-	if (proc_gen != proc_gen_p8 || chip_quirk(QUIRK_NO_PBA))
+	if (chip_quirk(QUIRK_NO_PBA))
 		return;
 
+	switch (proc_gen) {
+	case proc_gen_p8:
+		pba_bar0 = P8_PBA_BAR0;
+		pba_barmask0 = P8_PBA_BARMASK0;
+		bar_homer = P8_BAR_HOMER;
+		bar_slw = P8_BAR_SLW;
+		bar_occ_common = P8_BAR_OCC_COMMON;
+		break;
+	case proc_gen_p9:
+		pba_bar0 = P9_PBA_BAR0;
+		pba_barmask0 = P9_PBA_BARMASK0;
+		bar_homer = P9_BAR_HOMER;
+		bar_occ_common = P9_BAR_OCC_COMMON;
+		break;
+	default:
+		return;
+	};
+
 	/*
 	 * XXX This is temporary, on P8 we look for any configured
 	 * SLW/OCC BAR and reserve the memory. Eventually, this will be
@@ -140,6 +199,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 +210,12 @@  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.
+		 */
 	} else {
 		/* Allocate memory for HOMER and OCC common area */
 		host_services_occ_base_setup();