[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