@@ -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);
}
@@ -29,6 +29,13 @@ define(`CORE',
THREAD(1)
THREAD(2)
THREAD(3)
+
+ htm@20010680 {
+ compatible = "ibm,power10-chtm";
+ reg = < 0x20010680 >;
+ index = < 0x$1 >;
+ };
+
};
')dnl
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(-)