Skip to content

Commit 6dee960

Browse files
Li Mengdcrowell77
authored andcommitted
Adds LRDIMM coarse class
Change-Id: I6677f026134b2ef7898315671c7002acf01727f3 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72028 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/103318 Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com> Tested-by: Daniel M Crowell <dcrowell@us.ibm.com>
1 parent ca83359 commit 6dee960

File tree

5 files changed

+166
-267
lines changed

5 files changed

+166
-267
lines changed

src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training_helper.H

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,127 @@ class mrep_dwl_result
153153

154154
};
155155

156+
///
157+
/// @class coarse_recorder
158+
/// @brief Records results on a per-nibble level for coarse calibration algorithms
159+
/// @note Each vector's array position represents one nibble
160+
/// @note Each bit in an element represents whether the data compared or mis-compared at that delay
161+
/// @note Coarse calibration algorithms refer to sub-cycle calibration algorithms (MRD_COARSE and MWD_COARSE)
162+
///
163+
struct coarse_recorder
164+
{
165+
public:
166+
static constexpr uint64_t CLEAN = 0;
167+
168+
// Default delay value 2 is for 0 nck
169+
static constexpr uint8_t DEFAULT_DELAYS = 2;
170+
static constexpr uint8_t DEFAULT_TO_PASS = 0xF8;
171+
static constexpr uint8_t PASSING_RESULT = 0x0f;
172+
static constexpr uint8_t FAILING_RESULT = 0x00;
173+
174+
///
175+
/// @brief Default constructor
176+
///
177+
coarse_recorder() :
178+
iv_results(DEFAULT_TO_PASS),
179+
iv_final_delay(DEFAULT_DELAYS),
180+
iv_invalid_data_count(CLEAN)
181+
{}
182+
183+
///
184+
/// @brief constructor
185+
/// @param[in] i_results results from the COARSE run
186+
/// @param[in] i_final final delay chosen by the COARSE run
187+
/// @param[in] i_invalid_count invalid data count from COARSE run
188+
///
189+
coarse_recorder(const fapi2::buffer<uint8_t> i_results, const uint8_t i_final_delay,
190+
const uint64_t i_invalid_count = CLEAN) :
191+
iv_results(i_results),
192+
iv_final_delay(i_final_delay),
193+
iv_invalid_data_count(i_invalid_count)
194+
{}
195+
196+
// Records a given bit per nibble per delay
197+
// 1 = compare
198+
// 0 = miscompare
199+
// Fun thing is the LRDIMM spec sends out 1's for compares, so no enums needed
200+
fapi2::buffer<uint8_t> iv_results;
201+
uint8_t iv_final_delay;
202+
uint64_t iv_invalid_data_count;
203+
204+
///
205+
/// @brief Adds results to the recorder
206+
/// @param[in] i_delay the current delay
207+
/// @param[in] i_result the result for the current nibble - right aligned
208+
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
209+
///
210+
fapi2::ReturnCode add_results(const uint8_t i_delay, const uint8_t i_result)
211+
{
212+
bool l_passed = false;
213+
214+
// 0 is not passed
215+
if(i_result == FAILING_RESULT)
216+
{
217+
l_passed = false;
218+
}
219+
220+
// F is passed - only if we had already passed at this location
221+
else if(i_result == PASSING_RESULT)
222+
{
223+
l_passed = iv_results.getBit(i_delay);
224+
}
225+
226+
// Anything else is an error case
227+
else
228+
{
229+
l_passed = false;
230+
FAPI_DBG("delay%u has a invalid result of 0x%02x", i_delay, i_result);
231+
iv_invalid_data_count++;
232+
}
233+
234+
FAPI_TRY(iv_results.writeBit(l_passed, i_delay));
235+
236+
fapi_try_exit:
237+
return fapi2::current_err;
238+
}
239+
240+
241+
///
242+
/// @brief Finds the final result for the whole buffer
243+
/// @param[in] i_target the DIMM target for the data
244+
/// @param[in] i_dimm_rank the DIMM rank on which to set the delay
245+
/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ok
246+
///
247+
fapi2::ReturnCode find_final_delay(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
248+
const uint64_t i_dimm_rank)
249+
{
250+
// uint8_t() is to make the bit count compile as it's expecting an integral type
251+
// buffers don't count as an integral type as they're classes
252+
const uint8_t l_results(iv_results);
253+
254+
// If we never find a passing region, just log an error and set a 2
255+
if(iv_results == 0)
256+
{
257+
iv_final_delay = 2;
258+
FAPI_ERR("%s rank%u found no passing regions setting to an offset of 0 data:0x%02x", mss::c_str(i_target), i_dimm_rank,
259+
iv_results);
260+
return fapi2::FAPI2_RC_SUCCESS;
261+
}
262+
263+
// Otherwise, find our first passing region
264+
// We should really only have 1, so let's log an error if that's not the case
265+
if(bit_count(l_results) > 1)
266+
{
267+
FAPI_ERR("%s rank%u found more than one passing region data:0x%02x", mss::c_str(i_target), i_dimm_rank, iv_results);
268+
}
269+
270+
iv_final_delay = first_bit_set(l_results);
271+
272+
return fapi2::FAPI2_RC_SUCCESS;
273+
}
274+
};
275+
276+
156277
///
157278
/// @class fine_recorder
158279
/// @brief Records results on a per-bit level for fine calibration algorithms

src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_mrd_coarse.C

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ fapi_try_exit:
176176
fapi2::ReturnCode mrd_coarse::analyze_results(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
177177
const uint64_t i_dimm_rank,
178178
const uint8_t i_delay,
179-
std::vector<std::pair<recorder, recorder>>& io_results) const
179+
std::vector<std::pair<coarse_recorder, coarse_recorder>>& io_results) const
180180
{
181181
uint8_t l_buffer = 0;
182182
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
@@ -239,7 +239,7 @@ fapi_try_exit:
239239
///
240240
uint32_t mrd_coarse::flag_invalid_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
241241
const uint8_t i_rank,
242-
const std::vector<std::pair<recorder, recorder>>& i_recorders,
242+
const std::vector<std::pair<coarse_recorder, coarse_recorder>>& i_recorders,
243243
uint64_t& o_invalid_count) const
244244
{
245245
o_invalid_count = 0;
@@ -263,8 +263,8 @@ uint32_t mrd_coarse::flag_invalid_data( const fapi2::Target<fapi2::TARGET_TYPE_D
263263

264264
// Updates the bitmap
265265
o_invalid_count += l_recorder.first.iv_invalid_data_count + l_recorder.second.iv_invalid_data_count;
266-
append_nibble_flags(l_recorder.first.iv_invalid_data_count != recorder::CLEAN,
267-
l_recorder.second.iv_invalid_data_count != recorder::CLEAN,
266+
append_nibble_flags(l_recorder.first.iv_invalid_data_count != coarse_recorder::CLEAN,
267+
l_recorder.second.iv_invalid_data_count != coarse_recorder::CLEAN,
268268
l_per_nibble_flags);
269269

270270
l_buffer++;
@@ -283,7 +283,7 @@ uint32_t mrd_coarse::flag_invalid_data( const fapi2::Target<fapi2::TARGET_TYPE_D
283283
///
284284
fapi2::ReturnCode mrd_coarse::callout_invalid_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
285285
const uint8_t i_rank,
286-
const std::vector<std::pair<recorder, recorder>>& i_recorders) const
286+
const std::vector<std::pair<coarse_recorder, coarse_recorder>>& i_recorders) const
287287
{
288288
// Per nibble invalid data - bitmap
289289
// A bitmap is used to simplify the error callouts
@@ -315,7 +315,7 @@ fapi_try_exit:
315315
///
316316
uint32_t mrd_coarse::flag_not_one_passing_region( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
317317
const uint8_t i_rank,
318-
const std::vector<std::pair<recorder, recorder>>& i_recorders) const
318+
const std::vector<std::pair<coarse_recorder, coarse_recorder>>& i_recorders) const
319319
{
320320
uint8_t l_buffer = 0;
321321

@@ -356,7 +356,7 @@ uint32_t mrd_coarse::flag_not_one_passing_region( const fapi2::Target<fapi2::TAR
356356
///
357357
fapi2::ReturnCode mrd_coarse::callout_not_one_passing_region( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
358358
const uint8_t i_rank,
359-
const std::vector<std::pair<recorder, recorder>>& i_recorders) const
359+
const std::vector<std::pair<coarse_recorder, coarse_recorder>>& i_recorders) const
360360
{
361361
// Per nibble weird data and no transition flags - bitmap
362362
// A bitmap is used to simplify the error callouts
@@ -382,7 +382,7 @@ fapi_try_exit:
382382
///
383383
fapi2::ReturnCode mrd_coarse::find_final_results(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
384384
const uint64_t i_dimm_rank,
385-
std::vector<std::pair<recorder, recorder>>& io_results) const
385+
std::vector<std::pair<coarse_recorder, coarse_recorder>>& io_results) const
386386
{
387387
for(auto& l_buffer_result : io_results)
388388
{
@@ -407,7 +407,7 @@ fapi_try_exit:
407407
///
408408
fapi2::ReturnCode mrd_coarse::set_final_delays_helper(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
409409
const uint64_t i_dimm_rank,
410-
const std::vector<std::pair<recorder, recorder>>& i_results,
410+
const std::vector<std::pair<coarse_recorder, coarse_recorder>>& i_results,
411411
mss::ddr4::pba::commands& o_container) const
412412
{
413413
uint8_t l_buffer = 0;
@@ -470,7 +470,7 @@ fapi_try_exit:
470470
///
471471
fapi2::ReturnCode mrd_coarse::set_final_delays(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
472472
const uint64_t i_dimm_rank,
473-
const std::vector<std::pair<recorder, recorder>>& i_results) const
473+
const std::vector<std::pair<coarse_recorder, coarse_recorder>>& i_results) const
474474
{
475475

476476
mss::ddr4::pba::commands l_container;
@@ -542,7 +542,7 @@ fapi2::ReturnCode mrd_coarse::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
542542
const auto l_dimm_rank = mss::index(l_rank);
543543

544544
// Creates our structure of data for the recorders
545-
std::vector<std::pair<recorder, recorder>> l_results(MAX_LRDIMM_BUFFERS);
545+
std::vector<std::pair<coarse_recorder, coarse_recorder>> l_results(MAX_LRDIMM_BUFFERS);
546546

547547
// Gets our DIMM from this rank
548548
fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm;

0 commit comments

Comments
 (0)