summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp
diff options
context:
space:
mode:
authorBen Gass <bgass@us.ibm.com>2018-10-19 07:32:27 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2019-04-04 09:25:38 -0500
commitb823dd50837a9f05cf69dc75d5942319f537024d (patch)
tree7414d5b461004c3d475ba2cb0ed25bd11c5b71c6 /src/import/chips/p9/procedures/hwp
parente5622fb032dc8b23627d8ca06d82a10b612d5435 (diff)
downloadtalos-hostboot-b823dd50837a9f05cf69dc75d5942319f537024d.tar.gz
talos-hostboot-b823dd50837a9f05cf69dc75d5942319f537024d.zip
Update p9_mss_eff_grouping for Axone support
Add p9a_omi_setup_bars procedure Add eclipse project files to .gitignore Change-Id: Ia18cd213ac8b3682e5718b3c631dad631b97170f Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67755 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: PPE CI <ppe-ci+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: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67764 Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Tested-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp')
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_cxa_scom.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_int_scom.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_nx_scom.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/initfiles/p9_vas_scom.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C734
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H5
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.mk3
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C1039
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.mk3
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_query_mssinfo.C9
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C187
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.H52
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C222
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.H74
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.mk29
15 files changed, 2193 insertions, 180 deletions
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_cxa_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_cxa_scom.C
index 29d6e2b1c..affeb906f 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_cxa_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_cxa_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -154,7 +154,7 @@ fapi2::ReturnCode p9_cxa_scom(const fapi2::Target<fapi2::TARGET_TYPE_CAPP>& TGT0
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
&& (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
|| ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
- && (l_chip_ec == 0x13)) )
+ && (l_chip_ec == 0x13)) || ((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
{
l_scom_buffer.insert<21, 4, 60, uint64_t>(l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID );
l_scom_buffer.insert<25, 3, 61, uint64_t>(l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID );
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_int_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_int_scom.C
index da4f761cb..8951137fa 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_int_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_int_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -97,7 +97,7 @@ fapi2::ReturnCode p9_int_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
&& (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
|| ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
- && (l_chip_ec == 0x13)) )
+ && (l_chip_ec == 0x13)) || ((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
{
l_scom_buffer.insert<5, 4, 60, uint64_t>(l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID );
l_scom_buffer.insert<9, 3, 61, uint64_t>(l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID );
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_nx_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_nx_scom.C
index e48166c54..6ac32f566 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_nx_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_nx_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -662,7 +662,7 @@ fapi2::ReturnCode p9_nx_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
&& (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
|| ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
- && (l_chip_ec == 0x13)) )
+ && (l_chip_ec == 0x13)) || ((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
{
l_scom_buffer.insert<56, 4, 60, uint64_t>(l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID );
l_scom_buffer.insert<60, 3, 61, uint64_t>(l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID );
diff --git a/src/import/chips/p9/procedures/hwp/initfiles/p9_vas_scom.C b/src/import/chips/p9/procedures/hwp/initfiles/p9_vas_scom.C
index 44cd049f9..69b80637c 100644
--- a/src/import/chips/p9/procedures/hwp/initfiles/p9_vas_scom.C
+++ b/src/import/chips/p9/procedures/hwp/initfiles/p9_vas_scom.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -126,7 +126,7 @@ fapi2::ReturnCode p9_vas_scom(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&
if (((l_chip_id == 0x5) && (l_chip_ec == 0x20)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x21)) || ((l_chip_id == 0x5)
&& (l_chip_ec == 0x22)) || ((l_chip_id == 0x5) && (l_chip_ec == 0x23)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x10))
|| ((l_chip_id == 0x6) && (l_chip_ec == 0x11)) || ((l_chip_id == 0x6) && (l_chip_ec == 0x12)) || ((l_chip_id == 0x6)
- && (l_chip_ec == 0x13)) )
+ && (l_chip_ec == 0x13)) || ((l_chip_id == 0x7) && (l_chip_ec == 0x10)) )
{
l_scom_buffer.insert<0, 4, 60, uint64_t>(l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID );
l_scom_buffer.insert<4, 3, 61, uint64_t>(l_TGT1_ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID );
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C
index 231c83426..342e32247 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C
@@ -90,6 +90,16 @@ enum GroupAllowed
GROUP_8,
};
+// -----------------------
+// Used to indicate which subchannels of an OMI channel are used
+enum OMISubChannelConfig
+{
+ NONE = 0b00000000, // Neither sub channel is enabled
+ A = 0b10000000, // Sub-channel A is used
+ B = 0b01000000, // Sub-channel B is used
+ BOTH = A | B, // Both are enabled (mirroring is allowed)
+};
+
// matrix for port-pair based deconfiguration combinations
const uint8_t MAX_MBA_PERMUTATIONS = 9;
const uint8_t MBA_PERMUTATIONS[MAX_MBA_PERMUTATIONS][NUM_PORTS_PER_PAIR][NUM_MBA_PER_MEMBUF] =
@@ -160,6 +170,8 @@ struct EffGroupingSysAttrs
///
fapi2::ReturnCode getAttrs();
+ void updateGroupsAllowed(bool i_is_axone);
+
// Public data
uint8_t iv_selectiveMode = 0; // ATTR_MEM_MIRROR_PLACEMENT_POLICY
uint8_t iv_hwMirrorEnabled = 0; // ATTR_MRW_HW_MIRRORING_ENABLE
@@ -167,8 +179,42 @@ struct EffGroupingSysAttrs
uint8_t iv_smfSupported = 0; // ATTR_CHIP_EC_FEATURE_SMF_SUPPORTED
uint8_t iv_smfConfig = 0; // ATTR_SMF_CONFIG
uint8_t iv_smfEnabled = 0; // ATTR_SMF_ENABLED
+ fapi2::ATTR_CHIP_EC_FEATURE_HW423589_OPTION2_Type iv_hw423589_option2;
};
+void EffGroupingSysAttrs::updateGroupsAllowed(bool i_is_axone)
+{
+ // derate requested interleave options based on hardware workarounds/
+ // restrictions or mirroring requirements
+
+ // 1. Disallow 6-way/3-way interleave to prevent overflow of 512 GB
+ // footprint with 7 of 8 max-sized DIMMs present
+ if (iv_hw423589_option2)
+ {
+ FAPI_INF("Groups of 6 & 3 are not allowed with HW423589 option2");
+ iv_groupsAllowed &= ~GROUP_6;
+ iv_groupsAllowed &= ~GROUP_3;
+ }
+
+ // 2. HW423110 - Disallow 6-way interleave if mirroring is desired
+ if (iv_hwMirrorEnabled != fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_FALSE && !i_is_axone)
+ {
+ FAPI_INF("Group of 6 is not allowed with Mirroring");
+ iv_groupsAllowed &= ~GROUP_6;
+ }
+
+ // 3. SW433435 - Disallow 3-way/1-way interleave if all channels are required
+ // to be mirrored (unless Axone). 2-way cross port interleaving is also prohibited
+ // in this case, but is handled in grouping_group2PortsPerGroup()
+ if (iv_hwMirrorEnabled == fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_TRUE && !i_is_axone)
+ {
+ FAPI_INF("Groups of 3 & 1 are not allowed with Mirroring Required");
+ iv_groupsAllowed &= ~GROUP_3;
+ iv_groupsAllowed &= ~GROUP_1;
+ }
+}
+
+
// See doxygen in struct definition.
fapi2::ReturnCode EffGroupingSysAttrs::getAttrs()
{
@@ -180,7 +226,6 @@ fapi2::ReturnCode EffGroupingSysAttrs::getAttrs()
uint8_t l_addr_extension_chip_id = 0;
uint64_t l_max_interleave_group_size;
fapi2::ATTR_CHIP_EC_FEATURE_EXTENDED_ADDRESSING_MODE_Type l_extended_addressing_mode = 0;
- fapi2::ATTR_CHIP_EC_FEATURE_HW423589_OPTION2_Type l_hw423589_option2 = 0;
auto l_targets = FAPI_SYSTEM.getChildren<fapi2::TARGET_TYPE_PROC_CHIP>();
@@ -193,12 +238,12 @@ fapi2::ReturnCode EffGroupingSysAttrs::getAttrs()
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW423589_OPTION2,
l_targets.front(),
- l_hw423589_option2),
+ iv_hw423589_option2),
"Error from FAPI_ATTR_GET (ATTR_CHIP_EC_FEATURE_HW423589_OPTION2)");
FAPI_DBG("Extended addressing supported: %d, HW423589 option2: %d",
l_extended_addressing_mode,
- l_hw423589_option2);
+ iv_hw423589_option2);
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SMF_CONFIG, FAPI_SYSTEM, iv_smfConfig),
"Error from FAPI_ATTR_GET (ATTR_SMF_CONFIG)");
@@ -211,7 +256,7 @@ fapi2::ReturnCode EffGroupingSysAttrs::getAttrs()
if (l_extended_addressing_mode)
{
- if (l_hw423589_option2)
+ if (iv_hw423589_option2)
{
l_addr_extension_group_id = CHIP_ADDRESS_EXTENSION_GROUP_ID_MASK_HW423589_OPTION2;
l_addr_extension_chip_id = CHIP_ADDRESS_EXTENSION_CHIP_ID_MASK_HW423589_OPTION2;
@@ -236,7 +281,7 @@ fapi2::ReturnCode EffGroupingSysAttrs::getAttrs()
"Error from FAPI_ATTR_SET (ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID)");
}
- if (l_hw423589_option2)
+ if (iv_hw423589_option2)
{
// restrict max size for MCD issue
l_max_interleave_group_size = MAX_INTERLEAVE_GROUP_SIZE_HW423589_OPTION2;
@@ -277,35 +322,6 @@ fapi2::ReturnCode EffGroupingSysAttrs::getAttrs()
"Error getting ATTR_MSS_INTERLEAVE_ENABLE, l_rc 0x%.8X",
(uint64_t)fapi2::current_err);
- // derate requested interleave options based on hardware workarounds/
- // restrictions or mirroring requirements
-
- // 1. Disallow 6-way/3-way interleave to prevent overflow of 512 GB
- // footprint with 7 of 8 max-sized DIMMs present
- if (l_hw423589_option2)
- {
- FAPI_INF("Groups of 6 & 3 are not allowed with HW423589 option2");
- iv_groupsAllowed &= ~GROUP_6;
- iv_groupsAllowed &= ~GROUP_3;
- }
-
- // 2. HW423110 - Disallow 6-way interleave if mirroring is desired
- if (iv_hwMirrorEnabled != fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_FALSE)
- {
- FAPI_INF("Group of 6 is not allowed with Mirroring");
- iv_groupsAllowed &= ~GROUP_6;
- }
-
- // 3. SW433435 - Disallow 3-way/1-way interleave if all channels are required
- // to be mirrored. 2-way cross port interleaving is also prohibited
- // in this case, but is handled in grouping_group2PortsPerGroup()
- if (iv_hwMirrorEnabled == fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_TRUE)
- {
- FAPI_INF("Groups of 3 & 1 are not allowed with Mirroring Required");
- iv_groupsAllowed &= ~GROUP_3;
- iv_groupsAllowed &= ~GROUP_1;
- }
-
// Display attribute values
FAPI_INF("EffGroupingSysAttrs: ");
FAPI_INF(" ATTR_MEM_MIRROR_PLACEMENT_POLICY 0x%.8X", iv_selectiveMode);
@@ -631,6 +647,115 @@ fapi_try_exit:
///----------------------------------------------------------------------------
+/// struct EffGroupingMccAttrs
+///----------------------------------------------------------------------------
+///
+/// @struct EffGroupingMccAttrs
+///
+/// Contains attributes for an MCC Chiplet (Axone only)
+///
+struct EffGroupingMccAttrs
+{
+ ///
+ /// @brief Getting attribute of a MCC chiplet
+ ///
+ /// Function that reads the MCC target attributes and load their
+ /// values into the struct.
+ ///
+ /// @param[in] i_target Reference to MCC chiplet target
+ ///
+ /// @return FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ fapi2::ReturnCode getAttrs(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCC>& i_target);
+
+ // Unit Position
+ uint8_t iv_unitPos = 0;
+
+ // Total Dimm size behind this MCC
+ uint64_t iv_dimmSize = 0;
+
+ // The ocmbs associated with this MCC
+ // (for deconfiguring if cannot group)
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>> iv_ocmbs;
+ std::vector<uint8_t> iv_omi_pos;
+};
+
+// See doxygen in struct definition.
+fapi2::ReturnCode EffGroupingMccAttrs::getAttrs(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCC>& i_target)
+{
+ FAPI_DBG("Entering EffGroupingMccAttrs::getAttrs");
+
+ uint8_t l_omi_pos = 0;
+ uint64_t l_min_size = 0;
+ uint64_t l_ocmb_size = 0;
+
+ // Get the ocmbs attached to this MCC
+ auto l_omis = i_target.getChildren<fapi2::TARGET_TYPE_OMI>();
+ FAPI_DBG("Found %d omi children for MCC", l_omis.size());
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_target, iv_unitPos),
+ "Error getting OMI ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // There could be up to 2 OMI/OCMB's per channel
+ for (auto l_omi : l_omis)
+ {
+ // Get the OMI unit position - this should match the OCMB position.
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_omi, l_omi_pos),
+ "Error getting OMI ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Get attached ocmb
+ auto l_ocmbs = l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>();
+ FAPI_DBG("Found %d OCMBs attached", l_ocmbs.size());
+
+ if (l_ocmbs.size() > 0)
+ {
+ // Get the amount of memory behind this OCMB
+ FAPI_TRY(mss::eff_memory_size<mss::mc_type::EXPLORER>(l_ocmbs[0], l_ocmb_size),
+ "Error returned from eff_memory_size - ocmb, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ FAPI_DBG("OMI size: %llx", l_ocmb_size);
+
+ if (l_ocmb_size > 0)
+ {
+ if (l_min_size != 0)
+ {
+ if (l_min_size != l_ocmb_size)
+ {
+ l_min_size = (l_min_size > l_ocmb_size) ? l_ocmb_size : l_min_size;
+ FAPI_DBG("Sub-channels for MCC %d have different size. Limiting to the smallest: %lld",
+ iv_unitPos, l_min_size)
+ }
+ }
+ else
+ {
+ l_min_size = l_ocmb_size;
+ }
+
+ iv_ocmbs.push_back(l_ocmbs.front());
+ iv_omi_pos.push_back(l_omi_pos);
+ }
+ }
+ }
+
+ iv_dimmSize = (iv_ocmbs.size() * l_min_size);
+
+ // Display this OMI's attribute info
+ FAPI_INF("EffGroupingMccAttrs::getAttrs: MCC %d, OCMBs attached %d, "
+ "iv_dimmSize %d GB ",
+ iv_unitPos, iv_ocmbs.size(), iv_dimmSize);
+
+fapi_try_exit:
+ FAPI_DBG("Exiting EffGroupingMccAttrs::getAttrs");
+ return fapi2::current_err;
+}
+
+
+///----------------------------------------------------------------------------
/// struct EffGroupingMemInfo
///----------------------------------------------------------------------------
///
@@ -704,12 +829,61 @@ fapi_try_exit:
/// ----------------------------------------------------------------
/// Total 4 8
///
+///
+/// Axone - 4 MIs total, each MI has 2 MCCs (MC ports/channels).
+/// Each channel has two OMI sub-channels that may be
+/// connected to an OCMB.
+/// Each Explorer ocmb supports up to 2 DIMMs.
+/// If both sub-channels have memory connected, the
+/// same size must be used for both.
+/// Mirroring is done accross sub-channels not
+/// accross channels.
+///
+/// MI0 --> MCC0 --> OMI0 --> OCMB0 --> DIMM0
+/// --> DIMM1
+/// OMI1 --> OCMB1 --> DIMM0
+/// --> DIMM1
+/// MCC1 --> OMI2 --> OCMB2 --> DIMM0
+/// --> DIMM1
+/// OMI3 --> OCMB3 --> DIMM0
+/// --> DIMM1
+///
+/// MI1 --> MCC2 --> OMI4 --> OCMB4 --> DIMM0
+/// --> DIMM1
+/// OMI5 --> OCMB5 --> DIMM0
+/// --> DIMM1
+/// MCC3 --> OMI6 --> OCMB6 --> DIMM0
+/// --> DIMM1
+/// OMI7 --> OCMB7 --> DIMM0
+/// --> DIMM1
+///
+/// MI2 --> MCC4 --> OMI8 --> OCMB8 --> DIMM0
+/// --> DIMM1
+/// OMI9 --> OCMB9 --> DIMM0
+/// --> DIMM1
+/// MCC5 --> OMI10--> OCMB10--> DIMM0
+/// --> DIMM1
+/// OMI11--> OCMB11--> DIMM0
+/// --> DIMM1
+///
+/// MI3 --> MCC6 --> OMI12--> OCMB12--> DIMM0
+/// --> DIMM1
+/// OMI13--> OCMB13--> DIMM0
+/// --> DIMM1
+/// MCC7 --> OMI14--> OCMB14--> DIMM0
+/// --> DIMM1
+/// OMI15--> OCMB15--> DIMM0
+/// --> DIMM1
+/// ----------------------------------------------------------------
+/// Total 4 8
+///
struct EffGroupingMemInfo
{
// Constructor
EffGroupingMemInfo()
{
memset(iv_portSize, 0, sizeof(iv_portSize));
+ memset(iv_SubChannelsEnabled, 0, sizeof(iv_SubChannelsEnabled));
memset(iv_NVdimmType, false, sizeof(iv_NVdimmType));
}
@@ -725,6 +899,8 @@ struct EffGroupingMemInfo
// Mark if this proc is a Nimbus
bool iv_nimbusProc = false;
+ // Mark if this proc uses OMI (Axone)
+ bool iv_omi = false;
// Memory sizes behind MC ports
uint32_t iv_portSize[NUM_MC_PORTS_PER_PROC];
@@ -735,6 +911,9 @@ struct EffGroupingMemInfo
// NVDIMM types behind MC ports
bool iv_NVdimmType[NUM_MC_PORTS_PER_PROC];
+ // Axone sub-channels enabled per port: 00, 10, 01, 11
+ uint8_t iv_SubChannelsEnabled[NUM_MC_PORTS_PER_PROC];
+
};
// See doxygen in struct definition.
@@ -746,14 +925,29 @@ fapi2::ReturnCode EffGroupingMemInfo::getMemInfo (
// Memory info will be filled in differently for Nimbus vs Cumulus
// due to chip structure
- // Get the functional MCAs
+ // Get the functional MCAs (Nimbus)
auto l_mcaChiplets = i_target.getChildren<fapi2::TARGET_TYPE_MCA>();
+ // Get the functional DMIs (Cumulus)
+ auto l_dmiChiplets = i_target.getChildren<fapi2::TARGET_TYPE_DMI>();
+
+ // Get the functional MCCs (Axone)
+ auto l_mccChiplets = i_target.getChildren<fapi2::TARGET_TYPE_MCC>();
+
+
+ fapi2::ATTR_CHIP_EC_FEATURE_OMI_Type l_omi;
+
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MAX_INTERLEAVE_GROUP_SIZE,
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
iv_maxGroupMemSize),
"Error from FAPI_ATTR_GET (ATTR_MAX_INTERLEAVE_GROUP_SIZE)");
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI,
+ i_target,
+ l_omi),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_EC_FEATURE_OMI)");
+ iv_omi = l_omi;
+
FAPI_DBG("iv_maxGroupMemSize: 0x%016lX", iv_maxGroupMemSize);
if (l_mcaChiplets.size() > 0)
@@ -776,36 +970,59 @@ fapi2::ReturnCode EffGroupingMemInfo::getMemInfo (
iv_NVdimmType[l_mcaAttrs.iv_unitPos] = l_mcaAttrs.iv_NVdimmType;
}
}
- else
+ else if (l_dmiChiplets.size() > 0)
{
- auto l_dmiChiplets = i_target.getChildren<fapi2::TARGET_TYPE_DMI>();
+ FAPI_DBG("Number of DMIs found: %d", l_dmiChiplets.size());
- if (l_dmiChiplets.size() > 0)
+ // DMI found, proc is a Cumulus.
+ for (auto l_dmi : l_dmiChiplets)
{
- FAPI_DBG("Number of DMIs found: %d", l_dmiChiplets.size());
+ // Get this DMI attribute info
+ EffGroupingDmiAttrs l_dmiAttrs;
+ FAPI_TRY(l_dmiAttrs.getAttrs(l_dmi),
+ "l_dmiAttrs.getAttrs() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
- // DMI found, proc is a Cumulus.
- for (auto l_dmi : l_dmiChiplets)
- {
- // Get this DMI attribute info
- EffGroupingDmiAttrs l_dmiAttrs;
- FAPI_TRY(l_dmiAttrs.getAttrs(l_dmi),
- "l_dmiAttrs.getAttrs() returns error, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
-
- // Fill in memory info
- iv_portSize[l_dmiAttrs.iv_unitPos] = l_dmiAttrs.iv_dimmSize;
- // No NVDIMM in Cumulus systems (for now)
- iv_NVdimmType[l_dmiAttrs.iv_unitPos] = false;
- }
+ // Fill in memory info
+ iv_portSize[l_dmiAttrs.iv_unitPos] = l_dmiAttrs.iv_dimmSize;
+ // No NVDIMM in Cumulus systems (for now)
+ iv_NVdimmType[l_dmiAttrs.iv_unitPos] = false;
}
- else
+ }
+ else if (l_mccChiplets.size() > 0)
+ {
+ FAPI_DBG("Number of MCCs found: %d", l_mccChiplets.size());
+
+ for (auto l_mcc : l_mccChiplets)
{
- // Note: You may have none of DMI nor MCA but it's a valid state;
- // therefore don't flag an error
- FAPI_INF("No MCA or DMI found in this proc target");
+ // Get this MCC attribute info
+ EffGroupingMccAttrs l_mccAttrs;
+ FAPI_TRY(l_mccAttrs.getAttrs(l_mcc),
+ "l_mccAttrs.getAttrs() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Fill in memory info
+ iv_portSize[l_mccAttrs.iv_unitPos] = l_mccAttrs.iv_dimmSize;
+
+ for (auto l_omi_pos : l_mccAttrs.iv_omi_pos)
+ {
+ iv_SubChannelsEnabled[l_mccAttrs.iv_unitPos] |=
+ (OMISubChannelConfig::A >> (l_omi_pos % SUBCHANNEL_PER_CHANNEL));
+ FAPI_DBG("OMI: l_omi_pos = %d iv_SubChannelsEnabled[%d] = %llx",
+ l_omi_pos, l_mccAttrs.iv_unitPos, iv_SubChannelsEnabled[l_mccAttrs.iv_unitPos])
+ }
+
+ // No NVDIMM in Axone systems (for now - At some point we may have storage class memory)
+ iv_NVdimmType[l_mccAttrs.iv_unitPos] = false;
}
}
+ else
+ {
+ // Note: You may have none of DMI, MCC nor MCA but it's a valid state;
+ // therefore don't flag an error
+ FAPI_INF("No MCA, DMI, or MCC found in this proc target");
+ }
+
// Display amount of memory for each MC port
for (uint8_t ii = 0; ii < NUM_MC_PORTS_PER_PROC; ii++)
@@ -837,6 +1054,11 @@ struct EffGroupingData
{
iv_portGrouped[l_port] = false;
}
+
+ for (uint8_t l_grp = 0; l_grp < DATA_GROUPS / 2; l_grp++)
+ {
+ iv_OMIMirrorable[l_grp] = false;
+ }
}
// The ATTR_MSS_MCS_GROUP_32 attribute
@@ -854,6 +1076,12 @@ struct EffGroupingData
// Indicates if mirror group is to be created
// from data of this non-mirror group
uint8_t iv_mirrorOn[DATA_GROUPS / 2];
+
+ // Indicates if we have OMI type memory
+ bool iv_omi = false;
+ // Indicates if all sub-channels in the groups are full
+ // and therefore mirrorable
+ bool iv_OMIMirrorable[DATA_GROUPS / 2];
};
@@ -971,16 +1199,26 @@ struct EffGroupingBaseSizeData
const EffGroupingSysAttrs& i_sysAttrs,
EffGroupingData& io_groupData);
+ ///
+ /// @brief getNumMirrorRegions
+ /// Return the number of mirrored memory regions there are for this chip
+ ///
+ /// @return the number of mirrored memory regions
+ uint64_t getNumMirrorRegions()
+ {
+ return iv_omi ? NUM_MIRROR_REGIONS_OMI : NUM_MIRROR_REGIONS;
+ }
+
// Public data
uint64_t iv_mem_bases[NUM_NON_MIRROR_REGIONS];
uint64_t iv_mem_bases_ack[NUM_NON_MIRROR_REGIONS];
uint64_t iv_memory_sizes[NUM_NON_MIRROR_REGIONS];
uint64_t iv_memory_sizes_ack[NUM_NON_MIRROR_REGIONS];
- uint64_t iv_mirror_bases[NUM_MIRROR_REGIONS];
- uint64_t iv_mirror_bases_ack[NUM_MIRROR_REGIONS];
- uint64_t iv_mirror_sizes[NUM_MIRROR_REGIONS];
- uint64_t iv_mirror_sizes_ack[NUM_MIRROR_REGIONS];
+ uint64_t iv_mirror_bases[NUM_MIRROR_REGIONS_MAX];
+ uint64_t iv_mirror_bases_ack[NUM_MIRROR_REGIONS_MAX];
+ uint64_t iv_mirror_sizes[NUM_MIRROR_REGIONS_MAX];
+ uint64_t iv_mirror_sizes_ack[NUM_MIRROR_REGIONS_MAX];
uint64_t iv_smf_bar_base = 0;
uint64_t iv_occ_sandbox_base = 0;
@@ -989,6 +1227,7 @@ struct EffGroupingBaseSizeData
// Num of HTM queues to be reserved for each port
uint8_t iv_numHtmQueues[NUM_MC_PORTS_PER_PROC];
+ bool iv_omi = false;
};
// See description in struct definition
@@ -1035,10 +1274,14 @@ void EffGroupingBaseSizeData::setBaseSizeData(
// Process mirrored ranges
if (i_sysAttrs.iv_hwMirrorEnabled != fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_FALSE)
{
- for (uint8_t ii = 0; ii < NUM_MIRROR_REGIONS; ii++)
+ FAPI_DBG("Mirror enabled. Setting values.");
+
+ for (uint8_t ii = 0; ii < getNumMirrorRegions(); ii++)
{
uint8_t l_index = ii + MIRR_OFFSET;
+ FAPI_DBG("Mirror enabled. Ports in group %d", i_groupData.iv_data[l_index][PORTS_IN_GROUP]);
+
if (i_groupData.iv_data[l_index][PORTS_IN_GROUP] != 0)
{
// Set base address for distinct mirrored ranges
@@ -1103,7 +1346,7 @@ uint8_t EffGroupingBaseSizeData::getMemoryRegionIndex(
fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_FLIPPED)
{
l_memSizePtr = &iv_mirror_sizes[0] ;
- l_numRegions = NUM_MIRROR_REGIONS;
+ l_numRegions = getNumMirrorRegions();
l_startBaseAddr = iv_mirror_bases[0];
}
@@ -1242,7 +1485,7 @@ fapi2::ReturnCode EffGroupingBaseSizeData::set_HTM_OCC_base_addr(
}
else // Flipped
{
- l_numRegions = NUM_MIRROR_REGIONS;
+ l_numRegions = getNumMirrorRegions();
memcpy(l_mem_bases, iv_mirror_bases, sizeof(iv_mirror_bases));
memcpy(l_mem_sizes, iv_mirror_sizes, sizeof(iv_mirror_sizes));
}
@@ -1463,7 +1706,7 @@ fapi2::ReturnCode EffGroupingBaseSizeData::setSMFBaseSizeData(
}
else // Flipped
{
- l_numRegions = NUM_MIRROR_REGIONS;
+ l_numRegions = getNumMirrorRegions();
memcpy(l_mem_bases, iv_mirror_bases, sizeof(iv_mirror_bases));
memcpy(l_mem_sizes, iv_mirror_sizes, sizeof(iv_mirror_sizes));
}
@@ -1739,26 +1982,26 @@ fapi2::ReturnCode EffGroupingBaseSizeData::setBaseSizeAttr(
// Display mirror mode attribute values
if (i_sysAttrs.iv_hwMirrorEnabled != fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_FALSE)
{
- for (uint8_t ii = 0; ii < NUM_MIRROR_REGIONS; ii++)
+ for (uint8_t ii = 0; ii < getNumMirrorRegions(); ii++)
{
FAPI_INF("ATTR_PROC_MIRROR_BASES[%u]: 0x%.16llX (%d GB)",
ii, iv_mirror_bases[ii], iv_mirror_bases[ii] >> 30);
}
- for (uint8_t ii = 0; ii < NUM_MIRROR_REGIONS; ii++)
+ for (uint8_t ii = 0; ii < getNumMirrorRegions(); ii++)
{
FAPI_INF("ATTR_PROC_MIRROR_BASES_ACK[%u] "
"0x%.16llX (%d GB)",
ii, iv_mirror_bases_ack[ii], iv_mirror_bases_ack[ii] >> 30);
}
- for (uint8_t ii = 0; ii < NUM_MIRROR_REGIONS; ii++)
+ for (uint8_t ii = 0; ii < getNumMirrorRegions(); ii++)
{
FAPI_INF("ATTR_PROC_MIRROR_SIZES[%u]: 0x%.16llX (%d GB)",
ii, iv_mirror_sizes[ii], iv_mirror_sizes[ii] >> 30);
}
- for (uint8_t ii = 0; ii < NUM_MIRROR_REGIONS; ii++)
+ for (uint8_t ii = 0; ii < getNumMirrorRegions(); ii++)
{
FAPI_INF("ATTR_PROC_MIRROR_SIZES_ACK[%u]: 0x%.16llX (%d GB)",
ii, iv_mirror_sizes_ack[ii], iv_mirror_sizes_ack[ii] >> 30);
@@ -1850,9 +2093,10 @@ fapi_try_exit:
/// @param[out] o_groupData Reference to output data
///
void grouping_group8PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
- EffGroupingData& o_groupData)
+ EffGroupingData& o_groupData,
+ const bool& i_mirrorRequired)
{
- // There are 8 MC ports (MCA/DMI) in a proc (Nimbus/Cumulus) and they can
+ // There are 8 MC ports (MCA/DMI/MCC) in a proc (Nimbus/Cumulus/Axone) and they can
// be grouped together if they all have the same memory size per ports
// and there is no mix of NVDIMM/RDIMM between ports.
FAPI_DBG("Entering");
@@ -1868,6 +2112,8 @@ void grouping_group8PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
for (uint8_t l_pos = 1; l_pos < NUM_MC_PORTS_PER_PROC; l_pos++)
{
if ( (i_memInfo.iv_portSize[0] != i_memInfo.iv_portSize[l_pos]) ||
+ (i_mirrorRequired && ((i_memInfo.iv_SubChannelsEnabled[0] == OMISubChannelConfig::BOTH) !=
+ (i_memInfo.iv_SubChannelsEnabled[l_pos] == OMISubChannelConfig::BOTH))) ||
(i_memInfo.iv_NVdimmType[0] != i_memInfo.iv_NVdimmType[l_pos]) )
{
// This port does not have the same memory size as port 0, or
@@ -1876,6 +2122,8 @@ void grouping_group8PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
FAPI_DBG("Can not group by 8: ");
FAPI_DBG(" i_memInfo.iv_portSize[0] = %d GB, i_memInfo.iv_portSize[%d] = %d GB",
i_memInfo.iv_portSize[0], l_pos, i_memInfo.iv_portSize[l_pos]);
+ FAPI_DBG(" mirrorReq = %d i_memInfo.iv_SubChannelsEnabled[0] = %d, i_memInfo.iv_SubChannelsEnabled[%d] = %d",
+ i_mirrorRequired, i_memInfo.iv_SubChannelsEnabled[0], l_pos, i_memInfo.iv_SubChannelsEnabled[l_pos]);
FAPI_DBG(" i_memInfo.iv_NVdimmType[0] = %d, i_memInfo.iv_NVdimmType[%d] = %d",
i_memInfo.iv_NVdimmType[0], l_pos, i_memInfo.iv_NVdimmType[l_pos]);
grouped = false;
@@ -1902,9 +2150,17 @@ void grouping_group8PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
g++; // increase o_groupData.iv_numGroups
// Record which MC ports were grouped
+ // Check if OMI mirrorable
+ o_groupData.iv_OMIMirrorable[g] = o_groupData.iv_omi;
+
for (uint8_t ii = 0; ii < NUM_MC_PORTS_PER_PROC; ii++)
{
o_groupData.iv_portGrouped[ii] = true;
+
+ if (o_groupData.iv_OMIMirrorable[g] && i_memInfo.iv_SubChannelsEnabled[ii] != OMISubChannelConfig::BOTH)
+ {
+ o_groupData.iv_OMIMirrorable[g] = false;
+ }
}
FAPI_INF("grouping_group8PortsPerGroup: Successfully grouped 8 "
@@ -1931,7 +2187,8 @@ void grouping_group8PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
/// @param[out] o_groupData Reference to output data
///
void grouping_group6PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
- EffGroupingData& o_groupData)
+ EffGroupingData& o_groupData,
+ const bool& i_mirrorRequired)
{
FAPI_DBG("Entering");
@@ -1979,6 +2236,8 @@ void grouping_group6PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
if ( (o_groupData.iv_portGrouped[CFG_6MCPORT[ii][jj]]) ||
(i_memInfo.iv_portSize[CFG_6MCPORT[ii][0]] !=
i_memInfo.iv_portSize[CFG_6MCPORT[ii][jj]]) ||
+ (i_mirrorRequired && ((i_memInfo.iv_SubChannelsEnabled[CFG_6MCPORT[ii][0]] == OMISubChannelConfig::BOTH) !=
+ (i_memInfo.iv_SubChannelsEnabled[CFG_6MCPORT[ii][jj]] == OMISubChannelConfig::BOTH))) ||
(i_memInfo.iv_NVdimmType[CFG_6MCPORT[ii][0]] !=
i_memInfo.iv_NVdimmType[CFG_6MCPORT[ii][jj]]) )
{
@@ -1993,6 +2252,11 @@ void grouping_group6PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
ii, i_memInfo.iv_portSize[CFG_6MCPORT[ii][0]]);
FAPI_DBG(" i_memInfo.iv_portSize[CFG_6MCPORT[%d][%d]] = %d GB",
ii, jj, i_memInfo.iv_portSize[CFG_6MCPORT[ii][jj]]);
+ // Display subchannels of first port vs port jj in row
+ FAPI_DBG(" i_mirrorReq = %d i_memInfo.iv_SubChannelsEnabled[CFG_6MCPORT[%d][0]] = %d",
+ i_mirrorRequired, ii, i_memInfo.iv_SubChannelsEnabled[CFG_6MCPORT[ii][0]]);
+ FAPI_DBG(" i_memInfo.iv_SubChannelsEnabled[CFG_6MCPORT[%d][%d]] = %d",
+ ii, jj, i_memInfo.iv_SubChannelsEnabled[CFG_6MCPORT[ii][jj]]);
// Display DIMM type of first port vs port jj in row
FAPI_DBG(" i_memInfo.iv_NVdimmType[CFG_6MCPORT[%d][0]] = %d",
ii, i_memInfo.iv_NVdimmType[CFG_6MCPORT[ii][0]]);
@@ -2015,10 +2279,19 @@ void grouping_group6PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
PORTS_PER_GROUP * i_memInfo.iv_portSize[CFG_6MCPORT[ii][0]];
// Record which MC ports were grouped
+ // Check if OMI mirrorable
+ o_groupData.iv_OMIMirrorable[g] = o_groupData.iv_omi;
+
for (uint8_t jj = 0; jj < PORTS_PER_GROUP; jj++)
{
o_groupData.iv_data[g][MEMBER_IDX(jj)] = CFG_6MCPORT[ii][jj];
o_groupData.iv_portGrouped[CFG_6MCPORT[ii][jj]] = true;
+
+ if (o_groupData.iv_OMIMirrorable[g]
+ && i_memInfo.iv_SubChannelsEnabled[CFG_6MCPORT[ii][jj]] != OMISubChannelConfig::BOTH)
+ {
+ o_groupData.iv_OMIMirrorable[g] = false;
+ }
}
g++;
@@ -2051,7 +2324,8 @@ void grouping_group6PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
/// @param[out] o_groupData Reference to output data
///
void grouping_group4PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
- EffGroupingData& o_groupData)
+ EffGroupingData& o_groupData,
+ const bool& i_mirrorRequired)
{
FAPI_DBG("Entering");
@@ -2108,6 +2382,8 @@ void grouping_group4PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
if ( (o_groupData.iv_portGrouped[CFG_4MCPORT[ii][jj]]) ||
(i_memInfo.iv_portSize[CFG_4MCPORT[ii][0]] !=
i_memInfo.iv_portSize[CFG_4MCPORT[ii][jj]]) ||
+ (i_mirrorRequired && ((i_memInfo.iv_SubChannelsEnabled[CFG_4MCPORT[ii][0]] == OMISubChannelConfig::BOTH) !=
+ (i_memInfo.iv_SubChannelsEnabled[CFG_4MCPORT[ii][jj]] == OMISubChannelConfig::BOTH))) ||
(i_memInfo.iv_NVdimmType[CFG_4MCPORT[ii][0]] !=
i_memInfo.iv_NVdimmType[CFG_4MCPORT[ii][jj]]) )
{
@@ -2122,6 +2398,11 @@ void grouping_group4PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
ii, i_memInfo.iv_portSize[CFG_4MCPORT[ii][0]]);
FAPI_DBG(" i_memInfo.iv_portSize[CFG_4MCPORT[%d][%d]] = %d GB",
ii, jj, i_memInfo.iv_portSize[CFG_4MCPORT[ii][jj]]);
+ // Display subchannels of first port vs port jj in row
+ FAPI_DBG(" i_mirrorReq = %d i_memInfo.iv_SubChannelsEnabled[CFG_4MCPORT[%d][0]] = %d",
+ i_mirrorRequired, ii, i_memInfo.iv_SubChannelsEnabled[CFG_4MCPORT[ii][0]]);
+ FAPI_DBG(" i_memInfo.iv_SubChannelsEnabled[CFG_4MCPORT[%d][%d]] = %d",
+ ii, jj, i_memInfo.iv_SubChannelsEnabled[CFG_4MCPORT[ii][jj]]);
// Display DIMM type of first port vs port jj in row
FAPI_DBG(" i_memInfo.iv_NVdimmType[CFG_4MCPORT[%d][0]] = %d",
ii, i_memInfo.iv_NVdimmType[CFG_4MCPORT[ii][0]]);
@@ -2184,14 +2465,24 @@ void grouping_group4PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
o_groupData.iv_data[g][MEMBER_IDX(1)] = CFG_4MCPORT[gp1][2];
o_groupData.iv_data[g][MEMBER_IDX(2)] = CFG_4MCPORT[gp1][1];
o_groupData.iv_data[g][MEMBER_IDX(3)] = CFG_4MCPORT[gp1][3];
- g++;
// Record which MC ports were grouped
+ // Check if OMI mirrorable
+ o_groupData.iv_OMIMirrorable[g] = o_groupData.iv_omi;
+
for (uint8_t ii = 0; ii < PORTS_PER_GROUP; ii++)
{
o_groupData.iv_portGrouped[CFG_4MCPORT[gp1][ii]] = true;
+
+ if (o_groupData.iv_OMIMirrorable[g] &&
+ i_memInfo.iv_SubChannelsEnabled[CFG_4MCPORT[gp1][ii]] != OMISubChannelConfig::BOTH)
+ {
+ o_groupData.iv_OMIMirrorable[g] = false;
+ }
}
+ g++;
+
FAPI_INF("grouping_group4PortsPerGroup: Successfully grouped 4 "
"MC ports. CFG_4MCPORT[%d] %u, %u, %u, %u", gp1,
CFG_4MCPORT[gp1][0], CFG_4MCPORT[gp1][1],
@@ -2210,14 +2501,24 @@ void grouping_group4PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
o_groupData.iv_data[g][MEMBER_IDX(1)] = CFG_4MCPORT[gp2][2];
o_groupData.iv_data[g][MEMBER_IDX(2)] = CFG_4MCPORT[gp2][1];
o_groupData.iv_data[g][MEMBER_IDX(3)] = CFG_4MCPORT[gp2][3];
- g++;
// Record which MC ports were grouped
+ // Check if OMI mirrorable
+ o_groupData.iv_OMIMirrorable[g] = o_groupData.iv_omi;
+
for (uint8_t ii = 0; ii < PORTS_PER_GROUP; ii++)
{
o_groupData.iv_portGrouped[CFG_4MCPORT[gp2][ii]] = true;
+
+ if (o_groupData.iv_OMIMirrorable[g] &&
+ i_memInfo.iv_SubChannelsEnabled[CFG_4MCPORT[gp2][ii]] != OMISubChannelConfig::BOTH)
+ {
+ o_groupData.iv_OMIMirrorable[g] = false;
+ }
}
+ g++;
+
FAPI_INF("grouping_group4PortsPerGroup: Successfully grouped 4 "
"MC ports. CFG_4MCPORT[%d] %u, %u, %u, %u", gp2,
CFG_4MCPORT[gp2][0], CFG_4MCPORT[gp2][1],
@@ -2239,11 +2540,13 @@ void grouping_group4PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
/// - iv_portGrouped[<group>]
/// - iv_numGroups
///
-/// @param[in] i_memInfo Reference to EffGroupingMemInfo structure
-/// @param[out] o_groupData Reference to output data
+/// @param[in] i_memInfo Reference to EffGroupingMemInfo structure
+/// @param[out] o_groupData Reference to output data
+/// @param[in] i_mirrorRequired Mirroring is required by the system
///
void grouping_group3PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
- EffGroupingData& o_groupData)
+ EffGroupingData& o_groupData,
+ const bool& i_mirrorRequired)
{
FAPI_DBG("Entering");
@@ -2325,8 +2628,10 @@ void grouping_group3PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
// Skip if this port is already grouped or has different
// amount of memory or dimm type
if ( (o_groupData.iv_portGrouped[CFG_3MCPORT[ii][jj]]) ||
- (i_memInfo.iv_portSize[CFG_3MCPORT[ii][0]] !=
- i_memInfo.iv_portSize[CFG_3MCPORT[ii][jj]]) ||
+ (i_memInfo.iv_portSize[CFG_3MCPORT[ii][0]] != i_memInfo.iv_portSize[CFG_3MCPORT[ii][jj]]) ||
+ (i_mirrorRequired && ((i_memInfo.iv_SubChannelsEnabled[CFG_3MCPORT[ii][0]] == OMISubChannelConfig::BOTH) !=
+ (i_memInfo.iv_SubChannelsEnabled[CFG_3MCPORT[ii][jj]] == OMISubChannelConfig::BOTH))
+ ) ||
(i_memInfo.iv_NVdimmType[CFG_3MCPORT[ii][0]] !=
i_memInfo.iv_NVdimmType[CFG_3MCPORT[ii][jj]]) )
{
@@ -2365,6 +2670,10 @@ void grouping_group3PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
ii, i_memInfo.iv_portSize[CFG_3MCPORT[ii][0]]);
FAPI_DBG(" i_memInfo.iv_portSize[CFG_3MCPORT[%d][%d]] = %d GB",
ii, jj, i_memInfo.iv_portSize[CFG_3MCPORT[ii][jj]]);
+ FAPI_DBG(" i_mirrorReq = %d i_memInfo.iv_SubChannelsEnabled[CFG_3MCPORT[%d][0]] = %d",
+ i_mirrorRequired, ii, i_memInfo.iv_SubChannelsEnabled[CFG_3MCPORT[ii][0]]);
+ FAPI_DBG(" i_memInfo.iv_SubChannelsEnabled[CFG_3MCPORT[%d][%d]] = %d",
+ ii, jj, i_memInfo.iv_SubChannelsEnabled[CFG_3MCPORT[ii][jj]]);
FAPI_DBG(" i_memInfo.iv_NVdimmType[CFG_3MCPORT[%d][0]] = %d",
ii, i_memInfo.iv_NVdimmType[CFG_3MCPORT[ii][0]]);
FAPI_DBG(" i_memInfo.iv_NVdimmType[CFG_3MCPORT[%d][%d]] = %d",
@@ -2380,14 +2689,24 @@ void grouping_group3PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
o_groupData.iv_data[g][MEMBER_IDX(0)] = CFG_3MCPORT[ii][0];
o_groupData.iv_data[g][MEMBER_IDX(1)] = CFG_3MCPORT[ii][1];
o_groupData.iv_data[g][MEMBER_IDX(2)] = CFG_3MCPORT[ii][2];
- g++;
- // Record which MC ports were grouped
+ // Record which MC ports were grouped,
+ // Check if OMI mirrorable
+ o_groupData.iv_OMIMirrorable[g] = o_groupData.iv_omi;
+
for (uint8_t jj = 0; jj < PORTS_PER_GROUP; jj++)
{
o_groupData.iv_portGrouped[CFG_3MCPORT[ii][jj]] = true;
+
+ if (o_groupData.iv_OMIMirrorable[g] &&
+ i_memInfo.iv_SubChannelsEnabled[CFG_3MCPORT[ii][jj]] != OMISubChannelConfig::BOTH)
+ {
+ o_groupData.iv_OMIMirrorable[g] = false;
+ }
}
+ g++;
+
FAPI_INF("grouping_group3PortsPerGroup: Successfully grouped 3 "
"MC ports. CFG_3MCPORT[%d] %u, %u, %u, %u", ii,
CFG_3MCPORT[ii][0], CFG_3MCPORT[ii][1],
@@ -2418,7 +2737,8 @@ void grouping_group3PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
/// @param[out] o_groupData Reference to output data
///
void grouping_2ports_same_MCS(const EffGroupingMemInfo& i_memInfo,
- EffGroupingData& o_groupData)
+ EffGroupingData& o_groupData,
+ const bool i_mirrorRequired)
{
FAPI_DBG("Entering");
FAPI_INF("grouping_2ports_same_MCS: Attempting to group 2 ports on same MCS");
@@ -2440,6 +2760,8 @@ void grouping_2ports_same_MCS(const EffGroupingMemInfo& i_memInfo,
// Check 2nd port
if ( (o_groupData.iv_portGrouped[pos + 1]) ||
(i_memInfo.iv_portSize[pos + 1] != i_memInfo.iv_portSize[pos]) ||
+ (i_mirrorRequired && ((i_memInfo.iv_SubChannelsEnabled[pos + 1] == OMISubChannelConfig::BOTH) !=
+ (i_memInfo.iv_SubChannelsEnabled[pos] == OMISubChannelConfig::BOTH))) ||
(i_memInfo.iv_NVdimmType[pos + 1] != i_memInfo.iv_NVdimmType[pos]) )
{
FAPI_DBG("Port %u already grouped or has different memory size/type, skip",
@@ -2449,6 +2771,9 @@ void grouping_2ports_same_MCS(const EffGroupingMemInfo& i_memInfo,
FAPI_DBG(" i_memInfo.iv_portSize[%d] = %d GB; i_memInfo.iv_portSize[%d] = %d GB",
pos, i_memInfo.iv_portSize[pos],
pos + 1, i_memInfo.iv_portSize[pos + 1]);
+ FAPI_DBG(" i_mirrorReq = %d i_memInfo.iv_SubChannelsEnabled[%d] = %d; i_memInfo.iv_SubChannelsEnabled[%d] = %d",
+ i_mirrorRequired, pos, i_memInfo.iv_portSize[pos],
+ pos + 1, i_memInfo.iv_portSize[pos + 1]);
FAPI_DBG(" i_memInfo.iv_NVdimmType[%d] = %d; i_memInfo.iv_NVdimmType[%d] = %d",
pos, i_memInfo.iv_NVdimmType[pos],
pos + 1, i_memInfo.iv_NVdimmType[pos + 1]);
@@ -2470,12 +2795,21 @@ void grouping_2ports_same_MCS(const EffGroupingMemInfo& i_memInfo,
PORTS_PER_GROUP * i_memInfo.iv_portSize[pos];
o_groupData.iv_data[g][MEMBER_IDX(0)] = pos;
o_groupData.iv_data[g][MEMBER_IDX(1)] = pos + 1;
- g++;
// Record which MC ports were grouped
o_groupData.iv_portGrouped[pos] = true;
o_groupData.iv_portGrouped[pos + 1] = true;
+ o_groupData.iv_OMIMirrorable[g] = o_groupData.iv_omi;
+
+ if (i_memInfo.iv_SubChannelsEnabled[pos] != OMISubChannelConfig::BOTH ||
+ i_memInfo.iv_SubChannelsEnabled[pos + 1] != OMISubChannelConfig::BOTH)
+ {
+ o_groupData.iv_OMIMirrorable[g] = false;
+ }
+
+ g++;
+
FAPI_INF("grouping_2ports_same_MCS: Successfully grouped "
"MC ports: %u, %u", pos, pos + 1);
}
@@ -2503,7 +2837,8 @@ void grouping_2ports_same_MCS(const EffGroupingMemInfo& i_memInfo,
/// @param[out] o_groupData Reference to output data
///
void grouping_2groupsOf2_cross_MCS(const EffGroupingMemInfo& i_memInfo,
- EffGroupingData& o_groupData)
+ EffGroupingData& o_groupData,
+ const bool& i_mirrorRequired)
{
FAPI_DBG("Entering");
FAPI_INF("grouping_2groupsOf2_cross_MCS: Attempting to group 2 groups of 2 on cross-MCS");
@@ -2570,6 +2905,8 @@ void grouping_2groupsOf2_cross_MCS(const EffGroupingMemInfo& i_memInfo,
if ( (i_memInfo.iv_portSize[mcs1pos0] == i_memInfo.iv_portSize[mcs2pos0]) &&
(i_memInfo.iv_NVdimmType[mcs1pos0] == i_memInfo.iv_NVdimmType[mcs2pos0]) &&
+ ((!i_mirrorRequired) || ((i_memInfo.iv_SubChannelsEnabled[mcs1pos0] == OMISubChannelConfig::BOTH) ==
+ (i_memInfo.iv_SubChannelsEnabled[mcs2pos0] == OMISubChannelConfig::BOTH))) &&
(i_memInfo.iv_portSize[mcs1pos0 + 1] == i_memInfo.iv_portSize[mcs2pos0 + 1]) &&
(i_memInfo.iv_NVdimmType[mcs1pos0 + 1] == i_memInfo.iv_NVdimmType[mcs2pos0 + 1]) )
{
@@ -2581,6 +2918,8 @@ void grouping_2groupsOf2_cross_MCS(const EffGroupingMemInfo& i_memInfo,
}
else if ( (i_memInfo.iv_portSize[mcs1pos0] == i_memInfo.iv_portSize[mcs2pos0 + 1]) &&
(i_memInfo.iv_NVdimmType[mcs1pos0] == i_memInfo.iv_NVdimmType[mcs2pos0 + 1]) &&
+ ((!i_mirrorRequired) || ((i_memInfo.iv_SubChannelsEnabled[mcs1pos0] == OMISubChannelConfig::BOTH) ==
+ (i_memInfo.iv_SubChannelsEnabled[mcs2pos0 + 1] == OMISubChannelConfig::BOTH))) &&
(i_memInfo.iv_portSize[mcs1pos0 + 1] == i_memInfo.iv_portSize[mcs2pos0]) &&
(i_memInfo.iv_NVdimmType[mcs1pos0 + 1] == i_memInfo.iv_NVdimmType[mcs2pos0]) )
{
@@ -2624,11 +2963,23 @@ void grouping_2groupsOf2_cross_MCS(const EffGroupingMemInfo& i_memInfo,
o_groupData.iv_portGrouped[l_twoGroupOf2[1][0]] = true;
o_groupData.iv_portGrouped[l_twoGroupOf2[1][1]] = true;
+ // See if OMI mirrorable
+ o_groupData.iv_OMIMirrorable[g] = o_groupData.iv_omi;
+
+ if (i_memInfo.iv_SubChannelsEnabled[l_twoGroupOf2[0][0]] != OMISubChannelConfig::BOTH ||
+ i_memInfo.iv_SubChannelsEnabled[l_twoGroupOf2[0][1]] != OMISubChannelConfig::BOTH ||
+ i_memInfo.iv_SubChannelsEnabled[l_twoGroupOf2[1][0]] != OMISubChannelConfig::BOTH ||
+ i_memInfo.iv_SubChannelsEnabled[l_twoGroupOf2[1][1]] != OMISubChannelConfig::BOTH)
+ {
+ o_groupData.iv_OMIMirrorable[g] = false;
+ }
+
FAPI_INF("grouping_2groupsOf2_cross_MCS: Successfully grouped "
"2 groups of 2 from MCS %u and %u", mcs1, mcs2);
FAPI_INF(" Group: Ports %u and %u; Group: ports %u and %u",
l_twoGroupOf2[0][0], l_twoGroupOf2[0][1],
l_twoGroupOf2[1][0], l_twoGroupOf2[1][1]);
+
// Break out of mcs2 loop
break;
}
@@ -2651,12 +3002,12 @@ void grouping_2groupsOf2_cross_MCS(const EffGroupingMemInfo& i_memInfo,
///
/// @param[in] i_memInfo Reference to EffGroupingMemInfo structure
/// @param[out] o_groupData Reference to output data
-/// @param[in] i_disallow_cross_mcs Disallow grouping of ports which are not
+/// @param[in] i_mirrorRequired Mirroring required, and disallow grouping of ports which are not
/// in the same MCS
///
void grouping_group2PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
EffGroupingData& o_groupData,
- const bool& i_disallow_cross_mcs)
+ const bool& i_mirrorRequired)
{
FAPI_DBG("Entering");
FAPI_INF("grouping_group2PortsPerGroup: Attempting to group 2 MC ports");
@@ -2665,16 +3016,16 @@ void grouping_group2PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
uint8_t l_otherPort = 0;
// 1. Try to group 2 ports that are in the same MCS (highest priority)
- grouping_2ports_same_MCS(i_memInfo, o_groupData);
+ grouping_2ports_same_MCS(i_memInfo, o_groupData, i_mirrorRequired);
// do not permit cross-MCS grouping
- if (i_disallow_cross_mcs)
+ if (i_mirrorRequired)
{
goto fapi_try_exit;
}
// 2. Try two groups of 2 on cross-MCS
- grouping_2groupsOf2_cross_MCS(i_memInfo, o_groupData);
+ grouping_2groupsOf2_cross_MCS(i_memInfo, o_groupData, i_mirrorRequired);
// 3. Attempt group of 2 for the remaining un-grouped ports (cross-MCS)
FAPI_INF("Attempting to group the remaining ports as group of 2");
@@ -2734,7 +3085,9 @@ void grouping_group2PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
// Can not group if this port already grouped or has different memory size
if ( (o_groupData.iv_portGrouped[ii]) ||
- (i_memInfo.iv_portSize[ii] != i_memInfo.iv_portSize[pos]) )
+ (i_memInfo.iv_portSize[ii] != i_memInfo.iv_portSize[pos]) ||
+ (i_mirrorRequired && ((i_memInfo.iv_SubChannelsEnabled[ii] == OMISubChannelConfig::BOTH) !=
+ (i_memInfo.iv_SubChannelsEnabled[pos] == OMISubChannelConfig::BOTH)) ))
{
FAPI_DBG("Skip port %u, it's already grouped or memsize is not equal", ii);
continue;
@@ -2764,12 +3117,21 @@ void grouping_group2PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
PORTS_PER_GROUP * i_memInfo.iv_portSize[pos];
o_groupData.iv_data[g][MEMBER_IDX(0)] = pos;
o_groupData.iv_data[g][MEMBER_IDX(1)] = ii;
- g++;
+ // See if OMI Mirrable
+ o_groupData.iv_OMIMirrorable[g] = o_groupData.iv_omi;
+
+ if (i_memInfo.iv_SubChannelsEnabled[pos] != OMISubChannelConfig::BOTH ||
+ i_memInfo.iv_SubChannelsEnabled[ii] != OMISubChannelConfig::BOTH)
+ {
+ o_groupData.iv_OMIMirrorable[g] = false;
+ }
// Record which MC ports were grouped
o_groupData.iv_portGrouped[pos] = true;
o_groupData.iv_portGrouped[ii] = true;
+ g++;
+
FAPI_INF("grouping_group2PortsPerGroup: Successfully grouped 2 "
"MC ports: %u, %u", pos, ii);
@@ -2816,6 +3178,9 @@ void grouping_group1PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
o_groupData.iv_data[g][PORTS_IN_GROUP] = 1;
o_groupData.iv_data[g][GROUP_SIZE] = i_memInfo.iv_portSize[pos];
o_groupData.iv_data[g][MEMBER_IDX(0)] = pos;
+ o_groupData.iv_OMIMirrorable[g] = o_groupData.iv_omi &&
+ (i_memInfo.iv_SubChannelsEnabled[pos] == OMISubChannelConfig::BOTH);
+
g++;
// Record which MCS was grouped
@@ -2933,6 +3298,57 @@ void getAttachedDimms(
FAPI_DBG("End");
}
+/// template specialization for OCMB target type
+template <>
+void getAttachedDimms(
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets)
+{
+ FAPI_DBG("Start");
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_dimm_targets =
+ i_target.template getChildren<fapi2::TARGET_TYPE_DIMM>();
+
+ o_dimm_targets.insert(o_dimm_targets.end(),
+ l_dimm_targets.begin(),
+ l_dimm_targets.end());
+ FAPI_DBG("End");
+}
+
+/// template specialization for DMI target type
+template <>
+void getAttachedDimms(
+ const fapi2::Target<fapi2::TARGET_TYPE_OMI>& i_target,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets)
+{
+ FAPI_DBG("Start");
+
+ // determine attached Centaur chip
+ for (auto l_ocmb_target : i_target.template getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>())
+ {
+ // get set of valid MBAs
+ getAttachedDimms<fapi2::TARGET_TYPE_OCMB_CHIP>(l_ocmb_target, o_dimm_targets);
+ }
+
+ FAPI_DBG("End");
+}
+
+/// template specialization for DMI target type
+template <>
+void getAttachedDimms(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCC>& i_target,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets)
+{
+ FAPI_DBG("Start");
+
+ // determine attached Centaur chip
+ for (auto l_omi_target : i_target.template getChildren<fapi2::TARGET_TYPE_OMI>())
+ {
+ getAttachedDimms<fapi2::TARGET_TYPE_OMI>(l_omi_target, o_dimm_targets);
+ }
+
+ FAPI_DBG("End");
+}
+
/// template specialization for DMI target type
template <>
void getAttachedDimms(
@@ -3345,6 +3761,61 @@ fapi_try_exit:
}
+
+/// template specialization for MCC target type
+template<>
+fapi2::ReturnCode calloutDimmsForUngroupedPorts(
+ const uint8_t i_ports_functional[NUM_MC_PORTS_PER_PROC],
+ const uint8_t i_ports_ungrouped[NUM_MC_PORTS_PER_PROC],
+ const uint8_t i_ports_tgt_index[NUM_MC_PORTS_PER_PROC],
+ const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCC>>& i_port_targets,
+ const EffGroupingMemInfo& i_memInfo,
+ const uint8_t i_hwMirrorEnabled,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets,
+ fapi2::ReturnCode& o_rc)
+{
+ FAPI_DBG("Start");
+
+ // o_rc contains the error we're going to append to
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // callout each DIMM which is associated with each ungrouped port
+ for (uint8_t ii = 0; (ii < NUM_MC_PORTS_PER_PROC); ii += 1)
+ {
+ if (i_ports_functional[ii] && i_ports_ungrouped[ii])
+ {
+ getAttachedDimms(i_port_targets[i_ports_tgt_index[ii]],
+ o_dimm_targets);
+ }
+ }
+
+ // add DIMM callouts
+ for (const auto& l_dimm_target : o_dimm_targets)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_MCC> l_port_target = l_dimm_target
+ .getParent<fapi2::TARGET_TYPE_OCMB_CHIP>()
+ .getParent<fapi2::TARGET_TYPE_OMI>()
+ .getParent<fapi2::TARGET_TYPE_MCC>();
+ uint8_t l_port_index = 0;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ l_port_target,
+ l_port_index),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)");
+
+ calloutDIMM(l_dimm_target,
+ l_port_target,
+ l_port_index,
+ i_memInfo.iv_portSize[l_port_index],
+ o_rc);
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
///
/// @brief Finds ungrouped ports
///
@@ -3629,24 +4100,37 @@ void setupMirrorGroup(
// Loop thru groups to see if mirror group is possible
for (uint8_t l_group = 0; l_group < io_groupData.iv_numGroups; l_group++)
{
- // If group of 4, 6, or 8, mirror is allowed
- // Note: For group of 4/6/8, the ports are always in the same MC
- // port pair per design.
- if ( (io_groupData.iv_data[l_group][PORTS_IN_GROUP] == 4) ||
- (io_groupData.iv_data[l_group][PORTS_IN_GROUP] == 6) ||
- (io_groupData.iv_data[l_group][PORTS_IN_GROUP] == 8) )
+ if (io_groupData.iv_omi)
{
- io_groupData.iv_mirrorOn[l_group] = 1;
- }
+ FAPI_DBG("io_groupData.iv_omi: true io_groupData.iv_OMIMirrorable[%d] = %d",
+ l_group, io_groupData.iv_OMIMirrorable[l_group]);
- // For group of 2, determine if both ports are in the same MCS/MI
- else if (io_groupData.iv_data[l_group][PORTS_IN_GROUP] == 2)
+ if (io_groupData.iv_OMIMirrorable[l_group])
+ {
+ io_groupData.iv_mirrorOn[l_group] = 1;
+ }
+ }
+ else
{
- if ( (io_groupData.iv_data[l_group][MEMBER_IDX(0)] / 2) ==
- (io_groupData.iv_data[l_group][MEMBER_IDX(1)] / 2) )
+ // If group of 4, 6, or 8, mirror is allowed
+ // Note: For group of 4/6/8, the ports are always in the same MC
+ // port pair per design.
+ if ( (io_groupData.iv_data[l_group][PORTS_IN_GROUP] == 4) ||
+ (io_groupData.iv_data[l_group][PORTS_IN_GROUP] == 6) ||
+ (io_groupData.iv_data[l_group][PORTS_IN_GROUP] == 8))
{
io_groupData.iv_mirrorOn[l_group] = 1;
}
+
+ // For group of 2, determine if both ports are in the same MCS/MI
+ else if (io_groupData.iv_data[l_group][PORTS_IN_GROUP] == 2)
+ {
+ if ( (io_groupData.iv_data[l_group][MEMBER_IDX(0)] / 2) ==
+ (io_groupData.iv_data[l_group][MEMBER_IDX(1)] / 2) )
+ {
+ io_groupData.iv_mirrorOn[l_group] = 1;
+ }
+ }
}
FAPI_INF("setupMirrorGroup: Group %d, PortsInGroup %d, Mirror = %d",
@@ -3706,6 +4190,7 @@ fapi2::ReturnCode grouping_calcRegions(
if (i_cfgMirror)
{
l_cur_m_base_addr = i_procAttrs.iv_mirrorBaseAddr[l_cur_m_region_idx];
+ FAPI_DBG("l_cur_m_base_addr %016llx", l_cur_m_base_addr);
for (uint8_t pos = 0; pos < io_groupData.iv_numGroups; pos++)
{
@@ -3747,7 +4232,8 @@ fapi2::ReturnCode grouping_calcRegions(
for (uint8_t pos = 0; pos < io_groupData.iv_numGroups; pos++)
{
bool l_map_mirror = i_cfgMirror &&
- (io_groupData.iv_data[pos][PORTS_IN_GROUP] > 1);
+ ((io_groupData.iv_data[pos][PORTS_IN_GROUP] > 1) ||
+ io_groupData.iv_OMIMirrorable[pos]);
FAPI_DBG("pos: %d, l_map_mirror: %d",
pos, l_map_mirror);
@@ -3912,9 +4398,16 @@ fapi2::ReturnCode grouping_calcRegions(
if (l_map_mirror)
{
+ FAPI_DBG("io_groupData.iv_data[pos + MIRR_OFFSET][BASE_ADDR]: %016llx",
+ io_groupData.iv_data[pos + MIRR_OFFSET][BASE_ADDR]);
+ FAPI_DBG("io_groupData.iv_data[pos + MIRR_OFFSET][GROUP_SIZE]: %016llx",
+ io_groupData.iv_data[pos + MIRR_OFFSET][GROUP_SIZE]);
+ FAPI_DBG("io_groupData.iv_data[pos + MIRR_OFFSET][ALT_SIZE(ii)]: %016llx",
+ io_groupData.iv_data[pos + MIRR_OFFSET][ALT_SIZE(ii)]);
io_groupData.iv_data[pos + MIRR_OFFSET][ALT_BASE_ADDR(ii)] =
io_groupData.iv_data[pos + MIRR_OFFSET][BASE_ADDR] +
- io_groupData.iv_data[pos + MIRR_OFFSET][GROUP_SIZE] / 2;
+ io_groupData.iv_data[pos + MIRR_OFFSET][GROUP_SIZE] -
+ io_groupData.iv_data[pos + MIRR_OFFSET][ALT_SIZE(ii)];
io_groupData.iv_data[pos + MIRR_OFFSET][ALT_VALID(ii)] = 1;
}
}
@@ -4066,6 +4559,7 @@ fapi2::ReturnCode p9_mss_eff_grouping(
EffGroupingBaseSizeData l_baseSizeData;
EffGroupingData l_groupData;
bool l_mirrorIsOn = false;
+ bool l_mirrorReq = false;
// ----------------------------------------------
// Get the attributes needed for memory grouping
@@ -4095,6 +4589,13 @@ fapi2::ReturnCode p9_mss_eff_grouping(
"p9_mss_eff_grouping: l_memInfo.get_memInfo() returns an error, "
"l_rc 0x%.8X", (uint64_t)fapi2::current_err);
+ // ------------------------------------------------------------------
+ // Update groupings allowed - set omi
+ // ------------------------------------------------------------------
+ l_sysAttrs.updateGroupsAllowed(l_memInfo.iv_omi);
+ l_baseSizeData.iv_omi = l_memInfo.iv_omi;
+ l_groupData.iv_omi = l_memInfo.iv_omi;
+
// ----------------------------------------------------------------------
// Attempt to group the memory per Group port (per MCA/DMI).
// P9 MC architecture allows 1, 2, 3, 4, 6, or 8 MC ports to be grouped
@@ -4105,25 +4606,27 @@ fapi2::ReturnCode p9_mss_eff_grouping(
// ----------------------------------------------------------------------
FAPI_INF("Attempt memory grouping");
+ l_mirrorReq = (l_sysAttrs.iv_hwMirrorEnabled == fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_TRUE);
+
// Group MCs
if (l_sysAttrs.iv_groupsAllowed & GROUP_8)
{
- grouping_group8PortsPerGroup(l_memInfo, l_groupData);
+ grouping_group8PortsPerGroup(l_memInfo, l_groupData, l_mirrorReq);
}
if (l_sysAttrs.iv_groupsAllowed & GROUP_6)
{
- grouping_group6PortsPerGroup(l_memInfo, l_groupData);
+ grouping_group6PortsPerGroup(l_memInfo, l_groupData, l_mirrorReq);
}
if (l_sysAttrs.iv_groupsAllowed & GROUP_4)
{
- grouping_group4PortsPerGroup(l_memInfo, l_groupData);
+ grouping_group4PortsPerGroup(l_memInfo, l_groupData, l_mirrorReq);
}
if (l_sysAttrs.iv_groupsAllowed & GROUP_3)
{
- grouping_group3PortsPerGroup(l_memInfo, l_groupData);
+ grouping_group3PortsPerGroup(l_memInfo, l_groupData, l_mirrorReq);
}
if (l_sysAttrs.iv_groupsAllowed & GROUP_2)
@@ -4131,7 +4634,7 @@ fapi2::ReturnCode p9_mss_eff_grouping(
grouping_group2PortsPerGroup(
l_memInfo,
l_groupData,
- (l_sysAttrs.iv_hwMirrorEnabled == fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_TRUE));
+ l_mirrorReq);
}
if (l_sysAttrs.iv_groupsAllowed & GROUP_1)
@@ -4149,6 +4652,15 @@ fapi2::ReturnCode p9_mss_eff_grouping(
"grouping_findUngroupedPorts() returns an error, l_rc 0x%.8X",
(uint64_t)fapi2::current_err);
}
+ else if (l_memInfo.iv_omi)
+ {
+ FAPI_TRY(grouping_findUngroupedPorts<fapi2::TARGET_TYPE_MCC>(i_target,
+ l_memInfo,
+ l_groupData,
+ l_sysAttrs.iv_hwMirrorEnabled),
+ "grouping_findUngroupedPorts() returns an error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
else
{
FAPI_TRY(grouping_findUngroupedPorts<fapi2::TARGET_TYPE_DMI>(i_target,
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H
index 1bb1d0f71..ca0ec14c6 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -56,6 +56,7 @@
const uint8_t DATA_GROUPS = 16; // 8 regular groups, 8 mirrored groups
const uint8_t MIRR_OFFSET = 8; // Start of mirrored offset in DATA_GROUPS
const uint8_t DATA_ELEMENTS = 21; // 21 items of data for each group
+const uint8_t SUBCHANNEL_PER_CHANNEL = 2; // Number of OMI's per MCC
// Indexes used for EffGroupingData::iv_data DATA ELEMENTS
const uint8_t PORT_SIZE = 0; // Memory size of each port in group (GB)
@@ -73,6 +74,8 @@ const uint8_t SMF_BASE_ADDR = 20; // SMF Base Address
// Number of memory regions
const uint8_t NUM_NON_MIRROR_REGIONS = 8;
const uint8_t NUM_MIRROR_REGIONS = 4;
+const uint8_t NUM_MIRROR_REGIONS_OMI = 8; // Each port does its own mirroring
+const uint8_t NUM_MIRROR_REGIONS_MAX = NUM_MIRROR_REGIONS_OMI; // Max mirror regions
const uint8_t NUM_OF_CHTM_REGIONS = 24; // 24 CHTM memory regions
const uint8_t NUM_OF_ALT_MEM_REGIONS = 2; // 2 memory holes
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.mk b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.mk
index d960a266a..bde482fa3 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.mk
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2018
+# Contributors Listed Below - COPYRIGHT 2015,2019
# [+] International Business Machines Corp.
#
#
@@ -27,6 +27,7 @@
PROCEDURE=p9_mss_eff_grouping
$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/procedures/hwp/memory/)
lib$(PROCEDURE)_DEPLIBS+=cen
+lib$(PROCEDURE)_DEPLIBS+=mss_p9a
OBJS+=p9_fbc_utils.o
$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C b/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C
index 1138a3447..cb80ca77b 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.C
@@ -44,9 +44,13 @@
#include <p9_mc_scom_addresses_fld.H>
#include <p9n2_mc_scom_addresses.H>
#include <p9n2_mc_scom_addresses_fld.H>
+#include <p9a_misc_scom_addresses.H>
+#include <p9a_misc_scom_addresses_fld.H>
+#include <p9a_addr_ext.H>
#include <map>
#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/memory_size.H>
+#include <chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H>
///----------------------------------------------------------------------------
/// Constant definitions
@@ -100,17 +104,22 @@ static const struct groupSizeTable_t
} GROUP_SIZE_TABLE[] =
{
// GroupSize Encoded GroupSize
- { 4, 0b00000000000 }, // 4 GB
- { 8, 0b00000000001 }, // 8 GB
- { 16, 0b00000000011 }, // 16 GB
- { 32, 0b00000000111 }, // 32 GB
- { 64, 0b00000001111 }, // 64 GB
- { 128, 0b00000011111 }, // 128 GB
- { 256, 0b00000111111 }, // 256 GB
- { 512, 0b00001111111 }, // 512 GB
- { 1024, 0b00011111111 }, // 1 TB
- { 2048, 0b00111111111 }, // 2 TB
- { 4096, 0b01111111111 }, // 4 TB
+ { 4, 0b00000000000 }, // 4 GB
+ { 8, 0b00000000001 }, // 8 GB
+ { 16, 0b00000000011 }, // 16 GB
+ { 32, 0b00000000111 }, // 32 GB
+ { 64, 0b00000001111 }, // 64 GB
+ { 128, 0b00000011111 }, // 128 GB
+ { 256, 0b00000111111 }, // 256 GB
+ { 512, 0b00001111111 }, // 512 GB
+ { 1024, 0b00011111111 }, // 1 TB
+ { 2048, 0b00111111111 }, // 2 TB
+ { 4096, 0b01111111111 }, // 4 TB
+ { 8192, 0b000011111111111 }, // 8 TB
+ { 16384, 0b000111111111111 }, // 16 TB
+ { 32768, 0b001111111111111 }, // 32 TB
+ { 65536, 0b011111111111111 }, // 64 TB
+ { 131072, 0b111111111111111 } // 128 TB
};
/**
@@ -318,7 +327,7 @@ fapi2::ReturnCode getMcMemSize(
// Figure out the amount of memory behind this MI
// by adding up all memory from its DMI ports
auto l_dmiChiplets = i_target.getChildren<fapi2::TARGET_TYPE_DMI>();
- uint64_t l_dmiSize = 0;
+ uint64_t l_chSize = 0;
for (auto l_dmi : l_dmiChiplets)
{
@@ -328,12 +337,12 @@ fapi2::ReturnCode getMcMemSize(
(uint64_t)fapi2::current_err);
// Get the amount of memory behind this DMI target
- FAPI_TRY(mss::eff_memory_size<mss::mc_type::CENTAUR>(l_dmi, l_dmiSize),
+ FAPI_TRY(mss::eff_memory_size<mss::mc_type::CENTAUR>(l_dmi, l_chSize),
"Error returned from eff_memory_size - DMI, l_rc 0x%.8X",
(uint64_t)fapi2::current_err);
- FAPI_INF("DMI %u: Total DIMM size %lu GB", l_dmiPos, l_dmiSize);
- o_mcSize += l_dmiSize;
+ FAPI_INF("DMI %u: Total DIMM size %lu GB", l_dmiPos, l_chSize);
+ o_mcSize += l_chSize;
}
fapi_try_exit:
@@ -341,6 +350,64 @@ fapi_try_exit:
return fapi2::current_err;
}
+/// MC = MCC (Axone)
+template<>
+fapi2::ReturnCode getMcMemSize(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCC>& i_target,
+ uint64_t& o_mcSize)
+{
+ FAPI_DBG("Entering");
+
+ // Figure out the amount of memory behind this MI
+ // by adding up all memory from its OMI ports
+ uint64_t l_chSize = 0;
+ uint64_t l_sub_size[SUBCHANNEL_PER_CHANNEL];
+ uint64_t l_sub_minsize = 0;
+ uint64_t l_num_sub = 0;
+
+ auto l_omiChiplets = i_target.getChildren<fapi2::TARGET_TYPE_OMI>();
+ memset(l_sub_size, 0, sizeof(l_sub_size));
+
+ for (auto l_omi : l_omiChiplets)
+ {
+ const auto& l_ocmb_chiplets = l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>();
+
+ if (!l_ocmb_chiplets.empty())
+ {
+ uint8_t l_omiPos = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_omi, l_omiPos),
+ "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Get the amount of memory behind this OMI
+ FAPI_TRY(mss::eff_memory_size<mss::mc_type::EXPLORER>(l_ocmb_chiplets[0], l_chSize),
+ "Error returned from eff_memory_size - ocmb, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ FAPI_INF("OMI %u: Total DIMM size %lu GB", l_omiPos, l_chSize);
+
+ l_sub_size[l_omiPos % SUBCHANNEL_PER_CHANNEL] = l_chSize;
+
+ if (l_chSize > 0)
+ {
+ l_num_sub++;
+
+ if (l_sub_minsize == 0 || l_sub_minsize > l_chSize)
+ {
+ l_sub_minsize = l_chSize;
+ }
+ }
+ }
+ }
+
+ l_chSize = (l_num_sub * l_sub_minsize);
+ o_mcSize += l_chSize;
+
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
+
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
///
@@ -348,6 +415,7 @@ fapi_try_exit:
/// from group data.
///
/// @param[in] i_mcPos MC position
+/// @param[in] i_omi Chip uses OMI?
/// @param[in] i_groupData Array of Group data info
/// @param[out] o_portFound Mark how many time a port is found.
/// @param[out] o_mcSize The total mem size calculated
@@ -356,6 +424,7 @@ fapi_try_exit:
///
void getGroupDataMcMemSize(
uint8_t i_mcPos,
+ const bool i_omi,
const uint32_t i_groupData[DATA_GROUPS][DATA_ELEMENTS],
uint8_t o_portFound[NUM_MC_PORTS_PER_PROC],
uint64_t& o_mcSize)
@@ -381,7 +450,8 @@ void getGroupDataMcMemSize(
uint8_t l_mcId = getMCPosition(i_groupData[l_group][MEMBER_IDX(0) +
l_memberIdx]);
- if (l_mcId == i_mcPos)
+ if ((!i_omi && l_mcId == i_mcPos) ||
+ (i_omi && i_mcPos == i_groupData[l_group][MEMBER_IDX(0) + l_memberIdx]))
{
o_mcSize += i_groupData[l_group][PORT_SIZE];
FAPI_INF("getGroupDataMcMemSize - Port %u, DIMM size %lu GB",
@@ -409,6 +479,7 @@ void getGroupDataMcMemSize(
/// - An MCA/DMMI port can only appear once in any group.
///
/// @param[in] i_mcTargets Vector of reference of MC targets (MCS or MI)
+/// @param[in] i_omi Chip uses OMI?
/// @param[in] i_groupData Array of Group data info
///
/// @return FAPI2_RC_SUCCESS if success, else error code.
@@ -416,6 +487,7 @@ void getGroupDataMcMemSize(
template<fapi2::TargetType T>
fapi2::ReturnCode validateGroupData(
const std::vector< fapi2::Target<T> >& i_mcTargets,
+ const bool i_omi,
const uint32_t i_groupData[DATA_GROUPS][DATA_ELEMENTS])
{
FAPI_DBG("Entering");
@@ -444,7 +516,7 @@ fapi2::ReturnCode validateGroupData(
(uint64_t)fapi2::current_err);
// Get this MC memsize reported in Group data
- getGroupDataMcMemSize(l_mcPos, i_groupData, l_portFound,
+ getGroupDataMcMemSize(l_mcPos, i_omi, i_groupData, l_portFound,
l_mcSizeGroupData);
FAPI_DBG("validateGroupData: MemSize %.16lld, Group Memsize %.16lld",
@@ -655,6 +727,28 @@ fapi2::ReturnCode getNonMirrorBarData(const fapi2::Target<T>& i_mcTarget,
}
}
+ FAPI_TRY(getNonMirrorBarIdSize(i_mcTarget, i_portInfo, o_mcBarData));
+
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculate the BAR data for each MC (MCS/MI) based on group info
+/// of port0/1
+///
+/// @param[in] i_mcTarget MC target (MCS/MI)
+/// @param[in] i_portInfo The port group info
+/// @param[in] o_mcBarData MC BAR data
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+template<fapi2::TargetType T>
+fapi2::ReturnCode getNonMirrorBarIdSize(const fapi2::Target<T>& i_mcTarget,
+ const mcPortGroupInfo_t i_portInfo[],
+ mcBarData_t& o_mcBarData)
+{
// MCFGP Channel_0 Group member ID (bits 5:7)
o_mcBarData.MCFGP_chan0_group_member_id = i_portInfo[0].channelId;
// MCFGP Channel_1 Group member ID (bits 8:10)
@@ -756,6 +850,154 @@ fapi_try_exit:
}
///
+/// @brief Calculate the BAR data for each MC (MCS/MI) based on group info
+/// of port0/1
+///
+/// @param[in] i_mcTarget MC target (MCS/MI)
+/// @param[in] i_portInfo The port group info
+/// @param[in] o_mcBarData MC BAR data
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode getNonMirrorBarIdSize(const fapi2::Target<fapi2::TARGET_TYPE_MCC>& i_mcTarget,
+ const mcPortGroupInfo_t& i_portInfo,
+ mcBarData_t& o_mcBarData)
+{
+ // MCFGP Channel_0 Group member ID (bits 5:7)
+ o_mcBarData.MCFGP_chan0_group_member_id = i_portInfo.channelId;
+
+ // If MCFGP is valid, set other fields
+ if (o_mcBarData.MCFGP_valid == true)
+ {
+ // MCFGP Group size
+ FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo.groupSize,
+ o_mcBarData.MCFGP_group_size),
+ "getGroupSizeEncodedValue() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Group base address
+ o_mcBarData.MCFGP_groupBaseAddr = i_portInfo.groupBaseAddr;
+ }
+
+ // If MCFGPM is valid, set other fields
+ if (o_mcBarData.MCFGPM_valid == true)
+ {
+ // MCFGPM Group size
+ FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo.groupSize,
+ o_mcBarData.MCFGPM_group_size),
+ "getGroupSizeEncodedValue() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Group base address
+ o_mcBarData.MCFGPM_groupBaseAddr = i_portInfo.groupBaseAddr;
+ }
+
+ // ----------------------------------------------------
+ // Determine data for MCFGPA and MCFGPMA registers
+ // ----------------------------------------------------
+
+ // Alternate Memory MCFGPA
+ for (uint8_t ii = 0; ii < NUM_OF_ALT_MEM_REGIONS; ii++)
+ {
+ if ( i_portInfo.altMemValid[ii] )
+ {
+ o_mcBarData.MCFGPA_HOLE_valid[ii] = 1;
+ o_mcBarData.MCFGPA_HOLE_LOWER_addr[ii] = i_portInfo.altBaseAddr[ii];
+ o_mcBarData.MCFGPA_HOLE_UPPER_addr[ii] =
+ i_portInfo.altBaseAddr[ii] + i_portInfo.altMemSize[ii];
+ }
+ else
+ {
+ o_mcBarData.MCFGPA_HOLE_valid[ii] = 0;
+ o_mcBarData.MCFGPA_HOLE_LOWER_addr[ii] = 0;
+ o_mcBarData.MCFGPA_HOLE_UPPER_addr[ii] = 0;
+ }
+
+ }
+
+ // SMF Section of MCFGPA and MCFGPMA
+ if ( i_portInfo.smfMemValid )
+ {
+ o_mcBarData.MCFGPA_SMF_valid = 1;
+ o_mcBarData.MCFGPA_SMF_LOWER_addr = i_portInfo.smfBaseAddr;
+ o_mcBarData.MCFGPA_SMF_UPPER_addr = i_portInfo.smfBaseAddr + i_portInfo.smfMemSize;
+ }
+ else
+ {
+ o_mcBarData.MCFGPA_SMF_valid = 0;
+ o_mcBarData.MCFGPA_SMF_LOWER_addr = 0;
+ o_mcBarData.MCFGPA_SMF_UPPER_addr = 0;
+ }
+
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculate the BAR data for each MCC based on group info
+/// of port0/1 - OMI specific
+///
+/// @param[in] i_mcTarget MC target (MCC)
+/// @param[in] i_portInfo The port group info
+/// @param[in] o_mcBarData MC BAR data
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode getNonMirrorBarData(const fapi2::Target<fapi2::TARGET_TYPE_MCC>& i_mcTarget,
+ const mcPortGroupInfo_t& i_portInfo,
+ mcBarData_t& o_mcBarData)
+{
+ FAPI_DBG("Entering");
+
+ // Initialize
+ o_mcBarData.MCFGP_chan_per_group = NO_CHANNEL_PER_GROUP;
+ o_mcBarData.MCFGP_valid = false;
+ o_mcBarData.MCFGPM_valid = false;
+
+ // MCFGP valid (MCFGP bit 0)
+ if ( i_portInfo.numPortsInGroup > 0)
+ {
+ o_mcBarData.MCFGP_valid = true;
+ o_mcBarData.MCFGPM_valid = false;
+
+ // ----------------------------------------------------
+ // Determine data for MCFGP and MCFGPM registers
+ // ----------------------------------------------------
+ if (i_portInfo.numPortsInGroup == 8)
+ {
+ o_mcBarData.MCFGP_chan_per_group = 0;
+ }
+ else if (i_portInfo.numPortsInGroup == 1 ||
+ i_portInfo.numPortsInGroup == 2 ||
+ i_portInfo.numPortsInGroup == 3 ||
+ i_portInfo.numPortsInGroup == 4 ||
+ i_portInfo.numPortsInGroup == 6 )
+ {
+ o_mcBarData.MCFGP_chan_per_group = i_portInfo.numPortsInGroup;
+ }
+
+ // Assert if ports 0/1 don't match any entry in table
+ FAPI_ASSERT(o_mcBarData.MCFGP_chan_per_group != NO_CHANNEL_PER_GROUP,
+ fapi2::MSS_SETUP_BARS_INVALID_PORTS_CONFIG()
+ .set_MC_TARGET(i_mcTarget)
+ .set_PORT_0_PORTS_IN_GROUP(i_portInfo.numPortsInGroup)
+ .set_PORT_0_GROUP(i_portInfo.myGroup)
+ .set_PORT_1_PORTS_IN_GROUP(0)
+ .set_PORT_1_GROUP(0),
+ "Error: Invalid number of ports per group"
+ "group %u, ports in group %u",
+ i_portInfo.myGroup, i_portInfo.numPortsInGroup);
+ }
+
+ FAPI_TRY(getNonMirrorBarIdSize(i_mcTarget, i_portInfo, o_mcBarData));
+
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
+
+///
/// @brief Calculate the mirror BAR data for each MC based on group info
/// of port0/1
///
@@ -779,8 +1021,8 @@ fapi2::ReturnCode getMirrorBarData(const fapi2::Target<T>& i_mcTarget,
// Check MCFGP value to see if mirror is possible
// (See Table 1 of P9 Cumulus Memory Controller Workbook)
//
- if ( (io_mcBarData.MCFGP_chan_per_group < 0b0101) ||
- (io_mcBarData.MCFGP_chan_per_group > 0b1000) )
+ if ( ((io_mcBarData.MCFGP_chan_per_group < 0b0101) ||
+ (io_mcBarData.MCFGP_chan_per_group > 0b1000)))
{
FAPI_IMP("Mirror is not possible with MCFGP = 0x%.8X, NO MIRROR is "
"programmed. ", io_mcBarData.MCFGP_chan_per_group);
@@ -832,39 +1074,121 @@ fapi_try_exit:
}
///
-/// @brief Display the Memory controller BAR data resulted from the BAR
-/// data calculations.
+/// @brief Calculate the mirror BAR data for each MC based on group info
+/// of port0/1
///
-/// @param[in] i_portInfo Port data
+/// @param[in] i_mcTarget MCC target
+/// @param[in] i_portInfo The port group info
+/// @param[in] io_mcBarData MC BAR data
///
/// @return FAPI2_RC_SUCCESS if success, else error code.
///
-void displayMCPortInfoData(const mcPortGroupInfo_t i_portInfo[])
+fapi2::ReturnCode getMirrorBarData(const fapi2::Target<fapi2::TARGET_TYPE_MCC>& i_mcTarget,
+ const mcPortGroupInfo_t& i_portInfo,
+ mcBarData_t& io_mcBarData)
{
- for (uint8_t ii = 0; ii < MAX_MC_PORTS_PER_MCS; ii++)
+ FAPI_DBG("Entering");
+
+ // ---------------------------------------------------
+ // Build MC register values for mirror groups
+ // ---------------------------------------------------
+
+ // Set MCFGPM_VALID
+ if (i_portInfo.groupSize > 0)
{
- FAPI_INF(" Port %u:", ii);
+ io_mcBarData.MCFGPM_valid = true;
- if (i_portInfo[ii].numPortsInGroup > 0)
- {
- FAPI_INF(" myGroup %u", i_portInfo[ii].myGroup);
- FAPI_INF(" numPortsInGroup %u", i_portInfo[ii].numPortsInGroup);
- FAPI_INF(" groupSize %u", i_portInfo[ii].groupSize);
- FAPI_INF(" groupBaseAddr 0x%.16llX", i_portInfo[ii].groupBaseAddr);
- FAPI_INF(" channelId %u", i_portInfo[ii].channelId);
+ // ----------------------------------------------------
+ // Determine data for MCFGPM register
+ // ----------------------------------------------------
+
+ // MCFGPM Group size
+ FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo.groupSize,
+ io_mcBarData.MCFGPM_group_size),
+ "getGroupSizeEncodedValue() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Group base address
+ io_mcBarData.MCFGPM_groupBaseAddr = i_portInfo.groupBaseAddr;
- for (uint8_t jj = 0; jj < NUM_OF_ALT_MEM_REGIONS; jj++)
+ // ----------------------------------------------------
+ // Determine data for MCFGPMA registers
+ // ----------------------------------------------------
+ // Alternate Memory MCFGPMA
+ for (uint8_t ii = 0; ii < NUM_OF_ALT_MEM_REGIONS; ii++)
+ {
+ if ( i_portInfo.altMemValid[ii] )
+ {
+ io_mcBarData.MCFGPMA_HOLE_valid[ii] = 1;
+ io_mcBarData.MCFGPMA_HOLE_LOWER_addr[ii] =
+ i_portInfo.altBaseAddr[ii];
+ io_mcBarData.MCFGPMA_HOLE_UPPER_addr[ii] =
+ i_portInfo.altBaseAddr[ii] + i_portInfo.altMemSize[ii];
+ }
+ else
{
- FAPI_INF(" altMemValid[%u] %u", jj, i_portInfo[ii].altMemValid[jj]);
- FAPI_INF(" altMemSize[%u] %u", jj, i_portInfo[ii].altMemSize[jj]);
- FAPI_INF(" altBaseAddr[%u] 0x%.16llX", jj, i_portInfo[ii].altBaseAddr[jj]);
+ io_mcBarData.MCFGPMA_HOLE_valid[ii] = 0;
+ io_mcBarData.MCFGPMA_HOLE_LOWER_addr[ii] = 0;
+ io_mcBarData.MCFGPMA_HOLE_UPPER_addr[ii] = 0;
}
+
}
- else
+ }
+
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Display the Memory controller BAR data resulted from the BAR
+/// data calculations.
+///
+/// @param[in] i_portInfo Port data
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+void displayMCPortInfoData(const mcPortGroupInfo_t i_portInfo)
+{
+ if (i_portInfo.numPortsInGroup > 0)
+ {
+ FAPI_INF(" myGroup %u", i_portInfo.myGroup);
+ FAPI_INF(" numPortsInGroup %u", i_portInfo.numPortsInGroup);
+ FAPI_INF(" groupSize %u", i_portInfo.groupSize);
+ FAPI_INF(" groupBaseAddr 0x%.16llX", i_portInfo.groupBaseAddr);
+ FAPI_INF(" channelId %u", i_portInfo.channelId);
+
+ for (uint8_t jj = 0; jj < NUM_OF_ALT_MEM_REGIONS; jj++)
{
- FAPI_INF(" Not configured");
+ FAPI_INF(" altMemValid[%u] %u", jj, i_portInfo.altMemValid[jj]);
+ FAPI_INF(" altMemSize[%u] %u", jj, i_portInfo.altMemSize[jj]);
+ FAPI_INF(" altBaseAddr[%u] 0x%.16llX", jj, i_portInfo.altBaseAddr[jj]);
}
}
+ else
+ {
+ FAPI_INF(" Not configured");
+ }
+
+ return;
+}
+
+///
+/// @brief Display the Memory controller BAR data resulted from the BAR
+/// data calculations.
+///
+/// @param[in] i_portInfo Port data
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+void displayMCPortInfoData(const mcPortGroupInfo_t i_portInfo[])
+{
+ for (uint8_t ii = 0; ii < MAX_MC_PORTS_PER_MCS; ii++)
+ {
+ FAPI_INF(" Port %u:", ii);
+
+ displayMCPortInfoData(i_portInfo[ii]);
+ }
return;
}
@@ -949,6 +1273,7 @@ void getPortData(const bool i_nonMirror,
// Skip empty groups
if (i_groupData[l_group][GROUP_SIZE] == 0)
{
+ FAPI_DBG("Skipping zero group %d (nonMirror: %d)", l_group, i_nonMirror);
continue;
}
@@ -1022,6 +1347,95 @@ void getPortData(const bool i_nonMirror,
}
///
+/// @brief Load the mcPortGroupInfo_t data for the input MC based on
+/// MC position, input group data, and mirror/non-mirror setting.
+///
+/// @param[in] i_nonMirror Type of group data:
+/// true = non-mirror; false = mirrored
+/// @param[in] i_mcPos MCC position
+/// @param[in] i_groupData Array of Group data info
+/// @param[out] o_portInfo Output mcPortGroupInfo_t
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+void getPortData(const bool i_nonMirror,
+ const uint8_t i_mccPos,
+ const uint32_t i_groupData[DATA_GROUPS][DATA_ELEMENTS],
+ mcPortGroupInfo_t& o_portInfo)
+{
+ FAPI_DBG("Entering");
+
+ // Non-mirrored groups: 0->7
+ // Mirrored groups: 8->11
+ uint8_t l_startGroup = 0;
+ uint8_t l_endGroup = (DATA_GROUPS / 2);
+
+ if (i_nonMirror == false)
+ {
+ l_startGroup = MIRR_OFFSET;
+ l_endGroup = (MIRR_OFFSET + NUM_MIRROR_REGIONS);
+ }
+
+ // Loop thru specified groups
+ for (uint8_t l_group = l_startGroup; l_group < l_endGroup; l_group++)
+ {
+ // Skip empty groups
+ if (i_groupData[l_group][GROUP_SIZE] == 0)
+ {
+ continue;
+ }
+
+ // Loop thru the ports (MCA/DMI) and determine if they belong
+ // to this MC (MCS/MI)
+ for (uint8_t l_memberIdx = 0;
+ l_memberIdx < i_groupData[l_group][PORTS_IN_GROUP]; l_memberIdx++)
+ {
+ uint8_t l_mccPos = i_groupData[l_group][MEMBER_IDX(0) + l_memberIdx];
+
+ // If the PORT_ID belongs to this MC
+ if (l_mccPos == i_mccPos)
+ {
+ // Set the port group info for this port
+ o_portInfo.myGroup = l_group;
+ o_portInfo.numPortsInGroup = i_groupData[l_group][PORTS_IN_GROUP];
+ o_portInfo.groupSize = i_groupData[l_group][GROUP_SIZE];
+ o_portInfo.groupBaseAddr = i_groupData[l_group][BASE_ADDR];
+ o_portInfo.channelId = l_memberIdx;
+
+ // ALT memory regions
+ for (uint8_t ii = 0; ii < NUM_OF_ALT_MEM_REGIONS; ii++)
+ {
+ if (i_groupData[l_group][ALT_VALID(ii)])
+ {
+ o_portInfo.altMemValid[ii] = 1;
+ o_portInfo.altMemSize[ii] = i_groupData[l_group][ALT_SIZE(ii)];
+ o_portInfo.altBaseAddr[ii] = i_groupData[l_group][ALT_BASE_ADDR(ii)];
+ }
+ }
+
+ // SMF memory regions
+ if (i_groupData[l_group][SMF_VALID])
+ {
+ o_portInfo.smfMemValid = 1;
+ o_portInfo.smfMemSize = i_groupData[l_group][SMF_SIZE];
+ o_portInfo.smfBaseAddr = i_groupData[l_group][SMF_BASE_ADDR];
+ }
+ }
+
+ } // Port loop
+
+ } // Group loop
+
+ // Display MC port info data
+ FAPI_INF("getPortData from %s group - Results for MCC pos %d",
+ i_nonMirror ? "NON-MIRROR" : "MIRROR", i_mccPos);
+ displayMCPortInfoData(o_portInfo);
+
+ FAPI_DBG("Exit");
+ return;
+}
+
+///
/// @brief Use Group data obtained from p9_mss_eff_grouping to build
/// data to be programmed into each Memory controller target (MCS
/// or MI).
@@ -1123,6 +1537,101 @@ fapi_try_exit:
}
///
+/// @brief Use Group data obtained from p9_mss_eff_grouping to build
+/// data to be programmed into each Memory controller target MCC
+/// for OMI based memory
+///
+/// @param[in] i_mcTargets Vector of reference of MCC
+/// @param[in] i_groupData Array of Group data info
+/// @param[out] o_mcDataPair Output data pair MCC<->Data
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+template<>
+fapi2::ReturnCode buildMCBarData(
+ const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCC> >& i_mccTargets,
+ const uint32_t i_groupData[DATA_GROUPS][DATA_ELEMENTS],
+ std::vector<std::pair<fapi2::Target<fapi2::TARGET_TYPE_MCC>, mcBarData_t>>& o_mcBarDataPair)
+{
+ FAPI_DBG("Entering");
+
+ char l_targetStr[fapi2::MAX_ECMD_STRING_LEN];
+ const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
+ fapi2::ATTR_MRW_HW_MIRRORING_ENABLE_Type l_mirror_ctl;
+
+ // Get mirror policy
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MRW_HW_MIRRORING_ENABLE,
+ FAPI_SYSTEM, l_mirror_ctl),
+ "Error getting ATTR_MRW_HW_MIRRORING_ENABLE, "
+ "l_rc 0x%.8X", (uint64_t)fapi2::current_err);
+
+ for (auto l_mcc : i_mccTargets)
+ {
+ mcBarData_t l_mcBarData;
+ mcPortGroupInfo_t l_portInfo;
+
+ // Get this MC unit position
+ uint8_t l_unitPos = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mcc, l_unitPos),
+ "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ fapi2::toString(l_mcc, l_targetStr, sizeof(l_targetStr));
+ FAPI_INF("Build BAR data for MC target: %s", l_targetStr);
+
+ // -----------------------------------------------
+ // Build MC register values for non-mirror groups
+ // -----------------------------------------------
+
+ // Get port data from non-mirrored groups (true = non-mirrored)
+ getPortData(true, l_unitPos, i_groupData, l_portInfo);
+
+ // If one of MC port is configured in a group, proceed with
+ // getting BAR data
+ if ( (l_portInfo.numPortsInGroup > 0) )
+ {
+ // ---- Build MCFGP/MCFGM data based on port group info ----
+ FAPI_TRY(getNonMirrorBarData(l_mcc, l_portInfo, l_mcBarData),
+ "getNonMirrorBarData() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // ---------------------------------------------------------------
+ // Set MC register values for mirror groups
+ // - Nimbus: No mirror
+ // - Cumulus: If ATTR_MRW_HW_MIRRORING_ENABLE != false
+ // ---------------------------------------------------------------
+ if (l_mirror_ctl != fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_FALSE)
+ {
+ FAPI_INF("ATTR_MRW_HW_MIRRORING_ENABLE is enabled: checking mirrored groups");
+ mcPortGroupInfo_t l_portInfoMirrored;
+ // Get port data from mirrored groups (false = mirrored)
+ getPortData(false, l_unitPos, i_groupData, l_portInfoMirrored);
+
+ // ---- Build MCFGM data based on port group info ----
+ FAPI_TRY(getMirrorBarData(l_mcc, l_portInfoMirrored, l_mcBarData),
+ "getMirrorBarData() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+
+ // Add to output pair
+ o_mcBarDataPair.push_back(std::make_pair(l_mcc, l_mcBarData));
+
+ // Display data
+ displayMCBarData(l_unitPos, l_mcBarData);
+ }
+ else
+ {
+ FAPI_INF("MC pos %u is not configured in a memory group.", l_unitPos);
+ }
+
+ } // MC loop
+
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
+
+///
/// @brief Set MCFGPA MEMORY HOLE UPPER_ADDRESS_AT_END_OF_RANGE bit
///
/// @param[in] i_target MC target (MCS or MI)
@@ -1196,6 +1705,7 @@ fapi2::ReturnCode writeMCBarData(
MCS_MCFGP_GROUP_SIZE_LEN>(
l_data.MCFGP_group_size);
+
// Group base address (bits 24:47) 0b000000000000000000000001 = 4GB
// 000000001 (base addr of 4GB)
// 000000010 (base addr of 8GB)
@@ -1443,15 +1953,378 @@ fapi_try_exit:
}
///
-/// @brief Unmask FIR before opening BARs
+/// @brief Write BAR data to a memory controller
+///
+/// @param[in] i_mcBarDataPair Target pair <target, data>
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode writeMCCInterleaveGranularity(
+ const std::vector<std::pair<fapi2::Target<fapi2::TARGET_TYPE_MCC>, mcBarData_t>>& i_mcBarDataPair)
+{
+ FAPI_DBG("Entering");
+
+ std::map<fapi2::Target<fapi2::TARGET_TYPE_MI>, bool> l_granule_supported;
+
+ fapi2::ATTR_MSS_INTERLEAVE_GRANULARITY_Type l_interleave_granule_size;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_INTERLEAVE_GRANULARITY,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ l_interleave_granule_size),
+ "Error getting ATTR_MSS_INTERLEAVE_GRANULARITY, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ for (auto l_pair : i_mcBarDataPair)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_MCC> l_target = l_pair.first;
+ mcBarData_t l_data = l_pair.second;
+
+ // MCFGP valid (bit 0)
+ if (l_data.MCFGP_valid == true)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_MI> l_mi_target = l_target.getParent<fapi2::TARGET_TYPE_MI>();
+
+ // configure interleave granularity if 1/2/4/8 MC per group only
+ if ((l_data.MCFGP_chan_per_group == 0) || // 8 MC/group
+ (l_data.MCFGP_chan_per_group == 1) || // 1 MC/group
+ (l_data.MCFGP_chan_per_group == 2) || // 2 MC/group
+ (l_data.MCFGP_chan_per_group == 4)) // 4 MC/group
+ {
+ //Only set to true if the value for the target is not set yet
+ if (l_granule_supported.find(l_mi_target) == l_granule_supported.end())
+ {
+ l_granule_supported[l_mi_target] = true;
+ }
+ }
+ else
+ {
+ //Always set to false if we find one channel that cannot support it.
+ l_granule_supported[l_mi_target] = false;
+ }
+ }
+ }
+
+ for ( auto l_it = l_granule_supported.begin(); l_it != l_granule_supported.end(); l_it++ )
+ {
+ if (l_it->second)
+ {
+ auto l_mi_target = l_it->first;
+
+ fapi2::buffer<uint64_t> l_mcmode0_scom_data;
+ FAPI_TRY(fapi2::getScom(l_mi_target, P9A_MI_MCMODE0, l_mcmode0_scom_data),
+ "Error reading from MCS_MCMODE0 reg");
+ l_mcmode0_scom_data.insertFromRight<P9A_MI_MCMODE0_GROUP_ADDRESS_INTERLEAVE_GRANULARITY,
+ P9A_MI_MCMODE0_GROUP_ADDRESS_INTERLEAVE_GRANULARITY_LEN>(l_interleave_granule_size);
+ FAPI_TRY(fapi2::putScom(l_mi_target, P9A_MI_MCMODE0, l_mcmode0_scom_data),
+ "Error writing to MCS_MCMODE0 reg");
+ }
+ }
+
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Translate a bar value in GB to a 32 bit extended value
+///
+/// @param[in] i_ext_mask The extension mask
+/// @param[in] i_bar The bar in GB
+/// @param[out] o_extBar is the upper 32 bits of the extended address
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+fapi2::ReturnCode extBar(const uint64_t& i_ext_mask, const uint32_t& i_bar, fapi2::buffer<uint64_t>& o_extBar)
+{
+ FAPI_DBG("Entering");
+ fapi2::buffer<uint64_t> l_norAddr(0);
+
+ FAPI_DBG("i_bar: %016llx", i_bar);
+ o_extBar = 0;
+ l_norAddr.insert<0, 32>(i_bar >> 2); //i_bar is in GB
+ FAPI_DBG("l_norAddr: %016llx", l_norAddr);
+ FAPI_TRY(extendBarAddress(i_ext_mask, l_norAddr, o_extBar));
+ FAPI_DBG("o_extBar: %016llx", o_extBar);
+
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write BAR data to a memory controller
///
/// @param[in] i_mcBarDataPair Target pair <target, data>
///
/// @return FAPI2_RC_SUCCESS if success, else error code.
///
+fapi2::ReturnCode writeMCBarData(
+ const std::vector<std::pair<fapi2::Target<fapi2::TARGET_TYPE_MCC>, mcBarData_t>>& i_mcBarDataPair)
+{
+ FAPI_DBG("Entering");
+
+ uint8_t l_pos;
+
+ fapi2::buffer<uint64_t> l_scomData(0);
+ fapi2::buffer<uint64_t> l_extAddr(0);
+ fapi2::buffer<uint64_t> l_norAddr;
+ uint64_t l_ext_mask;
+
+ FAPI_TRY(p9a_get_ext_mask(l_ext_mask));
+
+ FAPI_TRY(writeMCCInterleaveGranularity(i_mcBarDataPair));
+
+ for (auto l_pair : i_mcBarDataPair)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_MCC> l_target = l_pair.first;
+ mcBarData_t l_data = l_pair.second;
+
+ char l_targetStr[fapi2::MAX_ECMD_STRING_LEN];
+ fapi2::toString(l_target, l_targetStr, sizeof(l_targetStr));
+ FAPI_INF("Program MC target: %s", l_targetStr);
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_target, l_pos),
+ "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // 1. ---- Set MCFGP reg -----
+ l_scomData = 0;
+
+ // MCFGP valid (bit 0)
+ if (l_data.MCFGP_valid == true)
+ {
+ l_scomData.setBit<P9A_MI_MCFGP0_VALID>();
+
+ // Group size (bits 13:23)
+ l_scomData.insertFromRight<P9A_MI_MCFGP0_GROUP_SIZE,
+ P9A_MI_MCFGP0_GROUP_SIZE_LEN>(
+ l_data.MCFGP_group_size);
+
+ FAPI_TRY(extBar(l_ext_mask, l_data.MCFGP_groupBaseAddr, l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGP0_GROUP_BASE_ADDRESS,
+ P9A_MI_MCFGP0_GROUP_BASE_ADDRESS_LEN>(
+ (l_extAddr));
+ }
+
+ // Channel per group (bits 1:4)
+ l_scomData.insertFromRight<P9A_MI_MCFGP0_MC_CHANNELS_PER_GROUP,
+ P9A_MI_MCFGP0_MC_CHANNELS_PER_GROUP_LEN>(
+ l_data.MCFGP_chan_per_group);
+
+ // Channel 0 group id (bits 5:7)
+ l_scomData.insertFromRight<P9A_MI_MCFGP0_GROUP_MEMBER_IDENTIFICATION,
+ P9A_MI_MCFGP0_GROUP_MEMBER_IDENTIFICATION_LEN>(
+ l_data.MCFGP_chan0_group_member_id);
+
+ // 2GB cfg and MMIO
+ l_scomData.insertFromRight<P9A_MI_MCFGP0_MCFGPR0_CONFIGURATION_GROUP_SIZE,
+ P9A_MI_MCFGP0_MCFGPR0_CONFIGURATION_GROUP_SIZE_LEN>(mss::exp::ib::EXPLR_IB_BAR_SIZE);
+ l_scomData.insertFromRight<P9A_MI_MCFGP0_MCFGPR0_MMIO_GROUP_SIZE,
+ P9A_MI_MCFGP0_MCFGPR0_MMIO_GROUP_SIZE_LEN>(mss::exp::ib::EXPLR_IB_BAR_SIZE);
+
+ // Write to reg
+ if (l_pos % 2 == 0)
+ {
+ FAPI_INF("Write MCFGP0 reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGP0, l_scomData);
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP0, l_scomData),
+ "Error writing to MCS_MCFGP reg");
+ }
+ else
+ {
+ FAPI_INF("Write MCFGP1 reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGP1, l_scomData);
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP1, l_scomData),
+ "Error writing to MCS_MCFGP reg");
+ }
+
+ // 2. ---- Set MCFGPM reg -----
+ l_scomData = 0;
+
+ if (l_data.MCFGPM_valid == true)
+ {
+ // MCFGP valid (bit 0)
+ l_scomData.setBit<P9A_MI_MCFGPM0_VALID>();
+
+ // Group size (bits 13:23)
+ l_scomData.insertFromRight<P9A_MI_MCFGPM0_GROUP_SIZE,
+ P9A_MI_MCFGPM0_GROUP_SIZE_LEN>(
+ l_data.MCFGPM_group_size);
+
+ FAPI_TRY(extBar(l_ext_mask, l_data.MCFGPM_groupBaseAddr, l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGPM0_GROUP_BASE_ADDRESS,
+ P9A_MI_MCFGPM0_GROUP_BASE_ADDRESS_LEN>(
+ (l_extAddr));
+
+ }
+
+ if (l_pos % 2 == 0)
+ {
+ // Write to reg
+ FAPI_INF("Write MCFGPM0 reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGPM0, l_scomData);
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM0, l_scomData),
+ "Error writing to P9A_MI_MCFGPM0 reg");
+ }
+ else
+ {
+ // Write to reg
+ FAPI_INF("Write MCFGPM1 reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGPM1, l_scomData);
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM1, l_scomData),
+ "Error writing to P9A_MI_MCFGPM1 reg");
+ }
+
+ // 3. ---- Set MCFGPA reg -----
+ l_scomData = 0;
+
+ // Assert if both HOLE1 and SMF are valid, settings will overlap
+ FAPI_ASSERT((l_data.MCFGPA_HOLE_valid[1] && l_data.MCFGPA_SMF_valid) == 0,
+ fapi2::MSS_SETUP_BARS_HOLE1_SMF_CONFLICT()
+ .set_TARGET(l_target)
+ .set_HOLE1_VALID(l_data.MCFGPA_HOLE_valid[1])
+ .set_SMF_VALID(l_data.MCFGPA_SMF_valid),
+ "Error: MCFGPA HOLE1 and SMF are both valid, settings will overlap");
+
+ // Hole 0
+ if (l_data.MCFGPA_HOLE_valid[0] == true)
+ {
+ // MCFGPA HOLE0 valid (bit 0)
+ l_scomData.setBit<P9A_MI_MCFGP0A_HOLE_VALID>();
+
+ // Hole 0 lower addr
+ // Hole 0 always extends to end of range
+ FAPI_DBG("l_data.MCFGPA_HOLE_LOWER_addr[0]: %016llx", l_data.MCFGPA_HOLE_LOWER_addr[0]);
+ FAPI_TRY(extBar(l_ext_mask, l_data.MCFGPA_HOLE_LOWER_addr[0], l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGP0A_HOLE_LOWER_ADDRESS,
+ P9A_MI_MCFGP0A_HOLE_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 9)); //matches 17:31 extendedBarAddress shifts left 8 (17-8) = 9
+ }
+
+ // SMF
+ if (l_data.MCFGPA_SMF_valid == true)
+ {
+ // MCFGPA SMF valid (bit 0)
+ l_scomData.setBit<P9A_MI_MCFGP0A_SMF_VALID>();
+
+ // MCFGPA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE
+ l_scomData.setBit<P9A_MI_MCFGP0A_SMF_EXTEND_TO_END_OF_RANGE>();
+
+ // SMF lower addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<22, 14>(l_data.MCFGPA_SMF_LOWER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGP0A_SMF_LOWER_ADDRESS,
+ P9A_MI_MCFGP0A_SMF_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 14)); //matches 22:35 extendBarAddress shifts left 8 (22-8) = 14
+ // SMF upper addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<22, 14>(l_data.MCFGPA_SMF_UPPER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGP0A_SMF_UPPER_ADDRESS,
+ P9A_MI_MCFGP0A_SMF_UPPER_ADDRESS_LEN>(
+ (l_extAddr << 14)); //matches 22:35 extendBarAddress shifts left 8 (22-8) = 14
+ }
+
+ // Write to reg
+ if (l_pos % 2 == 0)
+ {
+ FAPI_INF("Write MCFGP0A reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGP0A, l_scomData);
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP0A, l_scomData),
+ "Error writing to P9A_MI_MCFGP0A reg");
+ }
+ else
+ {
+ FAPI_INF("Write MCFGP1A reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGP1A, l_scomData);
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP1A, l_scomData),
+ "Error writing to P9A_MI_MCFGP1A reg");
+ }
+
+ // 4. ---- Set MCFGPMA reg -----
+ l_scomData = 0;
+
+ // Assert if both HOLE1 and SMF are valid, settings will overlap
+ FAPI_ASSERT((l_data.MCFGPMA_HOLE_valid[1] && l_data.MCFGPMA_SMF_valid) == 0,
+ fapi2::MSS_SETUP_BARS_HOLE1_SMF_CONFLICT()
+ .set_TARGET(l_target)
+ .set_HOLE1_VALID(l_data.MCFGPMA_HOLE_valid[1])
+ .set_SMF_VALID(l_data.MCFGPMA_SMF_valid),
+ "Error: MCFGPMA HOLE1 and SMF are both valid, settings will overlap");
+
+ // Hole 0
+ if (l_data.MCFGPMA_HOLE_valid[0] == true)
+ {
+ // MCFGPMA HOLE0 valid (bit 0)
+ l_scomData.setBit<P9A_MI_MCFGPM0A_HOLE_VALID>();
+
+ // Hole 0 lower addr
+ // 0b0000000001 = 4GB
+ FAPI_TRY(extBar(l_ext_mask, l_data.MCFGPMA_HOLE_LOWER_addr[0], l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGPM0A_HOLE_LOWER_ADDRESS,
+ P9A_MI_MCFGPM0A_HOLE_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 9)); //matches 17:31 extendedBarAddress shifts left 8 (17-8) = 9
+ }
+
+ // SMF
+ if (l_data.MCFGPMA_SMF_valid == true)
+ {
+ // MCFGPMA SMF valid (bit 0)
+ l_scomData.setBit<P9A_MI_MCFGPM0A_SMF_VALID>();
+
+ // MCFGPMA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE
+ l_scomData.setBit<P9A_MI_MCFGPM0A_SMF_EXTEND_TO_END_OF_RANGE>();
+
+ // SMF lower addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<22, 14>(l_data.MCFGPMA_SMF_LOWER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS,
+ P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS_LEN>(
+ (l_extAddr << 14 )); //matches 22:35 extendBarAddress shifts left 8 (22-8) = 14
+ // SMF upper addr
+ l_norAddr = 0;
+ l_norAddr.insertFromRight<22, 14>(l_data.MCFGPMA_SMF_UPPER_addr);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr));
+ l_scomData.insert<P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS,
+ P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS_LEN>(
+ (l_extAddr << 14)); //matches 22:35 extendBarAddress shifts left 8 (22-8) = 14
+ }
+
+ // Write to reg
+ if (l_pos % 2 == 0)
+ {
+ FAPI_INF("Write P9A_MI_MCFGPM0A reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGPM0A, l_scomData);
+
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM0A, l_scomData),
+ "Error writing to P9A_MI_MCFGPM0A reg");
+ }
+ else
+ {
+ FAPI_INF("Write P9A_MI_MCFGPM1A reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGPM1A, l_scomData);
+
+ FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM1A, l_scomData),
+ "Error writing to P9A_MI_MCFGPM1A reg");
+ }
+
+ } // Data pair loop
+
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Unmask FIR before opening BARs
+///
+/// @param[in] i_target target to set actions/mask
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
template<fapi2::TargetType T>
-fapi2::ReturnCode unmaskMCFIR(
- const std::vector<std::pair<fapi2::Target<T>, mcBarData_t>>& i_mcBarDataPair)
+fapi2::ReturnCode unmaskMCFIR(const fapi2::Target<T> i_target)
{
FAPI_DBG("Entering");
@@ -1495,20 +2368,40 @@ fapi2::ReturnCode unmaskMCFIR(
// Defect HW451708, HW451711
// Leave MCS_MCFIR_INVALID_SMF_ACCESS masked if MCD cl_probes are enabled
+ char l_targetStr[fapi2::MAX_ECMD_STRING_LEN];
+ fapi2::toString(i_target, l_targetStr, sizeof(l_targetStr));
+ FAPI_INF("Unmask FIR for MC target: %s", l_targetStr);
+
+ // Write MC FIR action1
+ FAPI_TRY(fapi2::putScom(i_target, MCS_MCFIRACT1, l_mcfiraction),
+ "Error from putScom (MCS_MCFIRACT1)");
+
+ // Write mask
+ FAPI_TRY(fapi2::putScom(i_target, MCS_MCFIRMASK_AND, l_mcfirmask_and),
+ "Error from putScom (MCS_MCFIRMASK_AND)");
+
+fapi_try_exit:
+ FAPI_DBG("Exit");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Unmask FIR before opening BARs
+///
+/// @param[in] i_mcBarDataPair Target pair <target, data>
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+template<fapi2::TargetType T>
+fapi2::ReturnCode unmaskMCFIR(
+ const std::vector<std::pair<fapi2::Target<T>, mcBarData_t>>& i_mcBarDataPair)
+{
+ FAPI_DBG("Entering");
+
for (auto l_pair : i_mcBarDataPair)
{
fapi2::Target<T> l_target = l_pair.first;
- char l_targetStr[fapi2::MAX_ECMD_STRING_LEN];
- fapi2::toString(l_target, l_targetStr, sizeof(l_targetStr));
- FAPI_INF("Unmask FIR for MC target: %s", l_targetStr);
-
- // Write MC FIR action1
- FAPI_TRY(fapi2::putScom(l_target, MCS_MCFIRACT1, l_mcfiraction),
- "Error from putScom (MCS_MCFIRACT1)");
-
- // Write mask
- FAPI_TRY(fapi2::putScom(l_target, MCS_MCFIRMASK_AND, l_mcfirmask_and),
- "Error from putScom (MCS_MCFIRMASK_AND)");
+ FAPI_TRY(unmaskMCFIR(l_target));
} // Data pair loop
@@ -1534,14 +2427,25 @@ fapi2::ReturnCode p9_mss_setup_bars(
std::vector<std::pair<fapi2::Target<fapi2::TARGET_TYPE_MCS>, mcBarData_t>> l_mcsBarDataPair;
// std_pair<MI target, MI data>
std::vector<std::pair<fapi2::Target<fapi2::TARGET_TYPE_MI>, mcBarData_t>> l_miBarDataPair;
+ // std_pair<MCC target, MCC data>
+ std::vector<std::pair<fapi2::Target<fapi2::TARGET_TYPE_MCC>, mcBarData_t>> l_mccBarDataPair;
+
+ fapi2::ATTR_CHIP_EC_FEATURE_OMI_Type l_omi;
// Get functional MCS chiplets, should be none for Cumulus
auto l_mcsChiplets = i_target.getChildren<fapi2::TARGET_TYPE_MCS>();
// Get functional MI chiplets, should be none for Nimbus
auto l_miChiplets = i_target.getChildren<fapi2::TARGET_TYPE_MI>();
+ // Get MCC chiplets for Axone
+ auto l_mccChiplets = i_target.getChildren<fapi2::TARGET_TYPE_MCC>();
FAPI_INF("Num of MCS %u; Num of MIs %u", l_mcsChiplets.size(), l_miChiplets.size());
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI,
+ i_target,
+ l_omi),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_EC_FEATURE_OMI)");
+
if ( (l_mcsChiplets.size() > 0) && (l_miChiplets.size() > 0) )
{
FAPI_ASSERT(false,
@@ -1564,7 +2468,7 @@ fapi2::ReturnCode p9_mss_setup_bars(
if (l_mcsChiplets.size() > 0)
{
// Validate group data from attributes
- FAPI_TRY(validateGroupData(l_mcsChiplets, l_groupData),
+ FAPI_TRY(validateGroupData(l_mcsChiplets, false, l_groupData),
"validateGroupData() returns error, l_rc 0x%.8X",
(uint64_t)fapi2::current_err);
@@ -1584,11 +2488,38 @@ fapi2::ReturnCode p9_mss_setup_bars(
(uint64_t)fapi2::current_err);
}
+ // Setup BAR for Axone
+ else if (l_mccChiplets.size() > 0)
+ {
+ // Validate group data from attributes
+ FAPI_TRY(validateGroupData(l_mccChiplets, true, l_groupData),
+ "validateGroupData() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Build MC BAR data based on Group data info
+ FAPI_TRY(buildMCBarData(l_mccChiplets, l_groupData, l_mccBarDataPair),
+ "buildMCBarData() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ // Unmask MC FIRs
+ for (auto l_target : l_miChiplets)
+ {
+ FAPI_TRY(unmaskMCFIR(l_target),
+ "unmaskMCFIR() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+ }
+
+ // Write data to MI
+ FAPI_TRY(writeMCBarData(l_mccBarDataPair),
+ "writeMCBarData() returns error, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ }
// Setup BAR for Cumulus
else if (l_miChiplets.size() > 0)
{
// Validate group data from attributes
- FAPI_TRY(validateGroupData(l_miChiplets, l_groupData),
+ FAPI_TRY(validateGroupData(l_miChiplets, false, l_groupData),
"validateGroupData() returns error, l_rc 0x%.8X",
(uint64_t)fapi2::current_err);
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.mk b/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.mk
index db115d16a..1c01fdbc7 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.mk
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_mss_setup_bars.mk
@@ -25,7 +25,8 @@
# Include the macros and things for MSS procedures
PROCEDURE=p9_mss_setup_bars
-$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/procedures/hwp/memory/)
+OBJS+=p9a_addr_ext.o
lib$(PROCEDURE)_DEPLIBS+=cen
+$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9/procedures/hwp/memory/)
$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_query_mssinfo.C b/src/import/chips/p9/procedures/hwp/nest/p9_query_mssinfo.C
index ea80302fc..3309552ec 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_query_mssinfo.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_query_mssinfo.C
@@ -64,8 +64,8 @@ fapi2::ReturnCode p9_query_mssinfo(const std::vector<fapi2::Target<fapi2::TARGET
//vars for attrs
uint64_t sizes[8];
uint64_t bases[8];
- uint64_t mirror_sizes[4] = {0, 0, 0, 0};
- uint64_t mirror_bases[4];
+ uint64_t mirror_sizes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ uint64_t mirror_bases[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t groupID[MBA_GROUP_SIZE][MBA_GROUP_DATA];
uint64_t nhtm_base;
uint64_t nhtm_size;
@@ -83,6 +83,7 @@ fapi2::ReturnCode p9_query_mssinfo(const std::vector<fapi2::Target<fapi2::TARGET
const int ONE_GIG = 30;
+ FAPI_DBG("i_vect_pu_targets.size(): %d", i_vect_pu_targets.size());
//loop over all elements in the vector
for(uint32_t i = 0; i < i_vect_pu_targets.size(); i++)
@@ -257,7 +258,7 @@ fapi2::ReturnCode p9_query_mssinfo(const std::vector<fapi2::Target<fapi2::TARGET
for(int j = 0; j < 8; j++)
{
if ((sizes[j] != 0) ||
- ((j < 4) && (mirror_sizes[j] != 0)))
+ ((mirror_sizes[j] != 0)))
{
printf("Group:%d (", j);
@@ -284,7 +285,7 @@ fapi2::ReturnCode p9_query_mssinfo(const std::vector<fapi2::Target<fapi2::TARGET
}
- if ((j < 4) && (mirror_sizes[j] != 0))
+ if ((mirror_sizes[j] != 0))
{
if (mirror_policy == fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_FLIPPED)
{
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C b/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C
new file mode 100644
index 000000000..4f6aeeb07
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C
@@ -0,0 +1,187 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9a_addr_ext.C
+/// @brief Handle address extension mask for Axone
+///
+
+// *HWP HWP Owner: Ben Gass bgass@us.ibm.com
+// *HWP FW Owner: Thi Tran thi@us.ibm.com
+// *HWP Team: Nest
+// *HWP Level: 3
+// *HWP Consumed by: HB
+
+//-----------------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------------
+#include <p9a_addr_ext.H>
+
+//-----------------------------------------------------------------------------------
+// Function definitions
+//-----------------------------------------------------------------------------------
+
+fapi2::ReturnCode p9a_get_ext_mask(uint64_t& o_ext_mask)
+{
+ FAPI_DBG("Start");
+ uint8_t l_addr_extension_group_id = 0;
+ uint8_t l_addr_extension_chip_id = 0;
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID,
+ FAPI_SYSTEM,
+ l_addr_extension_group_id),
+ "Error from FAPI_ATTR_GET (ATTR_FABRIC_ADDR_EXTENSION_GROUP_ID)");
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID,
+ FAPI_SYSTEM,
+ l_addr_extension_chip_id),
+ "Error from FAPI_ATTR_GET (ATTR_FABRIC_ADDR_EXTENSION_CHIP_ID");
+
+ o_ext_mask = ((l_addr_extension_group_id & 0xF) << 4) | (l_addr_extension_chip_id & 0xF);
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
+
+/*
+ * As documented
+ * BAR Bits 6 8 9 7 10 11 12 13
+ * 0x00 15 16 17 18 21 20 19 14
+ * 0x04 15 16 17 18 21 20 14 19
+ * 0x06 15 16 17 18 21 14 20 19
+ * 0x07 15 16 17 18 14 21 20 19
+ * 0x80 15 16 17 18 21 20 19 14
+ * 0x84 15 16 17 18 21 20 14 19
+ * 0x86 15 16 17 18 21 14 20 19
+ * 0x87 15 16 17 18 14 21 20 19
+ * 0xC0 15 17 18 21 20 19 14 16
+ * 0xC4 15 17 18 21 20 14 19 16
+ * 0xC6 15 17 18 21 14 20 19 16
+ * 0xC7 15 17 18 14 21 20 19 16
+ * 0xE0 15 18 21 20 19 14 17 16
+ * 0xE4 15 18 21 20 14 19 17 16
+ * 0xE6 15 18 21 14 20 19 17 16
+ * 0xE7 15 18 14 21 20 19 17 16
+ * 0xF0 15 21 20 19 14 18 17 16
+ * 0xF4 15 21 20 14 19 18 17 16
+ * 0xF6 15 21 14 20 19 18 17 16
+ * 0xF7 15 14 21 20 19 18 17 16
+ *
+ * Ordered bar bits
+ * BAR Bits 5 6 7 8 9 10 11 12 13 14 ...
+ * 0x00 13 15 18 16 17 21 20 19 14 22 ...
+ * 0x04 13 15 18 16 17 21 20 14 19 22 ...
+ * 0x06 13 15 18 16 17 21 14 20 19 22 ...
+ * 0x07 13 15 18 16 17 14 21 20 19 22 ...
+ * 0x80 13 15 18 16 17 21 20 19 14 22 ...
+ * 0x84 13 15 18 16 17 21 20 14 19 22 ...
+ * 0x86 13 15 18 16 17 21 14 20 19 22 ...
+ * 0x87 13 15 18 16 17 14 21 20 19 22 ...
+ * 0xC0 13 15 21 17 18 20 19 14 16 22 ...
+ * 0xC4 13 15 21 17 18 20 14 19 16 22 ...
+ * 0xC6 13 15 21 17 18 14 20 19 16 22 ...
+ * 0xC7 13 15 14 17 18 21 20 19 16 22 ...
+ * 0xE0 13 15 20 18 21 19 14 17 16 22 ...
+ * 0xE4 13 15 20 18 21 14 19 17 16 22 ...
+ * 0xE6 13 15 14 18 21 20 19 17 16 22 ...
+ * 0xE7 13 15 21 18 14 20 19 17 16 22 ...
+ * 0xF0 13 15 19 21 20 14 18 17 16 22 ...
+ * 0xF4 13 15 14 21 20 19 18 17 16 22 ...
+ * 0xF6 13 15 20 21 14 19 18 17 16 22 ...
+ * 0xF7 13 15 20 14 21 19 18 17 16 22 ...
+ *
+ *
+ */
+fapi2::ReturnCode extendBarAddress(const uint64_t& i_ext_mask, const fapi2::buffer<uint64_t>& i_bar_addr,
+ fapi2::buffer<uint64_t>& o_bar)
+{
+ static const uint64_t BAR_START_BIT = 8;
+ static const uint64_t BAR_MASK_STATIC_BITS = 0xFC03FFFE00000000ull; //31 bit bar, bits 6:13 reordered
+ static const uint64_t REORDER_START_BIT = 6; // reordering of bar starts at bit 6
+ static const int REORDER_END_BIT = 13; // reordering of bar stops at bit 13
+ static const int NUM_EXT_MASKS = 20; // 20 different extension masks are supported
+ static const uint64_t EXT_MASK_REORDER[][9] = // Workbook table 7
+ {
+ // B 6 7 8 9 10 11 12 13
+ { 0x00, 15, 18, 16, 17, 21, 20, 19, 14 },
+ { 0x04, 15, 18, 16, 17, 21, 20, 14, 19 },
+ { 0x06, 15, 18, 16, 17, 21, 14, 20, 19 },
+ { 0x07, 15, 18, 16, 17, 14, 21, 20, 19 },
+ { 0x80, 15, 18, 16, 17, 21, 20, 19, 14 },
+ { 0x84, 15, 18, 16, 17, 21, 20, 14, 19 },
+ { 0x86, 15, 18, 16, 17, 21, 14, 20, 19 },
+ { 0x87, 15, 18, 16, 17, 14, 21, 20, 19 },
+ { 0xC0, 15, 21, 17, 18, 20, 19, 14, 16 },
+ { 0xC4, 15, 21, 17, 18, 20, 14, 19, 16 },
+ { 0xC6, 15, 21, 17, 18, 14, 20, 19, 16 },
+ { 0xC7, 15, 14, 17, 18, 21, 20, 19, 16 },
+ { 0xE0, 15, 20, 18, 21, 19, 14, 17, 16 },
+ { 0xE4, 15, 20, 18, 21, 14, 19, 17, 16 },
+ { 0xE6, 15, 14, 18, 21, 20, 19, 17, 16 },
+ { 0xE7, 15, 21, 18, 14, 20, 19, 17, 16 },
+ { 0xF0, 15, 19, 21, 20, 14, 18, 17, 16 },
+ { 0xF4, 15, 14, 21, 20, 19, 18, 17, 16 },
+ { 0xF6, 15, 20, 21, 14, 19, 18, 17, 16 },
+ { 0xF7, 15, 20, 14, 21, 19, 18, 17, 16 }
+ };
+
+ uint64_t l_bar = i_bar_addr;
+ l_bar = i_bar_addr << BAR_START_BIT;
+ l_bar = l_bar & BAR_MASK_STATIC_BITS;
+ o_bar = l_bar;
+ FAPI_DBG("i_bar_addr: %llx o_bar: %llx", i_bar_addr, o_bar);
+
+ for (auto l_i = 0; l_i < NUM_EXT_MASKS; l_i++)
+ {
+ if (EXT_MASK_REORDER[l_i][0] == i_ext_mask)
+ {
+ int l_ro_idx = 1;
+
+ for (auto l_i2 = REORDER_START_BIT; l_i2 <= REORDER_END_BIT; l_i2++)
+ {
+ if (i_bar_addr.getBit(EXT_MASK_REORDER[l_i][l_ro_idx]))
+ {
+ o_bar.setBit(l_i2);
+ }
+
+ l_ro_idx++;
+ }
+
+ goto fapi_try_exit;
+ }
+ }
+
+ FAPI_DBG("o_bar: %llx", o_bar);
+ FAPI_ASSERT(false,
+ fapi2::PROC_OMI_SETUP_BARS_INVALID_ADDR_EXT_MASK()
+ .set_EXT_MASK(i_ext_mask),
+ "An invalid address extension mask was selected");
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.H b/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.H
new file mode 100644
index 000000000..de85fac47
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.H
@@ -0,0 +1,52 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9a_addr_ext.H
+/// @brief Handle address extension mask for Axone
+///
+
+// *HWP HWP Owner: Ben Gass bgass@us.ibm.com
+// *HWP FW Owner: Thi Tran thi@us.ibm.com
+// *HWP Team: Nest
+// *HWP Level: 3
+// *HWP Consumed by: HB
+
+#ifndef _P9A_ADDR_EXT_H_
+#define _P9A_ADDR_EXT_H_
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+
+//-----------------------------------------------------------------------------------
+// Function definitions
+//-----------------------------------------------------------------------------------
+
+fapi2::ReturnCode p9a_get_ext_mask(uint64_t& o_ext_mask);
+
+fapi2::ReturnCode extendBarAddress(const uint64_t& i_ext_mask, const fapi2::buffer<uint64_t>& i_bar_addr,
+ fapi2::buffer<uint64_t>& o_bar);
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C
new file mode 100644
index 000000000..e5efc07c5
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C
@@ -0,0 +1,222 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9a_omi_setup_bars.H
+/// @brief configure Axone inband address
+///
+/// Set the inband base address in the MC
+/// driven by attributes representing system memory map.
+///
+
+// *HWP HWP Owner: Ben Gass bgass@us.ibm.com
+// *HWP FW Owner: Thi Tran thi@us.ibm.com
+// *HWP Team: Nest
+// *HWP Level: 3
+// *HWP Consumed by: HB
+
+//-----------------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------------
+#include <p9a_omi_setup_bars.H>
+#include <p9a_addr_ext.H>
+#include <p9_fbc_utils.H>
+#include <p9_mc_scom_addresses.H>
+#include <p9a_misc_scom_addresses.H>
+#include <p9a_misc_scom_addresses_fld.H>
+#include <chips/ocmb/explorer/procedures/hwp/memory/exp_inband.H>
+
+//-----------------------------------------------------------------------------------
+// Function definitions
+//-----------------------------------------------------------------------------------
+
+fapi2::ReturnCode p9a_omi_setup_bars(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+{
+ FAPI_DBG("Start");
+ std::vector<uint64_t> l_base_addr_nm0;
+ std::vector<uint64_t> l_base_addr_nm1;
+ std::vector<uint64_t> l_base_addr_m;
+ fapi2::buffer<uint64_t> l_mmio_bar;
+ fapi2::buffer<uint64_t> l_cfg_bar;
+ uint64_t l_base_addr_mmio;
+ uint8_t l_pos;
+ uint8_t l_mcc_pos;
+ uint64_t l_ext_mask;
+
+ // determine base address of chip MMIO range
+ FAPI_TRY(p9_fbc_utils_get_chip_base_address(i_target,
+ EFF_FBC_GRP_CHIP_IDS,
+ l_base_addr_nm0,
+ l_base_addr_nm1,
+ l_base_addr_m,
+ l_base_addr_mmio),
+ "Error from p9_fbc_utils_get_chip_base_address");
+
+ FAPI_TRY(p9a_get_ext_mask(l_ext_mask));
+
+ FAPI_DBG("l_ext_mask: %x", l_ext_mask);
+ FAPI_DBG("l_base_addr_mmio: 0x%llx", l_base_addr_mmio);
+
+ for (auto l_mcc : i_target.getChildren<fapi2::TARGET_TYPE_MCC>())
+ {
+ fapi2::ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET_Type l_bar_offset;
+ uint64_t l_omi_inband_addr = 0;
+ fapi2::buffer<uint64_t> l_scom_data;
+
+ auto l_omi_targets = l_mcc.getChildren<fapi2::TARGET_TYPE_OMI>();
+
+ if (l_omi_targets.size() > 0)
+ {
+
+ // Set the sizes for the MMIO/Config bars
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mcc, l_pos),
+ "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
+ (uint64_t)fapi2::current_err);
+
+ l_scom_data.flush<0>();
+ // 2GB cfg and MMIO
+ l_scom_data.insertFromRight<P9A_MI_MCFGP0_MCFGPR0_CONFIGURATION_GROUP_SIZE,
+ P9A_MI_MCFGP0_MCFGPR0_CONFIGURATION_GROUP_SIZE_LEN>(mss::exp::ib::EXPLR_IB_BAR_SIZE);
+ l_scom_data.insertFromRight<P9A_MI_MCFGP0_MCFGPR0_MMIO_GROUP_SIZE,
+ P9A_MI_MCFGP0_MCFGPR0_MMIO_GROUP_SIZE_LEN>(mss::exp::ib::EXPLR_IB_BAR_SIZE);
+
+ // Write to reg
+ if (l_pos % 2 == 0)
+ {
+ FAPI_INF("Write MCFGP0 reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGP0, l_scom_data);
+ FAPI_TRY(fapi2::putScom(l_mcc.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP0, l_scom_data),
+ "Error writing to MCS_MCFGP reg");
+ }
+ else
+ {
+ FAPI_INF("Write MCFGP1 reg 0x%.16llX, Value 0x%.16llX",
+ P9A_MI_MCFGP1, l_scom_data);
+ FAPI_TRY(fapi2::putScom(l_mcc.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP1, l_scom_data),
+ "Error writing to MCS_MCFGP reg");
+ }
+
+ for (auto l_omi : l_omi_targets)
+ {
+ // retrieve OMI pos
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ l_omi,
+ l_pos),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)");
+
+ // retrieve inband BAR offset
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET,
+ l_omi,
+ l_bar_offset),
+ "Error from FAPI_ATTR_GET (ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET)");
+
+ FAPI_DBG("l_bar_offset: 0x%llx", l_bar_offset);
+
+ // If this is channel B, then the B bit must be set. If it is not, then the B bit must not be set.
+ FAPI_ASSERT( ((l_pos % 2) == 1) == // Is this B channel?
+ ((l_bar_offset & mss::exp::ib::EXPLR_IB_BAR_B_BIT) == mss::exp::ib::EXPLR_IB_BAR_B_BIT),
+
+ fapi2::PROC_OMI_SETUP_BARS_INVALID_BAR()
+ .set_TARGET(l_omi)
+ .set_BAR_VALUE(l_bar_offset),
+ "B Channel requires BAR size bit set");
+
+ FAPI_ASSERT(((l_bar_offset & mss::exp::ib::EXPLR_IB_BAR_MASK_ZERO) == 0),
+ fapi2::PROC_OMI_SETUP_BARS_INVALID_BAR()
+ .set_TARGET(l_omi)
+ .set_BAR_VALUE(l_bar_offset),
+ "Bar size not honored");
+
+ FAPI_ASSERT(((l_bar_offset & mss::exp::ib::EXPLR_IB_MMIO_OFFSET) == 0),
+ fapi2::PROC_OMI_SETUP_BARS_INVALID_BAR()
+ .set_TARGET(l_omi)
+ .set_BAR_VALUE(l_bar_offset),
+ "MMIO bit must not be set");
+
+ l_omi_inband_addr = l_bar_offset;
+ }
+
+ FAPI_DBG("l_omi_inband_addr: 0x%llx", l_omi_inband_addr);
+
+ // Force A Bar value
+ l_omi_inband_addr = l_omi_inband_addr & (~mss::exp::ib::EXPLR_IB_BAR_B_BIT);
+
+ FAPI_DBG("l_omi_inband_addr: 0x%llx", l_omi_inband_addr);
+
+ // Add MMIO address for the chip
+ l_omi_inband_addr = l_omi_inband_addr | l_base_addr_mmio;
+
+ FAPI_DBG("l_omi_inband_addr: 0x%llx", l_omi_inband_addr);
+
+ // Get cfg bar value
+ fapi2::buffer<uint64_t> l_omi_inband_buf = l_omi_inband_addr;
+ FAPI_DBG("l_omi_inband_buf: 0x%llx", l_omi_inband_buf);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_omi_inband_buf, l_cfg_bar));
+
+ FAPI_DBG("l_cfg_bar: 0x%llx", l_cfg_bar);
+
+ // Get MMIO bar value
+ l_omi_inband_addr = l_omi_inband_addr | mss::exp::ib::EXPLR_IB_MMIO_OFFSET;
+ l_omi_inband_buf = l_omi_inband_addr;
+ FAPI_DBG("l_omi_inband_buf: 0x%llx", l_omi_inband_buf);
+ FAPI_TRY(extendBarAddress(l_ext_mask, l_omi_inband_buf, l_mmio_bar));
+
+ FAPI_DBG("l_mmio_bar: 0x%llx", l_mmio_bar);
+
+ // Write the channel cfg reg
+ l_scom_data.flush<0>();
+ l_scom_data.setBit<P9A_MI_MCFGPR0_CONFIGURATION_VALID>(); //Enable CFG
+ l_scom_data.setBit<P9A_MI_MCFGPR0_MMIO_VALID>(); //Enable MMIO
+ l_scom_data.insert<P9A_MI_MCFGPR0_CONFIGURATION_GROUP_BASE_ADDRESS,
+ P9A_MI_MCFGPR0_CONFIGURATION_GROUP_BASE_ADDRESS_LEN>(l_cfg_bar);
+ l_scom_data.insert<P9A_MI_MCFGPR0_MMIO_GROUP_BASE_ADDRESS,
+ P9A_MI_MCFGPR0_MMIO_GROUP_BASE_ADDRESS_LEN>(l_mmio_bar);
+
+ // get MI target to configure MCFGPR
+ fapi2::Target<fapi2::TARGET_TYPE_MI> l_mi =
+ l_mcc.getParent<fapi2::TARGET_TYPE_MI>();
+ // retrieve DMI pos
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ l_mcc,
+ l_mcc_pos),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)");
+
+ // configure inband channel 0 MCFGPR0
+ if(l_mcc_pos % 2 == 0)
+ {
+ FAPI_TRY(putScom(l_mi, P9A_MI_MCFGPR0, l_scom_data));
+ }
+ // configure inband channel 1 MCFGPR1
+ else
+ {
+ FAPI_TRY(putScom(l_mi, P9A_MI_MCFGPR1, l_scom_data));
+ }
+ }
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.H b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.H
new file mode 100644
index 000000000..b313bf2d0
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.H
@@ -0,0 +1,74 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9a_omi_setup_bars.H
+/// @brief configure Axone inband address
+///
+/// Set the inband base address in the MC
+/// driven by attributes representing system memory map.
+///
+
+// *HWP HWP Owner: Ben Gass bgass@us.ibm.com
+// *HWP FW Owner: Thi Tran thi@us.ibm.com
+// *HWP Team: Nest
+// *HWP Level: 3
+// *HWP Consumed by: HB
+
+#ifndef _p9a_omi_setup_bars_H_
+#define _p9a_omi_setup_bars_H_
+
+
+//-----------------------------------------------------------------------------------
+// Includes
+//-----------------------------------------------------------------------------------
+#include <fapi2.H>
+
+//-----------------------------------------------------------------------------------
+// Structure definitions
+//-----------------------------------------------------------------------------------
+
+// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*p9a_omi_setup_bars_FP_t) (
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
+
+//-----------------------------------------------------------------------------------
+// Function prototype
+//-----------------------------------------------------------------------------------
+
+extern "C" {
+
+///
+/// @brief configure Cumulus inband address
+///
+/// @param[in] i_target => Processor chip target
+///
+/// @return FAPI_RC_SUCCESS if the setup completes successfully, else error
+//
+ fapi2::ReturnCode p9a_omi_setup_bars(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);
+
+} //extern"C"
+
+#endif //_p9a_omi_setup_bars_H_
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.mk b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.mk
new file mode 100644
index 000000000..d24e4e5f0
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.mk
@@ -0,0 +1,29 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/p9/procedures/hwp/nest/p9a_omi_setup_bars.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2017,2019
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+PROCEDURE=p9a_omi_setup_bars
+OBJS+=p9_fbc_utils.o
+OBJS+=p9a_addr_ext.o
+$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH))
+$(call BUILD_PROCEDURE)
OpenPOWER on IntegriCloud