aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/homer.c82
1 files 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;
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();