summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2016-04-05 14:43:41 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-04-25 13:45:00 -0400
commit84245de79e62f285cd4bd3201dcf8ec8c92d1f42 (patch)
tree6b8e5de5183fd98f90875631798d1c68bcfae3a8 /src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
parent6d41c4bef52f59d6363d813d6b2b3b8a0d4f828c (diff)
downloadtalos-hostboot-84245de79e62f285cd4bd3201dcf8ec8c92d1f42.tar.gz
talos-hostboot-84245de79e62f285cd4bd3201dcf8ec8c92d1f42.zip
Add L2 p9_mss_scrub
Change inversion so in sim we run with inversion off Change address counting mode to be disabled by default Remove ATTR_MCBIST attributes Change-Id: I233851de5186e053df0b5a4b25eee42763b35755 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22914 Tested-by: Jenkins Server Tested-by: Hostboot CI Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22917 Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C110
1 files changed, 109 insertions, 1 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
index 47fb236a9..85a221a37 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
@@ -30,7 +30,14 @@
#include <fapi2.H>
#include <p9_mss_scrub.H>
+#include <lib/dimm/rank.H>
+#include <lib/mcbist/address.H>
+#include <lib/mcbist/mcbist.H>
+#include <lib/dimm/kind.H>
+
using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_SYSTEM;
using fapi2::FAPI2_RC_SUCCESS;
///
@@ -41,6 +48,107 @@ using fapi2::FAPI2_RC_SUCCESS;
fapi2::ReturnCode p9_mss_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
{
FAPI_INF("Start mss scrub");
+
+ // If we're running in the simulator, we want to only touch the addresses which training touched
+ uint8_t is_sim = 0;
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<TARGET_TYPE_SYSTEM>(), is_sim) );
+
+ for (const auto& p : i_target.getChildren<TARGET_TYPE_MCA>())
+ {
+ std::vector<uint64_t> l_pr;
+ mss::mcbist::program<TARGET_TYPE_MCBIST> l_program;
+
+ // In sim we know a few things ...
+ // Get the primary ranks for this port. We know there can only be 4, and we know we only trained the primary
+ // ranks. Therefore, we only need to clean up the primary ranks. And because there's 4 max, we can do it
+ // all using the 4 address range registers of tne MCBIST (broadcast currently not considered.)
+ // So we can write 0's to those to get their ECC fixed up.
+ FAPI_TRY( mss::primary_ranks(p, l_pr) );
+
+ for (const auto& r : l_pr)
+ {
+ mss::mcbist::address l_start;
+ mss::mcbist::address l_end;
+
+ // Setup l_start to represent this rank, and then make the end address from that.
+ l_start.set_master_rank(r);
+
+ // l_end starts like as the max as we want to scrub the entire thing. If we're in sim,
+ // we'll wratchet that back.
+ l_start.get_range<mss::mcbist::address::MRANK>(l_end);
+
+ if (is_sim)
+ {
+ l_start.get_range<mss::mcbist::address::COL>(l_end);
+ // Set C3 bit to get an entire cache line
+ l_end.set_field<mss::mcbist::address::COL>(0b1000000);
+ }
+
+ // By default we're in maint address mode, not address counting mode. So we give it a start and end, and ignore
+ // anything invalid - that's what maint address mode is all about
+ mss::mcbist::config_address_range(i_target, l_start, l_end, r);
+
+ // Write
+ {
+ // Run in ECC mode, 64B writes (superfast mode)
+
+ mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fw_subtest =
+ mss::mcbist::write_subtest<TARGET_TYPE_MCBIST>();
+
+ l_fw_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
+ l_fw_subtest.change_addr_sel(r);
+ l_fw_subtest.enable_dimm(mss::get_dimm_from_rank(r));
+ l_program.iv_subtests.push_back(l_fw_subtest);
+ FAPI_DBG("adding superfast write for %s rank %d (dimm %d)", mss::c_str(p), r, mss::get_dimm_from_rank(r));
+ }
+
+ // Read
+ {
+ // Run in ECC mode, 64B writes (superfast mode)
+ mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fr_subtest =
+ mss::mcbist::read_subtest<TARGET_TYPE_MCBIST>();
+
+ l_fr_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
+ l_fr_subtest.change_addr_sel(r);
+ l_fr_subtest.enable_dimm(mss::get_dimm_from_rank(r));
+ l_program.iv_subtests.push_back(l_fr_subtest);
+ FAPI_DBG("adding superfast read for %s rank %d (dimm %d)", mss::c_str(p), r, mss::get_dimm_from_rank(r));
+ }
+ }
+
+ // Write 0's
+ FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD0Q, 0) );
+ FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD1Q, 0) );
+ FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD2Q, 0) );
+ FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD3Q, 0) );
+ FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD4Q, 0) );
+ FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD5Q, 0) );
+ FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD6Q, 0) );
+ FAPI_TRY( mss::putScom(i_target, MCBIST_MCBFD7Q, 0) );
+
+ // Setup the sim polling based on a heuristic <cough>guess</cough>
+ // Looks like ~250ck per address for a write/read program on the sim-dimm, and add a long number of polls
+ // and a 64x fudge factor. Testing shows this takes about 50 or so poll loops to complete, which is ok
+ l_program.iv_poll.iv_initial_sim_delay = mss::cycles_to_simcycles((64 * l_pr.size()) * 250);
+ l_program.iv_poll.iv_delay = 200;
+
+ // On real hardware wait 100ms and then start polling for another 5s
+ l_program.iv_poll.iv_initial_delay = 100 * mss::DELAY_1MS;
+ l_program.iv_poll.iv_delay = 10 * mss::DELAY_1MS;
+
+ l_program.iv_poll.iv_poll_count = 500;
+
+ // Just one port for now. Per Shelton we need to set this in maint address mode
+ // even tho we specify the port/dimm in the subtest.
+ fapi2::buffer<uint8_t> l_port;
+ l_port.setBit(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
+ l_program.select_ports(l_port >> 4);
+
+ // Kick it off, wait for a result
+ FAPI_TRY( mss::mcbist::execute(i_target, l_program) );
+ }
+
+fapi_try_exit:
FAPI_INF("End mss scrub");
- return FAPI2_RC_SUCCESS;
+ return fapi2::current_err;
}
OpenPOWER on IntegriCloud