summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2018-09-13 14:05:32 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2018-09-27 09:44:14 -0500
commit99d8a2ec0d3f4e83b1089f7358a8d930dddf2bee (patch)
treef6f52a8423c0b8f31979b2a476f3292a2f514f87 /src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4
parent0fb82ef1a41044a7dce49adee8215e8fbf448d0e (diff)
downloadtalos-hostboot-99d8a2ec0d3f4e83b1089f7358a8d930dddf2bee.tar.gz
talos-hostboot-99d8a2ec0d3f4e83b1089f7358a8d930dddf2bee.zip
Adds insert function space helpers for LRDIMM
Change-Id: I2ad35dc3d1a72606b7a0ce72ad407fe7ce10e0c2 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/66086 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+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/66097 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-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>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/control_word_ddr4.H241
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H130
2 files changed, 299 insertions, 72 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/control_word_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/control_word_ddr4.H
index e35d143ad..bbef1f8c9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/control_word_ddr4.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/control_word_ddr4.H
@@ -46,6 +46,9 @@
namespace mss
{
+///
+/// @brief Control word types
+///
enum control_word
{
// buffer control words
@@ -56,6 +59,10 @@ enum control_word
RCW_4BIT,
RCW_8BIT,
};
+
+// Constexprs to make our lives easier
+static constexpr uint64_t CW4_DATA_LEN = 4;
+static constexpr uint64_t CW8_DATA_LEN = 8;
}
///
@@ -80,7 +87,7 @@ class cwTraits< mss::BCW_8BIT >
// Address bits denoted by A
// Data settings are set by A[7:0]
- static constexpr uint64_t DATA_LEN = 8;
+ static constexpr uint64_t DATA_LEN = mss::CW8_DATA_LEN;
// Control words are set by A[11:4]
static constexpr uint64_t WORD_LEN = 4;
@@ -107,7 +114,7 @@ class cwTraits< mss::BCW_4BIT >
// Address bits denoted by A
// Data settings are set by A[3:0]
- static constexpr uint64_t DATA_LEN = 4;
+ static constexpr uint64_t DATA_LEN = mss::CW4_DATA_LEN;
// Control words are set by A[11:4]
// Word length is technically 8
@@ -136,7 +143,7 @@ class cwTraits< mss::RCW_8BIT >
// Address bits denoted by A
// Data settings are set by A[7:0]
- static constexpr uint64_t DATA_LEN = 8;
+ static constexpr uint64_t DATA_LEN = mss::CW8_DATA_LEN;
// Control words are set by A[12:8]
// Word length is technically 5
@@ -165,7 +172,7 @@ class cwTraits< mss::RCW_4BIT >
// Address bits denoted by A
// Data settings are set by A[3:0]
- static constexpr uint64_t DATA_LEN = 4;
+ static constexpr uint64_t DATA_LEN = mss::CW4_DATA_LEN;
// Control words are set by A[12:4]
// Word length is technically 9
@@ -215,7 +222,12 @@ struct cw_data
}
///
- /// @brief default ctor for attribute driven data
+ /// @brief default dtor
+ ///
+ ~cw_data() = default;
+
+ ///
+ /// @brief default ctor
///
cw_data() = default;
@@ -267,16 +279,17 @@ struct cw_data
/// @tparam OT the TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_data control word data to send
-/// @param[in,out] io_inst a vector of CCS instructions we should add to
-/// @param[in] i_turn_on_cke flag that states whether we want CKE on for this RCW (defaulted to true)
+/// @param[in] i_sim true if in simulation mode
+/// @param[in] i_turn_on_cke flag that states whether we want CKE on for this RCW
+/// @param[out] o_instruction CCS instruction we created
/// @return FAPI2_RC_SUCCESS if and only if ok
///
template< control_word T, typename TT = cwTraits<T>, fapi2::TargetType OT >
fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const cw_data& i_data,
const bool i_sim,
- std::vector< ccs::instruction_t<OT> >& io_inst,
- const bool i_turn_on_cke = true)
+ const bool i_turn_on_cke,
+ ccs::instruction_t<OT>& o_instruction)
{
// You're probably asking "Why always turn off CKE's? What is this madness?"
// Well, due to a vendor sensitivity, we need to have the CKE's off until we run RC09 at the very end
@@ -285,7 +298,7 @@ fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIM
// Therefore, we want to setup all RCW commands to have CKE's off across both DIMM's
// We then manually turn on the CKE's associated with a specific DIMM
constexpr bool CKE_OFF = false;
- ccs::instruction_t<OT> l_inst = ccs::rcd_command<OT>(i_target, i_sim, CKE_OFF);
+ ccs::instruction_t<OT> l_inst = ccs::rcd_command<OT>(i_target, i_sim, CKE_OFF);
// Turn on the CKE's for the ranks we're not touching, if it's needed
// Note: we only have the whole CKE field, not the per DIMM one by default
@@ -332,10 +345,39 @@ fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIM
i_data.iv_delay,
uint64_t(l_inst.arr0), uint64_t(l_inst.arr1),
mss::c_str(i_target));
-
- io_inst.push_back(l_inst);
}
+ // All setup now, output it
+ o_instruction = l_inst;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Control word engine that sets the CCS instruction
+/// @tparam T the buffer control word type (4 bit or 8 bit)
+/// @tparam TT traits type defaults to cwTraits<T>
+/// @tparam OT the TargetType of the CCS instruction
+/// @param[in] i_target a DIMM target
+/// @param[in] i_data control word data to send
+/// @param[in] i_sim true if in simulation mode
+/// @param[in,out] io_inst a vector of CCS instructions we should add to
+/// @param[in] i_turn_on_cke flag that states whether we want CKE on for this RCW (defaulted to true)
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< control_word T, typename TT = cwTraits<T>, fapi2::TargetType OT >
+fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const cw_data& i_data,
+ const bool i_sim,
+ std::vector< ccs::instruction_t<OT> >& io_inst,
+ const bool i_turn_on_cke = true)
+{
+ ccs::instruction_t<OT> l_inst;
+ FAPI_TRY(control_word_engine<T>(i_target, i_data, i_sim, i_turn_on_cke, l_inst));
+ io_inst.push_back(l_inst);
+
fapi_try_exit:
return fapi2::current_err;
}
@@ -347,6 +389,7 @@ fapi_try_exit:
/// @tparam OT the TargetType of the CCS instruction
/// @param[in] i_target a DIMM target
/// @param[in] i_data_list a vector of control word data to send
+/// @param[in] i_sim true if in simulation mode
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @param[in] i_turn_on_cke flag that states whether we want CKE on for all RCWs in the vector (defaulted to true)
/// @return FAPI2_RC_SUCCESS if and only if ok
@@ -358,11 +401,11 @@ fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIM
std::vector< ccs::instruction_t<OT> >& io_inst,
const bool i_turn_on_cke = true)
{
- if( i_data_list.empty() )
- {
- FAPI_ERR("%s. cw_data vector is empty!", mss::c_str(i_target) );
- fapi2::Assert(false);
- }
+ FAPI_ASSERT( !i_data_list.empty(),
+ fapi2::MSS_EMPTY_VECTOR().
+ set_FUNCTION(CW_DATA_ENGINE).
+ set_TARGET(i_target),
+ "%s. cw_data vector is empty!", mss::c_str(i_target) );
for (const auto& data : i_data_list)
{
@@ -373,6 +416,170 @@ fapi_try_exit:
return fapi2::current_err;
}
+/////////////////////////////////////////////////
+// Now for the API related to CW information
+/////////////////////////////////////////////////
+
+///
+/// @class cw_info
+/// @brief class that represents (register/buffer) control word data as well as length and RCW vs BCW
+/// @note used to store all CW data to move the knowledge of 4-bit vs 8-bit to runtime
+///
+struct cw_info
+{
+// Values of A12 which determines BCW vs RCW
+// A12 is 1 for BCW and 0 for RCW
+ static constexpr bool BCW = true;
+ static constexpr bool RCW = false;
+
+ // CW data
+ cw_data iv_cw_data;
+
+ // Data length 4 vs 8 bits
+ uint64_t iv_data_len;
+
+ // Boolean that controls BCW vs RCW - true if BCW
+ bool iv_is_bcw;
+
+ ///
+ /// @brief default dtor
+ ///
+ ~cw_info() = default;
+
+ ///
+ /// @brief default ctor
+ ///
+ cw_info() = default;
+
+ ///
+ /// @brief ctor for attribute driven data
+ /// @param[in] i_func_space the function space number
+ /// @param[in] i_number register control word number
+ /// @param[in] i_func attribute accessor function pointer
+ /// @param[in] i_delay delay in cycles after current RCW
+ /// @param[in] i_data_len data length
+ /// @param[in] i_bcw buffer control word
+ ///
+ cw_info( const uint64_t i_func_space,
+ const uint64_t i_number,
+ fapi2::ReturnCode (*i_func)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&, uint8_t&),
+ const uint64_t i_delay,
+ const uint64_t i_data_len,
+ const bool i_bcw ):
+ iv_cw_data(i_func_space, i_number, i_func, i_delay),
+ iv_data_len(i_data_len),
+ iv_is_bcw(i_bcw)
+ {}
+
+ ///
+ /// @brief ctor for custom data
+ /// @param[in] i_func_space the function space number
+ /// @param[in] i_number register control word number
+ /// @param[in] i_data RCW data to write
+ /// @param[in] i_delay delay in cycles after current RCW
+ /// @param[in] i_data_len data length
+ /// @param[in] i_bcw buffer control word
+ ///
+ cw_info( const uint64_t i_func_space,
+ const uint64_t i_number,
+ const uint64_t i_data,
+ const uint64_t i_delay,
+ const uint64_t i_data_len,
+ const bool i_bcw ):
+ iv_cw_data(i_func_space, i_number, i_data, i_delay),
+ iv_data_len(i_data_len),
+ iv_is_bcw(i_bcw)
+ {}
+
+};
+
+///
+/// @brief Control word engine that sets the CCS instruction
+/// @tparam OT the TargetType of the CCS instruction
+/// @param[in] i_target a DIMM target
+/// @param[in] i_info control word data and information about how to send it
+/// @param[in] i_sim true if in simulation mode
+/// @param[in] i_turn_on_cke flag that states whether we want CKE on for this RCW
+/// @param[out] o_instruction CCS instruction we created
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< fapi2::TargetType OT >
+fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const cw_info& i_info,
+ const bool i_sim,
+ const bool i_turn_on_cke,
+ ccs::instruction_t<OT>& o_instruction)
+{
+ // BCW 4-bit
+ if(i_info.iv_is_bcw && i_info.iv_data_len == CW4_DATA_LEN)
+ {
+ FAPI_TRY(control_word_engine<BCW_4BIT>(i_target, i_info.iv_cw_data, i_sim, i_turn_on_cke, o_instruction));
+ }
+ // BCW 8-bit
+ else if(i_info.iv_is_bcw && i_info.iv_data_len == CW8_DATA_LEN)
+ {
+ FAPI_TRY(control_word_engine<BCW_8BIT>(i_target, i_info.iv_cw_data, i_sim, i_turn_on_cke, o_instruction));
+ }
+ // RCW 4-bit
+ else if(!i_info.iv_is_bcw && i_info.iv_data_len == CW4_DATA_LEN)
+ {
+ FAPI_TRY(control_word_engine<RCW_4BIT>(i_target, i_info.iv_cw_data, i_sim, i_turn_on_cke, o_instruction));
+ }
+ // RCW 8-bit
+ else if(!i_info.iv_is_bcw && i_info.iv_data_len == CW8_DATA_LEN)
+ {
+ FAPI_TRY(control_word_engine<RCW_8BIT>(i_target, i_info.iv_cw_data, i_sim, i_turn_on_cke, o_instruction));
+ }
+ // Error case
+ else
+ {
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_CW_ENCODING()
+ .set_CW_DATA_LEN(i_info.iv_data_len)
+ .set_BCW(i_info.iv_is_bcw)
+ .set_TARGET(i_target),
+ "%s data_len: %u and %s are an invalid combination",
+ mss::c_str(i_target), i_info.iv_data_len, i_info.iv_is_bcw ? "BCW" : "RCW");
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Control word engine that sets the CCS instruction
+/// @tparam OT the TargetType of the CCS instruction
+/// @param[in] i_target a DIMM target
+/// @param[in] i_info_list a vector of control word data to send
+/// @param[in] i_sim true if in simulation mode
+/// @param[in,out] io_inst a vector of CCS instructions we should add to
+/// @param[in] i_turn_on_cke flag that states whether we want CKE on for all RCWs in the vector (defaulted to true)
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< fapi2::TargetType OT >
+fapi2::ReturnCode control_word_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<cw_info>& i_info_list,
+ const bool i_sim,
+ std::vector< ccs::instruction_t<OT> >& io_inst,
+ const bool i_turn_on_cke = true)
+{
+ FAPI_ASSERT( !i_info_list.empty(),
+ fapi2::MSS_EMPTY_VECTOR().
+ set_FUNCTION(CW_INFO_ENGINE).
+ set_TARGET(i_target),
+ "%s. cw_info vector is empty!", mss::c_str(i_target) );
+
+ for (const auto& l_info : i_info_list)
+ {
+ ccs::instruction_t<OT> l_inst;
+ FAPI_TRY( control_word_engine(i_target, l_info, i_sim, i_turn_on_cke, l_inst) );
+ io_inst.push_back(l_inst);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
}// mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H
index 638122ea6..db26abc36 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H
@@ -73,6 +73,9 @@ enum db02_def : size_t
FUNC_SPACE_6 = 6,
FUNC_SPACE_7 = 7,
+ // From DB02 spec - F[3:0]BC7x control word
+ MAX_FUNC_SPACE = 7,
+
// 4 bit BCWs
DQ_RTT_NOM_CW = 0x0,
DQ_RTT_WR_CW = 0x1,
@@ -125,89 +128,106 @@ enum command : size_t
///
/// @brief Sets the function space for the BCW
-/// @tparam T the functon space number we want
/// @param[in] i_target a DIMM target
+/// @param[in] i_func_space the functon space number we want
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-template< uint64_t T >
inline fapi2::ReturnCode function_space_select(const fapi2::Target< fapi2::TARGET_TYPE_DIMM >& i_target,
+ const uint64_t i_func_space,
std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
{
- // From DB02 spec - F[3:0]BC7x control word
- constexpr size_t MAX_FUNC_SPACE = 7;
-
- uint8_t l_sim = 0;
- mss::is_simulation(l_sim);
-
- // Function spaces are typically user selected.
- // Sometimes function spaces are selected based on rank number
- // or MDQ lane number which currently are also user inputs.
-
- // We assert out for user programming erros
- static_assert( T <= MAX_FUNC_SPACE, "Invalid function space selection received. Must be <= 7");
+ FAPI_ASSERT(i_func_space <= MAX_FUNC_SPACE,
+ fapi2::MSS_LRDIMM_FUNC_SPACE_OUT_OF_RANGE()
+ .set_TARGET(i_target)
+ .set_MAX_FUNC_SPACE(MAX_FUNC_SPACE)
+ .set_FUNC_SPACE(i_func_space),
+ "%s function space (%u) greater than maximum range (%u)",
+ mss::c_str(i_target), i_func_space, MAX_FUNC_SPACE);
// function space bits for the function space selector are
// don't cares (XXX). We choose 0 for simplicity.
- cw_data l_data( FUNC_SPACE_0, FUNC_SPACE_SELECT_CW, T, mss::tmrd() );
+ {
+ uint8_t l_sim = 0;
+ mss::is_simulation(l_sim);
- FAPI_TRY( control_word_engine<BCW_8BIT>(i_target, l_data, l_sim, io_inst),
- "%s. Failed control_word_engine for 8-bit BCW (F%dBC%02lxX)",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number) );
+ cw_data l_data( FUNC_SPACE_0, FUNC_SPACE_SELECT_CW, i_func_space, mss::tmrd() );
- // I don't know what already existed in this ccs instruction vector beforehand so
- // I use the back() method to access the last added ccs instruction of interest
- FAPI_INF("%s. F%dBC%02lx ccs inst 0x%016llx:0x%016llx, data: %d",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number),
- uint64_t(io_inst.back().arr0), uint64_t(io_inst.back().arr1), uint8_t(l_data.iv_data) );
+ FAPI_TRY( control_word_engine<BCW_8BIT>(i_target, l_data, l_sim, io_inst),
+ "%s. Failed control_word_engine for 8-bit BCW (F%dBC%02lxX)",
+ mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number) );
+
+ // I don't know what already existed in this ccs instruction vector beforehand so
+ // I use the back() method to access the last added ccs instruction of interest
+ FAPI_INF("%s. F%dBC%02lx ccs inst 0x%016llx:0x%016llx, data: %d",
+ mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number),
+ uint64_t(io_inst.back().arr0), uint64_t(io_inst.back().arr1), uint8_t(l_data.iv_data) );
+ }
fapi_try_exit:
return fapi2::current_err;
}
///
-/// @brief Sets the function space for the BCW
-/// @param[in] i_target a DIMM target
+/// @brief Inserts a function space selector into a vector of cw_info functions
/// @param[in] i_func_space the functon space number we want
-/// @param[in,out] io_inst a vector of CCS instructions we should add to
+/// @param[in] i_iterator an iterator to a vector of cw_info structures
+/// @param[in,out] io_vector vector in which to insert the function space selector
/// @return FAPI2_RC_SUCCESS if and only if ok
///
-inline fapi2::ReturnCode function_space_select(const fapi2::Target< fapi2::TARGET_TYPE_DIMM >& i_target,
- const uint64_t i_func_space,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+inline fapi2::ReturnCode insert_function_space_select(const uint64_t i_func_space,
+ const std::vector< cw_info >::iterator& i_iterator,
+ std::vector< cw_info >& io_vector)
{
- // From DB02 spec - F[3:0]BC7x control word
- constexpr size_t MAX_FUNC_SPACE = 7;
-
- if( i_func_space > MAX_FUNC_SPACE )
+ FAPI_ASSERT(i_func_space <= MAX_FUNC_SPACE,
+ fapi2::MSS_LRDIMM_INSERT_FUNC_SPACE_OUT_OF_RANGE()
+ .set_MAX_FUNC_SPACE(MAX_FUNC_SPACE)
+ .set_FUNC_SPACE(i_func_space),
+ "function space (%u) greater than maximum range (%u)",
+ i_func_space, MAX_FUNC_SPACE);
{
- // Function spaces are typically user selected.
- // Sometimes function spaces are selected based on rank number
- // or MDQ lane number which currently are also user inputs.
-
- // We assert out for user programming erros
- FAPI_ERR("%s. Invalid function space selection: %d, max valid function space is %d",
- mss::c_str(i_target), i_func_space, MAX_FUNC_SPACE);
-
- fapi2::Assert(false);
+ constexpr uint64_t FUNC_SPACE_LEN = 8;
+ cw_info l_info( FUNC_SPACE_0, FUNC_SPACE_SELECT_CW, i_func_space, mss::tmrd(), FUNC_SPACE_LEN, cw_info::BCW );
+ io_vector.insert(i_iterator, l_info);
}
+ return fapi2::FAPI2_RC_SUCCESS;
- uint8_t l_sim = 0;
- mss::is_simulation(l_sim);
+fapi_try_exit:
+ return fapi2::current_err;
+}
- // function space bits for the function space selector are
- // don't cares (XXX). We choose 0 for simplicity.
- cw_data l_data( FUNC_SPACE_0, FUNC_SPACE_SELECT_CW, i_func_space, mss::tmrd() );
+///
+/// @brief Inserts all needed function space selects into a vector of cw_info functions
+/// @param[in,out] io_vector vector in which to insert the function space selector
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+inline fapi2::ReturnCode insert_function_space_select(std::vector< cw_info >& io_vector)
+{
+ fapi2::buffer<uint8_t> l_func_space(FUNC_SPACE_0);
- FAPI_TRY( control_word_engine<BCW_8BIT>(i_target, l_data, l_sim, io_inst),
- "%s. Failed control_word_engine for 8-bit BCW (F%dBC%02lxX)",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number) );
+ // Looping on numbers here as using iterators creates memfaults due to the insert
+ for(uint64_t i = 0; i < io_vector.size(); ++i)
+ {
+ // If the current function space is different than our desired one...
+ if(l_func_space != io_vector[i].iv_cw_data.iv_func_space)
+ {
+ // Add in a CW to do the function space change
+ l_func_space = io_vector[i].iv_cw_data.iv_func_space;
+ auto l_it = io_vector.begin() + i;
+ FAPI_TRY(insert_function_space_select(l_func_space, l_it, io_vector));
+ }
+ }
- // I don't know what already existed in this ccs instruction vector beforehand so
- // I use the back() method to access the last added ccs instruction of interest
- FAPI_INF("%s. F%dBC%02lx ccs inst 0x%016llx:0x%016llx, data: %d",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number),
- uint64_t(io_inst.back().arr0), uint64_t(io_inst.back().arr1), uint8_t(l_data.iv_data) );
+ // So, we always want to know what function space we're in
+ // The way to do that is to always return to one function space
+ // The LR spec recommends that we return to the default function space - function space 0
+ // If the vector is not at our default function space of function space 0, return to function space 0
+ if(l_func_space != FUNC_SPACE_0)
+ {
+ FAPI_TRY(insert_function_space_select(FUNC_SPACE_0, io_vector.end(), io_vector));
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
fapi_try_exit:
return fapi2::current_err;
OpenPOWER on IntegriCloud