Message ID | 1488943702-5674-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com |
---|---|
State | Accepted |
Headers | show |
* 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
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
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();