summaryrefslogtreecommitdiffstats
path: root/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C')
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C
index 0dddd27a6..dcef63ec8 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C
@@ -22,3 +22,161 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+/// @file exp_getecid_utils.C
+/// @brief Gets ECID from explorer fuse registers
+///
+/// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+/// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB
+
+#include <fapi2.H>
+#include <lib/i2c/exp_i2c.H>
+#include <lib/shared/exp_consts.H>
+#include <explorer_scom_addresses.H>
+#include <explorer_scom_addresses_fld.H>
+#include <mss_explorer_attribute_setters.H>
+#include <generic/memory/lib/utils/mss_buffer_utils.H>
+
+
+namespace mss
+{
+namespace exp
+{
+namespace ecid
+{
+
+///
+/// @brief Determines enterprise and half dimm states from explorer FUSE
+/// @param[in] i_target the controller
+/// @param[out] o_enterprise_mode state
+/// @param[out] o_half_dimm_mode state
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode get_enterprise_and_half_dimm_from_fuse(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint8_t& o_enterprise_mode,
+ uint8_t& o_half_dimm_mode)
+{
+ fapi2::buffer<uint64_t> l_reg_resp_buffer;
+ FAPI_TRY(fapi2::getScom( i_target, static_cast<uint64_t>(EXPLR_EFUSE_IMAGE_OUT_0), l_reg_resp_buffer ),
+ "exp_getecid: could not read explorer fuse register 0x%08x", EXPLR_EFUSE_IMAGE_OUT_0);
+
+ // Default to disabled
+ o_enterprise_mode = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_NON_ENTERPRISE; // 0
+
+ // If we support enterprise mode, enable it until otherwise overridden in OMI_SETUP
+ if(!l_reg_resp_buffer.getBit < EXPLR_EFUSE_IMAGE_OUT_0_ENTERPRISE_MODE_DIS
+ + mss::exp::ecid_consts::REG_BIT_OFFSET > ())
+ {
+ o_enterprise_mode = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_ENTERPRISE; // 1, enabled
+ }
+
+ // half_dimm_mode will remain disabled for P systems
+ o_half_dimm_mode = fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_FULL_DIMM; // 0, disabled
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Reads ECID into output array from fuse
+/// @param[in] i_target the controller
+/// @param[out] o_array ECID contents
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode read_from_fuse(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint16_t (&o_ecid_array)[mss::exp::ecid_consts::FUSE_ARRAY_SIZE])
+{
+
+ // FUSE registers mapping to the above bit-structure
+ static constexpr uint64_t l_ecid_regs[mss::exp::ecid_consts::FUSE_ARRAY_SIZE] =
+ {
+ EXPLR_EFUSE_PE_DATA_0,
+ EXPLR_EFUSE_PE_DATA_1,
+ EXPLR_EFUSE_PE_DATA_2,
+ EXPLR_EFUSE_PE_DATA_3,
+ EXPLR_EFUSE_PE_DATA_4,
+ EXPLR_EFUSE_PE_DATA_5,
+ EXPLR_EFUSE_PE_DATA_6, // PE_DATA_7 does not exist
+ EXPLR_EFUSE_PE_DATA_8,
+ EXPLR_EFUSE_PE_DATA_9,
+ EXPLR_EFUSE_PE_DATA_10,
+ EXPLR_EFUSE_PE_DATA_11,
+ EXPLR_EFUSE_PE_DATA_12,
+ EXPLR_EFUSE_PE_DATA_13,
+ EXPLR_EFUSE_PE_DATA_14
+ };
+
+ fapi2::buffer<uint64_t> l_efuse_contents;
+ static constexpr uint32_t START_BIT = 48; // Last 16 bits
+
+ for (uint16_t l_pe_reg = 0; l_pe_reg < mss::exp::ecid_consts::FUSE_ARRAY_SIZE; ++l_pe_reg)
+ {
+ l_efuse_contents.flush<0>();
+
+ // Assuming this will fall back to I2C.
+ FAPI_TRY(fapi2::getScom( i_target, l_ecid_regs[l_pe_reg], l_efuse_contents ),
+ "exp_getecid: could not read explorer fuse register 0x%08x", l_ecid_regs[l_pe_reg]);
+
+ // Each EFUSE register in question looks like this according to the spec:
+ //
+ // BIT FUNCTION
+ // 31:16 Unused
+ // 15:0 EFUSE_IMAGE_OUT [HIGH:LOW]
+ //
+ // So, we are expecting the data in question to be in the right-most 16 bits.
+ l_efuse_contents.extract<START_BIT, mss::exp::ecid_consts::DATA_IN_SIZE>(o_ecid_array[l_pe_reg]);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Stores ECID in ATTR_ECID
+/// @param[in] i_target the controller
+/// @param[in] i_ecid 16-bit array of ECID contents
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode set_attr(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const uint16_t i_ecid[mss::exp::ecid_consts::FUSE_ARRAY_SIZE])
+{
+
+ //
+ // TK - ATTR_ECID is only two 64-bit integers, but our OCMB ECID is larger.
+ // Per Dan Crowell, there are plans in the future to make ATTR_ECID larger
+ // This will need to be updated once that is changed. Currently, this is
+ // only storing the first 128 bits of the ECID.
+ //
+ // TK - Once the above is implemented, we no longer need ATTR_OCMB_ECID (see exp_getecid.C)
+ //
+
+ // ATTR_ECID is an array of 2 64-bit integers
+ uint64_t l_attr_ecid[mss::exp::ecid_consts::ATTR_ECID_SIZE] = {0};
+
+ fapi2::buffer<uint64_t> l_constructed_ecid;
+
+ // Build 64 bit ECID from right to left (from lowest to highest)
+ // Places l_ecid[0] in 48:64, l_ecid[1] in 32:48, etc.
+ mss::right_aligned_insert(l_constructed_ecid, i_ecid[3], i_ecid[2], i_ecid[1], i_ecid[0]);
+ l_attr_ecid[0] = l_constructed_ecid;
+ l_constructed_ecid.flush<0>();
+
+ // Places l_ecid[4] in 48:64, l_ecid[5] in 32:48, etc.
+ mss::right_aligned_insert(l_constructed_ecid, i_ecid[7], i_ecid[6], i_ecid[5], i_ecid[4]);
+ l_attr_ecid[1] = l_constructed_ecid;
+
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_ECID, i_target, l_attr_ecid),
+ "exp_getecid: Could not set ATTR_ECID on %s", mss::c_str(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+} // ecid
+} // exp
+} // mss
OpenPOWER on IntegriCloud