aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorAnju T Sudhakar <anju@linux.vnet.ibm.com>2019-03-22 12:13:51 +0530
committerStewart Smith <stewart@linux.ibm.com>2019-03-28 15:24:13 +1100
commitdf2a1e579aaa4c6ac8831e4a24b16b11a7e2588d (patch)
tree8f738da476c328283c23126cf24f5759fcdab072 /hw
parentfa8f3f3fceadcf33212d0449e0c8e787e893401a (diff)
downloadskiboot-df2a1e579aaa4c6ac8831e4a24b16b11a7e2588d.zip
skiboot-df2a1e579aaa4c6ac8831e4a24b16b11a7e2588d.tar.gz
skiboot-df2a1e579aaa4c6ac8831e4a24b16b11a7e2588d.tar.bz2
hw/imc: Enable opal calls to init/start/stop IMC Trace mode
Patch to enhance the imc opal call to support and handle trace_imc mode. To initialize the trace-mode, TRACE_IMC_SCOM value is written to TRACE_IMC_ADDR of the respective core. TRACE_IMC_SCOM is a 64bit value, and each bit represent the following: 0:1 : SAMPSEL 2:33 : CPMC_LOAD 34:40 : CPMC1SEL 41:47 : CPMC2SEL 48:50 : BUFFERSIZE 51:63 : RESERVED Currently the value for TRACE_IMC_SCOM is hard coded. During initialization htm_mode is disabled, and enabled only at start. The opal calls to start/stop the counters, will write CORE_IMC_HTM_MODE_ENABLE/ CORE_IMC_HTM_MODE_DISABLE respectively to the htm_scom_index of the desired cores. Additional switch cases are added to the current opal calls to start/stop the counters for trace-mode. Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/imc.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/hw/imc.c b/hw/imc.c
index 843ffe3..5ccb085 100644
--- a/hw/imc.c
+++ b/hw/imc.c
@@ -23,6 +23,19 @@
#include <p9_stop_api.H>
/*
+ * IMC trace scom values
+ */
+#define IMC_TRACE_SAMPLESEL_VAL 1 /* select cpmc2 */
+#define IMC_TRACE_CPMCLOAD_VAL 0xfa /*
+ * Value to be loaded into cpmc2
+ * at sampling start
+ */
+#define IMC_TRACE_CPMC2SEL_VAL 2 /* Event: CPM_32MHZ_CYC */
+#define IMC_TRACE_BUFF_SIZE 0 /*
+ * b’000’- 4K entries * 64 per
+ * entry = 256K buffersize
+ */
+/*
* Nest IMC PMU names along with their bit values as represented in the
* imc_chip_avl_vector(in struct imc_chip_cb, look at include/imc.h).
* nest_pmus[] is an array containing all the possible nest IMC PMU node names.
@@ -212,6 +225,8 @@ static int get_imc_device_type(struct dt_node *node)
return IMC_COUNTER_CORE;
case IMC_COUNTER_THREAD:
return IMC_COUNTER_THREAD;
+ case IMC_COUNTER_TRACE:
+ return IMC_COUNTER_TRACE;
default:
break;
}
@@ -231,11 +246,23 @@ static bool is_nest_node(struct dt_node *node)
static bool is_imc_device_type_supported(struct dt_node *node)
{
u32 val = get_imc_device_type(node);
+ struct proc_chip *chip = get_chip(this_cpu()->chip_id);
+ uint64_t pvr;
if ((val == IMC_COUNTER_CHIP) || (val == IMC_COUNTER_CORE) ||
(val == IMC_COUNTER_THREAD))
return true;
+ if (val == IMC_COUNTER_TRACE) {
+ pvr = mfspr(SPR_PVR);
+ /*
+ * Trace mode is supported in Nimbus DD2.2
+ * and later versions.
+ */
+ if ((chip->type == PROC_CHIP_P9_NIMBUS) &&
+ (PVR_VERS_MAJ(pvr) == 2) && (PVR_VERS_MIN(pvr) >= 2))
+ return true;
+ }
return false;
}
@@ -641,7 +668,10 @@ static int64_t opal_imc_counters_init(uint32_t type, uint64_t addr, uint64_t cpu
int port_id, phys_core_id;
int ret;
uint32_t scoms;
-
+ uint64_t trace_scom_val = TRACE_IMC_SCOM(IMC_TRACE_SAMPLESEL_VAL,
+ IMC_TRACE_CPMCLOAD_VAL, 0,
+ IMC_TRACE_CPMC2SEL_VAL,
+ IMC_TRACE_BUFF_SIZE);
switch (type) {
case OPAL_IMC_COUNTERS_NEST:
return OPAL_SUCCESS;
@@ -727,6 +757,48 @@ static int64_t opal_imc_counters_init(uint32_t type, uint64_t addr, uint64_t cpu
return OPAL_HARDWARE;
}
return OPAL_SUCCESS;
+ case OPAL_IMC_COUNTERS_TRACE:
+ if (!c)
+ return OPAL_PARAMETER;
+
+ phys_core_id = cpu_get_core_index(c);
+ port_id = phys_core_id % 4;
+
+ if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS)
+ return OPAL_SUCCESS;
+
+ if (has_deep_states) {
+ if (wakeup_engine_state == WAKEUP_ENGINE_PRESENT) {
+ struct proc_chip *chip = get_chip(c->chip_id);
+
+ scoms = XSCOM_ADDR_P9_EC(phys_core_id,
+ TRACE_IMC_ADDR);
+ ret = stop_api_init(chip, phys_core_id, scoms,
+ trace_scom_val,
+ P9_STOP_SCOM_REPLACE,
+ P9_STOP_SECTION_CORE_SCOM,
+ "trace_imc");
+ if (ret)
+ return ret;
+ } else {
+ prerror("IMC-trace:Wakeup engine not present!");
+ return OPAL_HARDWARE;
+ }
+ }
+ if (xscom_write(c->chip_id,
+ XSCOM_ADDR_P9_EP(phys_core_id, htm_scom_index[port_id]),
+ (u64)CORE_IMC_HTM_MODE_DISABLE)) {
+ prerror("IMC-trace: error in xscom_write for htm mode\n");
+ return OPAL_HARDWARE;
+ }
+ if (xscom_write(c->chip_id,
+ XSCOM_ADDR_P9_EC(phys_core_id,
+ TRACE_IMC_ADDR), trace_scom_val)) {
+ prerror("IMC-trace: error in xscom_write for trace mode\n");
+ return OPAL_HARDWARE;
+ }
+ return OPAL_SUCCESS;
+
}
return OPAL_SUCCESS;
@@ -762,6 +834,7 @@ static int64_t opal_imc_counters_start(uint32_t type, uint64_t cpu_pir)
return OPAL_SUCCESS;
case OPAL_IMC_COUNTERS_CORE:
+ case OPAL_IMC_COUNTERS_TRACE:
/*
* Core IMC hardware mandates setting of htm_mode in specific
* scom ports (port_id are in htm_scom_index[])
@@ -823,6 +896,7 @@ static int64_t opal_imc_counters_stop(uint32_t type, uint64_t cpu_pir)
return OPAL_SUCCESS;
case OPAL_IMC_COUNTERS_CORE:
+ case OPAL_IMC_COUNTERS_TRACE:
/*
* Core IMC hardware mandates setting of htm_mode in specific
* scom ports (port_id are in htm_scom_index[])