diff options
author | Bilicon Patil <bilpatil@in.ibm.com> | 2016-02-29 23:22:08 -0600 |
---|---|---|
committer | Sachin Gupta <sgupta2m@in.ibm.com> | 2016-06-14 09:12:08 -0400 |
commit | 3e84e26a998aa57b6b2f452003fcbb941c5c9e37 (patch) | |
tree | 9cdeb81a4e6159e074d269c685d849771e6ce6d6 | |
parent | 37a6c05e8ef51cf4899cad053de87c80b26c185b (diff) | |
download | talos-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/Makefile | 47 | ||||
-rw-r--r-- | import/chips/p9/utils/imageProcs/p9_ringId.H | 242 | ||||
-rw-r--r-- | import/chips/p9/utils/p9_putRingUtils.C | 1001 | ||||
-rw-r--r-- | import/chips/p9/utils/p9_putRingUtils.H | 295 | ||||
-rw-r--r-- | import/chips/p9/utils/p9_putRingUtils.mk | 22 | ||||
-rw-r--r-- | import/chips/p9/utils/utils.mk | 29 | ||||
-rw-r--r-- | import/hwpf/fapi2/include/return_code_defs.H | 10 |
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 }; } |