From f595ecf7f9d00b2f89f72fb462913a151f9383b4 Mon Sep 17 00:00:00 2001 From: Andre Marin Date: Sat, 27 Jan 2018 06:27:56 -0600 Subject: Add address translation (xlate) support for 4Gbx8 and unit tests Change-Id: I2539fa5237fcae61d334362e54325368c9b12a2a CQ:SW415468 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/52442 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Tested-by: HWSV CI Tested-by: Hostboot CI Reviewed-by: STEPHEN GLANCY Reviewed-by: Louis Stermole Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/52457 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Daniel M. Crowell --- .../chips/p9/procedures/hwp/memory/lib/mc/xlate.C | 401 ++++++++++++++++++++- .../chips/p9/procedures/hwp/memory/lib/mc/xlate.H | 247 ++++++++++++- 2 files changed, 642 insertions(+), 6 deletions(-) (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/mc') diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C index ed291f248..87dd3db08 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -57,6 +57,19 @@ namespace mc /// A little vector of translators. We have one of these for each DIMM we support static const std::vector xlate_map = { + // 1R 4Gbx8 DDR4 RDIMM + { + dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R, + fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_1R, + fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G, + fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, + fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, + fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, + fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM15, + fapi2::ENUM_ATTR_EFF_DIMM_SIZE_4GB), + xlate_dimm_1R1T4Gbx8 + }, + // 1R 4Gbx4 DDR4 RDIMM { dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R, @@ -122,6 +135,19 @@ static const std::vector xlate_map = xlate_dimm_1R1T16Gbx4 }, + // 2R 4Gbx8 DDR4 RDIMM + { + dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R, + fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R, + fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G, + fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, + fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, + fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, + fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM15, + fapi2::ENUM_ATTR_EFF_DIMM_SIZE_8GB), + xlate_dimm_2R2T4Gbx8 + }, + // 2R 4Gbx4 DDR4 RDIMM { dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R, @@ -213,6 +239,19 @@ static const std::vector xlate_map = xlate_dimm_4R4T8Gbx8 }, + // 4R 4Gbx8 DDR4 RDIMM + { + dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R, + fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R, + fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G, + fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, + fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, + fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, + fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM16, + fapi2::ENUM_ATTR_EFF_DIMM_SIZE_16GB), + xlate_dimm_4R4T4Gbx8 + }, + // 4R 8Gbx4 DDR4 RDIMM { dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_4R, @@ -258,6 +297,19 @@ static const std::vector xlate_map = // 3DS RDIMM // + // 1R 2H 3DS 4Gbx8 DDR4 RDIMM + { + dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R, + fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_2R, + fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G, + fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, + fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, + fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, + fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM15, + fapi2::ENUM_ATTR_EFF_DIMM_SIZE_8GB), + xlate_dimm_1R2T4Gbx8 + }, + // 1R 2H 3DS 4Gbx4 DDR4 RDIMM { dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R, @@ -323,6 +375,19 @@ static const std::vector xlate_map = xlate_dimm_1R2T16Gbx4 }, + // 1R 4H 3DS 4Gbx8 DDR4 RDIMM + { + dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R, + fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R, + fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G, + fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, + fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, + fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, + fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM15, + fapi2::ENUM_ATTR_EFF_DIMM_SIZE_16GB), + xlate_dimm_1R4T4Gbx8 + }, + // 1R 4H 3DS 4Gbx4 DDR4 RDIMM { dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R, @@ -388,6 +453,19 @@ static const std::vector xlate_map = xlate_dimm_1R4T16Gbx4 }, + // 1R 8H 3DS 4Gbx8 DDR4 RDIMM + { + dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R, + fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R, + fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G, + fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, + fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, + fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, + fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM15, + fapi2::ENUM_ATTR_EFF_DIMM_SIZE_32GB), + xlate_dimm_1R8T4Gbx8 + }, + // 1R 8H 3DS 4Gbx4 DDR4 RDIMM { dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_1R, @@ -453,6 +531,18 @@ static const std::vector xlate_map = xlate_dimm_1R8T16Gbx4 }, + // 2R 2H 3DS 4Gbx8 DDR4 RDIMM + { + dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R, + fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_4R, + fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G, + fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, + fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, + fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, + fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM15, + fapi2::ENUM_ATTR_EFF_DIMM_SIZE_16GB), + xlate_dimm_2R4T4Gbx8 + }, // 2R 2H 3DS 4Gbx4 DDR4 RDIMM { @@ -519,6 +609,18 @@ static const std::vector xlate_map = xlate_dimm_2R4T16Gbx4 }, + // 2R 4H 3DS 4Gbx8 DDR4 RDIMM + { + dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R, + fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_8R, + fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G, + fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, + fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, + fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, + fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM15, + fapi2::ENUM_ATTR_EFF_DIMM_SIZE_32GB), + xlate_dimm_2R8T4Gbx8 + }, // 2R 4H 3DS 4Gbx4 DDR4 RDIMM { @@ -585,6 +687,18 @@ static const std::vector xlate_map = xlate_dimm_2R8T16Gbx4 }, + // 2R 8H 3DS 4Gbx8 DDR4 RDIMM + { + dimm::kind(fapi2::ENUM_ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_2R, + fapi2::ENUM_ATTR_EFF_NUM_RANKS_PER_DIMM_16R, + fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G, + fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, + fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, + fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, + fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM15, + fapi2::ENUM_ATTR_EFF_DIMM_SIZE_64GB), + xlate_dimm_2R16T4Gbx8 + }, // 2R 8H 3DS 4Gbx4 DDR4 RDIMM { @@ -1167,8 +1281,8 @@ fapi2::ReturnCode xlate_dimm_2R8T16Gbx4( const dimm::kind& i_kind, constexpr uint64_t R17_MAP(PORT_ADDRESS_2); constexpr uint64_t DBIT_MAP(PORT_ADDRESS_1); - // We're just like a 2R 2H 3DS 8Gbx4 so lets start there and modify - FAPI_TRY( xlate_dimm_2R4T8Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); + // We're just like a 2R 4H 3DS 8Gbx4 so lets start there and modify + FAPI_TRY( xlate_dimm_2R8T8Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); // We're a 18 row DIMM, so ROW17 is valid. FAPI_TRY( set_xlate_row(R17_MAP, i_offset, io_xlate0) ); @@ -1307,7 +1421,7 @@ fapi2::ReturnCode xlate_dimm_1R1T4Gbx4( const dimm::kind& i_kind, // this DIMM in the vector, so this is always safe. FAPI_TRY(set_xlate_dimm_slot(i_offset, io_xlate0) ); - // If we have all the slots filled in with 1R SDP DIMM, we build a very differnt mapping. + // If we have all the slots filled in with 1R SDP DIMM, we build a very different mapping. if (l_all_slots_1R) { constexpr uint64_t R15_MAP(PORT_ADDRESS_6); @@ -1410,7 +1524,7 @@ fapi2::ReturnCode xlate_dimm_1R1T8Gbx4( const dimm::kind& i_kind, // We're more or less a 1R 4Gbx4 with an extra row. So lets setup like that and add our row in. FAPI_TRY( xlate_dimm_1R1T4Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); - // If we have all the slots filled in with 1R SDP DIMM, we build a differnt mapping. + // If we have all the slots filled in with 1R SDP DIMM, we build a different mapping. // We're a 17 row DIMM, so ROW16 is valid. FAPI_TRY( set_xlate_row(R16_MAP, i_offset, io_xlate0) ); @@ -2456,5 +2570,282 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 1R 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_1R1T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ) +{ + // From the Nimbus MC workbook ver 0.4 + // Chapter 5: Address Translation pg 148 + // We're just like a 1R 4Gbx4 or 1R 8Gbx8 except we don't have R15 + FAPI_TRY( xlate_dimm_1R1T4Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); + FAPI_TRY( clear_xlate_row(i_offset, io_xlate0) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 1R 2H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_1R2T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ) +{ + // From the Nimbus MC workbook ver 0.4 + // Chapter 5: Address Translation pg 148 + // We're just like a 1R 2H 4Gbx4 or 1R 2H 8Gbx8 except we don't have R15 + // And the D bit is shifted over + FAPI_TRY( xlate_dimm_1R2T4Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); + FAPI_TRY( clear_xlate_row(i_offset, io_xlate0) ); + + FAPI_TRY( d_bit_helper(i_kind.iv_target, i_largest, i_offset, PORT_ADDRESS_6, io_xlate0) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 1R 4H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_1R4T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ) +{ + // From the Nimbus MC workbook ver 0.4 + // Chapter 5: Address Translation pg 148 + // We're just like a 1R 4H 4Gbx4 or 1R 4H 8Gbx8 except we don't have R15 + // And the D bit is shifted over + FAPI_TRY( xlate_dimm_1R4T4Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); + FAPI_TRY( clear_xlate_row(i_offset, io_xlate0) ); + + FAPI_TRY( d_bit_helper(i_kind.iv_target, i_largest, i_offset, PORT_ADDRESS_5, io_xlate0) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 1R 4H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_1R8T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ) +{ + // From the Nimbus MC workbook ver 0.4 + // Chapter 5: Address Translation pg 148 + // We're just like a 1R 8H 4Gbx4 or 1R 8H 8Gbx8 except we don't have R15 + // And the D bit is shifted over + FAPI_TRY( xlate_dimm_1R8T4Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); + FAPI_TRY( clear_xlate_row(i_offset, io_xlate0) ); + + FAPI_TRY( d_bit_helper(i_kind.iv_target, i_largest, i_offset, PORT_ADDRESS_4, io_xlate0) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ) +{ + // From the Nimbus MC workbook ver 0.4 + // Chapter 5: Address Translation pg 148 + // We're just like a 2R 4Gbx4 or 2R 8Gbx8 except we don't have R15 + // And the D bit is shifted over + FAPI_TRY( xlate_dimm_2R2T4Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); + FAPI_TRY( clear_xlate_row(i_offset, io_xlate0) ); + + FAPI_TRY( d_bit_helper(i_kind.iv_target, i_largest, i_offset, PORT_ADDRESS_6, io_xlate0) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 2H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ) +{ + // From the Nimbus MC workbook ver 0.4 + // Chapter 5: Address Translation pg 148 + // We're just like a 2R 2H 4Gbx4 or 2R 2H 8Gbx8 except we don't have R15 + // And the D bit is shifted over + FAPI_TRY( xlate_dimm_2R4T4Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); + FAPI_TRY( clear_xlate_row(i_offset, io_xlate0) ); + + FAPI_TRY( d_bit_helper(i_kind.iv_target, i_largest, i_offset, PORT_ADDRESS_5, io_xlate0) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 4H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ) +{ + // From the Nimbus MC workbook ver 0.4 + // Chapter 5: Address Translation pg 148 + // We're just like a 2R 4H 4Gbx4 or 2R 4H 8Gbx8 except we don't have R15 + // And the D bit is shifted over + FAPI_TRY( xlate_dimm_2R8T4Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); + FAPI_TRY( clear_xlate_row(i_offset, io_xlate0) ); + + FAPI_TRY( d_bit_helper(i_kind.iv_target, i_largest, i_offset, PORT_ADDRESS_4, io_xlate0) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 8H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R16T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ) +{ + // From the Nimbus MC workbook ver 0.4 + // Chapter 5: Address Translation pg 148 + // We're just like a 2R 8H 4Gbx4 or 2R 8H 8Gbx8 except we don't have R15 + // And the D bit is shifted over + FAPI_TRY( xlate_dimm_2R16T4Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); + FAPI_TRY( clear_xlate_row(i_offset, io_xlate0) ); + + FAPI_TRY( d_bit_helper(i_kind.iv_target, i_largest, i_offset, PORT_ADDRESS_3, io_xlate0) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 4R 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_4R4T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ) +{ + // From the Nimbus MC workbook ver 0.4 + // Chapter 5: Address Translation pg 148 + // We're just like a 4R 4Gbx4 or 4R 8Gbx8 except we don't have R15 + // And the D bit is shifted over + FAPI_TRY( xlate_dimm_4R4T4Gbx4(i_kind, i_offset, i_largest, io_xlate0, io_xlate1, io_xlate2) ); + FAPI_TRY( clear_xlate_row(i_offset, io_xlate0) ); + + FAPI_TRY( d_bit_helper(i_kind.iv_target, i_largest, i_offset, PORT_ADDRESS_5, io_xlate0) ); + +fapi_try_exit: + return fapi2::current_err; +} + + } // namespace mc } // namespace mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.H b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.H index 7b745da9a..9a168c0b5 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -113,6 +113,7 @@ class rowTraits public: static constexpr uint64_t ROW = 15; static constexpr uint64_t MAX_MAP_VALUE = PORT_ADDRESS_7; + static constexpr uint64_t CLEAR_MAP = PORT_ADDRESS_0; enum { @@ -132,6 +133,7 @@ class rowTraits public: static constexpr uint64_t ROW = 16; static constexpr uint64_t MAX_MAP_VALUE = PORT_ADDRESS_7; + static constexpr uint64_t CLEAR_MAP = PORT_ADDRESS_0; enum { @@ -151,6 +153,7 @@ class rowTraits public: static constexpr uint64_t ROW = 17; static constexpr uint64_t MAX_MAP_VALUE = PORT_ADDRESS_7; + static constexpr uint64_t CLEAR_MAP = PORT_ADDRESS_0; enum { @@ -196,6 +199,32 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief CLear row bits on the xlate register +/// @tparam T row enumerations to represent xlate master row bits +/// @tparam TT traits type defaults to rowTraits +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @return FAPI2_RC_SUCCESS iff okay +/// +template< rows T, typename TT = rowTraits > +inline fapi2::ReturnCode clear_xlate_row( const uint64_t i_offset, + fapi2::buffer& io_xlate0 ) +{ + FAPI_TRY( io_xlate0.clearBit( TT::SLOT0_ROW_VALID + i_offset ) ); + io_xlate0.insertFromRight(TT::CLEAR_MAP); + + FAPI_DBG( "Set MCP0XLT0_SLOT%d_ROW%d_VALID at bit %d. " + "Set bits for MCP0XLT0_R%d_BIT_MAP with 0x%lx (start: %d, len: %d). " + "MCP0XLT0: 0x%016lx.", + (i_offset == 0 ? 0 : 1), TT::ROW, TT::SLOT0_ROW_VALID + i_offset, TT::ROW, + TT::CLEAR_MAP, TT::ROW_BIT_MAP, TT::ROW_BIT_MAP_LEN, + uint64_t(io_xlate0) ); + +fapi_try_exit: + return fapi2::current_err; +} + /// /// @class mrankTraits /// @brief a collection of traits associated with the master rank xlate registers @@ -1334,6 +1363,222 @@ fapi2::ReturnCode xlate_dimm_4R4T16Gbx8( const dimm::kind& i_kind, fapi2::buffer& io_xlate0, fapi2::buffer& io_xlate1, fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 1R 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_1R1T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 1R 2H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_1R2T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 1R 4H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_1R4T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 1R 4H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_1R8T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R2T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 2H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 2H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R4T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 4H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 4H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R8T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 2R 8H 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_2R16T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); + +/// +/// @brief Perform initializations of the MC translation +/// @param[in] i_kind the DIMM to map +/// @param[in] i_offset the offset; whether the DIMM is in slot 0 or slot 1 +/// @param[in] i_largest whether or not we're the largest DIMM on the port. +/// @param[in,out] io_xlate0 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate1 a buffer representing the xlate register to modify +/// @param[in,out] io_xlate2 a buffer representing the xlate register to modify +/// @note Called for 4R 4Gbx8 DDR4 RDIMM +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode xlate_dimm_4R4T4Gbx8( const dimm::kind& i_kind, + const uint64_t i_offset, + const bool i_largest, + fapi2::buffer& io_xlate0, + fapi2::buffer& io_xlate1, + fapi2::buffer& io_xlate2 ); } // ns mc } // ns mss -- cgit v1.2.1