aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorShilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>2017-03-08 08:58:22 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-03-23 15:20:29 +1100
commitfc74d779c2187545f46a5d71bdbbdab9c546a74a (patch)
tree2bbad999fb819f4ad5acf40082ffd1eb387cbed8 /hw
parent84368bbf8c0bb1127ce08e1f5cd16832d84350f5 (diff)
downloadskiboot-fc74d779c2187545f46a5d71bdbbdab9c546a74a.zip
skiboot-fc74d779c2187545f46a5d71bdbbdab9c546a74a.tar.gz
skiboot-fc74d779c2187545f46a5d71bdbbdab9c546a74a.tar.bz2
homer : Enable HOMER region reservation for POWER9
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> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-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();