[v8,07/10] skiboot: Add opal call to enable/disable Nest IMC

Submitted by Madhavan Srinivasan on April 3, 2017, 7:41 a.m.

Details

Message ID 1491205307-20408-8-git-send-email-maddy@linux.vnet.ibm.com
State New
Headers show

Commit Message

Madhavan Srinivasan April 3, 2017, 7:41 a.m.
From: Hemant Kumar <hemant@linux.vnet.ibm.com>

Add a new opal call to start/stop the Nest IMC microcode running in the
OCC complex based on the "operation" parameter. Also, check the status
from the control block structure before starting/stopping the IMC
microcode.

Adds two operations for the Nest IMC microcode to opal-api :
OPAL_NEST_IMC_STOP : Stop the nest IMC PMU counters collection
OPAL_NEST_IMC_START : Start the nest IMC PMU counters

Signed-off-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
[maddy: fixed the opal call number]
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
 hw/imc.c           | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/opal-api.h | 13 ++++++++++++-
 2 files changed, 67 insertions(+), 1 deletion(-)

Comments

Michael Ellerman April 25, 2017, 12:44 p.m.
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> writes:

> diff --git a/hw/imc.c b/hw/imc.c
> index 76b9659b752d..8436fa3933f6 100644
> --- a/hw/imc.c
> +++ b/hw/imc.c
> @@ -255,3 +255,58 @@ err:
>  	prerror("IMC Devices not added\n");
>  	free(buf);
>  }
> +
> +/*
> + * opal_nest_imc_counters_control : This call controls the nest IMC microcode.
> + *
> + * mode      : For now, this call supports only OPAL_NEST_IMC_PRODUCTION_MODE.
> + *             This mode can start/stop the Nest IMC Microcode for nest
> + *             instrumentation from Host OS.
> + * operation : Start(0x0) or Stop(0x1) the engine.
> + *
> + * This call can be extended to include more operations to use the multiple
> + * debug modes provided by the nest IMC microcode and the parameters value_1
> + * and value_2 for the same purpose.
> + */
> +static int64_t opal_nest_imc_counters_control(uint64_t mode,
> +					      uint64_t operation,
> +					      uint64_t value_1,
> +					      uint64_t value_2)
> +{

Sorry but I don't like this API at all.

Am I counting right that this gives us 73,786,976,294,838,206,464
possible combinations of parameters? :)

There's also no good way for Linux to know what values of mode,
operation, value1 or value2 are supported by the currently running OPAL.

I don't see why we wouldn't just have two OPAL calls, start and stop.

If we want to add another mode in future, that can be a new OPAL call.
Linux can detect a new OPAL call easily & cleanly with OPAL_CHECK_TOKEN.

cheers
Madhavan Srinivasan April 25, 2017, 1:23 p.m.
On Tuesday 25 April 2017 06:14 PM, Michael Ellerman wrote:
> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> writes:
>
>> diff --git a/hw/imc.c b/hw/imc.c
>> index 76b9659b752d..8436fa3933f6 100644
>> --- a/hw/imc.c
>> +++ b/hw/imc.c
>> @@ -255,3 +255,58 @@ err:
>>   	prerror("IMC Devices not added\n");
>>   	free(buf);
>>   }
>> +
>> +/*
>> + * opal_nest_imc_counters_control : This call controls the nest IMC microcode.
>> + *
>> + * mode      : For now, this call supports only OPAL_NEST_IMC_PRODUCTION_MODE.
>> + *             This mode can start/stop the Nest IMC Microcode for nest
>> + *             instrumentation from Host OS.
>> + * operation : Start(0x0) or Stop(0x1) the engine.
>> + *
>> + * This call can be extended to include more operations to use the multiple
>> + * debug modes provided by the nest IMC microcode and the parameters value_1
>> + * and value_2 for the same purpose.
>> + */
>> +static int64_t opal_nest_imc_counters_control(uint64_t mode,
>> +					      uint64_t operation,
>> +					      uint64_t value_1,
>> +					      uint64_t value_2)
>> +{
> Sorry but I don't like this API at all.
>
> Am I counting right that this gives us 73,786,976,294,838,206,464
> possible combinations of parameters? :)
>
> There's also no good way for Linux to know what values of mode,
> operation, value1 or value2 are supported by the currently running OPAL.
>
> I don't see why we wouldn't just have two OPAL calls, start and stop.

As suggested, on the other hand, we will have 3 opal calls, _INIT, _START
and _STOP with a parameter as IMC type (nest or core).

Thanks for review
Maddy


>
> If we want to add another mode in future, that can be a new OPAL call.
> Linux can detect a new OPAL call easily & cleanly with OPAL_CHECK_TOKEN.
>
> cheers
>

Patch hide | download patch | download mbox

diff --git a/hw/imc.c b/hw/imc.c
index 76b9659b752d..8436fa3933f6 100644
--- a/hw/imc.c
+++ b/hw/imc.c
@@ -255,3 +255,58 @@  err:
 	prerror("IMC Devices not added\n");
 	free(buf);
 }
+
+/*
+ * opal_nest_imc_counters_control : This call controls the nest IMC microcode.
+ *
+ * mode      : For now, this call supports only OPAL_NEST_IMC_PRODUCTION_MODE.
+ *             This mode can start/stop the Nest IMC Microcode for nest
+ *             instrumentation from Host OS.
+ * operation : Start(0x0) or Stop(0x1) the engine.
+ *
+ * This call can be extended to include more operations to use the multiple
+ * debug modes provided by the nest IMC microcode and the parameters value_1
+ * and value_2 for the same purpose.
+ */
+static int64_t opal_nest_imc_counters_control(uint64_t mode,
+					      uint64_t operation,
+					      uint64_t value_1,
+					      uint64_t value_2)
+{
+	u64 op, status;
+	struct imc_chip_cb *cb;
+
+	if ((mode != OPAL_NEST_IMC_PRODUCTION_MODE) || value_1 || value_2)
+		return OPAL_PARAMETER;
+
+	/* Fetch the IMC control block structure */
+	cb = get_imc_cb();
+	status = be64_to_cpu(cb->imc_chip_run_status);
+
+	switch (operation) {
+	case OPAL_NEST_IMC_STOP:
+		/* Check whether the engine is already stopped */
+		if (status == NEST_IMC_PAUSE)
+			return OPAL_SUCCESS;
+
+		op = NEST_IMC_DISABLE;
+		break;
+	case OPAL_NEST_IMC_START:
+		/* Check whether the engine is already running */
+		if (status == NEST_IMC_RESUME)
+			return OPAL_SUCCESS;
+
+		op = NEST_IMC_ENABLE;
+		break;
+	default:
+		prerror("IMC: unknown operation for nest imc\n");
+		return OPAL_PARAMETER;
+	}
+
+	/* Write the command to the control block now */
+	cb->imc_chip_command = op;
+
+	return OPAL_SUCCESS;
+}
+
+opal_call(OPAL_NEST_IMC_COUNTERS_CONTROL, opal_nest_imc_counters_control, 4);
diff --git a/include/opal-api.h b/include/opal-api.h
index 7966200eb1b2..c20b85ed4279 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -204,7 +204,8 @@ 
 #define OPAL_NPU_INIT_CONTEXT			146
 #define OPAL_NPU_DESTROY_CONTEXT		147
 #define OPAL_NPU_MAP_LPAR			148
-#define OPAL_LAST				148
+#define OPAL_NEST_IMC_COUNTERS_CONTROL		149
+#define OPAL_LAST				149
 
 /* Device tree flags */
 
@@ -1148,6 +1149,16 @@  enum {
 	XIVE_DUMP_EMU_STATE	= 5,
 };
 
+/* Operation argument to Nest IMC Microcode */
+enum {
+	OPAL_NEST_IMC_PRODUCTION_MODE = 1,
+};
+
+enum {
+	OPAL_NEST_IMC_STOP,
+	OPAL_NEST_IMC_START,
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */