@@ -281,71 +281,107 @@ namespace check
281
281
{
282
282
283
283
///
284
- /// @brief Check that we recognize DDIMM module manufacturing ID
284
+ /// @brief Check that we recognize SPD lookup key and return the SPD versions associated with the key
285
285
/// @param[in] i_target dimm target
286
- /// @param[in] i_module_mfg_id DIMM module manufacturing ID
287
- /// @param[out] o_latest_combined_rev latest SPD combined revision
286
+ /// @param[in] i_key the SPD lookup key to be used to grab the combined revisions
287
+ /// @param[out] o_minimum_combined_rev minimum SPD combined revisions
288
+ /// @param[out] o_latest_combined_rev latest SPD combined revisions
288
289
/// @return fapi2::FAPI2_RC_SUCCESS if okay. A non-SUCCESS return will also produce an informational log
289
290
///
290
- fapi2 ::ReturnCode module_mfg_id (const fapi2 ::Target < fapi2 ::TARGET_TYPE_DIMM > & i_target ,
291
- const uint16_t i_module_mfg_id ,
292
- uint16_t & o_latest_combined_rev )
291
+ fapi2 ::ReturnCode spd_revision_key (const fapi2 ::Target < fapi2 ::TARGET_TYPE_DIMM > & i_target ,
292
+ const spd_lookup_key & i_key ,
293
+ uint16_t & o_minimum_combined_rev ,
294
+ uint16_t & o_latest_combined_rev )
293
295
{
294
296
// Check that we can find the ID in our latest revision list
295
- FAPI_ASSERT ( mss ::find_value_from_key (LATEST_SPD_COMBINED_REV , i_module_mfg_id , o_latest_combined_rev ),
296
- fapi2 ::MSS_UNKNOWN_DIMM_MODULE_MFG_ID ()
297
+ FAPI_ASSERT ( mss ::find_value_from_key (MINIMUM_SPD_KEY_COMBINED_REV , i_key , o_minimum_combined_rev ),
298
+ fapi2 ::MSS_UNKNOWN_DIMM_SPD_KEY ()
297
299
.set_DIMM_TARGET (i_target )
298
- .set_MODULE_MFG_ID (i_module_mfg_id ),
299
- "%s DDIMM has unrecognized module manufacturing ID (0x%04X)" ,
300
- mss ::c_str (i_target ), i_module_mfg_id );
300
+ .set_MODULE_MFG_ID (i_key .iv_module_mfg_id )
301
+ .set_DIMM_HEIGHT (i_key .iv_dimm_height )
302
+ .set_DIMM_SIZE (i_key .iv_dimm_size ),
303
+ "%s DDIMM has unrecognized key MFG_ID:0x%04X Height:%u Size:%u for minimum SPD rev" ,
304
+ mss ::c_str (i_target ), i_key .iv_module_mfg_id , i_key .iv_dimm_height , i_key .iv_dimm_size );
305
+
306
+ FAPI_ASSERT ( mss ::find_value_from_key (LATEST_SPD_KEY_COMBINED_REV , i_key , o_latest_combined_rev ),
307
+ fapi2 ::MSS_UNKNOWN_DIMM_SPD_KEY ()
308
+ .set_DIMM_TARGET (i_target )
309
+ .set_MODULE_MFG_ID (i_key .iv_module_mfg_id )
310
+ .set_DIMM_HEIGHT (i_key .iv_dimm_height )
311
+ .set_DIMM_SIZE (i_key .iv_dimm_size ),
312
+ "%s DDIMM has unrecognized key MFG_ID:0x%04X Height:%u Size:%u for latest SPD rev" ,
313
+ mss ::c_str (i_target ), i_key .iv_module_mfg_id , i_key .iv_dimm_height , i_key .iv_dimm_size );
301
314
302
315
return fapi2 ::FAPI2_RC_SUCCESS ;
303
316
304
317
fapi_try_exit :
305
318
// Log the error as recovered - we want this error to be informational
306
319
fapi2 ::logError (fapi2 ::current_err , fapi2 ::FAPI2_ERRL_SEV_RECOVERED );
307
320
fapi2 ::current_err = fapi2 ::FAPI2_RC_SUCCESS ;
308
- return fapi2 ::RC_MSS_UNKNOWN_DIMM_MODULE_MFG_ID ;
321
+ return fapi2 ::RC_MSS_UNKNOWN_DIMM_SPD_KEY ;
309
322
}
310
323
311
324
///
312
- /// @brief Check DDIMM SPD revision and content revision versus latest supported
325
+ /// @brief Check DDIMM SPD revision and content revision versus minimum supported
313
326
/// @param[in] i_target dimm target
314
- /// @param[in] i_spd_rev SPD revision
315
- /// @param[in] i_spd_content_rev SPD content revision
316
- /// @param[in] i_latest_combined_rev latest SPD combined revision
327
+ /// @param[in] i_spd_combined_revision the combined SPD revision and content
328
+ /// @param[in] i_min_combined_rev SPD minimum combined revision information
317
329
/// @return fapi2::FAPI2_RC_SUCCESS if okay. A non-SUCCESS return will also produce an informational log
318
330
/// @note The return code from this function is only used in unit tests.
319
331
///
320
- fapi2 ::ReturnCode spd_combined_revision (const fapi2 ::Target < fapi2 ::TARGET_TYPE_DIMM > & i_target ,
321
- const uint8_t i_spd_rev ,
322
- const uint8_t i_spd_content_rev ,
323
- const uint16_t i_latest_combined_rev )
332
+ fapi2 ::ReturnCode spd_minimum_combined_revision (const fapi2 ::Target < fapi2 ::TARGET_TYPE_DIMM > & i_target ,
333
+ const uint16_t i_spd_combined_rev ,
334
+ const uint16_t i_min_combined_rev )
324
335
{
325
- // Assemble the SPD combined revision
326
- // We simply put the SPD revision before the content revision
327
- fapi2 ::buffer < uint16_t > l_spd_combined_revision ;
328
- l_spd_combined_revision .insertFromRight < 0 , BITS_PER_BYTE > (i_spd_rev )
329
- .insertFromRight < BITS_PER_BYTE , BITS_PER_BYTE > (i_spd_content_rev );
330
336
331
337
// Check the combined revision
332
- if (l_spd_combined_revision < i_latest_combined_rev )
338
+ FAPI_ASSERT ( i_spd_combined_rev >= i_min_combined_rev ,
339
+ fapi2 ::MSS_UNSUPPORTED_SPD_COMBINED_REVISION ()
340
+ .set_DIMM_TARGET (i_target )
341
+ .set_SPD_COMBINED_REVISION (i_spd_combined_rev )
342
+ .set_MINIMUM_FUNCTIONAL_SPD_COMBINED_REVISION (i_min_combined_rev ),
343
+ "%s DDIMM has an unsupported SPD combined revision and needs to be updated (0x%04X < 0x%04X)" ,
344
+ mss ::c_str (i_target ), i_spd_combined_rev , i_min_combined_rev );
345
+
346
+ return fapi2 ::FAPI2_RC_SUCCESS ;
347
+
348
+ fapi_try_exit :
349
+ // Log the error as recovered - we want this error to be informational
350
+ fapi2 ::logError (fapi2 ::current_err , fapi2 ::FAPI2_ERRL_SEV_RECOVERED );
351
+ fapi2 ::current_err = fapi2 ::FAPI2_RC_SUCCESS ;
352
+ return fapi2 ::RC_MSS_UNSUPPORTED_SPD_COMBINED_REVISION ;
353
+ }
354
+
355
+ ///
356
+ /// @brief Check DDIMM SPD revision and content revision versus latest supported
357
+ /// @param[in] i_target dimm target
358
+ /// @param[in] i_spd_combined_revision the combined SPD revision and content
359
+ /// @param[in] i_latest_combined_rev latest SPD combined revision information
360
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay. A non-SUCCESS return will also produce an informational log
361
+ /// @note The return code from this function is only used in unit tests.
362
+ ///
363
+ fapi2 ::ReturnCode spd_latest_combined_revision (const fapi2 ::Target < fapi2 ::TARGET_TYPE_DIMM > & i_target ,
364
+ const uint16_t i_spd_combined_rev ,
365
+ const uint16_t i_latest_combined_rev )
366
+ {
367
+ // Check the combined revision
368
+ if (i_spd_combined_rev < i_latest_combined_rev )
333
369
{
334
370
// For the lab, we just want to log these as informational errors
335
371
#ifndef __HOSTBOOT_MODULE
336
372
FAPI_INF ("%s DDIMM has non-current SPD combined revision and could be updated (0x%04X < 0x%04X)" ,
337
- mss ::c_str (i_target ), l_spd_combined_revision , i_latest_combined_rev );
373
+ mss ::c_str (i_target ), i_spd_combined_rev , i_latest_combined_rev );
338
374
// Return a bad RC here for unit test confirmation
339
375
return fapi2 ::RC_MSS_NON_CURRENT_SPD_COMBINED_REVISION ;
340
376
#else
341
377
// For hostboot, we want to generate an informational error log
342
378
FAPI_ASSERT ( false,
343
379
fapi2 ::MSS_NON_CURRENT_SPD_COMBINED_REVISION ()
344
380
.set_DIMM_TARGET (i_target )
345
- .set_SPD_COMBINED_REVISION (l_spd_combined_revision )
381
+ .set_SPD_COMBINED_REVISION (i_spd_combined_rev )
346
382
.set_LATEST_SPD_COMBINED_REVISION (i_latest_combined_rev ),
347
383
"%s DDIMM has non-current SPD combined revision and could be updated (0x%04X < 0x%04X)" ,
348
- mss ::c_str (i_target ), l_spd_combined_revision , i_latest_combined_rev );
384
+ mss ::c_str (i_target ), i_spd_combined_rev , i_latest_combined_rev );
349
385
#endif
350
386
}
351
387
@@ -378,9 +414,11 @@ fapi2::ReturnCode ddimm_spd_revision(const fapi2::Target<fapi2::TARGET_TYPE_MEM_
378
414
379
415
for (const auto& l_dimm : mss ::find_targets < fapi2 ::TARGET_TYPE_DIMM > (i_target ))
380
416
{
381
- uint16_t l_latest_combined_rev = 0 ;
382
417
uint8_t l_dimm_type = 0 ;
383
- uint16_t l_module_mfg_id = 0 ;
418
+ uint16_t l_min_combined_rev = 0 ;
419
+ uint16_t l_latest_combined_rev = 0 ;
420
+ spd_lookup_key l_key (l_dimm , l_rc );
421
+ FAPI_TRY (l_rc , "%s failed to build spd_lookup_key" , mss ::c_str (l_dimm ));
384
422
385
423
FAPI_TRY ( mss ::attr ::get_dimm_type (l_dimm , l_dimm_type ) );
386
424
@@ -391,32 +429,37 @@ fapi2::ReturnCode ddimm_spd_revision(const fapi2::Target<fapi2::TARGET_TYPE_MEM_
391
429
continue ;
392
430
}
393
431
394
- FAPI_TRY ( mss ::attr ::get_module_mfg_id (l_dimm , l_module_mfg_id ) );
395
-
396
- // First make sure we can get the SPD content revision using the module manufacturing ID
432
+ // First make sure we can get the SPD combined revision using the key
397
433
// This is not necessarily a hard fail, so don't bomb out, but we have to skip the SPD revision checks.
398
- l_rc = check ::module_mfg_id (l_dimm , l_module_mfg_id , l_latest_combined_rev );
434
+ l_rc = check ::spd_revision_key (l_dimm , l_key , l_min_combined_rev , l_latest_combined_rev );
399
435
400
436
if (l_rc != fapi2 ::FAPI2_RC_SUCCESS )
401
437
{
402
- FAPI_INF ("Skipping SPD revision plug rule check on %s because it has an unrecognized module manufacturing ID 0x%04X" ,
403
- mss ::c_str (i_target ), l_module_mfg_id );
438
+ FAPI_INF ("Skipping SPD revision plug rule check on %s because it has an unrecognized SPD key MFG_ID: 0x%04X Height:%u Size:%u " ,
439
+ mss ::c_str (i_target ), l_key . iv_module_mfg_id , l_key . iv_dimm_height , l_key . iv_dimm_size );
404
440
continue ;
405
441
}
406
442
407
- // Now check the base SPD revision
408
- FAPI_ASSERT ( (MIN_FUNCTIONAL_SPD_REV <= l_spd_rev ),
409
- fapi2 ::MSS_UNSUPPORTED_SPD_REVISION ()
410
- .set_DIMM_TARGET (l_dimm )
411
- .set_SPD_REVISION (l_spd_rev )
412
- .set_MINIMUM_FUNCTIONAL_SPD_REVISION (MIN_FUNCTIONAL_SPD_REV ),
413
- "%s DDIMM has unsupported SPD revision and needs to be updated (0x%02X < 0x%02X)" ,
414
- mss ::c_str (l_dimm ), l_spd_rev , MIN_FUNCTIONAL_SPD_REV );
415
-
416
- // Finally check the SPD content revision
417
- // Don't bother checking the return code here because this check only produces informational logs
418
- // (and the RC is only used for unit tests)
419
- check ::spd_combined_revision (l_dimm , l_spd_rev , l_spd_content_rev , l_latest_combined_rev );
443
+ {
444
+ // Assemble the SPD combined revision
445
+ // We simply put the SPD revision before the content revision
446
+ fapi2 ::buffer < uint16_t > l_spd_combined_revision ;
447
+ l_spd_combined_revision .insertFromRight < 0 , BITS_PER_BYTE > (l_spd_rev )
448
+ .insertFromRight < BITS_PER_BYTE , BITS_PER_BYTE > (l_spd_content_rev );
449
+
450
+ // Now check the minimum SPD combined revision
451
+ // Note: skipping target trace here as the 4th variable appears to cause issues w/ FAPI_TRY
452
+ // The DIMM target should be called out in the combined revision code
453
+ // We do want to callout the key here, so we know what type of DIMM failed
454
+ FAPI_TRY ( check ::spd_minimum_combined_revision (l_dimm , l_spd_combined_revision , l_min_combined_rev ),
455
+ "SPD min rev check failed key MFG_ID:0x%04X Height:%u Size:%u" ,
456
+ l_key .iv_module_mfg_id , l_key .iv_dimm_height , l_key .iv_dimm_size );
457
+
458
+ // Finally check the latest SPD combined revision
459
+ // Don't bother checking the return code here because this check only produces informational logs
460
+ // (and the RC is only used for unit tests)
461
+ check ::spd_latest_combined_revision (l_dimm , l_spd_combined_revision , l_latest_combined_rev );
462
+ }
420
463
}
421
464
422
465
fapi_try_exit :
0 commit comments