@@ -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);
@@ -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 */
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> --- 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(-)