diff options
-rw-r--r-- | hw/homer.c | 82 |
1 files changed, 74 insertions, 8 deletions
@@ -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(); |