diff mbox series

[05/12] libpdbg: Add chtm hardware unit for p10

Message ID 20210802054112.461728-6-jniethe5@gmail.com
State Superseded
Headers show
Series P10 HTM Support | expand

Commit Message

Jordan Niethe Aug. 2, 2021, 5:41 a.m. UTC
p10 adds a Core HTM again. There is a hardware issue when the chtm is in
non-wrapping mode and changes to the stopped state the machine will
checkstop. Work around this by masking the FIR bit that is raised.

Add support for the p10 chtm.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 libpdbg/htm.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++--
 p10.dts.m4    |   7 +++
 2 files changed, 151 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/libpdbg/htm.c b/libpdbg/htm.c
index 6a6ffeca12a5..a2c548487ac9 100644
--- a/libpdbg/htm.c
+++ b/libpdbg/htm.c
@@ -56,6 +56,17 @@ 
 			  HID0_SINGLE_DECODE | HID0_EN_INST_TRACE |\
 			  HID0_TRACE_EN)
 
+#define HIDQ_REGISTER			0x20028415
+#define  HIDQ_ONE_PPC			PPC_BIT(0)
+#define  HIDQ_EN_INST_TRACE		PPC_BIT(1)
+#define  HIDQ_HILE			PPC_BIT(4)
+#define  HIDQ_DIS_PROC_REC		PPC_BIT(5)
+#define  HIDQ_TRACE_BITS (HIDQ_ONE_PPC | HIDQ_EN_INST_TRACE)
+
+#define CORE_FIR			0x20028440
+#define  CORE_FIR_PC_LOGIC		PPC_BIT(45)
+#define CORE_FIR_AND			0x20028441
+#define CORE_FIR_MASK			0x20028443
 /*
  * This is a CORE register not a HTM register, don't pass the HTM
  * target to it.
@@ -63,14 +74,22 @@ 
 #define NCU_MODE_REGISTER		0x10C0A
 #define NCU_MODE_HTM_ENABLE		PPC_BIT(0)
 
+#define IMA_EVENT_MASK			0x20020400
+
 #define HTM_COLLECTION_MODE		0
 #define	  HTM_MODE_ENABLE		PPC_BIT(0)
 #define	  HTM_MODE_CONTENT_SEL		PPC_BITMASK(1,2)
+#define   HTM_MODE_CORE_TRACE_EN	PPC_BIT(1)
+#define   HTM_MODE_LLAT_TRACE_EN	PPC_BIT(2)
+#define   HTM_MODE_DMW_TRACE_EN		PPC_BIT(3)
 #define   NHTM_MODE_CAPTURE		PPC_BITMASK(4,12)
 #define     NHTM_MODE_CAPTURE_PMISC	PPC_BIT(5)
 #define     NHTM_MODE_CRESP_PRECISE	PPC_BIT(6)
 #define     CHTM_MODE_NO_ASSERT_LLAT_L3 PPC_BIT(6)
 #define	  HTM_MODE_WRAP			PPC_BIT(13)
+#define	  HTM_MODE_DIS_TIMESTAMP	PPC_BIT(14)
+#define	  HTM_MODE_FULL_ON_ERR		PPC_BIT(8)
+#define	  HTM_MODE_DISABLE_STALL	PPC_BIT(16)
 #define HTM_MEMORY_CONF			1
 #define   HTM_MEM_ALLOC			PPC_BIT(0)
 #define   HTM_MEM_SCOPE			PPC_BITMASK(1,3)
@@ -108,6 +127,8 @@ 
 #define   HTM1_STATUS_STATE_MASK	(PPC_BITMASK(28,36) | HTM_STATUS_REPAIR)
 #define	  HTM1_STATUS_ERROR_MASK	(HTM_STATUS_CRESP_OV | PPC_BITMASK(24,27) | PPC_BITMASK(37,39))
 #define   HTM_STATUS_MASK		PPC_BITMASK(2,19)
+#define   HTM_STATUS_PURGING		PPC_BIT(0)
+#define   HTM_STATUS_PURGED		PPC_BIT(1)
 #define   HTM_STATUS_CRESP_OV		PPC_BIT(2)
 #define	  HTM_STATUS_REPAIR		PPC_BIT(3)
 #define   HTM_STATUS_BUF_WAIT		PPC_BIT(4)
@@ -142,7 +163,11 @@ 
 #define   HTM_TRIG_MARK_TYPE		PPC_BITMASK(6,15)
 #define HTM_TRIGGER_CONTROL		5
 #define   HTM_CTRL_TRIG			PPC_BITMASK(0,1)
+#define   HTM_CTRL_MTSPR_TRIG		PPC_BIT(2)
+#define   HTM_CTRL_MTSPR_MARKER		PPC_BIT(3)
 #define   HTM_CTRL_MASK			PPC_BITMASK(4,5)
+#define   HTM_CTRL_DBG_TRIG0		PPC_BIT(6)
+#define   HTM_CTRL_DBG_TRIG1		PPC_BIT(7)
 #define   HTM_CTRL_XSTOP_STOP		PPC_BIT(13)
 #define NHTM_FILTER_CONTROL		6
 #define   NHTM_FILTER_RCMD_SCOPE	PPC_BITMASK(17,19)
@@ -166,6 +191,10 @@ 
 #define   NHTM_FLEX_DEFAULT_P10		0xCB34561567
 #define NHTM_ADDR_PAT			0xb
 #define   NHTM_ADDR_PAT_MASK		PPC_BITMASK(0, 55)
+#define CHTM_PDBAR			0x0b
+#define   CHTM_PDBAR_PARITY		PPC_BIT(0)
+#define   CHTM_PDBAR_SCOPE		PPC_BITMASK(5, 7)
+#define   CHTM_PDBAR_ADDR		PPC_BITMASK(12, 52)
 #define NHTM_ADDR_MASK			0xc
 #define   NHTM_ADDR_MASK_MASK		PPC_BITMASK(0, 55)
 #define NHTM_STOP_FILTER		0xd
@@ -460,6 +489,9 @@  static int get_status(struct htm *htm, struct htm_status *status)
 	if (pdbg_target_compatible(&htm->target, "ibm,power10-nhtm")) {
 		status->mem_size_select = val & HTM_MEM_SIZE_SMALL_P10;
 		status->mem_base = val & HTM_MEM_BASE_P10;
+	} else if (pdbg_target_compatible(&htm->target, "ibm,power10-chtm")) {
+		status->mem_size_select = val & HTM_MEM_SIZE_SMALL_P10;
+		status->mem_base = val & HTM_MEM_BASE_P10;
 	} else if (pdbg_target_compatible(&htm->target, "ibm,power9-nhtm")) {
 		status->mem_size_select = val & HTM_MEM_SIZE_SMALL_P9;
 		status->mem_base = val & HTM_MEM_BASE_P9;
@@ -618,6 +650,23 @@  static int configure_chtm_p8(struct htm *htm)
 
 	return 0;
 }
+
+static int configure_chtm_p10(struct htm *htm)
+{
+	struct pdbg_target *core;
+	uint64_t mask;
+
+	/* P10 only: mask PC Logic checkstop in wrapping mode */
+	if (pdbg_target_compatible(&htm->target, "ibm,power10-chtm")) {
+		core = pdbg_target_require_parent("core", &htm->target);
+		if (HTM_ERR(pib_read(core, CORE_FIR_MASK, &mask)))
+			return -1;
+		if (HTM_ERR(pib_write(core, CORE_FIR_MASK, mask | CORE_FIR_PC_LOGIC)))
+			return -1;
+	}
+	return 0;
+}
+
 static int configure_chtm(struct htm *htm, bool wrap)
 {
 	uint64_t val;
@@ -630,16 +679,14 @@  static int configure_chtm(struct htm *htm, bool wrap)
 
 	val = wrap ? HTM_MODE_WRAP : 0;
 	if (HTM_ERR(pib_write(&htm->target, HTM_COLLECTION_MODE,
-		HTM_MODE_ENABLE | val)))
+		HTM_MODE_ENABLE | HTM_MODE_DIS_TIMESTAMP |
+		HTM_MODE_CORE_TRACE_EN | val)))
 		return -1;
 
 	if (configure_chtm_p8(htm) < 0)
 		return -1;
 
-	if (HTM_ERR(pib_read(core, NCU_MODE_REGISTER, &ncu)))
-		return -1;
-	ncu |= NCU_MODE_HTM_ENABLE;
-	if (HTM_ERR(pib_write(core, NCU_MODE_REGISTER, ncu)))
+	if (configure_chtm_p10(htm) < 0)
 		return -1;
 
 	return 0;
@@ -668,6 +715,25 @@  static int deconfigure_chtm_p8(struct htm *htm)
 	return 0;
 }
 
+static int deconfigure_chtm_p10(struct htm *htm)
+{
+	struct pdbg_target *core;
+	uint64_t mask;
+
+	if (pdbg_target_compatible(&htm->target, "ibm,power10-chtm")) {
+		core = pdbg_target_require_parent("core", &htm->target);
+		/* clear fir first before unmasking it */
+		if (HTM_ERR(pib_write(core, CORE_FIR_AND, ~CORE_FIR_PC_LOGIC)))
+			return -1;
+		if (HTM_ERR(pib_read(core, CORE_FIR_MASK, &mask)))
+			return -1;
+		if (HTM_ERR(pib_write(core, CORE_FIR_MASK, mask & ~CORE_FIR_PC_LOGIC)))
+			return -1;
+	}
+
+	return 0;
+}
+
 static int deconfigure_chtm(struct htm *htm)
 {
 
@@ -677,6 +743,7 @@  static int deconfigure_chtm(struct htm *htm)
 	if (deconfigure_chtm_p8(htm) < 0)
 		return -1;
 
+	if (deconfigure_chtm_p10(htm) < 0)
 		return -1;
 
 	if (HTM_ERR(pib_write(&htm->target, HTM_COLLECTION_MODE,0)))
@@ -922,6 +989,8 @@  static int configure_memory(struct htm *htm)
 		small = 1;
 	if (pdbg_target_compatible(&htm->target, "ibm,power10-nhtm"))
 		val = SETFIELD(HTM_MEM_SIZE_SMALL_P10, val, small);
+	else if (pdbg_target_compatible(&htm->target, "ibm,power10-chtm"))
+		val = SETFIELD(HTM_MEM_SIZE_SMALL_P10, val, small);
 	else if (pdbg_target_compatible(&htm->target, "ibm,power9-nhtm"))
 		val = SETFIELD(HTM_MEM_SIZE_SMALL_P9, val, small);
 	else
@@ -940,6 +1009,8 @@  static int configure_memory(struct htm *htm)
 	 */
 	if (pdbg_target_compatible(&htm->target, "ibm,power10-nhtm"))
 		val = SETFIELD(HTM_MEM_BASE_P10, val, 0);
+	else if (pdbg_target_compatible(&htm->target, "ibm,power10-chtm"))
+		val = SETFIELD(HTM_MEM_BASE_P10, val, 0);
 	else if (pdbg_target_compatible(&htm->target, "ibm,power9-nhtm"))
 		val = SETFIELD(HTM_MEM_BASE_P9, val, 0);
 	else
@@ -1004,6 +1075,41 @@  static int post_configure_chtm_p8(struct htm *htm)
 	return 0;
 }
 
+static int post_configure_chtm_p10(struct htm *htm)
+{
+	struct pdbg_target *core;
+	uint64_t hid0;
+
+	if (pdbg_target_compatible(&htm->target, "ibm,power10-chtm")) {
+		core = pdbg_target_require_parent("core", &htm->target);
+		if (HTM_ERR(pib_read(core, HIDQ_REGISTER, &hid0)))
+			return -1;
+		hid0 = HIDQ_ONE_PPC | HIDQ_DIS_PROC_REC | HIDQ_HILE;
+		if (HTM_ERR(pib_write(core, HIDQ_REGISTER, hid0)))
+			return -1;
+		hid0 |= HIDQ_EN_INST_TRACE;
+		if (HTM_ERR(pib_write(core, HIDQ_REGISTER, hid0)))
+			return -1;
+	}
+
+	return 0;
+}
+
+static int pre_deconfigure_chtm_p10(struct htm *htm)
+{
+	struct pdbg_target *core;
+	uint64_t hid0;
+
+	if (pdbg_target_compatible(&htm->target, "ibm,power10-chtm")) {
+		core = pdbg_target_require_parent("core", &htm->target);
+		hid0 = HIDQ_DIS_PROC_REC | HIDQ_HILE;
+		if (HTM_ERR(pib_write(core, HIDQ_REGISTER, hid0)))
+			return -1;
+	}
+
+	return 0;
+}
+
 static int __do_htm_start(struct htm *htm, bool wrap)
 {
 	struct htm_status status;
@@ -1026,9 +1132,19 @@  static int __do_htm_start(struct htm *htm, bool wrap)
 	if (HTM_ERR(pib_write(&htm->target, reg_off(htm, HTM_SCOM_TRIGGER), HTM_TRIG_START)))
 		return -1;
 
+	while (1) {
+		if (HTM_ERR(get_status(htm, &status)))
+			return -1;
+		if (status.state == TRACING)
+			break;
+	}
+
 	if (post_configure_chtm_p8(htm))
 		return -1;
 
+	if (post_configure_chtm_p10(htm))
+		return -1;
+
 	/*
 	 * Instead of the HTM_TRIG_START, this is where you might want
 	 * to call do_adu_magic()
@@ -1047,6 +1163,7 @@  static int do_htm_start(struct htm *htm)
 static int do_htm_stop(struct htm *htm)
 {
 	struct htm_status status;
+
 	get_status(htm, &status);
 	if (HTM_ERR(get_status(htm, &status)))
 		return -1;
@@ -1055,6 +1172,10 @@  static int do_htm_stop(struct htm *htm)
 		PR_INFO("* Skipping STOP trigger, HTM appears uninitialized\n");
 		return -1;
 	}
+
+	if (pre_deconfigure_chtm_p10(htm) < 0)
+		return -1;
+
 	if (status.state == TRACING) {
 		PR_INFO("* Sending STOP trigger to HTM\n");
 		if (HTM_ERR(pib_write(&htm->target, reg_off(htm, HTM_SCOM_TRIGGER), HTM_TRIG_STOP)))
@@ -1255,7 +1376,8 @@  static int do_htm_dump(struct htm *htm, char *filename)
 		goto out3;
 	}
 
-	if (pdbg_target_compatible(&htm->target, "ibm,power10-nhtm")) {
+	if (pdbg_target_compatible(&htm->target, "ibm,power10-nhtm") ||
+	    pdbg_target_compatible(&htm->target, "ibm,power10-chtm")) {
 		lseek(trace_fd, 8, SEEK_SET);
 		r = read(trace_fd, &eyecatcher, 8);
 	} else {
@@ -1434,6 +1556,21 @@  static struct htm p10_nhtm = {
 };
 DECLARE_HW_UNIT(p10_nhtm);
 
+static struct htm p10_chtm = {
+	.target = {
+		.name = "POWER10 Core HTM",
+		.compatible = "ibm,power10-chtm",
+		.class = "chtm",
+		.probe = chtm_probe,
+	},
+	.start = do_htm_start,
+	.stop = do_htm_stop,
+	.record = do_htm_record,
+	.status = do_htm_status,
+	.dump = do_htm_dump,
+};
+DECLARE_HW_UNIT(p10_chtm);
+
 __attribute__((constructor))
 static void register_htm(void)
 {
@@ -1441,4 +1578,5 @@  static void register_htm(void)
 	pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p9_nhtm_hw_unit);
 	pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_nhtm_hw_unit);
 	pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p8_chtm_hw_unit);
+	pdbg_hwunit_register(PDBG_DEFAULT_BACKEND, &p10_chtm_hw_unit);
 }
diff --git a/p10.dts.m4 b/p10.dts.m4
index d58086962bfb..492bae638bfc 100644
--- a/p10.dts.m4
+++ b/p10.dts.m4
@@ -29,6 +29,13 @@  define(`CORE',
 		THREAD(1)
 		THREAD(2)
 		THREAD(3)
+
+		htm@20010680 {
+			compatible = "ibm,power10-chtm";
+			reg = < 0x20010680 >;
+			index = < 0x$1 >;
+		};
+
 	};
 ')dnl