Skip to content

Commit

Permalink
hw/imc: Enable opal calls to init/start/stop IMC Trace mode
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
anjutsudhakar authored and stewartsmith committed Mar 28, 2019
1 parent fa8f3f3 commit df2a1e5
Showing 1 changed file with 75 additions and 1 deletion.
76 changes: 75 additions & 1 deletion hw/imc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@
#include <device.h>
#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 /*
* b000- 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).
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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[])
Expand Down Expand Up @@ -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[])
Expand Down

0 comments on commit df2a1e5

Please sign in to comment.