diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C | 249 | ||||
-rw-r--r-- | src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H | 3 |
2 files changed, 226 insertions, 26 deletions
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 023bef116..b6baead19 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 @@ -1722,7 +1722,7 @@ void grouping_group3PortsPerGroup(const EffGroupingMemInfo& i_memInfo, // Rules for group of 3: // 1. All 3 ports must have same amount of memory - // 2. Crossed-MCS ports can be grouped if and only if: + // 2. Cross-MCS ports can be grouped if and only if: // - it's an even port (port0) in the MCS // - it's an odd port (port1) in the MCS and the even port is empty. // Ex: MCPORTID_0, MCPORTID_1, MCPORTID_3: MCPORTID_2 must be empty @@ -1806,7 +1806,11 @@ void grouping_group3PortsPerGroup(const EffGroupingMemInfo& i_memInfo, } /// -/// @brief Attempts to group 2 ports per group +/// @brief Attempts to group 2 ports on same MCS +/// +/// Rules: Both ports must not be grouped yet +/// Both ports must have the same amound of memory. +/// Both ports must be on the same MCS /// /// If they can be grouped, fills in the following fields in o_groupData: /// - iv_data[<group>][PORT_SIZE] @@ -1819,35 +1823,36 @@ void grouping_group3PortsPerGroup(const EffGroupingMemInfo& i_memInfo, /// @param[in] i_memInfo Reference to EffGroupingMemInfo structure /// @param[out] o_groupData Reference to output data /// -void grouping_group2PortsPerGroup(const EffGroupingMemInfo& i_memInfo, - EffGroupingData& o_groupData) +void grouping_2ports_same_MCS(const EffGroupingMemInfo& i_memInfo, + EffGroupingData& o_groupData) { FAPI_DBG("Entering"); - FAPI_INF("grouping_group2PortsPerGroup: Attempting to group 2 MC ports"); + FAPI_INF("grouping_2ports_same_MCS: Attempting to group 2 ports on same MCS"); uint8_t& g = o_groupData.iv_numGroups; const uint8_t PORTS_PER_GROUP = 2; - // First, try to group 2 ports that are in the same MCS (highest priority) for (uint8_t pos = 0; pos < NUM_MC_PORTS_PER_PROC; pos += 2) { - FAPI_DBG("Trying to group 2 ports of the same MCS.. ports %u %u", pos, pos + 1); + FAPI_DBG("Trying ports %u & %u", pos, pos + 1); - // Skip if port is already grouped or has no memory + // Check 1st port of MCS if ( (o_groupData.iv_portGrouped[pos]) || (i_memInfo.iv_portSize[pos] == 0) ) { - FAPI_DBG("Port %u already grouped or has no memory, skip", pos); + FAPI_DBG("Port %u already grouped or empty, skip", pos); continue; } + // Check 2nd port if ( (o_groupData.iv_portGrouped[pos + 1]) || (i_memInfo.iv_portSize[pos + 1] != i_memInfo.iv_portSize[pos]) ) { - FAPI_DBG("Port %u already grouped or memory not matched with port %u, skip", pos + 1, pos); + FAPI_DBG("Port %u already grouped or has different memory size, skip", + pos + 1); continue; } - // Successfully find 2 ports to group + // Successfully find 2 ports on same MCS to group o_groupData.iv_data[g][PORT_SIZE] = i_memInfo.iv_portSize[pos]; o_groupData.iv_data[g][PORTS_IN_GROUP] = PORTS_PER_GROUP; o_groupData.iv_data[g][GROUP_SIZE] = @@ -1860,11 +1865,182 @@ void grouping_group2PortsPerGroup(const EffGroupingMemInfo& i_memInfo, o_groupData.iv_portGrouped[pos] = true; o_groupData.iv_portGrouped[pos + 1] = true; - FAPI_INF("grouping_group2PortsPerGroup: Successfully grouped 2 (same MCS) " + FAPI_INF("grouping_2ports_same_MCS: Successfully grouped " "MC ports: %u, %u", pos, pos + 1); } - // Group the remaining 2 ports of different MCS + FAPI_DBG("Exiting"); + return; +} + +/// +/// @brief Attempts to group 2 groups of 2 on cross-MCS +/// +/// Rules: Both ports must not be grouped yet +/// Both ports must have the same amound of memory. +/// The other 2 ports of the same cross-MCS are also grouped by 2. +/// +/// If they can be grouped, fills in the following fields in o_groupData: +/// - iv_data[<group>][PORT_SIZE] +/// - iv_data[<group>][PORTS_IN_GROUP] +/// - iv_data[<group>][GROUP_SIZE] +/// - iv_data[<group>][MEMBER_IDX(<members>)] +/// - iv_portGrouped[<group>] +/// - iv_numGroups +/// +/// @param[in] i_memInfo Reference to EffGroupingMemInfo structure +/// @param[out] o_groupData Reference to output data +/// +void grouping_2groupsOf2_cross_MCS(const EffGroupingMemInfo& i_memInfo, + EffGroupingData& o_groupData) +{ + FAPI_DBG("Entering"); + FAPI_INF("grouping_2groupsOf2_cross_MCS: Attempting to group 2 groups of 2 on cross-MCS"); + uint8_t& g = o_groupData.iv_numGroups; + const uint8_t PORTS_PER_GROUP = 2; + uint8_t l_port = 0; + + // Try 2 groups of 2 from 2 cross-MCS. Possible combinations: + // MCS0 and MCS1 --> MCA0/MCA2 & MCA1/MCA3 or MCA0/MCA3 & MCA1/MCA2 + // MCS0 and MCS2 --> MCA0/MCA4 & MCA1/MCA5 or MCA0/MCA5 & MCA1/MCA4 + // MCS0 and MCS3 --> MCA0/MCA6 & MCA1/MCA7 or MCA0/MCA7 & MCA1/MCA6 + // MCS1 and MCS2 --> MCA2/MCA4 & MCA3/MCA5 or MCA2/MCA5 & MCA3/MCA4 + // MCS1 and MCS3 --> MCA2/MCA6 & MCA3/MCA7 or MCA2/MCA7 & MCA3/MCA6 + // MCS2 and MCS3 --> MCA4/MCA6 & MCA5/MCA7 or MCA4/MCA7 & MCA5/MCA6 + + // Get the 1st MCS candidate + for (uint8_t mcs1 = 0; mcs1 < (NUM_MCS_PER_PROC - 1); mcs1++) + { + FAPI_DBG("Checking MCS %u", mcs1); + + // Skip if any port of this MCS is already grouped or empty + l_port = mcs1 * 2; // First port number of this MCS + + if ( (o_groupData.iv_portGrouped[l_port]) || + (i_memInfo.iv_portSize[l_port] == 0) || + (o_groupData.iv_portGrouped[l_port + 1]) || + (i_memInfo.iv_portSize[l_port + 1] == 0) ) + { + FAPI_DBG("Skip 1st MCS %u, one of its ports already grouped or empty", mcs1); + continue; + } + + // Found first potential MCS, look for the 2nd MCS + for (uint8_t mcs2 = mcs1 + 1; mcs2 < NUM_MCS_PER_PROC; mcs2++) + { + l_port = mcs2 * 2; // First port number of 2nd MCS + + if ( (o_groupData.iv_portGrouped[l_port]) || + (i_memInfo.iv_portSize[l_port] == 0) || + (o_groupData.iv_portGrouped[l_port + 1]) || + (i_memInfo.iv_portSize[l_port + 1] == 0) ) + { + FAPI_DBG("Skip 2nd MCS %u, one of its ports already grouped or empty", mcs2); + continue; + } + + // Found 2 potential cross-MCS to group 2 groups of 2 + uint8_t mcs1pos0 = mcs1 * 2; + uint8_t mcs2pos0 = mcs2 * 2; + bool l_groupSuccess = false; + uint8_t l_twoGroupOf2[2][PORTS_PER_GROUP] = {0}; + + if ( (i_memInfo.iv_portSize[mcs1pos0] == i_memInfo.iv_portSize[mcs2pos0]) && + (i_memInfo.iv_portSize[mcs1pos0 + 1] == i_memInfo.iv_portSize[mcs2pos0 + 1]) ) + { + l_groupSuccess = true; + l_twoGroupOf2[0][0] = mcs1pos0; + l_twoGroupOf2[0][1] = mcs2pos0; + l_twoGroupOf2[1][0] = mcs1pos0 + 1; + l_twoGroupOf2[1][1] = mcs2pos0 + 1; + } + else if ( (i_memInfo.iv_portSize[mcs1pos0] == i_memInfo.iv_portSize[mcs2pos0 + 1]) && + (i_memInfo.iv_portSize[mcs1pos0 + 1] == i_memInfo.iv_portSize[mcs2pos0]) ) + { + l_groupSuccess = true; + l_twoGroupOf2[0][0] = mcs1pos0; + l_twoGroupOf2[0][1] = mcs2pos0 + 1; + l_twoGroupOf2[1][0] = mcs1pos0 + 1; + l_twoGroupOf2[1][1] = mcs2pos0; + } + + if (l_groupSuccess == false) + { + FAPI_DBG("Skip 2nd MCS %u, memory size are not equal for 2 groups of 2", mcs2); + continue; + } + + // Successfully group 2 groups of 2 from cross-MCS + + // First group: + o_groupData.iv_data[g][PORT_SIZE] = + i_memInfo.iv_portSize[l_twoGroupOf2[0][0]]; + o_groupData.iv_data[g][PORTS_IN_GROUP] = PORTS_PER_GROUP; + o_groupData.iv_data[g][GROUP_SIZE] = + PORTS_PER_GROUP * i_memInfo.iv_portSize[l_twoGroupOf2[0][0]]; + o_groupData.iv_data[g][MEMBER_IDX(0)] = l_twoGroupOf2[0][0]; + o_groupData.iv_data[g][MEMBER_IDX(1)] = l_twoGroupOf2[0][1]; + g++; + // Record which MC ports were grouped + o_groupData.iv_portGrouped[l_twoGroupOf2[0][0]] = true; + o_groupData.iv_portGrouped[l_twoGroupOf2[0][1]] = true; + + // Second group: + o_groupData.iv_data[g][PORT_SIZE] = i_memInfo.iv_portSize[l_twoGroupOf2[1][0]]; + o_groupData.iv_data[g][PORTS_IN_GROUP] = PORTS_PER_GROUP; + o_groupData.iv_data[g][GROUP_SIZE] = + PORTS_PER_GROUP * i_memInfo.iv_portSize[l_twoGroupOf2[1][0]]; + o_groupData.iv_data[g][MEMBER_IDX(0)] = l_twoGroupOf2[1][0]; + o_groupData.iv_data[g][MEMBER_IDX(1)] = l_twoGroupOf2[1][1]; + g++; + // Record which MC ports were grouped + o_groupData.iv_portGrouped[l_twoGroupOf2[1][0]] = true; + o_groupData.iv_portGrouped[l_twoGroupOf2[1][1]] = true; + + 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]); + } + } + + FAPI_DBG("Exiting"); + return; +} + +/// +/// @brief Attempts to group 2 ports per group +/// +/// If they can be grouped, fills in the following fields in o_groupData: +/// - iv_data[<group>][PORT_SIZE] +/// - iv_data[<group>][PORTS_IN_GROUP] +/// - iv_data[<group>][GROUP_SIZE] +/// - iv_data[<group>][MEMBER_IDX(<members>)] +/// - iv_portGrouped[<group>] +/// - iv_numGroups +/// +/// @param[in] i_memInfo Reference to EffGroupingMemInfo structure +/// @param[out] o_groupData Reference to output data +/// +void grouping_group2PortsPerGroup(const EffGroupingMemInfo& i_memInfo, + EffGroupingData& o_groupData) +{ + FAPI_DBG("Entering"); + FAPI_INF("grouping_group2PortsPerGroup: Attempting to group 2 MC ports"); + uint8_t& g = o_groupData.iv_numGroups; + const uint8_t PORTS_PER_GROUP = 2; + 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); + + // 2. Try two groups of 2 on cross-MCS + grouping_2groupsOf2_cross_MCS(i_memInfo, o_groupData); + + // 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"); + for (uint8_t pos = 0; pos < (NUM_MC_PORTS_PER_PROC - 1); pos++) { FAPI_DBG("Trying to group port %u with another port..", pos); @@ -1874,20 +2050,35 @@ void grouping_group2PortsPerGroup(const EffGroupingMemInfo& i_memInfo, (i_memInfo.iv_portSize[pos] == 0) ) { - FAPI_DBG("Skip this port because already grouped or it doesn't have memory:"); + FAPI_DBG("Skip this port because already grouped or empty:"); FAPI_DBG(" o_groupData.iv_portGrouped[%d] = %d", pos, o_groupData.iv_portGrouped[pos]); FAPI_DBG(" i_memInfo.iv_portSize[%d] = %d", pos, i_memInfo.iv_portSize[pos]); continue; } - // Rules for group of 2: + // Rules for group of 2 for remaining ports on cross-MCS // 1. Both ports must not be grouped yet and have the same amount of memory. - // 2. Crossed-MCS ports can be grouped if and only if: - // - it's an even port (port0) in the MCS - // - it's an odd port (port1) in the MCS and the even port is empty. - // Ex: MCPORTID_1, MCPORTID_2: MCPORTID_0 must be empty + // 2. For both ports, the other port in their MCS must be empty + // Ex: MCPORTID_1, MCPORTID_2: MCPORTID_0 and MCPORTID_3 must be empty // MCPORTID_1, MCPORTID_3: MCPORTID_0 and MCPORTID_2 must be empty - // MCPORTID_0, MCPORTID_2: OK to group if memory are equal. + // MCPORTID_0, MCPORTID_2: MCPORTID_1 and MCPORTID_3 must be empty + + // Skip if the other port in this MCS is not empty + if (pos % 2) + { + l_otherPort = pos - 1; + } + else + { + l_otherPort = pos + 1; + } + + if (i_memInfo.iv_portSize[l_otherPort] != 0) + { + FAPI_DBG("Skip this port because the other port (%u) in its MCS is not empty", + l_otherPort); + continue; + } // Check to see if any remaining ungrouped port has the same amount of memory for (uint8_t ii = pos + 1; ii < NUM_MC_PORTS_PER_PROC; ii++) @@ -1902,12 +2093,20 @@ void grouping_group2PortsPerGroup(const EffGroupingMemInfo& i_memInfo, continue; } - // These 2 ports are on different MCS, can't group if they are odd - // ports and their even port is not empty - if ( ((pos % 2) && (i_memInfo.iv_portSize[pos - 1] != 0)) || - ((ii % 2) && (i_memInfo.iv_portSize[ii - 1] != 0)) ) + // The other port in the same MCS with ii must be empty + if (ii % 2) + { + l_otherPort = ii - 1; + } + else + { + l_otherPort = ii + 1; + } + + if (i_memInfo.iv_portSize[l_otherPort] != 0) { - FAPI_DBG("Crossed MCS, can't group port %u and %u because even port is not empty", pos, ii); + FAPI_DBG("Cross-MCS, can't group ports %u and %u because port %u is not empty", + pos, ii, l_otherPort); continue; } 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 cb5ef7da4..fbad034d6 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,2016 */ +/* Contributors Listed Below - COPYRIGHT 2015,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -79,6 +79,7 @@ const uint8_t NUM_OF_ALT_MEM_REGIONS = 2; // 2 memory holes // For Nimbus, MC port is an MCA (8 MCAs) // For Cumulus, MC port is a DMI (8 DMIs) // ------------------------------------------------------- +const uint8_t NUM_MCS_PER_PROC = 4; const uint8_t NUM_MC_PORTS_PER_PROC = 8; const uint8_t NUM_DIMMS_PER_DRAM_PORT = 2; // 2 DIMMs per DRAM port |