summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/perv
diff options
context:
space:
mode:
authorJoachim Fenkes <fenkes@de.ibm.com>2017-06-08 15:09:20 -0400
committerDean Sanner <dsanner@us.ibm.com>2017-07-20 07:30:55 -0400
commita848bf96d3c69880f1d6f61e41d5ce6cf979bd71 (patch)
treef9548b119e8cd3fc5e597d31d7b91f2fbbc01d24 /src/import/chips/p9/procedures/hwp/perv
parenteae4ede6428cfaad3911b083e7d3d35ddf8498a2 (diff)
downloadtalos-hostboot-a848bf96d3c69880f1d6f61e41d5ce6cf979bd71.tar.gz
talos-hostboot-a848bf96d3c69880f1d6f61e41d5ce6cf979bd71.zip
p9_sbe_tracearray: Nimbus DD2 updates
Adapt "trace still running" check for DD2, and make use of the new "hold trace_run off" functionality in the process. Backwards compatible with DD1. Change-Id: Iab06937700039a5bb9c14acfe4942e4ae1c29352 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41575 Dev-Ready: Joachim Fenkes <fenkes@de.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Matt K. Light <mklight@us.ibm.com> Reviewed-by: Joseph J. McGill <jmcgill@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41578 Reviewed-by: Hostboot Team <hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Dean Sanner <dsanner@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/perv')
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C191
1 files changed, 132 insertions, 59 deletions
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C
index ec0d5d9ab..e20d82c60 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C
@@ -87,6 +87,8 @@ const uint32_t EX_L31_SCOM_OFFSET = EQ_L3TRA1_TR0_TRACE_HI_DATA_REG - EQ_
const uint32_t TRACE_LO_DATA_RUNNING = PERV_1_TPCHIP_TRA0_TR0_TRACE_LO_DATA_REG_RUNNING;
const uint32_t TRCTRL_MUX0_SEL = 14;
const uint32_t TRCTRL_MUX0_SEL_LEN = 2;
+const uint32_t TRCTRL_HOLD_OFF = 18;
+const uint32_t TRCTRL_RUN_STATUS = 19;
const uint32_t TRACE_MUX_POSITIONS = 1 << TRCTRL_MUX0_SEL_LEN;
@@ -205,6 +207,125 @@ class TraceArrayFinder
//-----------------------------------------------------------------------------
// Function definitions
//-----------------------------------------------------------------------------
+
+/**
+ * @brief Perform the actual dumping of the trace array
+ *
+ * Make sure trace_run is held off during the dump, and check that the trace is no longer running after
+ * we enabled holding it off (holding it off only makes sure it doesn't turn back on during the trace,
+ * it will not force it off if it's currently running).
+ *
+ * On DD1 that capability is not available, so we have to skip the SCOM operations to the TRCTRL register
+ * and can check for running trace by looking at the trace_running bit in the returned trace data.
+ *
+ * The error handling makes sure that the hold_off bit is cleared even in case of an error.
+ *
+ * @param i_target The target to run SCOMs against
+ * @param i_scom_base The calculated base SCOM address for the targeted trace array
+ * @param i_num_rows The number of rows requested to be dumped
+ * @param o_ta_data The destination data array
+ *
+ * @return fapi2::RC_PROC_GETTRACEARRAY_TRACE_RUNNING if trace is still running, else fapi2::FAPI2_RC_SUCCESS
+ */
+fapi2::ReturnCode p9_sbe_tracearray_do_dump(
+ const fapi2::Target < P9_SBE_TRACEARRAY_TARGET_TYPES | fapi2::TARGET_TYPE_EQ > &i_target,
+ const uint32_t i_scom_base,
+ const uint32_t i_num_rows,
+ uint64_t* o_ta_data)
+{
+ bool l_reset_trace_ctrl = false;
+ fapi2::buffer<uint64_t> l_trace_ctrl;
+ fapi2::buffer<uint64_t> buf = 0;
+ uint8_t l_trctrl_has_no_run_bits = 0;
+
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> proc_target =
+ i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_TRCTRL_HAS_NO_RUN_BITS,
+ proc_target, l_trctrl_has_no_run_bits),
+ "Failed to query chip EC feature "
+ "ATTR_CHIP_EC_FEATURE_TRCTRL_HAS_NO_RUN_BITS");
+
+ /* weird doubly inverted logic because the EC attr XML definition doesn't have inversion
+ * and I don't want to add new XML every time we decide to build another P9 variant */
+ if (!l_trctrl_has_no_run_bits)
+ {
+ FAPI_TRY(fapi2::getScom(i_target, i_scom_base + TRACE_TRCTRL_CONFIG_OFS, l_trace_ctrl),
+ "Failed to read current trace control setting");
+
+ if (l_trace_ctrl.getBit<TRCTRL_RUN_STATUS>())
+ {
+ FAPI_TRY(fapi2::RC_PROC_GETTRACEARRAY_TRACE_RUNNING);
+ }
+
+ l_trace_ctrl.setBit<TRCTRL_HOLD_OFF>();
+ FAPI_TRY(fapi2::putScom(i_target, i_scom_base + TRACE_TRCTRL_CONFIG_OFS, l_trace_ctrl),
+ "Failed to enable holding trace_run off; a possible reason is that "
+ "tracing was started just before the SCOM access");
+ l_reset_trace_ctrl = true;
+ }
+
+ /* Start with the low data register because that's where the
+ * "trace running" bit is. */
+ for (uint32_t i = 0; i < i_num_rows; i++)
+ {
+ FAPI_TRY(fapi2::getScom(i_target, i_scom_base + TRACE_LO_DATA_OFS, buf),
+ "Failed to read trace array low data register,"
+ " iteration %d", i);
+
+ /* On DD1, the "trace running" bit is our best indicator of whether
+ * the array is currently running.
+ * If it is, the read won't have incremented the address,
+ * so it's okay to bail out. */
+ if (buf.getBit<TRACE_LO_DATA_RUNNING>())
+ {
+ FAPI_TRY(fapi2::RC_PROC_GETTRACEARRAY_TRACE_RUNNING);
+ }
+
+ *(o_ta_data + (2 * i + 1)) = buf;
+ }
+
+ /*
+ * Run empty scoms to move the address pointer of trace array control
+ * logic, till it reaches the same row again, as the trace array is
+ * a circular buffer
+ */
+ for (uint32_t i = 0; i < (P9_TRACEARRAY_NUM_ROWS - i_num_rows); i++)
+ {
+ FAPI_TRY(fapi2::getScom(i_target, i_scom_base + TRACE_LO_DATA_OFS, buf),
+ "Failed to read trace array low data register, "
+ "iteration %d", i);
+ }
+
+ /* Then dump the high data */
+ for (uint32_t i = 0; i < i_num_rows; i++)
+ {
+ FAPI_TRY(fapi2::getScom(i_target, i_scom_base + TRACE_HI_DATA_OFS, buf),
+ "Failed to read trace array high data register, "
+ "iteration %d", i);
+ *(o_ta_data + (2 * i + 0)) = buf;
+ }
+
+fapi_try_exit:
+
+ if (l_reset_trace_ctrl)
+ {
+ l_trace_ctrl.clearBit<TRCTRL_HOLD_OFF>();
+ fapi2::ReturnCode l_rc = fapi2::putScom(i_target, i_scom_base + TRACE_TRCTRL_CONFIG_OFS, l_trace_ctrl);
+
+ if (l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ FAPI_ERR("Failed to stop holding trace_run off");
+
+ if (fapi2::current_err == fapi2::FAPI2_RC_SUCCESS)
+ {
+ fapi2::current_err = l_rc;
+ }
+ }
+ }
+
+ return fapi2::current_err;
+}
+
fapi2::ReturnCode p9_sbe_tracearray(
const fapi2::Target<P9_SBE_TRACEARRAY_TARGET_TYPES>& i_target,
const proc_gettracearray_args& i_args,
@@ -213,8 +334,7 @@ fapi2::ReturnCode p9_sbe_tracearray(
const uint32_t i_num_rows
)
{
- fapi2::Target < P9_SBE_TRACEARRAY_TARGET_TYPES |
- fapi2::TARGET_TYPE_EQ > target = i_target;
+ fapi2::Target < P9_SBE_TRACEARRAY_TARGET_TYPES | fapi2::TARGET_TYPE_EQ > target = i_target;
FAPI_INF("Start");
const TraceArrayFinder l_ta_finder(i_args.trace_bus);
@@ -328,63 +448,16 @@ fapi2::ReturnCode p9_sbe_tracearray(
if (i_args.collect_dump)
{
- fapi2::buffer<uint64_t> buf = 0;
-
- /* Start with the low data register because that's where the
- * "trace running" bit is. */
- for (uint32_t i = 0; i < i_num_rows; i++)
- {
- FAPI_TRY(fapi2::getScom(target,
- (TRACE_SCOM_BASE +
- tra_scom_offset +
- TRACE_LO_DATA_OFS +
- l_proc_offset),
- buf),
- "Failed to read trace array low data register,"
- " iteration %d", i);
-
- /* The "trace running" bit is our best indicator of whether
- * the array is currently running.
- * If it is, the read won't have incremented the address,
- * so it's okay to bail out. */
- FAPI_ASSERT(!buf.getBit<TRACE_LO_DATA_RUNNING>(), fapi2::PROC_GETTRACEARRAY_TRACE_RUNNING()
- .set_TARGET(i_target).set_TRACE_BUS(i_args.trace_bus),
- "Trace array is still running -- If you think you stopped it, "
- "maybe the controlling debug macro is slaved to another debug macro?");
-
- *(o_ta_data + (2 * i + 1)) = buf;
- }
-
- /*
- * Run empty scoms to move the address pointer of trace array control
- * logic, till it reaches the same row again, as the trace array is
- * a circular buffer
- */
- for (uint32_t i = 0; i < (P9_TRACEARRAY_NUM_ROWS - i_num_rows); i++)
- {
- FAPI_TRY(fapi2::getScom(target,
- (TRACE_SCOM_BASE +
- tra_scom_offset +
- TRACE_LO_DATA_OFS +
- l_proc_offset),
- buf),
- "Failed to read trace array low data register, "
- "iteration %d", i);
- }
-
- /* Then dump the high data */
- for (uint32_t i = 0; i < i_num_rows; i++)
- {
- FAPI_TRY(fapi2::getScom(target,
- (TRACE_SCOM_BASE +
- tra_scom_offset +
- TRACE_HI_DATA_OFS +
- l_proc_offset),
- buf),
- "Failed to read trace array high data register, "
- "iteration %d", i);
- *(o_ta_data + (2 * i + 0)) = buf;
- }
+ /* Run the do_dump subroutine, turn the TRACE_RUNNING return code into FFDC */
+ fapi2::ReturnCode l_rc = p9_sbe_tracearray_do_dump(target,
+ TRACE_SCOM_BASE + tra_scom_offset + l_proc_offset,
+ i_num_rows, o_ta_data);
+ FAPI_ASSERT(l_rc != fapi2::ReturnCode(fapi2::RC_PROC_GETTRACEARRAY_TRACE_RUNNING),
+ fapi2::PROC_GETTRACEARRAY_TRACE_RUNNING()
+ .set_TARGET(i_target).set_TRACE_BUS(i_args.trace_bus),
+ "Trace array is still running -- If you think you stopped it, "
+ "maybe the controlling debug macro is slaved to another debug macro?");
+ FAPI_TRY(l_rc);
}
/* If control is requested along with dump, post dump condition should run
OpenPOWER on IntegriCloud