[Skiboot] [PATCH 6/6] Add base POWER9 support
Michael Neuling
mikey at neuling.org
Fri Apr 29 15:57:07 AEST 2016
Add PVR detection, chip id and other misc bits for POWER9.
POWER9 randomly changes the location of the HILE and attn enable bits
in the HID0 register, so add these definitions also.
Signed-off-by: Michael Neuling <mikey at neuling.org>
---
asm/head.S | 2 ++
core/affinity.c | 2 ++
core/chip.c | 12 +++++++++---
core/cpu.c | 12 ++++++++++++
hdata/cpu-common.c | 3 +++
hw/xscom.c | 18 ++++++++++++++----
include/chip.h | 20 ++++++++++++++++++++
include/processor.h | 4 ++++
include/skiboot.h | 1 +
9 files changed, 67 insertions(+), 7 deletions(-)
diff --git a/asm/head.S b/asm/head.S
index 5335846..5255d7d 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -259,6 +259,8 @@ boot_entry:
beq 2f
cmpwi cr0,%r3,PVR_TYPE_P8NVL
beq 2f
+ cmpwi cr0,%r3,PVR_TYPE_P9
+ beq 1f
attn /* Unsupported CPU type... what do we do ? */
/* P8 -> 8 threads */
diff --git a/core/affinity.c b/core/affinity.c
index df708a8..9f489d3 100644
--- a/core/affinity.c
+++ b/core/affinity.c
@@ -120,6 +120,8 @@ void add_core_associativity(struct cpu_thread *cpu)
core_id = (cpu->pir >> 2) & 0x7;
else if (proc_gen == proc_gen_p8)
core_id = (cpu->pir >> 3) & 0xf;
+ else if (proc_gen == proc_gen_p9)
+ core_id = (cpu->pir >> 2) & 0x1f;
else
return;
diff --git a/core/chip.c b/core/chip.c
index 49d2f1f..4d01b92 100644
--- a/core/chip.c
+++ b/core/chip.c
@@ -24,7 +24,9 @@ enum proc_chip_quirks proc_chip_quirks;
uint32_t pir_to_chip_id(uint32_t pir)
{
- if (proc_gen == proc_gen_p8)
+ if (proc_gen == proc_gen_p9)
+ return P9_PIR2GCID(pir);
+ else if (proc_gen == proc_gen_p8)
return P8_PIR2GCID(pir);
else
return P7_PIR2GCID(pir);
@@ -32,7 +34,9 @@ uint32_t pir_to_chip_id(uint32_t pir)
uint32_t pir_to_core_id(uint32_t pir)
{
- if (proc_gen == proc_gen_p8)
+ if (proc_gen == proc_gen_p9)
+ return P9_PIR2COREID(pir);
+ else if (proc_gen == proc_gen_p8)
return P8_PIR2COREID(pir);
else
return P7_PIR2COREID(pir);
@@ -40,7 +44,9 @@ uint32_t pir_to_core_id(uint32_t pir)
uint32_t pir_to_thread_id(uint32_t pir)
{
- if (proc_gen == proc_gen_p8)
+ if (proc_gen == proc_gen_p9)
+ return P9_PIR2THREADID(pir);
+ else if (proc_gen == proc_gen_p8)
return P8_PIR2THREADID(pir);
else
return P7_PIR2THREADID(pir);
diff --git a/core/cpu.c b/core/cpu.c
index 4fda5a2..c33c103 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -443,6 +443,12 @@ void init_boot_cpu(void)
hid0_hile = SPR_HID0_POWER8_HILE;
hid0_attn = SPR_HID0_POWER8_ENABLE_ATTN;
break;
+ case PVR_TYPE_P9:
+ proc_gen = proc_gen_p9;
+ hile_supported = true;
+ hid0_hile = SPR_HID0_POWER9_HILE;
+ hid0_attn = SPR_HID0_POWER9_ENABLE_ATTN;
+ break;
default:
proc_gen = proc_gen_unknown;
}
@@ -461,6 +467,12 @@ void init_boot_cpu(void)
prlog(PR_INFO, "CPU: P8 generation processor"
"(max %d threads/core)\n", cpu_thread_count);
break;
+ case proc_gen_p9:
+ cpu_thread_count = 4;
+ cpu_max_pir = SPR_PIR_P9_MASK;
+ prlog(PR_INFO, "CPU: P9 generation processor"
+ "(max %d threads/core)\n", cpu_thread_count);
+ break;
default:
prerror("CPU: Unknown PVR, assuming 1 thread\n");
cpu_thread_count = 1;
diff --git a/hdata/cpu-common.c b/hdata/cpu-common.c
index e0f335b..cf0ce8a 100644
--- a/hdata/cpu-common.c
+++ b/hdata/cpu-common.c
@@ -56,6 +56,9 @@ struct dt_node * add_core_common(struct dt_node *cpus,
case PVR_TYPE_P8NVL:
name = "PowerPC,POWER8";
break;
+ case PVR_TYPE_P9:
+ name = "PowerPC,POWER9";
+ break;
default:
name = "PowerPC,Unknown";
}
diff --git a/hw/xscom.c b/hw/xscom.c
index 1c45cbc..2c5035e 100644
--- a/hw/xscom.c
+++ b/hw/xscom.c
@@ -426,11 +426,13 @@ int64_t xscom_read_cfam_chipid(uint32_t partid, uint32_t *chip_id)
int64_t rc = OPAL_SUCCESS;
/* Mambo chip model lacks the f000f register, just make
- * something up (Murano DD2.1)
+ * something up
*/
- if (chip_quirk(QUIRK_NO_F000F))
- val = 0x221EF04980000000UL;
- else
+ if (chip_quirk(QUIRK_NO_F000F)) {
+ val = 0x221EF04980000000UL; /* P8 Murano DD2.1 */
+ if (proc_gen == proc_gen_p9)
+ val = 0x100D104980000000UL; /* P9 Numbus DD1.0 */
+ } else
rc = xscom_read(partid, 0xf000f, &val);
/* Extract CFAM id */
@@ -474,6 +476,14 @@ static void xscom_init_chip_info(struct proc_chip *chip)
chip->type = PROC_CHIP_P8_NAPLES;
assert(proc_gen == proc_gen_p8);
break;
+ case 0xd1:
+ chip->type = PROC_CHIP_P9_NIMBUS;
+ assert(proc_gen == proc_gen_p9);
+ break;
+ case 0xd4:
+ chip->type = PROC_CHIP_P9_CUMULUS;
+ assert(proc_gen == proc_gen_p9);
+ break;
default:
printf("CHIP: Unknown chip type 0x%02x !!!\n",
(unsigned char)(val & 0xff));
diff --git a/include/chip.h b/include/chip.h
index 72b85df..3409419 100644
--- a/include/chip.h
+++ b/include/chip.h
@@ -77,6 +77,24 @@
#define P8_PIR2THREADID(pir) ((pir) & 0x7)
+/*
+ * P9 GCID
+ * -------
+ *
+ * Global chip ID is a 7 bit number:
+ *
+ * NodeID ChipID
+ * | | |
+ * |___|___|___|___|___|___|___|
+ *
+ * Bit 56 is unused according to the manual by we add it to the coreid here.
+ */
+#define P9_PIR2GCID(pir) (((pir) >> 8) & 0x7f)
+
+#define P9_PIR2COREID(pir) (((pir) >> 2) & 0x3f)
+
+#define P9_PIR2THREADID(pir) ((pir) & 0x3)
+
struct dt_node;
struct centaur_chip;
struct mfsi;
@@ -89,6 +107,8 @@ enum proc_chip_type {
PROC_CHIP_P8_MURANO,
PROC_CHIP_P8_VENICE,
PROC_CHIP_P8_NAPLES,
+ PROC_CHIP_P9_NIMBUS,
+ PROC_CHIP_P9_CUMULUS,
};
/* Simulator quirks */
diff --git a/include/processor.h b/include/processor.h
index e05c4bb..1236c77 100644
--- a/include/processor.h
+++ b/include/processor.h
@@ -39,6 +39,7 @@
#define MSR_LE PPC_BIT(63) /* Little Endian */
/* PIR */
+#define SPR_PIR_P9_MASK 0x07ff /* Mask of implemented bits */
#define SPR_PIR_P8_MASK 0x1fff /* Mask of implemented bits */
#define SPR_PIR_P7_MASK 0x03ff /* Mask of implemented bits */
@@ -162,7 +163,9 @@
#define SPR_HID0_POWER8_4LPARMODE PPC_BIT(2)
#define SPR_HID0_POWER8_2LPARMODE PPC_BIT(6)
#define SPR_HID0_POWER8_HILE PPC_BIT(19)
+#define SPR_HID0_POWER9_HILE PPC_BIT(4)
#define SPR_HID0_POWER8_ENABLE_ATTN PPC_BIT(31)
+#define SPR_HID0_POWER9_ENABLE_ATTN PPC_BIT(3)
/* PVR bits */
#define SPR_PVR_TYPE 0xffff0000
@@ -179,6 +182,7 @@
#define PVR_TYPE_P8E 0x004b /* Murano */
#define PVR_TYPE_P8 0x004d /* Venice */
#define PVR_TYPE_P8NVL 0x004c /* Naples */
+#define PVR_TYPE_P9 0x004e
#ifdef __ASSEMBLY__
diff --git a/include/skiboot.h b/include/skiboot.h
index a85fafc..bece690 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -123,6 +123,7 @@ enum proc_gen {
proc_gen_unknown,
proc_gen_p7, /* P7 and P7+ */
proc_gen_p8,
+ proc_gen_p9,
};
extern enum proc_gen proc_gen;
--
2.7.4
More information about the Skiboot
mailing list