summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorspashabk-in <shakeebbk@in.ibm.com>2016-11-24 00:27:30 -0600
committerSachin Gupta <sgupta2m@in.ibm.com>2017-02-03 01:59:43 -0500
commit4acf986de40d873d8dc35725e7786ccf8a28b496 (patch)
treefbb54026c5031521d64ac0b940cdf7c1a869e2b9
parentedb753be279189a97014b2d685370b777e340c7c (diff)
downloadtalos-sbe-4acf986de40d873d8dc35725e7786ccf8a28b496.tar.gz
talos-sbe-4acf986de40d873d8dc35725e7786ccf8a28b496.zip
Trace Array on SBE L2
Change-Id: I9c67fe30efc023baa0a159c382267dedf3bcf91c RTC:161831 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/32984 Reviewed-by: Joachim Fenkes <fenkes@de.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com> Reviewed-by: PARVATHI RACHAKONDA <prachako@in.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35791 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.C334
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.H21
2 files changed, 341 insertions, 14 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 68ecf0bc..867869a7 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
@@ -6,6 +6,7 @@
/* OpenPOWER sbe Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -49,19 +50,340 @@
//-----------------------------------------------------------------------------------
#include <p9_sbe_tracearray.H>
-//-----------------------------------------------------------------------------------
+#include <p9_mc_scom_addresses.H>
+#include <p9_misc_scom_addresses.H>
+#include <p9_obus_scom_addresses.H>
+#include <p9_perv_scom_addresses.H>
+#include <p9_perv_scom_addresses_fld.H>
+#include <p9_quad_scom_addresses.H>
+#include <p9_xbus_scom_addresses.H>
+
+p9_tracearray_bus_id NO_TB = (p9_tracearray_bus_id)0;
+
+//------------------------------------------------------------------------------
+// Constant definitions
+//------------------------------------------------------------------------------
+
+// offset to store high/low data within a given entry
+const uint32_t HI_BIT_OFFSET = 0;
+const uint32_t LO_BIT_OFFSET = 64;
+
+const uint32_t DEBUG_TRACE_CONTROL_OFS = PERV_DEBUG_TRACE_CONTROL - PERV_DBG_MODE_REG;
+
+const uint32_t DEBUG_TRACE_CONTROL_START = 0;
+const uint32_t DEBUG_TRACE_CONTROL_STOP = 1;
+const uint32_t DEBUG_TRACE_CONTROL_RESET = 2;
+
+const uint32_t TRACE_HI_DATA_OFS =
+ PERV_TP_TPCHIP_TRA0_TR0_TRACE_HI_DATA_REG - PERV_TP_TPCHIP_TRA0_TR0_TRACE_HI_DATA_REG;
+const uint32_t TRACE_LO_DATA_OFS =
+ PERV_TP_TPCHIP_TRA0_TR0_TRACE_LO_DATA_REG - PERV_TP_TPCHIP_TRA0_TR0_TRACE_HI_DATA_REG;
+const uint32_t TRACE_TRCTRL_CONFIG_OFS =
+ PERV_TP_TPCHIP_TRA0_TR0_TRACE_TRCTRL_CONFIG - PERV_TP_TPCHIP_TRA0_TR0_TRACE_HI_DATA_REG;
+
+const uint32_t EX_L21_SCOM_OFFSET = EQ_TPLC21_TR0_TRACE_HI_DATA_REG - EQ_TPLC20_TR0_TRACE_HI_DATA_REG;
+const uint32_t EX_L31_SCOM_OFFSET = EQ_L3TRA1_TR0_TRACE_HI_DATA_REG - EQ_L3TRA0_TR0_TRACE_HI_DATA_REG;
+
+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 TRACE_MUX_POSITIONS = 1 << TRCTRL_MUX0_SEL_LEN;
+
+const uint32_t TA_BASE_SCOM_MULTIPLIER = 0x00000040;
+const uint32_t TA_EX_OFFSET_MULTIPLIER = 0x00000040;
+const uint32_t TA_DEBUG_BASE_SCOM = 0x000107C0;
+const uint32_t TA_TRACE_BASE_SCOM = 0x00010400;
+//------------------------------------------------------------------------------
+// Table of known trace arrays
+//------------------------------------------------------------------------------
+
+struct ta_def
+{
+ /* One entry per mux setting; value of 0 means N/A */
+ p9_tracearray_bus_id bus_ids[TRACE_MUX_POSITIONS];
+ const uint8_t chiplet;
+ const uint8_t base_multiplier;
+ const uint8_t ex_multiplier;
+};
+
+static const ta_def ta_defs[] =
+{
+ /* PERV */
+ { { PROC_TB_PIB, PROC_TB_OCC, PROC_TB_TOD }, 0x01, 0x00, 0x00},
+ { { PROC_TB_SBE, PROC_TB_PIB_ALT }, 0x01, 0x01, 0x00},
+ /* N0 */
+ { { PROC_TB_PBIOE0 }, 0x02, 0x00, 0x00},
+ { { PROC_TB_PBIOE1 }, 0x02, 0x01, 0x00},
+ { { PROC_TB_CXA0, PROC_TB_NX }, 0x02, 0x02, 0x00},
+ /* N1 */
+ { { PROC_TB_PB6 }, 0x03, 0x00, 0x00},
+ { { PROC_TB_PB7 }, 0x03, 0x01, 0x00},
+ { { PROC_TB_PB8 }, 0x03, 0x02, 0x00},
+ { { PROC_TB_PB9 }, 0x03, 0x03, 0x00},
+ { { PROC_TB_PB10 }, 0x03, 0x04, 0x00},
+ { { PROC_TB_PB11 }, 0x03, 0x05, 0x00},
+ { { PROC_TB_MCD0, PROC_TB_MCD1, PROC_TB_VAS }, 0x03, 0x06, 0x00},
+ { { PROC_TB_MCS2, PROC_TB_MCS3, PROC_TB_PB13 }, 0x03, 0x07, 0x00},
+ { { PROC_TB_PBIO0 }, 0x03, 0x08, 0x00},
+ { { PROC_TB_PBIO1 }, 0x03, 0x09, 0x00},
+ /* N2 */
+ { { PROC_TB_CXA1, PROC_TB_IOPSI }, 0x04, 0x00, 0x00},
+ { { PROC_TB_PCIS0, PROC_TB_PCIS1, PROC_TB_PCIS2 }, 0x04, 0x01, 0x00},
+ /* N3 */
+ { { PROC_TB_PB0 }, 0x05, 0x00, 0x00},
+ { { PROC_TB_PB1 }, 0x05, 0x01, 0x00},
+ { { PROC_TB_PB2 }, 0x05, 0x02, 0x00},
+ { { PROC_TB_PB3 }, 0x05, 0x03, 0x00},
+ { { PROC_TB_PB4 }, 0x05, 0x04, 0x00},
+ { { PROC_TB_PB5 }, 0x05, 0x05, 0x00},
+ { { PROC_TB_INT, PROC_TB_NPU1, PROC_TB_NMMU1 }, 0x05, 0x06, 0x00},
+ { { PROC_TB_MCS0, PROC_TB_MCS1, PROC_TB_PB12 }, 0x05, 0x07, 0x00},
+ { { PROC_TB_BRIDGE }, 0x05, 0x08, 0x00},
+ { { PROC_TB_NPU0 }, 0x05, 0x0A, 0x00},
+ { { PROC_TB_NMMU0 }, 0x05, 0x0B, 0x00},
+ /* XBUS */
+ { { PROC_TB_PBIOX0, PROC_TB_IOX0 }, 0x06, 0x00, 0x00},
+ { { PROC_TB_PBIOX1, PROC_TB_IOX1 }, 0x06, 0x01, 0x00},
+ { { PROC_TB_PBIOX2, PROC_TB_IOX2 }, 0x06, 0x03, 0x00},
+ /* PCIx */
+ { { PROC_TB_PCI0X, PROC_TB_PCI00 }, 0x0D, 0x00, 0x00},
+ { { PROC_TB_PCI1X, PROC_TB_PCI11, PROC_TB_PCI12 }, 0x0E, 0x00, 0x00},
+ { { PROC_TB_PCI2X, PROC_TB_PCI23, PROC_TB_PCI24, PROC_TB_PCI25 }, 0x0F, 0x00, 0x00},
+ /* OBUS */
+ { { PROC_TB_PBIOOA, PROC_TB_IOO }, 0x09, 0x00, 0x00},
+ /* MC */
+ { { PROC_TB_MCA0 }, 0x07, 0x20, 0x00},
+ { { PROC_TB_MCA1 }, 0x07, 0x21, 0x00},
+ { { PROC_TB_IOMC0, PROC_TB_IOMC1, PROC_TB_IOMC2, PROC_TB_IOMC3 }, 0x07, 0x00, 0x00},
+ /* EX */
+ { { PROC_TB_L20, NO_TB, NO_TB, PROC_TB_SKIT10 }, 0x10, 0x94, 0x0C},
+ { { PROC_TB_L21, NO_TB, NO_TB, PROC_TB_SKIT11 }, 0x10, 0x95, 0x0C},
+ { { PROC_TB_L30, PROC_TB_NCU0, PROC_TB_CME, PROC_TB_EQPB }, 0x10, 0x00, 0x02},
+ { { PROC_TB_L31, PROC_TB_NCU1, PROC_TB_IVRM, PROC_TB_SKEWADJ }, 0x10, 0x01, 0x02},
+ /* CORE */
+ { { PROC_TB_CORE0 }, 0x20, 0x01, 0x00},
+ { { PROC_TB_CORE1 }, 0x20, 0x02, 0x00},
+};
+
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+
+class TraceArrayFinder
+{
+ public:
+ uint32_t mux_sel;
+ uint32_t debug_scom_base;
+ uint32_t trace_scom_base;
+ uint32_t ex_odd_scom_offset;
+
+ TraceArrayFinder(p9_tracearray_bus_id i_trace_bus) :
+ mux_sel(0), debug_scom_base(0),
+ trace_scom_base(0), ex_odd_scom_offset(0)
+ {
+ for(auto& l_ta_def : ta_defs)
+ {
+ for(size_t sel = 0; sel < TRACE_MUX_POSITIONS; sel++)
+ {
+ if(l_ta_def.bus_ids[sel] == i_trace_bus)
+ {
+ fapi2::buffer<uint32_t> l_buffer;
+ l_buffer.insert<0, 8>(l_ta_def.chiplet);
+ debug_scom_base = l_buffer | TA_DEBUG_BASE_SCOM;
+
+ trace_scom_base = l_buffer |
+ (TA_TRACE_BASE_SCOM +
+ TA_BASE_SCOM_MULTIPLIER *
+ l_ta_def.base_multiplier);
+
+ // Special handling Core
+ if(l_ta_def.chiplet == 0x20)
+ {
+ trace_scom_base &= 0x00FFFFFF;
+ }
+
+ ex_odd_scom_offset = TA_EX_OFFSET_MULTIPLIER *
+ l_ta_def.ex_multiplier;
+
+ mux_sel = sel;
+ return;
+ }
+ }
+ }
+ }
+};
+
+//-----------------------------------------------------------------------------
// Function definitions
-//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
fapi2::ReturnCode p9_sbe_tracearray(
const fapi2::Target<P9_SBE_TRACEARRAY_TARGET_TYPES>& i_target,
- const proc_gettracearray_args& i_args,
+ const p9_sbe_tracearray_args& i_args,
uint64_t* o_ta_data,
+ const uint32_t i_cur_row,
const uint32_t i_num_rows
)
{
+ fapi2::Target < P9_SBE_TRACEARRAY_TARGET_TYPES |
+ fapi2::TARGET_TYPE_EQ > target = i_target;
FAPI_INF("Start");
- FAPI_INF("End");
- return fapi2::current_err;
-}
+ const TraceArrayFinder l_ta_finder(i_args.trace_bus);
+
+ fapi2::TargetType arg_type = i_target.getType();
+ fapi2::TargetType ta_type =
+ p9_sbe_tracearray_target_type(i_args.trace_bus);
+
+ const uint32_t DEBUG_TRACE_CONTROL = l_ta_finder.debug_scom_base +
+ DEBUG_TRACE_CONTROL_OFS;
+ const uint32_t TRACE_SCOM_BASE = l_ta_finder.trace_scom_base;
+ const uint32_t TRACE_SCOM_OFFSET = l_ta_finder.ex_odd_scom_offset;
+
+ if ((arg_type & ta_type) == 0)
+ {
+ FAPI_ERR("Specified trace array requires target type 0x%X,"
+ "but the supplied target is of type 0x%X", ta_type, arg_type);
+ return fapi2::RC_PROC_GETTRACEARRAY_INVALID_TARGET;
+ }
+
+ /* Nimbus DD1 core traces can't be read out via SCOM.
+ * Check an EC feature to see if that's fixed. */
+ if (ta_type == fapi2::TARGET_TYPE_CORE)
+ {
+ uint8_t l_core_trace_scomable = 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_CORE_TRACE_SCOMABLE,
+ proc_target, l_core_trace_scomable),
+ "Failed to query chip EC feature"
+ "ATTR_CHIP_EC_FEATURE_CORE_TRACE_SCOMABLE");
+
+ if (!l_core_trace_scomable)
+ {
+ FAPI_ERR("Core arrays cannot be dumped in this chip EC;"
+ "please use fastarray instead.");
+ return fapi2::RC_PROC_GETTRACEARRAY_CORE_NOT_DUMPABLE;
+ }
+ }
+
+ /* For convenience, we link Cache trace arrays to the virtual EX chiplets.
+ * Transform back to EQ chiplet. */
+ if (ta_type == fapi2::TARGET_TYPE_EX)
+ {
+ target = i_target.getParent<fapi2::TARGET_TYPE_EQ>();
+ }
+
+ /* Check that the trace mux is set up as expected */
+ if (!i_args.ignore_mux_setting)
+ {
+ fapi2::buffer<uint64_t> buf;
+ FAPI_TRY(fapi2::getScom(target,
+ TRACE_SCOM_BASE + TRACE_SCOM_OFFSET + TRACE_TRCTRL_CONFIG_OFS,
+ buf),
+ "Failed to read current trace mux setting");
+ uint32_t cur_sel = 0;
+ buf.extractToRight<TRCTRL_MUX0_SEL, TRCTRL_MUX0_SEL_LEN>(cur_sel);
+ if (cur_sel != l_ta_finder.mux_sel)
+ {
+ FAPI_ERR("Primary trace mux is set to %d,"
+ " but %d is needed for requested trace bus",
+ cur_sel, l_ta_finder.mux_sel);
+ return fapi2::RC_PROC_GETTRACEARRAY_TRACE_MUX_INCORRECT;
+ }
+ }
+ /* If control is requested along with dump, pre dump condition
+ * should run only once.
+ * */
+ if (i_args.stop_pre_dump && (!i_args.collect_dump || (i_cur_row == 0)))
+ {
+ FAPI_DBG("Stopping trace arrays");
+ fapi2::buffer<uint64_t> buf;
+ buf.flush<0>().setBit<DEBUG_TRACE_CONTROL_STOP>();
+ FAPI_TRY(fapi2::putScom(target, DEBUG_TRACE_CONTROL, buf),
+ "Failed to stop chiplet domain trace arrays");
+ }
+
+ if (i_args.collect_dump)
+ {
+ fapi2::buffer<uint64_t> buf;
+
+ /* 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 + TRACE_SCOM_OFFSET + TRACE_LO_DATA_OFS,
+ 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. */
+ if (buf.getBit<TRACE_LO_DATA_RUNNING>())
+ {
+ FAPI_ERR("Trace array is still running -- "
+ " If you think you stopped it, maybe the controlling "
+ "debug macro is slaved to another debug macro?");
+ return fapi2::RC_PROC_GETTRACEARRAY_TRACE_RUNNING;
+ }
+
+ *((uint64_t*)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 + TRACE_SCOM_OFFSET + 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(target,
+ TRACE_SCOM_BASE + TRACE_SCOM_OFFSET + TRACE_HI_DATA_OFS, buf),
+ "Failed to read trace array high data register, iteration %d", i);
+ *((uint64_t*)o_ta_data + (2 * i + 0)) = buf;
+ }
+ }
+
+ /* If control is requested along with dump, post dump condition should run
+ * only after all the P9_TRACEARRAY_NUM_ROWS rows are read.
+ * */
+ if (i_args.reset_post_dump &&
+ (!i_args.collect_dump || (i_cur_row >= P9_TRACEARRAY_NUM_ROWS)))
+ {
+ FAPI_DBG("Resetting trace arrays");
+ fapi2::buffer<uint64_t> buf;
+ buf.flush<0>().setBit<DEBUG_TRACE_CONTROL_RESET>();
+ FAPI_TRY(fapi2::putScom(target, DEBUG_TRACE_CONTROL, buf),
+ "Failed to reset chiplet domain trace arrays");
+ }
+
+ if (i_args.restart_post_dump &&
+ (!i_args.collect_dump || (i_cur_row >= P9_TRACEARRAY_NUM_ROWS)))
+ {
+ FAPI_DBG("Starting trace arrays");
+ fapi2::buffer<uint64_t> buf;
+ buf.flush<0>().setBit<DEBUG_TRACE_CONTROL_START>();
+ FAPI_TRY(fapi2::putScom(target, DEBUG_TRACE_CONTROL, buf),
+ "Failed to restart chiplet domain trace arrays");
+ }
+
+ // mark HWP exit
+ FAPI_INF("Success");
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.H b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.H
index 21e4dbb5..3cc9bb87 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.H
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_tracearray.H
@@ -6,6 +6,7 @@
/* OpenPOWER sbe Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -56,7 +57,7 @@
#include "p9_tracearray_defs.H"
// structure to represent HWP arguments
-struct proc_gettracearray_args
+struct p9_sbe_tracearray_args
{
p9_tracearray_bus_id trace_bus; ///< The trace bus whose associated trace array should be dumped
bool stop_pre_dump; ///< Stop the trace array before starting the dump
@@ -74,7 +75,7 @@ static const fapi2::TargetType P9_SBE_TRACEARRAY_TARGET_TYPES =
//function pointer typedef definition for HWP call support
typedef fapi2::ReturnCode (*p9_sbe_tracearray_FP_t) (
const fapi2::Target<P9_SBE_TRACEARRAY_TARGET_TYPES>& i_target,
- const proc_gettracearray_args& i_args,
+ const p9_sbe_tracearray_args& i_args,
uint8_t* o_ta_data,
const uint32_t i_num_rows
);
@@ -88,7 +89,7 @@ extern "C" {
* @return The type of target to hand to p9_sbe_tracearray to clearly
* identify the array instance.
*/
- static inline fapi2::TargetType proc_gettracearray_target_type(p9_tracearray_bus_id i_trace_bus)
+ static inline fapi2::TargetType p9_sbe_tracearray_target_type(p9_tracearray_bus_id i_trace_bus)
{
/* On SBE there is no support for MCBIST and OBUS fapi targets.
* But since the usage related to these targets in p9_sbe_tracearray
@@ -115,17 +116,20 @@ extern "C" {
* rows requested, from selected trace array via SCOM.
* Optionally performing trace stop (prior to dump) and/or
* trace restart, reset (after dump).
- * If dump is requested along with other control flags, pre-dump control
- * would take effect before reading row 0 and post-dump control would
- * take effect after reading last row.
+ * If a partial dump is requested along with other control flags,
+ * pre-dump control would take effect before reading row 0 and
+ * post-dump control would take effect after reading last row.
*
* @param i_target Chip or chiplet target. The necessary target type can be
- * queried through proc_gettracearray_target_type().
+ * queried through p9_sbe_tracearray_target_type().
* @param i_args Argument structure with additional parameters
* @param o_ta_data Trace array data. Will contain requested number of trace
* rows from the array concatenated,
* starting with the oldest trace entry after the previous
* dump call and ending with the newest
+ * @param i_cur_row Current count of the row being extracted.
+ * Internally used to determine the order of
+ * pre and post dump control in case of partial dump.
* @param i_num_rows Number of rows of the tracearray to read.
* By default P9_TRACEARRAY_NUM_ROWS are read
*
@@ -142,8 +146,9 @@ extern "C" {
*/
fapi2::ReturnCode p9_sbe_tracearray(
const fapi2::Target<P9_SBE_TRACEARRAY_TARGET_TYPES>& i_target,
- const proc_gettracearray_args& i_args,
+ const p9_sbe_tracearray_args& i_args,
uint64_t* o_ta_data,
+ const uint32_t i_cur_row = 0,
const uint32_t i_num_rows = P9_TRACEARRAY_NUM_ROWS
);
} // extern "C"
OpenPOWER on IntegriCloud