[Skiboot] [PATCH v4 4/8] skiboot: Add opal call to enable/disable Nest IMC microcode

Hemant Kumar hemant at linux.vnet.ibm.com
Wed Jan 4 16:50:36 AEDT 2017


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 at linux.vnet.ibm.com>
---
Changelog:
v2 -> v3:
 - Changed references from IMA to IMC.
 - Removed some of the gotos since, they seemed redundant.
 - Using get_ima_cb() helper function to get the IMC control block.
 - Using enum for nest IMC operations, also, exported them to opal-api.h. 
v1 -> v2:
 - Changed references from "pore_slw" to "IMA Microcode".
 - Changed the macro usage from "SLW_IMA_*" to "NEST_IMA_"*.

 hw/imc.c           | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/opal-api.h |  9 ++++++++-
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/hw/imc.c b/hw/imc.c
index f0eca7b..5809d51 100644
--- a/hw/imc.c
+++ b/hw/imc.c
@@ -186,3 +186,58 @@ void imc_init(void)
 err:
 	free(buf);
 }
+
+/*
+ * opal_nest_imc_counters_control : This call controls the nest IMC microcode.
+ *
+ * mode      : For now, this call supports only 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 != 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 05ff51d..9668758 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -181,7 +181,8 @@
 #define OPAL_INT_SET_MFRR			125
 #define OPAL_PCI_TCE_KILL			126
 #define OPAL_NMMU_SET_PTCR			127
-#define OPAL_LAST				127
+#define OPAL_NEST_IMC_COUNTERS_CONTROL		128
+#define OPAL_LAST				128
 
 /* Device tree flags */
 
@@ -1056,6 +1057,12 @@ enum {
 	OPAL_PCI_TCE_KILL_ALL,
 };
 
+/* Operation argument to Nest IMC Microcode */
+enum {
+	OPAL_NEST_IMC_STOP,
+	OPAL_NEST_IMC_START,
+};
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
-- 
2.7.4



More information about the Skiboot mailing list