Skip to content

Commit

Permalink
Adds Explorer OMI setup - step 12.8a
Browse files Browse the repository at this point in the history
Change-Id: I4e448a7ecc04b6f169b1688c7e8ffde2451f5f9e
Original-Change-Id: Ic3a15e25faf465c4beb2b722c79c12d4a79ae33b
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/63492
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/71349
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
  • Loading branch information
sglancy6 authored and crgeddes committed Feb 6, 2019
1 parent a97dbdf commit e112cf5
Show file tree
Hide file tree
Showing 6 changed files with 429 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,57 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */

///
/// @file exp_omi_setup.H
/// @brief Contains the explorer OMI setup
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: Memory

#include <fapi2.H>
#include <generic/memory/lib/utils/c_str.H>
#include <lib/exp_attribute_accessors_manual.H>
#include <lib/omi/exp_omi_utils.H>

extern "C"
{

///
/// @brief Setup the OCMB for enterprise and half-DIMM modes as desired
/// @param[in] i_target the OCMB target to operate on
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode exp_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
{
// Declares variables
fapi2::buffer<uint64_t> l_data;
bool l_is_enterprise = false;
bool l_is_half_dimm = false;

// Gets the configuration information
FAPI_TRY(mss::enterprise_mode(i_target, l_is_enterprise));
FAPI_TRY(mss::half_dimm_mode(i_target, l_is_half_dimm));

// Prints out the data
FAPI_INF("%s %s enterprise mode %s-DIMM mode", mss::c_str(i_target), l_is_enterprise ? "is" : "isn't",
l_is_half_dimm ? "half" : "full");

// Sets up the register
mss::exp::omi::set_enterprise_set_bit(l_data, l_is_enterprise);
mss::exp::omi::set_half_dimm_mode(l_data, l_is_half_dimm);

// Writes the data to the register
FAPI_TRY(mss::exp::omi::write_enterprise_config(i_target, l_data));

// Checks that the chip is configured correctly
FAPI_TRY(mss::exp::omi::read_enterprise_config(i_target, l_data));
FAPI_TRY(mss::exp::omi::check_enterprise_mode(i_target, l_is_enterprise, l_data));

fapi_try_exit:
return fapi2::current_err;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,32 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */

///
/// @file exp_omi_setup.H
/// @brief Contains the explorer OMI setup
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: Memory
#ifndef EXP_OMI_SETUP_H_
#define EXP_OMI_SETUP_H_

#include <fapi2.H>

typedef fapi2::ReturnCode (*exp_omi_setup_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&);

extern "C"
{

///
/// @brief Setup the OCMB for enterprise and half-DIMM modes as desired
/// @param[in] i_target the OCMB target to operate on
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode exp_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target);
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,10 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG

# Include the macros and things for MSS EXP procedures
-include 00exp_common.mk

PROCEDURE=exp_omi_setup
$(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,115 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */

///
/// @file exp_attribute_accessors_manual.H
/// @brief Manually created attribute accessors.
/// Some attributes aren't in files we want to incorporate in to our automated
/// accessor generator. EC workarounds is one example - everytime someone creates
/// a work-around they'd be burdened with updating this file.
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: Memory
#ifndef EXP_ATTR_ACCESS_MANUAL_H_
#define EXP_ATTR_ACCESS_MANUAL_H_

#include <fapi2.H>
#include <generic/memory/lib/utils/c_str.H>

namespace mss
{

///
/// @brief Gets whether the OCMB will be configred to enterprise mode
/// @param[in] i_target OCMB target on which to operate
/// @param[out] o_is_enterprise_mode true if the part is in enterprise mode
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
///
inline fapi2::ReturnCode enterprise_mode( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
bool& o_is_enterprise_mode )
{
// Constexprs for beautification
constexpr uint8_t ENTERPRISE = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_ENTERPRISE;
constexpr uint8_t NO_OVERRIDE = fapi2::ENUM_ATTR_MSS_OCMB_NONENTERPRISE_MODE_OVERRIDE_NO_OVERRIDE;

// Variables
o_is_enterprise_mode = false;
uint8_t l_enterprise = 0;
uint8_t l_override = 0;

FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_ENTERPRISE_MODE, i_target, l_enterprise) );
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_NONENTERPRISE_MODE_OVERRIDE, i_target, l_override) );

{
const bool l_enterprise_mode = l_enterprise == ENTERPRISE;
const bool l_no_override = l_override == NO_OVERRIDE;
// We will be in enterprise mode (true) IF
// 1) the chip is in enterprise mode (we can't run in enterprise mode if the part is non-enterprise capable) AND
// 2) we do not have the override to non-enterprise mode
o_is_enterprise_mode = l_enterprise_mode && l_no_override;

FAPI_INF("%s is in %s mode chip is %s override is %s", mss::c_str(i_target),
o_is_enterprise_mode ? "enterprise" : "non-enterprise", l_enterprise_mode ? "enterprise" : "non-enterprise",
l_no_override ? "no override" : "override to non-enterprise");
}

fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Gets whether the OCMB will be configured to half-DIMM mode
/// @param[in] i_target OCMB target on which to operate
/// @param[out] o_is_half_dimm_mode true if the part is in half-DIMM mode
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
///
inline fapi2::ReturnCode half_dimm_mode( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
bool& o_is_half_dimm_mode )
{
// Variables
o_is_half_dimm_mode = false;
bool l_is_enterprise = false;
uint8_t l_half_dimm = 0;
uint8_t l_override = 0;

FAPI_TRY( enterprise_mode(i_target, l_is_enterprise) );

// We're in full DIMM mode if we're in non-enterprise mode
if(!l_is_enterprise)
{
o_is_half_dimm_mode = false;
FAPI_INF("%s is in full-DIMM as the chip is in non-enterprise mode", mss::c_str(i_target));
return fapi2::FAPI2_RC_SUCCESS;
}

// Now that we're not in enterprise mode, check for overrides
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE, i_target, l_override) );

// If we have an override, set based upon the override
if(l_override != fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE_NO_OVERRIDE)
{
o_is_half_dimm_mode = l_override == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE_OVERRIDE_HALF_DIMM;
FAPI_INF("%s is in enterprise mode %s override is present. The chip is in %s (attribute %u)", mss::c_str(i_target),
"an", o_is_half_dimm_mode ? "half-DIMM mode" : "full-DIMM mode", l_override);
return fapi2::FAPI2_RC_SUCCESS;
}

// No override, so go with the attribute derived from the ECID
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_OCMB_HALF_DIMM_MODE, i_target, l_half_dimm) );

// Set half DIMM mode based upon the the normal attribute
o_is_half_dimm_mode = l_half_dimm == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_HALF_DIMM;
FAPI_INF("%s is in enterprise mode %s override is present. The chip is in %s (attribute %u)", mss::c_str(i_target),
"no", o_is_half_dimm_mode ? "half-DIMM mode" : "full-DIMM mode", l_half_dimm);

fapi_try_exit:
return fapi2::current_err;
}

} // ns mss

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,166 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */

///
/// @file exp_omi_utils.H
/// @brief OMI utility functions
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: Memory
#ifndef EXP_OMI_UTILS_H_
#define EXP_OMI_UTILS_H_

#include <fapi2.H>
#include <generic/memory/lib/utils/c_str.H>

namespace mss
{
namespace exp
{
namespace omi
{

///
/// @brief Constants used for the OMI register fields
///
// TODO:RTC196850 Update Explorer code to use actual register addresses/names
enum fields
{
// Bit we set to put ourselves into enterprise mode
ENTERPRISE_SET_BIT = 0,
HALF_DIMM_MODE = 1,
// How the HW is actually configured in enterprise mode
ENTERPRISE_BIT_CONFIG = 2,
};

///
/// @brief Constants used for the OMI registers
///
// TODO:RTC196850 Update Explorer code to use actual register addresses/names
enum registers
{
// Bit we set to put ourselves into enterprise mode
MENTERP = 0x080108e4,
};

///////////////////////////////////////////////////////////////////////////////////
/// Bit Field Operations
///////////////////////////////////////////////////////////////////////////////////

///
/// @brief Gets the enterprise set bit
/// @param[in] i_data the register data
/// @return The register's ENTERPRISE_SET_BIT
///
inline bool get_enterprise_set_bit( const fapi2::buffer<uint64_t>& i_data )
{
return i_data.getBit<fields::ENTERPRISE_SET_BIT>();
}

///
/// @brief Sets the enterprise set bit
/// @param[in,out] io_data the register data
/// @param[in] i_is_enterprise true IFF we're in enterprise mode
///
inline void set_enterprise_set_bit( fapi2::buffer<uint64_t>& io_data, const bool i_is_enterprise )
{
io_data.writeBit<fields::ENTERPRISE_SET_BIT>(i_is_enterprise);
}

///
/// @brief Gets the half-DIMM mode
/// @param[in] i_data the register data
/// @return The register's HALF_DIMM_MODE
///
inline bool get_half_dimm_mode( const fapi2::buffer<uint64_t>& i_data )
{
return i_data.getBit<fields::HALF_DIMM_MODE>();
}

///
/// @brief Sets the half-DIMM mode
/// @param[in,out] io_data the register data
/// @param[in] i_is_half_dimm_mode true IFF we're in half_dimm_mode mode
///
inline void set_half_dimm_mode( fapi2::buffer<uint64_t>& io_data, const bool i_is_half_dimm_mode )
{
io_data.writeBit<fields::HALF_DIMM_MODE>(i_is_half_dimm_mode);
}

// Note: ENTERPRISE_BIT_CONFIG is a Read only bit, so no setting it
///
/// @brief Gets the enterprise config bit
/// @param[in] i_data the register data
/// @return The register's ENTERPRISE_BIT_CONFIG
/// @note This bit indicates whether the hardware is in enterprise mode
///
inline bool get_enterprise_config( const fapi2::buffer<uint64_t>& i_data )
{
return i_data.getBit<fields::ENTERPRISE_BIT_CONFIG>();
}

///
/// @brief Checks if the enterprise config bit is in the correct mode
/// @param[in] i_target target on which we are operating - for logging
/// @param[in] i_is_enterprise true if the chip should be in enterprise mode
/// @param[in] i_data data from the enterprise mode register
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff everything is OK
///
inline fapi2::ReturnCode check_enterprise_mode( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const bool i_is_enterprise,
fapi2::buffer<uint64_t>& i_data )
{
const bool l_actual = mss::exp::omi::get_enterprise_config(i_data);
FAPI_ASSERT(l_actual == i_is_enterprise,
fapi2::MSS_EXP_ENTERPRISE_SETUP_ERROR()
.set_EXPECTED(i_is_enterprise)
.set_ACTUAL(l_actual)
.set_REGISTER_DATA(i_data)
.set_OCMB_TARGET(i_target),
"%s failed to setup enterprise mode properly expected: %u actual: %u register data 0x%016lx",
mss::c_str(i_target), i_is_enterprise, l_actual, i_data);

fapi_try_exit:
return fapi2::current_err;
}

///////////////////////////////////////////////////////////////////////////////////
/// Register access operations
///////////////////////////////////////////////////////////////////////////////////
// The scom API should be able to distinguish between the need for i2c vs MMIO

///
/// @brief Reads the register using I2C
/// @param[in] i_target the OCMB target on which to operate
/// @param[out] o_data the register contents
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
///
inline fapi2::ReturnCode read_enterprise_config( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
fapi2::buffer<uint64_t>& o_data )
{
return fapi2::getScom(i_target, registers::MENTERP, o_data);
}

///
/// @brief Writes the register using I2C
/// @param[in] i_target the OCMB target on which to operate
/// @param[in] i_data the register contents
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
///
inline fapi2::ReturnCode write_enterprise_config( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const fapi2::buffer<uint64_t>& i_data )
{
return fapi2::putScom(i_target, registers::MENTERP, i_data);
}

} // ns mss

} // ns exp

} // ns omi

#endif

0 comments on commit e112cf5

Please sign in to comment.