summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBilicon Patil <bilpatil@in.ibm.com>2016-02-29 23:22:08 -0600
committerSachin Gupta <sgupta2m@in.ibm.com>2016-06-14 09:12:08 -0400
commit3e84e26a998aa57b6b2f452003fcbb941c5c9e37 (patch)
tree9cdeb81a4e6159e074d269c685d849771e6ce6d6
parent37a6c05e8ef51cf4899cad053de87c80b26c185b (diff)
downloadtalos-sbe-3e84e26a998aa57b6b2f452003fcbb941c5c9e37.tar.gz
talos-sbe-3e84e26a998aa57b6b2f452003fcbb941c5c9e37.zip
PutRing utils to scan rings
Change-Id: Ieab183be571fda1013ef658568aee495c68c7100 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/21795 Tested-by: Jenkins Server Tested-by: PPE CI Tested-by: Hostboot CI Reviewed-by: Michael S. Floyd <mfloyd@us.ibm.com> Dev-Ready: Michael S. Floyd <mfloyd@us.ibm.com> Reviewed-by: Claus M. Olsen <cmolsen@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/21796 Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
-rw-r--r--import/chips/p9/utils/Makefile47
-rw-r--r--import/chips/p9/utils/imageProcs/p9_ringId.H242
-rw-r--r--import/chips/p9/utils/p9_putRingUtils.C1001
-rw-r--r--import/chips/p9/utils/p9_putRingUtils.H295
-rw-r--r--import/chips/p9/utils/p9_putRingUtils.mk22
-rw-r--r--import/chips/p9/utils/utils.mk29
-rw-r--r--import/hwpf/fapi2/include/return_code_defs.H10
7 files changed, 1645 insertions, 1 deletions
diff --git a/import/chips/p9/utils/Makefile b/import/chips/p9/utils/Makefile
new file mode 100644
index 00000000..f4c48d5d
--- /dev/null
+++ b/import/chips/p9/utils/Makefile
@@ -0,0 +1,47 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: chips/p9/utils/Makefile $
+#
+# IBM CONFIDENTIAL
+#
+# EKB Project
+#
+# COPYRIGHT 2016
+# [+] International Business Machines Corp.
+#
+#
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# IBM_PROLOG_END_TAG
+
+# @brief This Makefile compiles all of the PutRing Utils code.
+# All the generated files from this makefile will end up in obj/utils
+#
+#
+export SUB_OBJDIR = /utils
+
+include img_defs.mk
+include utils.mk
+
+OBJS := $(addprefix $(OBJDIR)/, $(UTILS_OBJECTS))
+
+libutils.a: utils
+ $(AR) crs $(OBJDIR)/libutils.a $(OBJDIR)/*.o
+
+.PHONY: clean utils
+utils: $(OBJS)
+
+$(OBJS) $(OBJS:.o=.d): | $(OBJDIR)
+
+$(OBJDIR):
+ mkdir -p $(OBJDIR)
+
+clean:
+ rm -fr $(OBJDIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(OBJS:.o=.d)
+endif
diff --git a/import/chips/p9/utils/imageProcs/p9_ringId.H b/import/chips/p9/utils/imageProcs/p9_ringId.H
index 643f6e85..0aa3dc67 100644
--- a/import/chips/p9/utils/imageProcs/p9_ringId.H
+++ b/import/chips/p9/utils/imageProcs/p9_ringId.H
@@ -29,7 +29,23 @@ enum RINGTYPE
COMMON_RING = 0,
INSTANCE_RING = 1
};
-}; //end of RS4 namespace
+}; //end of RING_TYPES namespace
+enum CHIPLET_TYPE
+{
+ PERV_TYPE,
+ N0_TYPE,
+ N1_TYPE,
+ N2_TYPE,
+ N3_TYPE,
+ MC_TYPE,
+ PCI0_TYPE,
+ PCI1_TYPE,
+ PCI2_TYPE,
+ OB_TYPE,
+ XB_TYPE,
+ EQ_TYPE,
+ EC_TYPE,
+};
///
/// @enum RingID
@@ -737,12 +753,23 @@ static const uint32_t INVALID_RING = 999;
// This structure is needed for mapping a RingID to it's corresponding name.
// The names will be used by the build scripts when generating the TOR.
+#ifndef __PPE__
struct ringProperties_t
{
uint32_t iv_torOffSet;
char iv_name[25];
+ CHIPLET_TYPE iv_type;
+};
+#endif
+#ifdef __PPE__
+struct ringProperties_t
+{
+ uint32_t iv_torOffSet;
+ CHIPLET_TYPE iv_type;
};
+#endif
+#ifndef __PPE__
static const ringProperties_t RING_PROPERTIES[P9_NUM_RINGS] =
{
// Pervasive Ring
@@ -952,3 +979,216 @@ static const ringProperties_t RING_PROPERTIES[P9_NUM_RINGS] =
{EC::ec_repr, "ec_repr"} // 181
};
#endif
+
+
+#ifdef __PPE__
+static const ringProperties_t RING_PROPERTIES[P9_NUM_RINGS] =
+{
+ // Pervasive Ring
+ {PERV::perv_fure, PERV_TYPE}, // 0
+ {PERV::perv_gptr, PERV_TYPE}, // 1
+ {PERV::perv_time, PERV_TYPE}, // 2
+ {PERV::occ_fure, PERV_TYPE}, // 3
+ {PERV::occ_gptr, PERV_TYPE}, // 4
+ {PERV::occ_time, PERV_TYPE}, // 5
+ {PERV::perv_ana_func, PERV_TYPE}, // 6
+ {PERV::perv_ana_gptr, PERV_TYPE}, // 7
+ {PERV::perv_pll_gptr, PERV_TYPE}, // 8
+ {PERV::perv_pll_bndy, PERV_TYPE}, // 9
+ {PERV::perv_pll_bndy_bucket_1, PERV_TYPE}, // 10
+ {PERV::perv_pll_bndy_bucket_2, PERV_TYPE}, // 11
+ {PERV::perv_pll_bndy_bucket_3, PERV_TYPE}, // 12
+ {PERV::perv_pll_bndy_bucket_4, PERV_TYPE}, // 13
+ {PERV::perv_pll_bndy_bucket_5, PERV_TYPE}, // 14
+ {PERV::perv_repr, PERV_TYPE}, // 15
+ {PERV::occ_repr, PERV_TYPE}, // 16
+ {INVALID_RING, PERV_TYPE}, // 17 // for future.
+ {INVALID_RING, PERV_TYPE}, // 18 // for future.
+
+ // Nest N0 Ring
+ {N0::n0_fure, N0_TYPE}, // 19
+ {N0::n0_gptr, N0_TYPE}, // 20
+ {N0::n0_time, N0_TYPE}, // 21
+ {N0::n0_nx_fure, N0_TYPE}, // 22
+ {N0::n0_nx_gptr, N0_TYPE}, // 23
+ {N0::n0_nx_time, N0_TYPE}, // 24
+ {N0::n0_cxa0_fure, N0_TYPE}, // 25
+ {N0::n0_cxa0_gptr, N0_TYPE}, // 26
+ {N0::n0_cxa0_time, N0_TYPE}, // 27
+ {N0::n0_repr, N0_TYPE}, // 28
+ {N0::n0_nx_repr, N0_TYPE}, // 29
+ {N0::n0_cxa0_repr, N0_TYPE}, // 30
+ {INVALID_RING, N0_TYPE}, // 31 // for future.
+ {INVALID_RING, N0_TYPE}, // 32 // for future.
+ {INVALID_RING, N0_TYPE}, // 33 // for future.
+
+ // Nest N1 Ring
+ {N1::n1_fure, N1_TYPE}, // 34
+ {N1::n1_gptr, N1_TYPE}, // 35
+ {N1::n1_time, N1_TYPE}, // 36
+ {N1::n1_ioo0_fure, N1_TYPE}, // 37
+ {N1::n1_ioo0_gptr, N1_TYPE}, // 38
+ {N1::n1_ioo0_time, N1_TYPE}, // 39
+ {N1::n1_ioo1_fure, N1_TYPE}, // 40
+ {N1::n1_ioo1_gptr, N1_TYPE}, // 41
+ {N1::n1_ioo1_time, N1_TYPE}, // 42
+ {N1::n1_mcs23_fure, N1_TYPE}, // 43
+ {N1::n1_mcs23_gptr, N1_TYPE}, // 44
+ {N1::n1_mcs23_time, N1_TYPE}, // 45
+ {N1::n1_repr, N1_TYPE}, // 46
+ {N1::n1_ioo0_repr, N1_TYPE}, // 47
+ {N1::n1_ioo1_repr, N1_TYPE}, // 48
+ {N1::n1_mcs23_repr, N1_TYPE}, // 49
+ {INVALID_RING, N1_TYPE}, // 50 // for future.
+ {INVALID_RING, N1_TYPE}, // 51 // for future.
+ {INVALID_RING, N1_TYPE}, // 52 // for future.
+
+ // Nest N2 Ring
+ {N2::n2_fure, N2_TYPE}, // 53
+ {N2::n2_gptr, N2_TYPE}, // 54
+ {N2::n2_time, N2_TYPE}, // 55
+ {N2::n2_cxa1_fure, N2_TYPE}, // 56
+ {N2::n2_cxa1_gptr, N2_TYPE}, // 57
+ {N2::n2_cxa1_time, N2_TYPE}, // 58
+ {N2::n2_repr, N2_TYPE}, // 59
+ {N2::n2_cxa1_repr, N2_TYPE}, // 60
+ {INVALID_RING, N2_TYPE}, // 61 // for future.
+ {INVALID_RING, N2_TYPE}, // 62 // for future.
+ {INVALID_RING, N2_TYPE}, // 63 // for future.
+
+ // Nest N3 Ring
+ {N3::n3_fure, N3_TYPE}, // 64
+ {N3::n3_gptr, N3_TYPE}, // 65
+ {N3::n3_time, N3_TYPE}, // 66
+ {N3::n3_mcs01_fure, N3_TYPE}, // 67
+ {N3::n3_mcs01_gptr, N3_TYPE}, // 68
+ {N3::n3_mcs01_time, N3_TYPE}, // 69
+ {N3::n3_repr, N3_TYPE}, // 70
+ {N3::n3_mcs01_repr, N3_TYPE}, // 71
+ {INVALID_RING, N3_TYPE}, // 72 // for future.
+ {INVALID_RING, N3_TYPE}, // 73 // for future.
+ {INVALID_RING, N3_TYPE}, // 74 // for future.
+
+ // XB Ring
+ {XB::xb_fure, XB_TYPE}, // 75
+ {XB::xb_gptr, XB_TYPE}, // 76
+ {XB::xb_time, XB_TYPE}, // 77
+ {XB::xb_io0_fure, XB_TYPE}, // 78
+ {XB::xb_io0_gptr, XB_TYPE}, // 79
+ {XB::xb_io0_time, XB_TYPE}, // 80
+ {XB::xb_io1_fure, XB_TYPE}, // 81
+ {XB::xb_io1_gptr, XB_TYPE}, // 82
+ {XB::xb_io1_time, XB_TYPE}, // 83
+ {XB::xb_io2_fure, XB_TYPE}, // 84
+ {XB::xb_io2_gptr, XB_TYPE}, // 85
+ {XB::xb_io2_time, XB_TYPE}, // 86
+ {XB::xb_pll_gptr, XB_TYPE}, // 87
+ {XB::xb_pll_other, XB_TYPE}, // 88
+ {XB::xb_pll_bndy, XB_TYPE}, // 89
+ {XB::xb_pll_bndy_bucket_1, XB_TYPE}, // 90
+ {XB::xb_pll_bndy_bucket_2, XB_TYPE}, // 91
+ {XB::xb_pll_bndy_bucket_3, XB_TYPE}, // 92
+ {XB::xb_pll_bndy_bucket_4, XB_TYPE}, // 93
+ {XB::xb_pll_bndy_bucket_5, XB_TYPE}, // 94
+ {XB::xb_repr, XB_TYPE}, // 95
+ {XB::xb_io0_repr, XB_TYPE}, // 96
+ {XB::xb_io1_repr, XB_TYPE}, // 97
+ {XB::xb_io2_repr, XB_TYPE}, // 98
+ {INVALID_RING, XB_TYPE}, // 99 // for future.
+ {INVALID_RING, XB_TYPE}, // 100 // for future.
+
+ // MC Ring
+ {MC::mc_fure, MC_TYPE}, // 101
+ {MC::mc_gptr, MC_TYPE}, // 102
+ {MC::mc_time, MC_TYPE}, // 103
+ {MC::mc_iom01_fure, MC_TYPE}, // 104
+ {MC::mc_iom01_gptr, MC_TYPE}, // 105
+ {MC::mc_iom01_time, MC_TYPE}, // 106
+ {MC::mc_iom23_fure, MC_TYPE}, // 107
+ {MC::mc_iom23_gptr, MC_TYPE}, // 108
+ {MC::mc_iom23_time, MC_TYPE}, // 119
+ {MC::mc_pll_gptr, MC_TYPE}, // 110
+ {MC::mc_pll_other, MC_TYPE}, // 111
+ {MC::mc_pll_bndy, MC_TYPE}, // 112
+ {MC::mc_pll_bndy_bucket_1, MC_TYPE}, // 113
+ {MC::mc_pll_bndy_bucket_2, MC_TYPE}, // 114
+ {MC::mc_pll_bndy_bucket_3, MC_TYPE}, // 115
+ {MC::mc_pll_bndy_bucket_4, MC_TYPE}, // 116
+ {MC::mc_pll_bndy_bucket_5, MC_TYPE}, // 117
+ {MC::mc_repr, MC_TYPE}, // 118
+ {MC::mc_iom01_repr, MC_TYPE}, // 119
+ {MC::mc_iom23_repr, MC_TYPE}, // 120
+ {INVALID_RING, MC_TYPE}, // 121 // for future.
+ {INVALID_RING, MC_TYPE}, // 122 // for future.
+ {INVALID_RING, MC_TYPE}, // 123 // for future.
+
+ // OB Ring
+ {OB::ob_fure, OB_TYPE}, // 124
+ {OB::ob_gptr, OB_TYPE}, // 125
+ {OB::ob_time, OB_TYPE}, // 126
+ {OB::ob_pll_gptr, OB_TYPE}, // 127
+ {OB::ob_pll_other, OB_TYPE}, // 128
+ {OB::ob_pll_bndy, OB_TYPE}, // 129
+ {OB::ob_pll_bndy_bucket_1, OB_TYPE}, // 130
+ {OB::ob_pll_bndy_bucket_2, OB_TYPE}, // 131
+ {OB::ob_pll_bndy_bucket_3, OB_TYPE}, // 132
+ {OB::ob_pll_bndy_bucket_4, OB_TYPE}, // 133
+ {OB::ob_pll_bndy_bucket_5, OB_TYPE}, // 134
+ {OB::ob_repr, OB_TYPE}, // 135
+ {INVALID_RING, OB_TYPE}, // 136 // for future.
+ {INVALID_RING, OB_TYPE}, // 137 // for future.
+
+ // PCI0 Ring
+ {PCI0::pci0_fure, PCI0_TYPE}, // 138
+ {PCI0::pci0_gptr, PCI0_TYPE}, // 139
+ {PCI0::pci0_time, PCI0_TYPE}, // 140
+ {PCI0::pci0_repr, PCI0_TYPE}, // 141
+ // PCI1 Ring
+ {PCI1::pci1_fure, PCI1_TYPE}, // 142
+ {PCI1::pci1_gptr, PCI1_TYPE}, // 143
+ {PCI1::pci1_time, PCI1_TYPE}, // 144
+ {PCI1::pci1_repr, PCI1_TYPE}, // 145
+ // PCI2 Ring
+ {PCI2::pci2_fure, PCI2_TYPE}, // 146
+ {PCI2::pci2_gptr, PCI2_TYPE}, // 147
+ {PCI2::pci2_time, PCI2_TYPE}, // 148
+ {PCI2::pci2_repr, PCI2_TYPE}, // 149
+ {INVALID_RING, PCI2_TYPE}, // 150 // for future.
+ {INVALID_RING, PCI2_TYPE}, // 151 // for future.
+ {INVALID_RING, PCI2_TYPE}, // 152 // for future.
+
+ // EQ Ring
+ {EQ::eq_fure, EQ_TYPE}, // 153
+ {EQ::eq_gptr, EQ_TYPE}, // 154
+ {EQ::eq_time, EQ_TYPE}, // 155
+ {EQ::ex_l3_fure, EQ_TYPE}, // 156
+ {EQ::ex_l3_gptr, EQ_TYPE}, // 157
+ {EQ::ex_l3_time, EQ_TYPE}, // 158
+ {EQ::ex_l2_fure, EQ_TYPE}, // 159
+ {EQ::ex_l2_gptr, EQ_TYPE}, // 160
+ {EQ::ex_l2_time, EQ_TYPE}, // 161
+ {EQ::ex_l3_refr_fure, EQ_TYPE}, // 162
+ {EQ::ex_l3_refr_gptr, EQ_TYPE}, // 163
+ {EQ::ex_l3_refr_time, EQ_TYPE}, // 164
+ {EQ::eq_ana_func, EQ_TYPE}, // 165
+ {EQ::eq_ana_gptr, EQ_TYPE}, // 166
+ {EQ::eq_dpll_func, EQ_TYPE}, // 167
+ {EQ::eq_dpll_gptr, EQ_TYPE}, // 168
+ {EQ::eq_dpll_other, EQ_TYPE}, // 169
+ {EQ::eq_repr, EQ_TYPE}, // 170
+ {EQ::ex_l3_repr, EQ_TYPE}, // 171
+ {EQ::ex_l2_repr, EQ_TYPE}, // 172
+ {EQ::ex_l3_refr_repr, EQ_TYPE}, // 173
+ {EQ::eq_ana_bndy, EQ_TYPE}, // 174
+ {INVALID_RING, EQ_TYPE}, // 175 // for future.
+ {INVALID_RING, EQ_TYPE}, // 176 // for future.
+
+ // Core Ring
+ {EC::ec_func, EC_TYPE}, // 177
+ {EC::ec_gptr, EC_TYPE}, // 178
+ {EC::ec_time, EC_TYPE}, // 179
+ {EC::ec_mode, EC_TYPE}, // 180
+ {EC::ec_repr, EC_TYPE} // 181
+};
+#endif
+#endif
diff --git a/import/chips/p9/utils/p9_putRingUtils.C b/import/chips/p9/utils/p9_putRingUtils.C
new file mode 100644
index 00000000..0cc6a7d2
--- /dev/null
+++ b/import/chips/p9/utils/p9_putRingUtils.C
@@ -0,0 +1,1001 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/utils/p9_putRingUtils.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/// @file p9_putRingUtils.C
+/// @brief Provide the service of decompressing the rs4 encoded string.
+///
+// *HWP HWP Owner: Bilicon Patil <bilpatil@in.ibm.com>
+// *HWP FW Owner: Prasad Ranganath <prasadbgr@in.ibm.com>
+// *HWP Team: PM
+// *HWP Level: 2
+// *HWP Consumed by: SBE:CME:SGPE:PGPE
+
+#include <p9_putRingUtils.H>
+
+using namespace RING_TYPES;
+namespace RS4
+{
+//
+// Function Definitions
+//
+
+///
+/// @brief Return a big-endian-indexed nibble from a byte string
+/// @param[in] i_rs4Str The RS4 scan string
+/// @param[in] i_nibbleIndx Index into i_rs4Str that need to converted
+/// into a nibble
+/// @return big-endian-indexed nibble
+///
+uint8_t rs4_get_nibble(const uint8_t* i_rs4Str, const uint32_t i_nibbleIndx)
+{
+ uint8_t l_byte;
+ uint8_t l_nibble;
+
+ l_byte = i_rs4Str[i_nibbleIndx / 2];
+
+
+ if(i_nibbleIndx % 2)
+ {
+ l_nibble = (l_byte & 0x0f);
+ }
+ else
+ {
+ l_nibble = (l_byte >> 4);
+ }
+
+ return l_nibble;
+}
+
+///
+/// @brief Return verbatim data from the RS4 string
+/// @param[in] i_rs4Str The RS4 scan string
+/// @param[in] i_nibbleIndx Index into i_rs4Str that need to converted
+/// into a nibble
+/// @param[in] i_nibbleCount The count of nibbles that need to be put
+/// in the return value.
+/// @return big-endian-indexed double word
+///
+uint64_t rs4_get_verbatim(const uint8_t* i_rs4Str,
+ const uint32_t i_nibbleIndx,
+ const uint8_t i_nibbleCount)
+{
+ uint8_t l_byte;
+ uint8_t l_nibble;
+ uint64_t l_doubleWord = 0;
+
+ uint32_t l_index = i_nibbleIndx;
+
+ for(uint8_t i = 1; i <= i_nibbleCount; i++, l_index++)
+ {
+ l_byte = i_rs4Str[l_index / 2];
+
+ if(l_index % 2)
+ {
+ l_nibble = (l_byte & 0x0f);
+ }
+ else
+ {
+ l_nibble = (l_byte >> 4);
+ }
+
+ uint64_t l_tempDblWord = l_nibble;
+ l_tempDblWord <<= (64 - (4 * i));
+
+ l_doubleWord |= l_tempDblWord;
+ }
+
+ return l_doubleWord;
+}
+
+///
+/// @brief Decode an unsigned integer from a 4-bit octal stop code.
+/// @param[in] i_rs4Str The RS4 scan string
+/// @param[in] i_nibbleIndx Index into i_rs4Str that has the stop-code
+/// @param[out] o_numRotate No.of rotates decoded from the stop-code.
+/// @return The number of nibbles decoded.
+///
+uint64_t stop_decode(const uint8_t* i_rs4Str,
+ uint32_t i_nibbleIndx,
+ uint64_t& o_numRotate)
+{
+ uint64_t l_numNibblesParsed = 0; // No.of nibbles that make up the stop-code
+ uint64_t l_numNonZeroNibbles = 0;
+ uint8_t l_nibble;
+
+ do
+ {
+ l_nibble = rs4_get_nibble(i_rs4Str, i_nibbleIndx);
+
+ l_numNonZeroNibbles = (l_numNonZeroNibbles * 8) + (l_nibble & 0x07);
+
+ i_nibbleIndx++;
+ l_numNibblesParsed++;
+ }
+ while((l_nibble & 0x08) == 0);
+
+ o_numRotate = l_numNonZeroNibbles;
+
+ return l_numNibblesParsed;
+}
+
+/// @brief Byte-reverse a 64-bit integer
+/// @param[in] i_x 64-bit word that need to be byte reversed
+/// @return Byte reversed 64-bit word
+uint64_t rs4_revle64(const uint64_t i_x)
+{
+ uint64_t rx;
+
+#ifndef _BIG_ENDIAN
+ uint8_t* pix = (uint8_t*)(&i_x);
+ uint8_t* prx = (uint8_t*)(&rx);
+
+ prx[0] = pix[7];
+ prx[1] = pix[6];
+ prx[2] = pix[5];
+ prx[3] = pix[4];
+ prx[4] = pix[3];
+ prx[5] = pix[2];
+ prx[6] = pix[1];
+ prx[7] = pix[0];
+#else
+ rx = i_x;
+#endif
+
+ return rx;
+}
+}; //end of namespace
+
+void getRingProperties(const RingID i_ringId,
+ uint32_t& o_torOffset,
+ RINGTYPE& o_ringType,
+ CHIPLET_TYPE& o_chipletType)
+{
+ do
+ {
+ // Determine the TOR ID
+ o_torOffset =
+ (INSTANCE_RING_MASK & (RING_PROPERTIES[i_ringId].iv_torOffSet));
+ o_chipletType = RING_PROPERTIES[i_ringId].iv_type;
+
+ if(INVALID_RING == o_torOffset)
+ {
+ break;
+ }
+
+ // Determine Ring Type
+ if(INSTANCE_RING_MARK & (RING_PROPERTIES[i_ringId].iv_torOffSet))
+ {
+ o_ringType = INSTANCE_RING;
+ }
+ else
+ {
+ o_ringType = COMMON_RING;
+ }
+ }
+ while(0);
+}
+/// @brief Function to apply the Ring data using the standard-scan method
+/// @param[in] i_target Chiplet Target of Scan
+// @param[in] i_chipletId data from RS4
+/// @param[in] i_operation Type of operation to perform - ROTATE/SCAN
+/// @param[in] i_opVal Number of bits for the operation
+/// @param[in] i_scanData This value has to be scanned when i_operation is SCAN
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode standardScan(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t i_chipletId,
+ opType_t i_operation,
+ uint64_t i_opVal,
+ uint64_t i_scanData)
+{
+ FAPI_INF(">> standardScan");
+
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ // @TODO: getChipletNumber is only supported on SBE plat.
+ // Need to have it supported in the eKB code.
+ uint32_t l_chiplet = i_chipletId << 24;
+#ifdef __PPE__
+ uint32_t l_chipletID = i_target.getChipletNumber();
+
+ if ( l_chipletID )
+ {
+ l_chiplet = (l_chipletID << 24);
+ }
+
+#endif
+
+#ifndef __PPE__
+
+ // Non-PPE platform - Cronus need a Chip target to be used
+ // in putScom/getScom.
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_parent;
+
+ if (i_target.getType() == fapi2::TARGET_TYPE_CORE)
+ {
+ l_parent = i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP> ();
+ }
+
+#endif
+
+ do
+ {
+ // **************
+ // Scan or Rotate
+ // **************
+ if(ROTATE == i_operation)
+ {
+ // Setup Scom Address for rotate operation
+ uint32_t l_scomAddress = 0x00039000;
+
+ // Add the chiplet ID in the Scom Address
+ l_scomAddress |= l_chiplet;
+
+ const uint64_t l_maxRotates = 0x100000;
+ uint64_t l_rotateCount = i_opVal;
+ uint32_t l_numRotateScoms = 1; // 1 - We need to do atleast one scom
+
+ if(i_opVal > l_maxRotates)
+ {
+ l_numRotateScoms = (i_opVal / l_maxRotates);
+ l_rotateCount = l_maxRotates;
+ }
+
+
+ // Scom Data needs to have the no.of rotates in the bits 12-31
+ l_rotateCount <<= 32;
+
+ for(uint32_t i = 0; i < (l_numRotateScoms + 1); i++)
+ {
+ if(i == l_numRotateScoms)
+ {
+ if(i_opVal <= l_maxRotates)
+ {
+ break;
+ }
+
+ l_rotateCount = (i_opVal % l_maxRotates);
+ l_rotateCount <<= 32;
+ }
+
+ FAPI_INF("l_rotateCount %u", l_rotateCount);
+ fapi2::buffer<uint64_t> l_scomData(l_rotateCount);
+
+#ifndef __PPE__
+ l_rc = fapi2::putScom(l_parent, l_scomAddress, l_scomData);
+#else
+ l_rc = fapi2::putScom(i_target, l_scomAddress, l_scomData);
+#endif
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ FAPI_ERR("ROTATE for %d, failed", i_opVal);
+ break;
+ }
+
+ // Check OPCG_DONE status
+ l_scomAddress = 0x00000100;
+
+ // Add the chiplet ID in the Scom Address
+ l_scomAddress |= l_chiplet;
+
+ // @TODO: Value 200 is a random number to start with.
+ uint8_t l_attempts = 200;
+
+ while(l_attempts > 0)
+ {
+ l_attempts--;
+
+ fapi2::buffer<uint64_t> l_opcgStatus;
+#ifndef __PPE__
+ l_rc = fapi2::getScom(l_parent, l_scomAddress, l_opcgStatus);
+#else
+ l_rc = fapi2::getScom(i_target, l_scomAddress, l_opcgStatus);
+#endif
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ FAPI_ERR("Failure during OPCG Check");
+ break;
+ }
+
+ if(l_opcgStatus.getBit<8>())
+ {
+ FAPI_INF("OPCG_DONE set");
+ break;
+ }
+
+ // @TODO: 1 micro second is a number that works now.
+ // Need to derive the real delay number.
+ fapi2::delay(1000, 0);
+
+ }
+
+ if(l_attempts == 0 )
+ {
+ l_rc = fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA;
+ FAPI_ERR("Max attempts exceeded checking OPCG_DONE");
+ break;
+ }
+ }// end of for loop
+ }
+ else if(SCAN == i_operation)
+ {
+ // Setting Scom Address for a 64-bit scan
+ uint32_t l_scomAddress = 0x0003E000;
+
+ // Add the chiplet ID in the Scom Address
+ l_scomAddress |= l_chiplet;
+
+ uint32_t l_scanCount = i_opVal;
+
+ fapi2::buffer<uint64_t> l_scomData(i_scanData);
+
+ // Set the scan count to the actual value
+ l_scomAddress |= l_scanCount;
+
+#ifndef __PPE__
+ l_rc = fapi2::putScom(l_parent, l_scomAddress, l_scomData);
+#else
+ l_rc = fapi2::putScom(i_target, l_scomAddress, l_scomData);
+#endif
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ FAPI_ERR("SCAN for %d, failed", i_opVal);
+ break;
+ }
+ } // end of if(SCAN == i_operation)
+ }
+ while(0);
+
+ FAPI_INF("<< standardScan");
+ return l_rc;
+}
+
+/// @brief Function to apply the Ring data using the queued-scan method
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_operation Type of operation to perform - ROTATE/SCAN
+/// @param[in] i_opVal Number of bits for the operation
+/// @param[in] i_scanData This value has to be scanned when i_operation is SCAN
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode queuedScan(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ opType_t i_operation,
+ uint32_t i_opVal,
+ uint64_t i_scanData)
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+/// @brief Function to apply the Ring data using the polled-scan method
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_operation Type of operation to perform - ROTATE/SCAN
+/// @param[in] i_opVal Number of bits for the operation
+/// @param[in] i_scanData This value has to be scanned when i_operation is SCAN
+fapi2::ReturnCode polledScan(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ opType_t i_operation,
+ uint64_t i_opVal,
+ uint64_t i_scanData)
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+/// @brief Wrapper function to check the scan-type and call the
+/// appropriate scan function
+/// @param[in] i_scanType Type of Scan
+/// @param[in] i_target Chiplet Target of Scan
+// @param[in] i_chipletId data from RS4
+/// @param[in] i_operation Type of operation to perform - ROTATE/SCAN
+/// @param[in] i_opVal Number for the type of operation
+/// @param[in] i_scanData This value has to be scanned when i_operation is SCAN
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode doOperation(
+ scanType_t i_scanType,
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t i_chipletId,
+ opType_t i_operation,
+ uint64_t i_opVal,
+ uint64_t i_scanData)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ switch(i_scanType)
+ {
+ case STANDARD_SCAN:
+ l_rc = standardScan(i_target,
+ i_chipletId,
+ i_operation,
+ i_opVal,
+ i_scanData);
+ break;
+
+ case QUEUED_SCAN:
+ l_rc = queuedScan(i_target,
+ i_operation,
+ i_opVal,
+ i_scanData);
+ break;
+
+ case POLLED_SCAN:
+ l_rc = polledScan(i_target,
+ i_operation,
+ i_opVal,
+ i_scanData);
+ break;
+ };
+
+ return l_rc;
+}
+
+/// @brief Function to set the Scan Region
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_scanRegion Value to be set to select a Scan Region
+// @param[in] i_chipletId data from RS4
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode setupScanRegion(const fapi2::Target<fapi2::TARGET_TYPE_ALL>&
+ i_target,
+ uint64_t i_scanRegion,
+ const uint8_t i_chipletId)
+{
+ fapi2::ReturnCode l_rc;
+ uint32_t l_chiplet = i_chipletId << 24;
+#ifdef __PPE__
+ uint32_t l_chipletID = i_target.getChipletNumber();
+
+ if ( l_chipletID )
+ {
+ l_chiplet = (l_chipletID << 24);
+ }
+
+#endif
+
+#ifndef __PPE__
+ // Non-PPE platform - Cronus need a Chip target to be used
+ // in putScom/getScom.
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_parent(
+ i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>());
+#endif
+
+ do
+ {
+ // **************************
+ // Setup Scan-Type and Region
+ // **************************
+ uint32_t l_scomAddress = 0x00030005;
+
+ // Add the chiplet ID in the Scom Address
+ l_scomAddress |= l_chiplet;
+
+ // Do the scom
+ fapi2::buffer<uint64_t> l_scanRegion(i_scanRegion);
+#ifndef __PPE__
+ l_rc = fapi2::putScom(l_parent, l_scomAddress, l_scanRegion);
+#else
+ l_rc = fapi2::putScom(i_target, l_scomAddress, l_scanRegion);
+#endif
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ FAPI_ERR("Setup Scan-Type and Region failed");
+ break;
+ }
+ }
+ while(0);
+
+ return l_rc;
+}
+
+/// @brief Function to write the header data to the ring.
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_header The header data that is to be written.
+// @param[in] i_chipletId data from RS4
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode writeHeader(const fapi2::Target<fapi2::TARGET_TYPE_ALL>&
+ i_target,
+ const uint64_t i_header,
+ const uint8_t i_chipletId)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ do
+ {
+ // @TODO: getChipletNumber is only supported on SBE plat.
+ // Need to have it supported in the eKB code.
+ uint32_t l_chiplet = i_chipletId << 24;
+#ifdef __PPE__
+ uint32_t l_chipletID = i_target.getChipletNumber();
+
+ if ( l_chipletID )
+ {
+ l_chiplet = (l_chipletID << 24);
+ }
+
+#endif
+
+ uint32_t l_scomAddress = 0x0003E040; // 64-bit scan
+ // Add the chiplet ID in the Scom Address
+ l_scomAddress |= l_chiplet;
+
+// I think we won't require this
+#ifndef __PPE__
+ l_rc = fapi2::putScom(
+ i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>(),
+ l_scomAddress,
+ i_header);
+#else
+ l_rc = fapi2::putScom(i_target, l_scomAddress, i_header);
+#endif
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ FAPI_ERR("Error during writing header %016x", i_header);
+ break;
+ }
+ }
+ while(0);
+
+ return l_rc;
+
+}
+
+/// @brief Function to reader the header data from the ring and verify it.
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_header The header data that is expected.
+// @param[in] i_chipletId data from RS4
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode verifyHeader(const fapi2::Target<fapi2::TARGET_TYPE_ALL>&
+ i_target,
+ const uint64_t i_header,
+ const uint8_t i_chipletId)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ do
+ {
+ // @TODO: getChipletNumber is only supported on SBE plat.
+ // Need to have it supported in the eKB code.
+ uint32_t l_chiplet = i_chipletId << 24;
+#ifdef __PPE__
+ uint32_t l_chipletID = i_target.getChipletNumber();
+
+ if ( l_chipletID )
+ {
+ l_chiplet = (l_chipletID << 24);
+ }
+
+#endif
+
+ uint32_t l_scomAddress = 0x0003E000; // 64-bit scan
+ // Add the chiplet ID in the Scom Address
+ l_scomAddress |= l_chiplet;
+
+ fapi2::buffer<uint64_t> l_readHeader;
+
+#ifndef __PPE__
+ l_rc = fapi2::getScom(
+ i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>(),
+ l_scomAddress,
+ l_readHeader);
+#else
+ l_rc = fapi2::getScom(i_target, l_scomAddress, l_readHeader);
+#endif
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ FAPI_ERR("Error during reading header %016x", i_header);
+ break;
+ }
+
+ FAPI_INF("Got header - %016x", uint64_t(l_readHeader));
+
+ if(l_readHeader != i_header)
+ {
+ FAPI_ERR("Read header(%016x) data incorrect", uint64_t(l_readHeader));
+ l_rc = fapi2::FAPI2_RC_PLAT_ERR_RING_HEADER_CHECK;
+ break;
+ }
+ }
+ while(0);
+
+ return l_rc;
+
+}
+
+/// @brief Function to decompress the RS4 and apply the Ring data
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_rs4 The RS4 compressed string
+/// @param[in] i_scanType Type of Scan
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode rs4DecompressionSvc(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t* i_rs4,
+ scanType_t i_scanType,
+ const fapi2::RingMode i_ringMode)
+{
+ FAPI_INF(">> rs4DecompressionSvc");
+ CompressedScanData* l_rs4Header = (CompressedScanData*) i_rs4;
+ const uint8_t* l_rs4Str = (i_rs4 + sizeof(CompressedScanData));
+
+ opType_t l_opType = ROTATE;
+ uint64_t l_nibbleIndx = 0;
+ uint64_t l_bitsDecoded = 0;
+ bool l_decompressionDone = false;
+ uint64_t l_scanRegion = rs4_revle64(l_rs4Header->iv_scanSelect);
+ uint8_t l_chipletId = l_rs4Header->iv_chipletId;
+ fapi2::ReturnCode l_rc;
+
+ do
+ {
+ if (l_rs4Header->iv_length == 0)
+ {
+ FAPI_ERR("Invalid ring length in RS4 image");
+ break;
+ }
+
+ // Set up the scan region for the ring.
+ l_rc = setupScanRegion(i_target, l_scanRegion, l_chipletId);
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+
+
+ // Write a 64 bit value for header.
+ const uint64_t l_header = 0xa5a5a5a5a5a5a5a5;
+ l_rc = writeHeader(i_target, l_header, l_chipletId);
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+
+ //if the ring length is not 8bit aligned, then we need to skip the
+ //padding bits
+ uint8_t l_padding_bits = 0;
+
+ if (l_rs4Header->iv_length % 4)
+ {
+ l_padding_bits = (4 - (l_rs4Header->iv_length % 4));
+ }
+
+ bool l_skip_64bits = true;
+
+ // Decompress the RS4 string and scan
+ do
+ {
+ if (l_opType == ROTATE)
+ {
+ // Determine the no.of ROTATE operations encoded in stop-code
+ uint64_t l_count = 0;
+ l_nibbleIndx += stop_decode(l_rs4Str, l_nibbleIndx, l_count);
+
+ // Determine the no.of rotates in bits
+ uint64_t l_bitRotates = (4 * l_count);
+
+ //Need to skip 64bits , because we have already written header
+ //data.
+ if (l_skip_64bits)
+ {
+ l_bitRotates -= SIXTYFOUR_BIT_HEADER;
+ l_skip_64bits = false;
+ }
+
+ l_bitsDecoded += l_bitRotates;
+
+ if(l_bitsDecoded > l_rs4Header->iv_length)
+ {
+ FAPI_ERR("Rotate decompression done."
+ "l_bitsDecoded = %d, length = %d",
+ l_bitsDecoded, l_rs4Header->iv_length);
+ l_decompressionDone = true;
+ l_rc = fapi2::FAPI2_RC_PLAT_RING_DECODE_LENGTH_EXCEEDED;
+ break;
+ }
+
+ // Do the ROTATE operation
+ if (l_bitRotates != 0)
+ {
+ l_rc = doOperation(i_scanType,
+ i_target,
+ l_chipletId,
+ ROTATE,
+ l_bitRotates);
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ l_opType = SCAN;
+ }
+ else if(l_opType == SCAN)
+ {
+ uint8_t l_scanCount = rs4_get_nibble(l_rs4Str, l_nibbleIndx);
+ l_nibbleIndx++;
+
+ if (l_scanCount == 0)
+ {
+ FAPI_INF("SCAN COUNT %u", l_scanCount);
+ break;
+ }
+
+ if (l_scanCount != 0xF)
+ {
+ l_bitsDecoded += (4 * l_scanCount);
+ }
+
+ if(l_bitsDecoded > l_rs4Header->iv_length)
+ {
+ FAPI_ERR("Scan decompression done."
+ "l_bitsDecoded = %d, length = %d",
+ l_bitsDecoded, l_rs4Header->iv_length);
+ l_decompressionDone = true;
+ l_rc = fapi2::FAPI2_RC_PLAT_RING_DECODE_LENGTH_EXCEEDED;
+ break;
+ }
+
+ if(0xF == l_scanCount) // We are parsing RS4 for override rings
+ {
+ uint8_t l_careMask = rs4_get_nibble(l_rs4Str, l_nibbleIndx);
+ l_nibbleIndx++;
+ uint8_t l_spyData = rs4_get_nibble(l_rs4Str, l_nibbleIndx);
+ l_nibbleIndx++;
+
+ uint8_t l_mask = 0x08;
+
+ for(uint8_t i = 0; i < 4; i++)
+ {
+ if((l_careMask & (l_mask >> i)))
+ {
+ uint64_t l_scomData = 0x0;
+
+ if((l_spyData & (l_mask >> i)))
+ {
+ l_scomData = 0xFFFFFFFFFFFFFFFF;
+ }
+
+ l_bitsDecoded += 1;
+
+ l_rc = doOperation(i_scanType,
+ i_target,
+ l_chipletId,
+ SCAN,
+ 1, // Insert 1 bit
+ l_scomData);
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+ }
+ else
+ {
+ l_bitsDecoded += 1;
+
+ l_rc = doOperation(i_scanType,
+ i_target,
+ l_chipletId,
+ ROTATE,
+ 1);
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+
+
+ }
+ } // end of looper for bit-parsing a non-zero nibble
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+ }
+ else // We are parsing RS4 for base rings
+ {
+ // Parse the non-zero nibbles of the RS4 string and
+ // scan them into the ring
+ uint64_t l_scomData = rs4_get_verbatim(l_rs4Str,
+ l_nibbleIndx,
+ l_scanCount);
+ l_nibbleIndx += l_scanCount;
+
+ FAPI_INF ("VERBATIm l_nibbleIndx %u l_scanCount %u "
+ "l_bitsDecoded %u", l_nibbleIndx, l_scanCount, l_bitsDecoded);
+
+ l_rc = doOperation(i_scanType,
+ i_target,
+ l_chipletId,
+ SCAN,
+ (l_scanCount * 4),
+ l_scomData);
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ l_opType = ROTATE;
+ } // end of - if(l_opType == SCAN)
+ }
+ while(1);
+
+ if((l_rc != fapi2::FAPI2_RC_SUCCESS) || (true == l_decompressionDone))
+ {
+ break;
+ }
+
+ // Handle the string termination
+ uint8_t l_nibble = rs4_get_nibble(l_rs4Str, l_nibbleIndx);
+ l_nibbleIndx++;
+
+ if (l_nibble != 0)
+ {
+ // Parse the non-zero nibbles of the RS4 string and
+ // scan them into the ring
+ if((l_bitsDecoded + l_nibble) > l_rs4Header->iv_length)
+ {
+ FAPI_ERR("Decompression Done."
+ "l_bitsDecoded = %d, l_nibble= %d, length = %d",
+ l_bitsDecoded, l_nibble, l_rs4Header->iv_length);
+ l_rc = fapi2::FAPI2_RC_PLAT_RING_DECODE_LENGTH_EXCEEDED;
+ break;
+ }
+ else
+ {
+ l_bitsDecoded += l_nibble;
+ uint64_t l_scomData = rs4_get_verbatim(l_rs4Str,
+ l_nibbleIndx,
+ 1); // return 1 nibble
+
+ FAPI_INF ("l_nibbleIndx %u l_scomData %llu l_bitsDecoded %u",
+ l_nibbleIndx, l_scomData, l_bitsDecoded);
+
+ l_rc = doOperation(i_scanType,
+ i_target,
+ l_chipletId,
+ SCAN,
+ (4 - l_padding_bits) , // scan 4 bits
+ l_scomData);
+ }
+ } // end of if(l_nibble != 0)
+
+ // Verify header
+ l_rc = verifyHeader(i_target, l_header, l_chipletId);
+
+ if(l_rc)
+ {
+ break;
+ }
+
+ // Clean scan region and type data
+ l_rc = cleanScanRegionandTypeData(i_target, l_chipletId);
+
+ if(l_rc)
+ {
+ break;
+ }
+ }
+ while(0);
+
+ FAPI_INF("<< rs4DecompressionSvc");
+ return l_rc;
+}
+
+/// @brief Function to call the RS4 decompression service and aply ring
+/// using the Standard Scan method
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_rs4 The RS4 compressed string
+/// @param[in] i_scanType Type of Scan
+fapi2::ReturnCode applyRS4_SS(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t* i_rs4,
+ const fapi2::RingMode i_ringMode)
+{
+ // Call the decompression functionality with the standard scan method
+ return rs4DecompressionSvc(i_target, i_rs4, STANDARD_SCAN,
+ i_ringMode);
+}
+
+/// @brief Function to call the RS4 decompression service and aply ring
+/// using the Queued Scan method
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_rs4 The RS4 compressed string
+/// @param[in] i_scanType Type of Scan
+fapi2::ReturnCode applyRS4_QS(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t* i_rs4,
+ const fapi2::RingMode i_ringMode)
+{
+ // Call the decompression functionality with the Queued scan method
+ return rs4DecompressionSvc(i_target, i_rs4, QUEUED_SCAN, i_ringMode);
+}
+
+/// @brief Function to call the RS4 decompression service and aply ring
+/// using the Polled Scan method
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_rs4 The RS4 compressed string
+/// @param[in] i_scanType Type of Scan
+fapi2::ReturnCode applyRS4_PS(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t* i_rs4,
+ const fapi2::RingMode i_ringMode)
+{
+ // Call the decompression functionality with the polled scan method
+ return rs4DecompressionSvc(i_target, i_rs4, POLLED_SCAN, i_ringMode);
+}
+/// @brief Function to clean up the scan region and type
+/// @param[in] i_target Chiplet Target of Scan
+// @param[in] chipletId data from RS4
+// @param[in] i_chipletId data from RS4
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode cleanScanRegionandTypeData(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t i_chipletId)
+{
+ fapi2::ReturnCode l_rc;
+ uint32_t l_chiplet = i_chipletId << 24;
+#ifdef __PPE__
+ uint32_t l_chipletID = i_target.getChipletNumber();
+
+ if ( l_chipletID )
+ {
+ l_chiplet = (l_chipletID << 24);
+ }
+
+#endif
+
+#ifndef __PPE__
+ // Non-PPE platform - Cronus need a Chip target to be used
+ // in putScom/getScom.
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_parent(
+ i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>());
+#endif
+
+ do
+ {
+ //////////////////////
+ //cleanup opcg_reg0
+ //////////////////////
+ uint32_t l_scomAddress = 0x00030005;
+
+ // Add the chiplet ID in the Scom Address
+ l_scomAddress |= l_chiplet;
+
+ fapi2::buffer<uint64_t> l_data(0);
+
+#ifndef __PPE__
+ l_rc = fapi2::putScom(l_parent, l_scomAddress, l_data);
+#else
+ l_rc = fapi2::putScom(i_target, l_scomAddress, l_data);
+#endif
+
+ if(l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ FAPI_ERR("OPCG_REG0 write op failed");
+ break;
+ }
+ }
+ while(0);
+
+ return l_rc;
+}
+
+
diff --git a/import/chips/p9/utils/p9_putRingUtils.H b/import/chips/p9/utils/p9_putRingUtils.H
new file mode 100644
index 00000000..a1735232
--- /dev/null
+++ b/import/chips/p9/utils/p9_putRingUtils.H
@@ -0,0 +1,295 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/utils/p9_putRingUtils.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/// @file p9_putRingUtils.H
+/// @brief Headers and Constants used by rs4 decompression and
+/// ring SCAN/ROTATE functionality
+///
+// *HWP HWP Owner: Bilicon Patil <bilpatil@in.ibm.com>
+// *HWP FW Owner: Prasad Ranganath <prasadbgr@in.ibm.com>
+// *HWP Team: PM
+// *HWP Level: 2
+// *HWP Consumed by: SBE:CME:SGPE:PGPE
+
+#ifndef _P9_PUTRINGUTILS_H_
+#define _P9_PUTRINGUTILS_H_
+
+#include <return_code.H>
+#include <fapi2.H>
+#include "imageProcs/p9_ringId.H"
+
+namespace RS4
+{
+
+//
+// Forward Declarations
+//
+
+/// @brief Byte-reverse a 64-bit integer
+/// @param[in] i_x 64-bit word that need to be byte reversed
+/// @return Byte reversed 64-bit word
+uint64_t rs4_revle64(const uint64_t i_x);
+
+///
+/// @brief Decode an unsigned integer from a 4-bit octal stop code.
+/// @param[in] i_rs4Str The RS4 scan string
+/// @param[in] i_nibbleIndx Index into i_rs4Str that has the stop-code
+/// @param[out] o_numRotate No.of rotates decoded from the stop-code.
+/// @return The number of nibbles decoded.
+///
+uint64_t stop_decode(const uint8_t* i_rs4Str,
+ uint32_t i_nibbleIndx,
+ uint64_t& o_numRotate);
+
+///
+/// @brief Return a big-endian-indexed nibble from a byte string
+/// @param[in] i_rs4Str The RS4 scan string
+/// @param[in] i_nibbleIndx Index into i_rs4Str that need to converted
+/// into a nibble
+/// @return big-endian-indexed nibble
+///
+uint8_t rs4_get_nibble(const uint8_t* i_rs4Str, const uint32_t i_nibbleIndx);
+
+///
+/// @brief Return verbatim data from the RS4 string
+/// @param[in] i_rs4Str The RS4 scan string
+/// @param[in] i_nibbleIndx Index into i_rs4Str that need to converted
+/// into a nibble
+/// @param[in] i_nibbleCount The count of nibbles that need to be put
+/// in the return value.
+/// @return big-endian-indexed double word
+///
+uint64_t rs4_get_verbatim(const uint8_t* i_rs4Str,
+ const uint32_t i_nibbleIndx,
+ const uint8_t i_nibbleCount);
+
+}; // end of RS4 namespace
+
+using namespace RS4;
+//
+// Constants and Structures
+//
+
+
+#define SIXTYFOUR_BIT_HEADER 64
+
+/// @brief Constants for operations performed by putRing function.
+enum opType_t
+{
+ ROTATE = 0, ///< Indicates a Rotate operation on the ring
+ SCAN = 1 ///< Indicates a Scan operation on the ring
+};
+
+/// @brief Constants for the type of Scans supported by putRing
+enum scanType_t
+{
+ STANDARD_SCAN = 1, ///< used in SBE Plat
+ QUEUED_SCAN = 2, ///< used in CME plat
+ POLLED_SCAN = 3 ///< used in SGPE plat
+};
+
+///
+/// @brief This structure represents the header information that preceeds the
+/// RS4 compressed string.
+/// @note This structure will only be used to typecast the address of the
+/// RS4 header and then to dereference the offsets represented by the
+/// structure members.
+/// This structure need to be identical to similarly named structure
+/// used in generating a Ring Container.
+///
+struct CompressedScanData
+{
+ /// Magic number - See \ref scan_compression_magic
+ uint32_t iv_magic;
+
+ /// Compressed Size. Total size in bytes, including the container header
+ uint32_t iv_size;
+
+ /// Reserved to the algorithm
+ uint32_t iv_algorithmReserved;
+
+ /// Length of the original scan chain in bits
+ uint32_t iv_length;
+
+ /// The 64 bits of Scan Select register value
+ uint64_t iv_scanSelect;
+
+ /// Data structure (header) version
+ uint8_t iv_headerVersion;
+
+ /// Flush-state optimization
+ /// Normally, modifying the state of the ring requires XOR-ing the
+ /// difference state (the compressed state) with the current ring state as
+ /// it will appear in the Scan Data Register. If the current state of the
+ /// ring is the scan-0 flush state, then by definition the Scan Data
+ /// Register is always 0. Therefore we can simply write the difference to
+ /// the Scan Data Register rather than using a read-XOR-write.
+ uint8_t iv_flushOptimization;
+
+ /// Ring ID uniquely identifying the repair name.
+ uint8_t iv_ringId;
+
+ /// 7-bit pervasive chiplet Id + Multicast bit
+ uint8_t iv_chipletId;
+};
+
+//
+// Function Definitions
+//
+using namespace RING_TYPES;
+void getRingProperties(const RingID i_ringId,
+ uint32_t& o_torOffset,
+ RINGTYPE& o_ringType,
+ CHIPLET_TYPE& o_type);
+
+/// @brief Function to apply the Ring data using the standard-scan method
+/// @param[in] i_target Chiplet Target of Scan
+// @param[in] i_chipletId data from RS4
+/// @param[in] i_operation Type of operation to perform - ROTATE/SCAN
+/// @param[in] i_opVal Number of bits for the operation
+/// @param[in] i_scanData This value has to be scanned when i_operation is SCAN
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode standardScan(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t i_chipletId,
+ opType_t i_operation,
+ uint64_t i_opVal,
+ uint64_t i_scanData = 0);
+
+
+/// @brief Function to apply the Ring data using the queued-scan method
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_operation Type of operation to perform - ROTATE/SCAN
+/// @param[in] i_opVal Number of bits for the operation
+/// @param[in] i_scanData This value has to be scanned when i_operation is SCAN
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode queuedScan(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ opType_t i_operation,
+ uint32_t i_opVal,
+ uint64_t i_scanData = 0);
+
+/// @brief Function to apply the Ring data using the polled-scan method
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_operation Type of operation to perform - ROTATE/SCAN
+/// @param[in] i_opVal Number of bits for the operation
+/// @param[in] i_scanData This value has to be scanned when i_operation is SCAN
+fapi2::ReturnCode polledScan(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ opType_t i_operation,
+ uint64_t i_opVal,
+ uint64_t i_scanData = 0);
+
+/// @brief Wrapper function to check the scan-type and call the
+/// appropriate scan function
+/// @param[in] i_scanType Type of Scan
+/// @param[in] i_target Chiplet Target of Scan
+// @param[in] i_chipletId data from RS4
+/// @param[in] i_operation Type of operation to perform - ROTATE/SCAN
+/// @param[in] i_opVal Number for the type of operation
+/// @param[in] i_scanData This value has to be scanned when i_operation is SCAN
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode doOperation(
+ scanType_t i_scanType,
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t i_chipletId,
+ opType_t i_operation,
+ uint64_t i_opVal,
+ uint64_t i_scanData = 0);
+
+
+/// @brief Function to set the Scan Region
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_scanRegion Value to be set to select a Scan Region
+// @param[in] i_chipletId data from RS4
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode setupScanRegion(const fapi2::Target<fapi2::TARGET_TYPE_ALL>&
+ i_target,
+ uint64_t i_scanRegion,
+ const uint8_t i_chipletId);
+
+
+/// @brief Function to write the header data to the ring.
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_header The header data that is to be written.
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode writeHeader(const fapi2::Target<fapi2::TARGET_TYPE_ALL>&
+ i_target,
+ const uint64_t i_header,
+ const uint8_t i_chipletId);
+
+
+/// @brief Function to reader the header data from the ring and verify it.
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_header The header data that is expected.
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode verifyHeader(const fapi2::Target<fapi2::TARGET_TYPE_ALL>&
+ i_target,
+ const uint64_t i_header,
+ const uint8_t i_chipletId);
+
+
+/// @brief Function to decompress the RS4 and apply the Ring data
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_rs4 The RS4 compressed string
+/// @param[in] i_scanType Type of Scan
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode rs4DecompressionSvc(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t* i_rs4,
+ scanType_t i_scanType,
+ const fapi2::RingMode i_ringMode);
+
+
+/// @brief Function to call the RS4 decompression service and aply ring
+/// using the Standard Scan method
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_rs4 The RS4 compressed string
+/// @param[in] i_scanType Type of Scan
+fapi2::ReturnCode applyRS4_SS(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t* i_rs4,
+ const fapi2::RingMode i_ringMode);
+
+
+/// @brief Function to call the RS4 decompression service and aply ring
+/// using the Queued Scan method
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_rs4 The RS4 compressed string
+/// @param[in] i_scanType Type of Scan
+fapi2::ReturnCode applyRS4_QS(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t* i_rs4,
+ const fapi2::RingMode i_ringMode);
+
+
+/// @brief Function to call the RS4 decompression service and aply ring
+/// using the Polled Scan method
+/// @param[in] i_target Chiplet Target of Scan
+/// @param[in] i_rs4 The RS4 compressed string
+/// @param[in] i_scanType Type of Scan
+fapi2::ReturnCode applyRS4_PS(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t* i_rs4,
+ const fapi2::RingMode i_ringMode);
+
+/// @brief Function to clean up the scan region and type
+/// @param[in] i_target Chiplet Target of Scan
+// @param[in] chipletId data from RS4
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+fapi2::ReturnCode cleanScanRegionandTypeData(
+ const fapi2::Target<fapi2::TARGET_TYPE_ALL>& i_target,
+ const uint8_t i_chipletId);
+
+#endif
diff --git a/import/chips/p9/utils/p9_putRingUtils.mk b/import/chips/p9/utils/p9_putRingUtils.mk
new file mode 100644
index 00000000..b2466e4d
--- /dev/null
+++ b/import/chips/p9/utils/p9_putRingUtils.mk
@@ -0,0 +1,22 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: chips/p9/utils/p9_putRingUtils.mk $
+#
+# IBM CONFIDENTIAL
+#
+# EKB Project
+#
+# COPYRIGHT 2016
+# [+] International Business Machines Corp.
+#
+#
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# IBM_PROLOG_END_TAG
+
+PROCEDURE=p9_putRingUtils
+$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/utils/imageProcs)
+$(call BUILD_PROCEDURE)
diff --git a/import/chips/p9/utils/utils.mk b/import/chips/p9/utils/utils.mk
new file mode 100644
index 00000000..60267d90
--- /dev/null
+++ b/import/chips/p9/utils/utils.mk
@@ -0,0 +1,29 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: chips/p9/utils/utils.mk $
+#
+# IBM CONFIDENTIAL
+#
+# EKB Project
+#
+# COPYRIGHT 2016
+# [+] International Business Machines Corp.
+#
+#
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# IBM_PROLOG_END_TAG
+# @file utils.mk
+#
+# @brief mk for including Utils object files
+#
+##########################################################################
+# Object Files
+##########################################################################
+
+UTILS-CPP-SOURCES = p9_putRingUtils.C
+
+UTILS_OBJECTS = $(UTILS-CPP-SOURCES:.C=.o)
diff --git a/import/hwpf/fapi2/include/return_code_defs.H b/import/hwpf/fapi2/include/return_code_defs.H
index 72fdc201..03c5aba3 100644
--- a/import/hwpf/fapi2/include/return_code_defs.H
+++ b/import/hwpf/fapi2/include/return_code_defs.H
@@ -98,6 +98,16 @@ enum ReturnCodes : uint32_t
FAPI2_RC_PLAT_NOT_SUPPORTED_AT_RUNTIME = FAPI2_RC_PLAT_MASK | 0x03,
///< Operation not supported by HB runtime
+
+ FAPI2_RC_PLAT_ERR_RING_HEADER_CHECK = FAPI2_RC_PLAT_MASK | 0x04,
+ //Operation on putring fail because of header data mismatch
+ //
+ FAPI2_RC_PLAT_RING_DECODE_LENGTH_EXCEEDED = FAPI2_RC_PLAT_MASK | 0x05,
+ //Operation on putring fail because of decode length greater than actual
+ //ring length.
+
+ FAPI2_RC_PLAT_RING_ID_NOT_FOUND_IN_RS4_IMAGE = FAPI2_RC_PLAT_MASK | 0x06,
+ //Operation on putring fail because of ringId not found in RS4 image
};
}
OpenPOWER on IntegriCloud