diff options
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/nest')
16 files changed, 1164 insertions, 322 deletions
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C b/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C index 9f1a45f6b..58e2393cc 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C +++ b/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -998,7 +998,7 @@ fapi2::ReturnCode p9_fab_iovalid_get_link_delay( { FAPI_DBG("Start"); fapi2::buffer<uint64_t> l_link_delay_reg; - uint32_t l_sublink_delay[2]; + uint32_t l_sublink_delay[2] = {}; // read link delay register, extract hi/lo delay values & return their average FAPI_TRY(fapi2::getScom(i_target, i_link_ctl.tl_link_delay_addr, l_link_delay_reg), 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 342e32247..0feeff44e 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 @@ -745,7 +745,7 @@ fapi2::ReturnCode EffGroupingMccAttrs::getAttrs( iv_dimmSize = (iv_ocmbs.size() * l_min_size); // Display this OMI's attribute info - FAPI_INF("EffGroupingMccAttrs::getAttrs: MCC %d, OCMBs attached %d, " + FAPI_INF("EffGroupingMccAttrs::getAttrs: MCC %d, OCMBs w/ memory attached %d, " "iv_dimmSize %d GB ", iv_unitPos, iv_ocmbs.size(), iv_dimmSize); @@ -1553,7 +1553,8 @@ fapi2::ReturnCode EffGroupingBaseSizeData::set_HTM_OCC_base_addr( } // Setting NHTM & OCC base addresses - if ( (l_nhtmSize + l_chtmSize) < i_procAttrs.iv_occSandboxSize) + // Set larger allocations on top (at higher addresses) + if ( (l_nhtmSize + l_chtmSize) >= i_procAttrs.iv_occSandboxSize) { iv_occ_sandbox_base = l_mem_bases[l_index] + l_mem_sizes[l_index]; iv_nhtm_bar_base = iv_occ_sandbox_base + i_procAttrs.iv_occSandboxSize; @@ -1564,6 +1565,23 @@ fapi2::ReturnCode EffGroupingBaseSizeData::set_HTM_OCC_base_addr( iv_occ_sandbox_base = iv_nhtm_bar_base + l_nhtmSize + l_chtmSize; } + // Verify NHTM base addresses aligned with allocated size. + // The OCC sandbox base is just a FW scratch area and no HW + // functions mapped to it so we don't need to check its base alignment. + if ( ((l_nhtmSize + l_chtmSize) > 0) && + (iv_nhtm_bar_base & ((l_nhtmSize + l_chtmSize) - 1)) ) + { + FAPI_ASSERT(false, + fapi2::MSS_EFF_GROUPING_ADDRESS_NOT_ALIGNED() + .set_NHTM_BAR_BASE(iv_nhtm_bar_base) + .set_NHTM_SIZE(l_nhtmSize) + .set_CHTM_SIZE(l_chtmSize), + "EffGroupingBaseSizeData::set_HTM_OCC_base_addr: " + "NHTM BAR base address is not aligned with its size " + "NHTM_BAR_BASE 0x%.16llX, NHTM_SIZE 0x%.16llX, CTHM_SIZE 0x%.16llX", + iv_nhtm_bar_base, l_nhtmSize, l_chtmSize); + } + // Setting CHTM base addresses for (uint8_t ii = 0; ii < NUM_OF_CHTM_REGIONS; ii++) { @@ -1608,7 +1626,8 @@ fapi2::ReturnCode EffGroupingBaseSizeData::set_HTM_OCC_base_addr( } // Update mem sizes with working array values - if (l_numRegions == NUM_NON_MIRROR_REGIONS) + if (i_sysAttrs.iv_selectiveMode == + fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) { memcpy(iv_memory_sizes, l_mem_sizes, sizeof(iv_memory_sizes)); } @@ -1809,7 +1828,8 @@ fapi2::ReturnCode EffGroupingBaseSizeData::setSMFBaseSizeData( } // Update mem sizes with working array values - if (l_numRegions == NUM_NON_MIRROR_REGIONS) + if (i_sysAttrs.iv_selectiveMode == + fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) { memcpy(iv_memory_sizes, l_mem_sizes, sizeof(iv_memory_sizes)); } @@ -1839,7 +1859,7 @@ fapi2::ReturnCode EffGroupingBaseSizeData::setSMFBaseSizeData( ii, l_mem_bases[ii], l_mem_sizes[ii]); } - FAPI_INF("SMF_BASE %.16lld (%d GB)", iv_smf_bar_base, iv_smf_bar_base >> 30); + FAPI_INF("SMF_BASE 0x%.16llX", iv_smf_bar_base); for (uint8_t ii = 0; ii < l_numRegions; ii++) { @@ -2147,7 +2167,6 @@ void grouping_group8PortsPerGroup(const EffGroupingMemInfo& i_memInfo, o_groupData.iv_data[g][MEMBER_IDX(5)] = MCPORTID_5; o_groupData.iv_data[g][MEMBER_IDX(6)] = MCPORTID_3; o_groupData.iv_data[g][MEMBER_IDX(7)] = MCPORTID_7; - g++; // increase o_groupData.iv_numGroups // Record which MC ports were grouped // Check if OMI mirrorable @@ -2163,6 +2182,8 @@ void grouping_group8PortsPerGroup(const EffGroupingMemInfo& i_memInfo, } } + g++; // increase o_groupData.iv_numGroups + FAPI_INF("grouping_group8PortsPerGroup: Successfully grouped 8 " "MC ports."); } 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 90e62859e..46a87c966 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 @@ -6,6 +6,7 @@ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2015,2019 */ +/* [+] Inspur Power Systems Corp. */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -44,17 +45,20 @@ #include <p9_mc_scom_addresses_fld.H> #include <p9n2_mc_scom_addresses.H> #include <p9n2_mc_scom_addresses_fld.H> +#include <p9a_mc_scom_addresses.H> +#include <p9a_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 <exp_inband.H> +#include <lib/inband/exp_inband.H> ///---------------------------------------------------------------------------- /// Constant definitions ///---------------------------------------------------------------------------- +const uint8_t USTL_MDI_EQUAL_ONE = 1; const uint8_t MAX_MC_PORTS_PER_MCS = 2; // 2 MC ports per MCS const uint8_t NO_CHANNEL_PER_GROUP = 0xFF; // Init value of channel per group @@ -300,12 +304,12 @@ fapi2::ReturnCode getMcMemSize( uint8_t l_mcaPos = 0; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mca, l_mcaPos), "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Get the amount of memory behind this MCA target FAPI_TRY(mss::eff_memory_size<mss::mc_type::NIMBUS>(l_mca, l_mcaSize), "Error returned from eff_memory_size - MCA, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); FAPI_INF("MCA %u: Total DIMM size %lu GB", l_mcaPos, l_mcaSize); o_mcSize += l_mcaSize; @@ -334,12 +338,12 @@ fapi2::ReturnCode getMcMemSize( uint8_t l_dmiPos = 0; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_dmi, l_dmiPos), "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + 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_chSize), "Error returned from eff_memory_size - DMI, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); FAPI_INF("DMI %u: Total DIMM size %lu GB", l_dmiPos, l_chSize); o_mcSize += l_chSize; @@ -370,19 +374,19 @@ fapi2::ReturnCode getMcMemSize( for (auto l_omi : l_omiChiplets) { - const auto& l_ocmb_chiplets = l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>(); + const auto& l_ocmb_chips = l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>(); - if (!l_ocmb_chiplets.empty()) + if (!l_ocmb_chips.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); + 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), + FAPI_TRY(mss::eff_memory_size<mss::mc_type::EXPLORER>(l_ocmb_chips[0], l_chSize), "Error returned from eff_memory_size - ocmb, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); FAPI_INF("OMI %u: Total DIMM size %lu GB", l_omiPos, l_chSize); @@ -506,14 +510,14 @@ fapi2::ReturnCode validateGroupData( uint8_t l_mcPos = 0; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mc, l_mcPos), "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); FAPI_INF("validateGroupData: MC unit pos %d", l_mcPos); // Get the memory size behind this MC FAPI_TRY(getMcMemSize(l_mc, l_mcSize), "Error returned from getMcMemSize, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Get this MC memsize reported in Group data getGroupDataMcMemSize(l_mcPos, i_omi, i_groupData, l_portFound, @@ -536,6 +540,8 @@ fapi2::ReturnCode validateGroupData( } // MC loop + FAPI_INF("Total memory size= %lu GB", l_mcSize); + // Assert if a PORT_ID is found more than once in any group for (uint8_t ii = 0; ii < NUM_MC_PORTS_PER_PROC; ii++) { @@ -590,7 +596,7 @@ fapi2::ReturnCode getGroupSizeEncodedValue( uint8_t l_mcPos = 0; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_mcTarget, l_mcPos), "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Assert if can't find Group size in the table FAPI_ASSERT( false, fapi2::MSS_SETUP_BARS_INVALID_GROUP_SIZE() @@ -761,7 +767,7 @@ fapi2::ReturnCode getNonMirrorBarIdSize(const fapi2::Target<T>& i_mcTarget, FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo[0].groupSize, o_mcBarData.MCFGP_group_size), "getGroupSizeEncodedValue() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Group base address o_mcBarData.MCFGP_groupBaseAddr = i_portInfo[0].groupBaseAddr; @@ -774,7 +780,7 @@ fapi2::ReturnCode getNonMirrorBarIdSize(const fapi2::Target<T>& i_mcTarget, FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo[1].groupSize, o_mcBarData.MCFGPM_group_size), "getGroupSizeEncodedValue() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Group base address o_mcBarData.MCFGPM_groupBaseAddr = i_portInfo[1].groupBaseAddr; @@ -873,7 +879,7 @@ fapi2::ReturnCode getNonMirrorBarIdSize(const fapi2::Target<fapi2::TARGET_TYPE_M 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); + uint64_t(fapi2::current_err)); // Group base address o_mcBarData.MCFGP_groupBaseAddr = i_portInfo.groupBaseAddr; @@ -886,7 +892,7 @@ fapi2::ReturnCode getNonMirrorBarIdSize(const fapi2::Target<fapi2::TARGET_TYPE_M 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); + uint64_t(fapi2::current_err)); // Group base address o_mcBarData.MCFGPM_groupBaseAddr = i_portInfo.groupBaseAddr; @@ -1040,7 +1046,7 @@ fapi2::ReturnCode getMirrorBarData(const fapi2::Target<T>& i_mcTarget, FAPI_TRY(getGroupSizeEncodedValue(i_mcTarget, i_portInfo[1].groupSize, io_mcBarData.MCFGPM_group_size), "getGroupSizeEncodedValue() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Group base address io_mcBarData.MCFGPM_groupBaseAddr = i_portInfo[1].groupBaseAddr; @@ -1106,7 +1112,7 @@ fapi2::ReturnCode getMirrorBarData(const fapi2::Target<fapi2::TARGET_TYPE_MCC>& 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); + uint64_t(fapi2::current_err)); // Group base address io_mcBarData.MCFGPM_groupBaseAddr = i_portInfo.groupBaseAddr; @@ -1462,7 +1468,7 @@ fapi2::ReturnCode buildMCBarData( 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); + "l_rc 0x%.8X", uint64_t(fapi2::current_err)); for (auto l_mc : i_mcTargets) { @@ -1473,7 +1479,7 @@ fapi2::ReturnCode buildMCBarData( uint8_t l_unitPos = 0; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mc, l_unitPos), "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); fapi2::toString(l_mc, l_targetStr, sizeof(l_targetStr)); FAPI_INF("Build BAR data for MC target: %s", l_targetStr); @@ -1493,7 +1499,7 @@ fapi2::ReturnCode buildMCBarData( // ---- Build MCFGP/MCFGM data based on port group info ---- FAPI_TRY(getNonMirrorBarData(l_mc, l_portInfo, l_mcBarData), "getNonMirrorBarData() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // --------------------------------------------------------------- // Set MC register values for mirror groups @@ -1514,7 +1520,7 @@ fapi2::ReturnCode buildMCBarData( // ---- Build MCFGM data based on port group info ---- FAPI_TRY(getMirrorBarData(l_mc, l_portInfoMirrored, l_mcBarData), "getMirrorBarData() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); } } @@ -1563,7 +1569,7 @@ fapi2::ReturnCode buildMCBarData( 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); + "l_rc 0x%.8X", uint64_t(fapi2::current_err)); for (auto l_mcc : i_mccTargets) { @@ -1574,7 +1580,7 @@ fapi2::ReturnCode buildMCBarData( 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); + 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); @@ -1593,7 +1599,7 @@ fapi2::ReturnCode buildMCBarData( // ---- 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); + uint64_t(fapi2::current_err)); // --------------------------------------------------------------- // Set MC register values for mirror groups @@ -1610,7 +1616,7 @@ fapi2::ReturnCode buildMCBarData( // ---- 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); + uint64_t(fapi2::current_err)); } // Add to output pair @@ -1675,13 +1681,12 @@ fapi2::ReturnCode writeMCBarData( FAPI_DBG("Entering"); fapi2::buffer<uint64_t> l_scomData(0); - 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); + uint64_t(fapi2::current_err)); for (auto l_pair : i_mcBarDataPair) { @@ -1718,11 +1723,13 @@ fapi2::ReturnCode writeMCBarData( MCS_MCFGP_GROUP_BASE_ADDRESS_LEN>( (l_data.MCFGP_groupBaseAddr >> 2)); + // configure interleave granularity if 2/4/8 MC per group only - if ((l_data.MCFGP_chan_per_group == 0b0100) || // 2 MC/group - (l_data.MCFGP_chan_per_group == 0b0101) || - (l_data.MCFGP_chan_per_group == 0b0110) || // 4 MC/group - (l_data.MCFGP_chan_per_group == 0b1000)) // 8 MC/group + if ( (l_data.MCFGP_chan_per_group == 0b0100) || // 2 MC/group + (l_data.MCFGP_chan_per_group == 0b0101) || + (l_data.MCFGP_chan_per_group == 0b0110) || // 4 MC/group + (l_data.MCFGP_chan_per_group == 0b1000) // 8 MC/group + ) { fapi2::buffer<uint64_t> l_mcmode0_scom_data; FAPI_TRY(fapi2::getScom(l_target, MCS_MCMODE0, l_mcmode0_scom_data), @@ -1971,7 +1978,7 @@ fapi2::ReturnCode writeMCCInterleaveGranularity( 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); + uint64_t(fapi2::current_err)); for (auto l_pair : i_mcBarDataPair) { @@ -1982,33 +1989,6 @@ fapi2::ReturnCode writeMCCInterleaveGranularity( 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"); @@ -2065,10 +2045,19 @@ fapi2::ReturnCode writeMCBarData( uint8_t l_pos; fapi2::buffer<uint64_t> l_scomData(0); + fapi2::buffer<uint64_t> l_scomData_mirror(0); + fapi2::buffer<uint64_t> l_scomData_mcmode(0); fapi2::buffer<uint64_t> l_extAddr(0); fapi2::buffer<uint64_t> l_norAddr; uint64_t l_ext_mask; + const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; + uint8_t mirror_policy; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEM_MIRROR_PLACEMENT_POLICY, FAPI_SYSTEM, mirror_policy), + "Error reading ATTR_MEM_MIRROR_PLACEMENT_POLICY, l_rc 0x%.8X", + (uint64_t)fapi2::current_err); + FAPI_TRY(p9a_get_ext_mask(l_ext_mask)); FAPI_TRY(writeMCCInterleaveGranularity(i_mcBarDataPair)); @@ -2084,7 +2073,7 @@ fapi2::ReturnCode writeMCBarData( 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); + uint64_t(fapi2::current_err)); // 1. ---- Set MCFGP reg ----- l_scomData = 0; @@ -2174,55 +2163,176 @@ fapi2::ReturnCode writeMCBarData( "Error writing to P9A_MI_MCFGPM1 reg"); } - // 3. ---- Set MCFGPA reg ----- + // 3. ---- Set MCFGPA/MCFGPMA regs ----- 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"); + l_scomData_mirror = 0; // Hole 0 if (l_data.MCFGPA_HOLE_valid[0] == true) { - // MCFGPA HOLE0 valid (bit 0) - l_scomData.setBit<P9A_MI_MCFGP0A_HOLE_VALID>(); + if(mirror_policy == + fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) //Non-mirrored mode, but still set up mirrored equiv addressses + { + // Non-mirrored + // MCFGP0A HOLE valid (bit 0) + l_scomData.setBit<P9A_MI_MCFGP0A_HOLE_VALID>(); + + // Hole lower addr + // Hole 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 + + // Mirrored Address = Non-mirrored >> 1 since bit 56 is not part of the dsaddr + // MCFGPM0A HOLE0 valid (bit 0) + l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_HOLE_VALID>(); + + // Hole lower addr + // Hole always extends to end of range + FAPI_DBG("l_data.MCFGPA_HOLE_LOWER_addr[0]: %016llx", (l_data.MCFGPA_HOLE_LOWER_addr[0] >> 1)); + FAPI_TRY(extBar(l_ext_mask, l_data.MCFGPA_HOLE_LOWER_addr[0], l_extAddr)); + l_scomData_mirror.insert<P9A_MI_MCFGPM0A_HOLE_LOWER_ADDRESS, + P9A_MI_MCFGPM0A_HOLE_LOWER_ADDRESS_LEN>( + (l_extAddr << 8)); //matches 17:31 extendedBarAddress shifts left 8 (17- (8 + 1)) = 8 + } + else + { + // Mirrored Address + // MCFGPM0A HOLE0 valid (bit 0) + l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_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_mirror.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 + + // Non-mirrored Address = Mirrored Address << 1 since bit 56 is part of the dsaddr + // 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] << 1)); + 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 << 10)); //matches 17:31 extendedBarAddress shifts left 8 (17- (8 - 1)) = 10 - // 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>(); + FAPI_DBG("Writing SMF bit into address extension now"); + // Set up Extension Address for SMF + FAPI_TRY(fapi2::getScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCMODE2, l_scomData_mcmode), + "Error reading to P9A_MI_MCMODE2 reg"); + l_scomData_mcmode.setBit<P9A_MI_MCMODE2_CHIP_ADDRESS_EXTENSION_MASK_ENABLE>(); + FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCMODE2, l_scomData_mcmode), + "Error writing to P9A_MI_MCMODE2 reg"); + + if(mirror_policy == + fapi2::ENUM_ATTR_MEM_MIRROR_PLACEMENT_POLICY_NORMAL) //Non-mirrored mode, but still set up mirrored equiv addressses + { + //Non-mirrored + // 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<17, 19>(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 << 9)); //matches 17:35 extendBarAddress shifts left 8 (17-8) = 9 + // SMF upper addr + l_norAddr = 0; + l_norAddr.insertFromRight<17, 19>(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 << 9)); //matches 17:35 extendBarAddress shifts left 8 (17-8) = 9 + + + //Mirrored BAR = Non-mirrored BAR >> 1 since bit 56 is not a dsaddr bit + // MCFGPA SMF valid (bit 0) + l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_SMF_VALID>(); + + // MCFGPA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE + l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_SMF_EXTEND_TO_END_OF_RANGE>(); + + // SMF lower addr + l_norAddr = 0; + l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_LOWER_addr); + FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr)); + l_scomData_mirror.insert<P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS, + P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS_LEN>( + (l_extAddr << 8)); //matches 17:35 extendBarAddress shifts left 8 (17- (8 + 1)) = 8 + // SMF upper addr + l_norAddr = 0; + l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_UPPER_addr); + FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr)); + l_scomData_mirror.insert<P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS, + P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS_LEN>( + (l_extAddr << 8)); //matches 17:35 extendBarAddress shifts left 8 (17- (8 + 1)) = 8 + } + else + { + //Mirrored + // MCFGPA SMF valid (bit 0) + l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_SMF_VALID>(); + + // MCFGPA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE + l_scomData_mirror.setBit<P9A_MI_MCFGPM0A_SMF_EXTEND_TO_END_OF_RANGE>(); + + // SMF lower addr + l_norAddr = 0; + l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_LOWER_addr); + FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr)); + l_scomData_mirror.insert<P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS, + P9A_MI_MCFGPM0A_SMF_LOWER_ADDRESS_LEN>( + (l_extAddr << 9)); //matches 17:35 extendBarAddress shifts left 8 (17- 8) = 9 + // SMF upper addr + l_norAddr = 0; + l_norAddr.insertFromRight<17, 19>(l_data.MCFGPA_SMF_UPPER_addr); + FAPI_TRY(extendBarAddress(l_ext_mask, l_norAddr, l_extAddr)); + l_scomData_mirror.insert<P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS, + P9A_MI_MCFGPM0A_SMF_UPPER_ADDRESS_LEN>( + (l_extAddr << 9)); //matches 17:35 extendBarAddress shifts left 8 (17- 8) = 9 + + //Non-Mirrored BAR = Mirrored BAR << 1 since bit 56 is now a dsaddr bit + // 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<17, 19>(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 << 10)); //matches 17:35 extendBarAddress shifts left 8 (17- (8 - 1)) = 10 + // SMF upper addr + l_norAddr = 0; + l_norAddr.insertFromRight<17, 19>(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 << 10)); //matches 17:35 extendBarAddress shifts left 8 (17- (8 - 1)) = 10 - // 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 @@ -2232,6 +2342,11 @@ fapi2::ReturnCode writeMCBarData( 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"); + + FAPI_INF("Write MCFGPM0A reg 0x%.16llX, Value 0x%.16llX", + P9A_MI_MCFGPM0A, l_scomData_mirror); + FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM0A, l_scomData_mirror), + "Error writing to P9A_MI_MCFGPM0A reg"); } else { @@ -2239,83 +2354,76 @@ fapi2::ReturnCode writeMCBarData( 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 + FAPI_INF("Write MCFGPM1A reg 0x%.16llX, Value 0x%.16llX", + P9A_MI_MCFGPM1A, l_scomData_mirror); + FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM1A, l_scomData_mirror), + "Error writing to P9A_MI_MCFGP1A reg"); } + } // Data pair loop - // SMF - if (l_data.MCFGPMA_SMF_valid == true) - { - // MCFGPMA SMF valid (bit 0) - l_scomData.setBit<P9A_MI_MCFGPM0A_SMF_VALID>(); +fapi_try_exit: + FAPI_DBG("Exit"); + return fapi2::current_err; +} - // MCFGPMA_SMF_UPPER_ADDRESS_AT_END_OF_RANGE - l_scomData.setBit<P9A_MI_MCFGPM0A_SMF_EXTEND_TO_END_OF_RANGE>(); +/// +/// @brief Apply Gemini MDI bit workaround and mask Channel Timeout +/// +/// @param[in] i_target target to set actions/mask +/// +/// @return FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode applyGeminiFixes(const fapi2::Target<fapi2::TARGET_TYPE_MCC> i_target) +{ + FAPI_DBG("Entering fixGeminiMDI on %s", mss::c_str(i_target)); - // 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 - } + fapi2::buffer<uint64_t> l_scom_data; + uint8_t l_any_gemini = 0; + const auto l_omiChiplets = i_target.getChildren<fapi2::TARGET_TYPE_OMI>(); - // 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); + for (const auto& l_omi : l_omiChiplets) + { + const auto& l_ocmb_chips = l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>(); - FAPI_TRY(fapi2::putScom(l_target.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGPM0A, l_scomData), - "Error writing to P9A_MI_MCFGPM0A reg"); - } - else + if (!l_ocmb_chips.empty()) { - 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"); + uint8_t l_workaround = 0; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_AXONE_GEMINI_MDI_ERROR, + l_ocmb_chips[0], + l_workaround), + "Error from FAPI_ATTR_GET (ATTR_CHIP_EC_FEATURE_AXONE_GEMINI_MDI_ERROR)"); + l_any_gemini |= l_workaround; } + } - } // Data pair loop + if(l_any_gemini) + { + // MDI Workaround + FAPI_TRY(fapi2::getScom(i_target, P9A_MCC_USTLCFG, l_scom_data), + "Error reading from MCC_USTLCFG reg"); + l_scom_data.setBit<P9A_MCC_USTLCFG_DEFAULT_META_DATA_ENABLE>(); + l_scom_data.insertFromRight<P9A_MC_USTLCFG_DEFAULT_META_DATA, + P9A_MC_USTLCFG_DEFAULT_META_DATA_LEN>(USTL_MDI_EQUAL_ONE); + FAPI_TRY(fapi2::putScom(i_target, P9A_MCC_USTLCFG, l_scom_data), + "Error writing to MCC_USTLCFG reg"); + + + fapi2::Target<fapi2::TARGET_TYPE_MI> l_mi_target = i_target.getParent<fapi2::TARGET_TYPE_MI>(); + // Channel Timeout + FAPI_TRY(fapi2::getScom(l_mi_target, P9A_MI_MCTO, l_scom_data), + "Error reading from MCC_USTLCFG reg"); + l_scom_data.clearBit<P9A_MI_MCTO_ENABLE_CHANNEL_HANG>(); + FAPI_TRY(fapi2::putScom(l_mi_target, P9A_MI_MCTO, l_scom_data), + "Error writing to MCC_USTLCFG reg"); + } + + return fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: - FAPI_DBG("Exit"); + FAPI_DBG("Exiting fixGeminiMDI on %s", mss::c_str(i_target)); return fapi2::current_err; } - /// /// @brief Unmask FIR before opening BARs /// @@ -2462,7 +2570,7 @@ fapi2::ReturnCode p9_mss_setup_bars( FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_MCS_GROUP_32, i_target, l_groupData), "Error getting ATTR_MSS_MCS_GROUP_32, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Setup BAR for Nimbus if (l_mcsChiplets.size() > 0) @@ -2470,22 +2578,22 @@ fapi2::ReturnCode p9_mss_setup_bars( // Validate group data from attributes FAPI_TRY(validateGroupData(l_mcsChiplets, false, l_groupData), "validateGroupData() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Build MC BAR data based on Group data info FAPI_TRY(buildMCBarData(l_mcsChiplets, l_groupData, l_mcsBarDataPair), "buildMCBarData() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Unmask MC FIRs FAPI_TRY(unmaskMCFIR(l_mcsBarDataPair), "unmaskMCFIR() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Write data to MCS FAPI_TRY(writeMCBarData(l_mcsBarDataPair), "writeMCBarData() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); } // Setup BAR for Axone @@ -2494,25 +2602,33 @@ fapi2::ReturnCode p9_mss_setup_bars( // 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); + 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); + 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); + uint64_t(fapi2::current_err)); + } + + // Apply Gemini MDI bit workaround + for (fapi2::Target<fapi2::TARGET_TYPE_MCC> l_target : l_mccChiplets) + { + FAPI_TRY(applyGeminiFixes(l_target), + "fixGeminiMDI() 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); + uint64_t(fapi2::current_err)); } // Setup BAR for Cumulus @@ -2521,22 +2637,22 @@ fapi2::ReturnCode p9_mss_setup_bars( // Validate group data from attributes FAPI_TRY(validateGroupData(l_miChiplets, false, l_groupData), "validateGroupData() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Build MC BAR data based on Group data info FAPI_TRY(buildMCBarData(l_miChiplets, l_groupData, l_miBarDataPair), "buildMCBarData() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Unmask MC FIRs FAPI_TRY(unmaskMCFIR(l_miBarDataPair), "unmaskMCFIR() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); // Write data to MI FAPI_TRY(writeMCBarData(l_miBarDataPair), "writeMCBarData() returns error, l_rc 0x%.8X", - (uint64_t)fapi2::current_err); + uint64_t(fapi2::current_err)); } diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C b/src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C index cf3edc4f4..cb2e6f175 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C +++ b/src/import/chips/p9/procedures/hwp/nest/p9_npu_scominit.C @@ -42,6 +42,7 @@ #include <p9_misc_scom_addresses_fld.H> #include <p9a_misc_scom_addresses.H> #include <p9a_misc_scom_addresses_fld.H> +#include <p9_fbc_ioo_dl_npu_scom.H> //------------------------------------------------------------------------------ // Constant definitions @@ -99,6 +100,30 @@ fapi2::ReturnCode p9_npu_scominit( goto fapi_try_exit; } + // Enable obus for NPU for Axone + if (l_axone) + { + auto l_obus_targets = i_target.getChildren<fapi2::TARGET_TYPE_OBUS>(); + + for (auto l_obus_target : l_obus_targets) + { + FAPI_DBG("Invoking p9.fbc.ioo_dl.npu.scom.initfile..."); + FAPI_EXEC_HWP(l_rc, + p9_fbc_ioo_dl_npu_scom, + l_obus_target, + i_target, + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>()); + + if (l_rc) + { + FAPI_ERR("Error from p9.fbc.ioo_dl.npu.scom.initfile"); + fapi2::current_err = l_rc; + goto fapi_try_exit; + } + + } + } + // apply additional SCOM inits l_atrmiss.setBit<PU_NPU_SM2_XTS_ATRMISS_FLAG_MAP>() .setBit<PU_NPU_SM2_XTS_ATRMISS_ENA>(); diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars.C b/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars.C index 844899466..31a20244d 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars.C +++ b/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -743,6 +743,160 @@ fapi_try_exit: } +/// @brief Configure an NPU instance +/// +/// @param[in] i_target Processor chip target +/// @param[in] i_attr_bar_enable Enable the NPU MMIO bar +/// @param[in] i_attr_bar The BAR for the NPU instance +/// @param[in] i_mmio_offset The MMIO offset for the chip +/// @param[in] i_attr_pri The private reg interface settings for each NDL +/// @param[in] i_npu_regs The registers for this NPU +/// @param[in] i_chip_info Structure describing chip properties/base addresses +/// +/// @return FAPI_RC_SUCCESS if all calls are successful, else error +fapi2::ReturnCode +p9a_setup_bars_npuX(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, + const uint8_t& i_attr_bar_enable, + fapi2::buffer<uint64_t> i_attr_bar, + const uint64_t& i_mmio_offset, + const uint8_t i_attr_pri[], + p9_setup_bars_p9a_npu_regs& i_npu_regs, + p9_setup_bars_chip_info& i_chip_info) +{ + FAPI_DBG("Start"); + + if (i_attr_bar_enable) + { + p9_setup_bars_addr_range l_mmio_range; + FAPI_ASSERT((i_attr_bar & P9_SETUP_BARS_OFFSET_MASK_16_MB) == 0, + fapi2::P9_SETUP_BARS_NPU_MMIO_BAR_ATTR_ERR() + .set_TARGET(i_target) + .set_BAR_OFFSET(i_attr_bar) + .set_BAR_OFFSET_MASK(P9_SETUP_BARS_OFFSET_MASK_16_MB) + .set_BAR_OVERLAP(i_attr_bar & P9_SETUP_BARS_OFFSET_MASK_2_MB), + "NPU MMIO BAR offset attribute is not aligned to HW implementation"); + + i_attr_bar &= NPU_BAR_BASE_ADDR_MASK; + i_attr_bar += i_mmio_offset; + i_attr_bar = i_attr_bar << NPU_BAR_ADDR_SHIFT; + i_attr_bar = NPU_BAR_REG_MASK & i_attr_bar; + i_attr_bar.setBit<PU_NPU0_SM0_PHY_BAR_CONFIG_ENABLE>(); + + for (uint8_t ll = 0; ll < NPU_NUM_BAR_SHADOWS; ll++) + { + FAPI_TRY(fapi2::putScom(i_target, i_npu_regs.bar_regs[ll], i_attr_bar), + "Error from putScom (0x08X)", i_npu_regs.bar_regs[ll]); + } + + l_mmio_range.base_addr = i_attr_bar; + l_mmio_range.size = P9_SETUP_BARS_SIZE_16_MB; + l_mmio_range.enabled = true; + i_chip_info.ranges.push_back(l_mmio_range); + i_chip_info.ranges.back().print(); + } + + for (uint8_t ll = 0; ll < NPU_NUM_BAR_SHADOWS; ll++) + { + uint64_t l_pri_val = static_cast<uint64_t>(i_attr_pri[ll]) << (64 - 8); + FAPI_TRY(fapi2::putScom(i_target, i_npu_regs.pri_regs[ll], l_pri_val), + "Error from putScom (0x08X)", i_npu_regs.pri_regs[ll]); + } + +fapi_try_exit: + FAPI_DBG("End"); + return fapi2::current_err; +} + +/// @brief Configure p9a NPU MMIO access +/// +/// @param[in] i_target Processor chip target +/// @param[in] i_target_sys System target +/// @param[in] i_chip_info Structure describing chip properties/base addresses +/// +/// @return FAPI_RC_SUCCESS if all calls are successful, else error +fapi2::ReturnCode +p9a_setup_bars_npu(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, + const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& i_target_sys, + p9_setup_bars_chip_info& i_chip_info) + +{ + FAPI_DBG("Start"); + + fapi2::buffer<uint64_t> l_mmio_bar = i_chip_info.base_address_mmio; + + //NPU0 + { + fapi2::ATTR_PROC_NPU0_MMIO_BAR_ENABLE_Type l_mmio_enable; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU0_MMIO_BAR_ENABLE, i_target, l_mmio_enable), + "Error from FAPI_ATTR_GET (ATTR_PROC_NPU0_MMIO_BAR_ENABLE)"); + + fapi2::ATTR_PROC_NPU0_MMIO_BAR_BASE_ADDR_OFFSET_Type l_mmio_offset; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU0_MMIO_BAR_BASE_ADDR_OFFSET, i_target_sys, l_mmio_offset), + "Error from FAPI_ATTR_GET (ATTR_PROC_NPU0_MMIO_BAR_BASE_ADDR_OFFSET)"); + + fapi2::ATTR_PROC_NPU0_PRI_CONFIG_Type l_pri_config; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU0_PRI_CONFIG, i_target, l_pri_config), + "Error from FAPI_ATTR_GET (ATTR_PROC_NPU0_PRI_CONFIG)"); + + FAPI_TRY(p9a_setup_bars_npuX(i_target, + l_mmio_enable, + l_mmio_offset, + l_mmio_bar, + l_pri_config, + p9_setup_bars_p9a_npu0_regs, + i_chip_info)); + } + //NPU1 + { + fapi2::ATTR_PROC_NPU1_MMIO_BAR_ENABLE_Type l_mmio_enable; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU1_MMIO_BAR_ENABLE, i_target, l_mmio_enable), + "Error from FAPI_ATTR_GET (ATTR_PROC_NPU1_MMIO_BAR_ENABLE)"); + + fapi2::ATTR_PROC_NPU1_MMIO_BAR_BASE_ADDR_OFFSET_Type l_mmio_offset; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU1_MMIO_BAR_BASE_ADDR_OFFSET, i_target_sys, l_mmio_offset), + "Error from FAPI_ATTR_GET (ATTR_PROC_NPU1_MMIO_BAR_BASE_ADDR_OFFSET)"); + + fapi2::ATTR_PROC_NPU1_PRI_CONFIG_Type l_pri_config; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU1_PRI_CONFIG, i_target, l_pri_config), + "Error from FAPI_ATTR_GET (ATTR_PROC_NPU1_PRI_CONFIG)"); + + FAPI_TRY(p9a_setup_bars_npuX(i_target, + l_mmio_enable, + l_mmio_offset, + l_mmio_bar, + l_pri_config, + p9_setup_bars_p9a_npu1_regs, + i_chip_info)); + } + //NPU2 + { + fapi2::ATTR_PROC_NPU2_MMIO_BAR_ENABLE_Type l_mmio_enable; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU2_MMIO_BAR_ENABLE, i_target, l_mmio_enable), + "Error from FAPI_ATTR_GET (ATTR_PROC_NPU2_MMIO_BAR_ENABLE)"); + + fapi2::ATTR_PROC_NPU2_MMIO_BAR_BASE_ADDR_OFFSET_Type l_mmio_offset; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU2_MMIO_BAR_BASE_ADDR_OFFSET, i_target_sys, l_mmio_offset), + "Error from FAPI_ATTR_GET (ATTR_PROC_NPU2_MMIO_BAR_BASE_ADDR_OFFSET)"); + + fapi2::ATTR_PROC_NPU2_PRI_CONFIG_Type l_pri_config; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NPU2_PRI_CONFIG, i_target, l_pri_config), + "Error from FAPI_ATTR_GET (ATTR_PROC_NPU2_PRI_CONFIG)"); + + FAPI_TRY(p9a_setup_bars_npuX(i_target, + l_mmio_enable, + l_mmio_offset, + l_mmio_bar, + l_pri_config, + p9_setup_bars_p9a_npu2_regs, + i_chip_info)); + } + +fapi_try_exit: + FAPI_DBG("End"); + return fapi2::current_err; +} + + /// @brief Configure NPU MMIO access /// /// @param[in] i_target Processor chip target @@ -1237,7 +1391,12 @@ p9_setup_bars_check_overlap(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i .set_BASE_ADDR2(i_chip_info.ranges[jj].base_addr) .set_END_ADDR2(i_chip_info.ranges[jj].end_addr()) .set_ENABLED2(i_chip_info.ranges[jj].enabled), - "Overlapping address regions detected!"); + "Overlapping address regions detected %llx->%llx %llx->%llx!", + i_chip_info.ranges[ii].base_addr, + i_chip_info.ranges[ii].end_addr(), + i_chip_info.ranges[jj].base_addr, + i_chip_info.ranges[jj].end_addr() + ); } } } @@ -1255,6 +1414,10 @@ p9_setup_bars(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) FAPI_INF("Start"); fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; p9_setup_bars_chip_info l_chip_info; + fapi2::ATTR_CHIP_EC_FEATURE_ONE_NPU_TOP_Type l_one_npu; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_ONE_NPU_TOP, i_target, l_one_npu), + "Error from FAPI_ATTR_GET (ATTR_CHIP_EC_FEATURE_ONE_NPU_TOP)"); // process chip information FAPI_TRY(p9_setup_bars_build_chip_info(i_target, @@ -1268,9 +1431,18 @@ p9_setup_bars(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) // PSI FAPI_TRY(p9_setup_bars_psi(i_target, FAPI_SYSTEM, l_chip_info), "Error from p9_setup_bars_psi"); + // NPU - FAPI_TRY(p9_setup_bars_npu(i_target, FAPI_SYSTEM, l_chip_info), - "Error from p9_setup_bars_npu"); + if (l_one_npu) + { + FAPI_TRY(p9_setup_bars_npu(i_target, FAPI_SYSTEM, l_chip_info), + "Error from p9_setup_bars_npu"); + } + else + { + FAPI_TRY(p9a_setup_bars_npu(i_target, FAPI_SYSTEM, l_chip_info), + "Error from p9a_setup_bars_npu"); + } // MCD if (!l_chip_info.hw423589_option1) diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars_defs.H b/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars_defs.H index ebf4682af..19a04873e 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars_defs.H +++ b/src/import/chips/p9/procedures/hwp/nest/p9_setup_bars_defs.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -344,6 +344,13 @@ const uint8_t NPU_NUM_BAR_SHADOWS = 4; const uint64_t NPU_BAR_BASE_ADDR_MASK = 0x0001FFFFFFFFFFFFULL; const uint64_t NPU_BAR_ADDR_SHIFT = 12; +// The NPU BAR does not include the Memory Select bits. +// This mask ensures after shifting the attribute bar value +// we only set the relivant BAR bits. +// 0001122233444556 +// 0482604826048260 +const uint64_t NPU_BAR_REG_MASK = 0x1FFFFFF000000000ULL; + const uint64_t NPU_PHY0_BAR_REGS_NDD1[NPU_NUM_BAR_SHADOWS] = { PU_NPU0_SM0_PHY_BAR, @@ -360,6 +367,14 @@ const uint64_t NPU_PHY0_BAR_REGS[NPU_NUM_BAR_SHADOWS] = 0x05011496 }; +const uint64_t NPU_PHY0_BAR_REGS_ADD1[NPU_NUM_BAR_SHADOWS] = +{ + 0x05011406, + 0x05011436, + 0x05011466, + 0x05011496 +}; + const uint64_t NPU_PHY1_BAR_REGS_NDD1[NPU_NUM_BAR_SHADOWS] = { PU_NPU1_SM0_PHY_BAR, @@ -392,4 +407,29 @@ const uint64_t NPU_MMIO_BAR_REGS[NPU_NUM_BAR_SHADOWS] = 0x05011096 }; +// P9A Npu instances +struct p9_setup_bars_p9a_npu_regs +{ + uint64_t bar_regs[NPU_NUM_BAR_SHADOWS]; + uint64_t pri_regs[NPU_NUM_BAR_SHADOWS]; +}; + +p9_setup_bars_p9a_npu_regs p9_setup_bars_p9a_npu0_regs = +{ + { 0x501103C, 0x501109C, 0x50110FC, 0x501115C }, + { 0x50111F6, 0x5011216, 0x50113D6, 0x50113F6 } +}; + +p9_setup_bars_p9a_npu_regs p9_setup_bars_p9a_npu1_regs = +{ + { 0x501143C, 0x501149C, 0x50114FC, 0x501155C }, + { 0x50115F6, 0x5011616, 0x50117D6, 0x50117F6 } +}; + +p9_setup_bars_p9a_npu_regs p9_setup_bars_p9a_npu2_regs = +{ + { 0x3011C3C, 0x3011C9C, 0x3011CFC, 0x3011D5C }, + { 0x3011DF6, 0x3011E16, 0x3011FD6, 0x3011FF6 } +}; + #endif //_P9_SETUP_BARS_DEFS_H_ diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.C b/src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.C index e62ff6ab1..3ed9cc44c 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.C +++ b/src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -43,7 +43,7 @@ //------------------------------------------------------------------------------ #include <p9_throttle_sync.H> #include <fapi2.H> -#include <generic/memory/lib/utils/find.H> +#include <lib/utils/nimbus_find.H> #include <p9_perv_scom_addresses.H> ///---------------------------------------------------------------------------- @@ -79,13 +79,30 @@ template<> uint8_t findNumDimms(const fapi2::Target<fapi2::TARGET_TYPE_MI>& i_miTarget) { FAPI_DBG("Entering findNumDimms"); - auto l_dmiChiplets = i_miTarget.getChildren<fapi2::TARGET_TYPE_DMI>(); uint8_t l_num_dimms = 0; - for (auto l_dmi : l_dmiChiplets) + // Cumulus code + const auto& l_dmiChiplets = i_miTarget.getChildren<fapi2::TARGET_TYPE_DMI>(); + + for (const auto& l_dmi : l_dmiChiplets) + { + const auto& l_memBufs = l_dmi.getChildren<fapi2::TARGET_TYPE_MEMBUF_CHIP>(); + + if (l_memBufs.size() > 0) + { + l_num_dimms++; + } + } + + FAPI_DBG("After number of DIMM's after cumulus targets %u", l_num_dimms); + + // Axone code + const auto& l_omiChiplets = i_miTarget.getChildren<fapi2::TARGET_TYPE_OMI>(); + + for (const auto& l_omi : l_omiChiplets) { - auto l_memBufs = l_dmi.getChildren<fapi2::TARGET_TYPE_MEMBUF_CHIP>(); + const auto& l_memBufs = l_omi.getChildren<fapi2::TARGET_TYPE_OCMB_CHIP>(); if (l_memBufs.size() > 0) { @@ -93,6 +110,8 @@ uint8_t findNumDimms(const fapi2::Target<fapi2::TARGET_TYPE_MI>& i_miTarget) } } + FAPI_DBG("After number of DIMM's after axone targets %u", l_num_dimms); + FAPI_DBG("Exiting findNumDimms"); return l_num_dimms; } @@ -374,7 +393,7 @@ fapi2::ReturnCode throttleSync( } // Program the MCMODE0 if HW397255 is not enabled which means we - // should have a chip with Nimbus DD2+ or Cumulus. + // should have a chip with Nimbus DD2+ or Cumulus/Axone. if (i_HW397255_enabled == 0) { progMCMODE0(l_mc, i_mcTargets); @@ -442,7 +461,7 @@ extern "C" // HW397255 requires to also program a master MCS on MC23 if // it has DIMMs. // This should only be enabled for Nimbus DD1, disabled for Nimbus DD2 - // and Cumulus. + // and Cumulus/Axone. fapi2::ATTR_CHIP_EC_FEATURE_HW397255_Type l_HW397255_enabled; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW397255, i_target, l_HW397255_enabled), @@ -456,7 +475,7 @@ extern "C" (uint64_t)fapi2::current_err); } - // Cumulus + // Cumulus/Axone if (l_miChiplets.size() > 0) { FAPI_TRY(throttleSync(l_miChiplets, l_HW397255_enabled), diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_tod_setup.C b/src/import/chips/p9/procedures/hwp/nest/p9_tod_setup.C index 04ce62cd9..18c0079b0 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9_tod_setup.C +++ b/src/import/chips/p9/procedures/hwp/nest/p9_tod_setup.C @@ -44,6 +44,7 @@ const uint64_t M_PATH_CTRL_REG_CLEAR_VALUE = 0x0000000000000000; const uint64_t S_PATH_CTRL_REG_CLEAR_VALUE = 0x0000003F00000000; +static const uint8_t P9A_PERV_ROOT_CTRL8_TP_PLL_CLKIN_SEL9_DC = 21; /// @brief MPIPL specific steps to clear the previous topology, this should be // called only during MPIPL @@ -778,6 +779,18 @@ fapi2::ReturnCode configure_m_path_ctrl_reg( const p9_tod_setup_osc_sel i_osc_sel) { fapi2::buffer<uint64_t> l_m_path_ctrl_reg = 0; + fapi2::buffer<uint64_t> l_root_ctrl8_reg = 0; + bool l_tod_on_lpc_clock = false; + + const bool is_mdmt = (i_tod_node->i_tod_master && i_tod_node->i_drawer_master); + + // Read ROOT_CTRL8 to determine TOD input clock selection + FAPI_TRY(fapi2::getScom(*(i_tod_node->i_target), + PERV_ROOT_CTRL8_SCOM, + l_root_ctrl8_reg), + "Error from getScom (PERV_ROOT_CTRL8_SCOM)!"); + + l_tod_on_lpc_clock = l_root_ctrl8_reg.getBit<P9A_PERV_ROOT_CTRL8_TP_PLL_CLKIN_SEL9_DC>(); // Read PERV_TOD_M_PATH_CTRL_REG to preserve any prior configuration FAPI_TRY(fapi2::getScom(*(i_tod_node->i_target), @@ -785,85 +798,91 @@ fapi2::ReturnCode configure_m_path_ctrl_reg( l_m_path_ctrl_reg), "Error from getScom (PERV_TOD_M_PATH_CTRL_REG)!"); - // Configure Master OSC0/OSC1 path - FAPI_DBG("Configuring Master OSC path in PERV_TOD_M_PATH_CTRL_REG"); + // Configure single or dual edge detect based on tod clock select + l_m_path_ctrl_reg.writeBit<PERV_TOD_M_PATH_CTRL_REG_STEP_CREATE_DUAL_EDGE_DISABLE>(l_tod_on_lpc_clock); - if (i_osc_sel == TOD_OSC_0 || - i_osc_sel == TOD_OSC_0_AND_1 || - i_osc_sel == TOD_OSC_0_AND_1_SEL_0 || - i_osc_sel == TOD_OSC_0_AND_1_SEL_1) + if (is_mdmt) { - FAPI_DBG("OSC0 is valid; master path-0 will be configured."); + // Configure Master OSC0/OSC1 path + FAPI_DBG("Configuring Master OSC path in PERV_TOD_M_PATH_CTRL_REG"); - // OSC0 is connected - l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_0_OSC_NOT_VALID>(); + if (i_osc_sel == TOD_OSC_0 || + i_osc_sel == TOD_OSC_0_AND_1 || + i_osc_sel == TOD_OSC_0_AND_1_SEL_0 || + i_osc_sel == TOD_OSC_0_AND_1_SEL_1) + { + FAPI_DBG("OSC0 is valid; master path-0 will be configured."); - // OSC0 step alignment enabled - l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_0_STEP_ALIGN_DISABLE>(); + // OSC0 is connected + l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_0_OSC_NOT_VALID>(); - // Set 512 steps per sync for path 0 - l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT, - PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT_LEN>( - TOD_M_PATH_CTRL_REG_M_PATH_SYNC_CREATE_SPS_512); + // OSC0 step alignment enabled + l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_0_STEP_ALIGN_DISABLE>(); - // Set step check CPS deviation to 50% - l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_CPS_DEVIATION, - PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_CPS_DEVIATION_LEN>( - STEP_CHECK_CPS_DEVIATION_50_00_PCENT); + // Set 512 steps per sync for path 0 + l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT, + PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT_LEN>( + TOD_M_PATH_CTRL_REG_M_PATH_SYNC_CREATE_SPS_512); - // 8 valid steps are required before step check is enabled - l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_VALIDITY_COUNT, - PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_VALIDITY_COUNT_LEN>( - STEP_CHECK_VALIDITY_COUNT_8); - } - else - { - FAPI_DBG("OSC0 is not connected."); + // Set step check CPS deviation to 50% + l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_CPS_DEVIATION, + PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_CPS_DEVIATION_LEN>( + STEP_CHECK_CPS_DEVIATION_50_00_PCENT); - // OSC0 is not connected; any previous path-0 settings will be ignored - l_m_path_ctrl_reg.setBit<PERV_TOD_M_PATH_CTRL_REG_0_OSC_NOT_VALID>(); - } + // 8 valid steps are required before step check is enabled + l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_VALIDITY_COUNT, + PERV_TOD_M_PATH_CTRL_REG_0_STEP_CHECK_VALIDITY_COUNT_LEN>( + STEP_CHECK_VALIDITY_COUNT_8); + } + else + { + FAPI_DBG("OSC0 is not connected."); - if (i_osc_sel == TOD_OSC_1 || - i_osc_sel == TOD_OSC_0_AND_1 || - i_osc_sel == TOD_OSC_0_AND_1_SEL_0 || - i_osc_sel == TOD_OSC_0_AND_1_SEL_1) - { - FAPI_DBG("OSC1 is valid; master path-1 will be configured."); + // OSC0 is not connected; any previous path-0 settings will be ignored + l_m_path_ctrl_reg.setBit<PERV_TOD_M_PATH_CTRL_REG_0_OSC_NOT_VALID>(); + } - // OSC1 is connected - l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_1_OSC_NOT_VALID>(); + if (i_osc_sel == TOD_OSC_1 || + i_osc_sel == TOD_OSC_0_AND_1 || + i_osc_sel == TOD_OSC_0_AND_1_SEL_0 || + i_osc_sel == TOD_OSC_0_AND_1_SEL_1) + { + FAPI_DBG("OSC1 is valid; master path-1 will be configured."); - // OSC1 step alignment enabled - l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_1_STEP_ALIGN_DISABLE>(); + // OSC1 is connected + l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_1_OSC_NOT_VALID>(); - // Set 512 steps per sync for path 1 - l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT, - PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT_LEN>( - TOD_M_PATH_CTRL_REG_M_PATH_SYNC_CREATE_SPS_512); + // OSC1 step alignment enabled + l_m_path_ctrl_reg.clearBit<PERV_TOD_M_PATH_CTRL_REG_1_STEP_ALIGN_DISABLE>(); - // Set step check CPS deviation to 50% - l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_CPS_DEVIATION, - PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_CPS_DEVIATION_LEN>( - STEP_CHECK_CPS_DEVIATION_50_00_PCENT); + // Set 512 steps per sync for path 1 + l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT, + PERV_TOD_M_PATH_CTRL_REG_SYNC_CREATE_SPS_SELECT_LEN>( + TOD_M_PATH_CTRL_REG_M_PATH_SYNC_CREATE_SPS_512); - // 8 valid steps are required before step check is enabled - l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_VALIDITY_COUNT, - PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_VALIDITY_COUNT_LEN>( - STEP_CHECK_VALIDITY_COUNT_8); - } - else - { - FAPI_DBG("OSC1 is not connected."); + // Set step check CPS deviation to 50% + l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_CPS_DEVIATION, + PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_CPS_DEVIATION_LEN>( + STEP_CHECK_CPS_DEVIATION_50_00_PCENT); - // OSC1 is not connected; any previous path-1 settings will be ignored - l_m_path_ctrl_reg.setBit<PERV_TOD_M_PATH_CTRL_REG_1_OSC_NOT_VALID>(); - } + // 8 valid steps are required before step check is enabled + l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_VALIDITY_COUNT, + PERV_TOD_M_PATH_CTRL_REG_1_STEP_CHECK_VALIDITY_COUNT_LEN>( + STEP_CHECK_VALIDITY_COUNT_8); + } + else + { + FAPI_DBG("OSC1 is not connected."); - // CPS deviation factor configures both path-0 and path-1 - l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_STEP_CHECK_CPS_DEVIATION_FACTOR, - PERV_TOD_M_PATH_CTRL_REG_STEP_CHECK_CPS_DEVIATION_FACTOR_LEN>( - STEP_CHECK_CPS_DEVIATION_FACTOR_1); + // OSC1 is not connected; any previous path-1 settings will be ignored + l_m_path_ctrl_reg.setBit<PERV_TOD_M_PATH_CTRL_REG_1_OSC_NOT_VALID>(); + } + + // CPS deviation factor configures both path-0 and path-1 + l_m_path_ctrl_reg.insertFromRight<PERV_TOD_M_PATH_CTRL_REG_STEP_CHECK_CPS_DEVIATION_FACTOR, + PERV_TOD_M_PATH_CTRL_REG_STEP_CHECK_CPS_DEVIATION_FACTOR_LEN>( + STEP_CHECK_CPS_DEVIATION_FACTOR_1); + } FAPI_TRY(fapi2::putScom(*(i_tod_node->i_target), PERV_TOD_M_PATH_CTRL_REG, @@ -1058,13 +1077,10 @@ fapi2::ReturnCode configure_tod_node( i_osc_sel), "Error from configure_port_ctrl_regs!"); - if (is_mdmt) - { - FAPI_TRY(configure_m_path_ctrl_reg(i_tod_node, - i_tod_sel, - i_osc_sel), - "Error from configure_m_path_ctrl_reg!"); - } + FAPI_TRY(configure_m_path_ctrl_reg(i_tod_node, + i_tod_sel, + i_osc_sel), + "Error from configure_m_path_ctrl_reg!"); FAPI_TRY(configure_i_path_ctrl_reg(i_tod_node, i_tod_sel, 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 index 4f6aeeb07..31f826501 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C +++ b/src/import/chips/p9/procedures/hwp/nest/p9a_addr_ext.C @@ -69,7 +69,8 @@ fapi_try_exit: /* - * As documented + * As documented (TYPO in BAR Bits) + * They should be naturally ordered. * 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 @@ -92,29 +93,6 @@ fapi_try_exit: * 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, @@ -127,27 +105,27 @@ fapi2::ReturnCode extendBarAddress(const uint64_t& i_ext_mask, const fapi2::buff 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 } + // B 6 7 8 9 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 } }; uint64_t l_bar = i_bar_addr; diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_get_mmio.C b/src/import/chips/p9/procedures/hwp/nest/p9a_get_mmio.C index c2cb8d8ef..836d63057 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9a_get_mmio.C +++ b/src/import/chips/p9/procedures/hwp/nest/p9a_get_mmio.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2018 */ +/* Contributors Listed Below - COPYRIGHT 2018,2020 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -55,8 +55,8 @@ fapi2::ReturnCode p9a_get_mmio(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> std::vector<uint8_t>& o_data) { uint8_t data[8]; - uint8_t l_idx; - uint8_t l_data_idx; + uint32_t l_idx; + uint32_t l_data_idx; uint32_t l_max_grans; uint32_t l_grans; p9_ADU_oper_flag l_myAduFlag; @@ -82,7 +82,7 @@ fapi2::ReturnCode p9a_get_mmio(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> } FAPI_TRY(addOMIBase(i_target, l_addr)); - FAPI_INF("Read address: 0x%lX transaction size: %d", l_addr, l_tsize); + FAPI_DBG("Read address: 0x%lX transaction size: %d", l_addr, l_tsize); l_proc_target = i_target.getParent<fapi2::TARGET_TYPE_OMI>().getParent<fapi2::TARGET_TYPE_PROC_CHIP>(); @@ -120,7 +120,7 @@ fapi2::ReturnCode p9a_get_mmio(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> sprintf(&l_hexdata[l_i * 2], "%02X", o_data[l_i]); } - FAPI_INF("Read data: 0x%s", l_hexdata); + FAPI_DBG("Read data: 0x%s", l_hexdata); fapi_try_exit: 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 index e5efc07c5..9801e8f30 100644 --- 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 @@ -45,7 +45,7 @@ #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> +#include <lib/inband/exp_inband.H> //----------------------------------------------------------------------------------- // Function definitions 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 index d24e4e5f0..b7428fc57 100644 --- 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 @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2017,2019 +# Contributors Listed Below - COPYRIGHT 2018,2019 # [+] International Business Machines Corp. # # @@ -25,5 +25,6 @@ PROCEDURE=p9a_omi_setup_bars OBJS+=p9_fbc_utils.o OBJS+=p9a_addr_ext.o +$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/ocmb/explorer/procedures/hwp/memory/) $(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)) $(call BUILD_PROCEDURE) diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_put_mmio.C b/src/import/chips/p9/procedures/hwp/nest/p9a_put_mmio.C index adebd16da..fb1a2c13b 100644 --- a/src/import/chips/p9/procedures/hwp/nest/p9a_put_mmio.C +++ b/src/import/chips/p9/procedures/hwp/nest/p9a_put_mmio.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2018 */ +/* Contributors Listed Below - COPYRIGHT 2018,2020 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -55,8 +55,8 @@ fapi2::ReturnCode p9a_put_mmio(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> const std::vector<uint8_t>& i_data) { uint8_t data[8]; - uint8_t l_idx; - uint8_t l_data_idx; + uint32_t l_idx; + uint32_t l_data_idx; uint32_t l_max_grans; uint32_t l_grans; p9_ADU_oper_flag l_myAduFlag; @@ -87,8 +87,8 @@ fapi2::ReturnCode p9a_put_mmio(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> } FAPI_TRY(addOMIBase(i_target, l_addr)); - FAPI_INF("Write address: %lX", l_addr); - FAPI_INF("Write data: %s", l_hexdata); + FAPI_DBG("Write address: %lX", l_addr); + FAPI_DBG("Write data: %s", l_hexdata); l_proc_target = i_target.getParent<fapi2::TARGET_TYPE_OMI>().getParent<fapi2::TARGET_TYPE_PROC_CHIP>(); diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.C b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.C new file mode 100644 index 000000000..c288c1fb2 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.C @@ -0,0 +1,346 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 p9_throttle_sync.C +/// +/// @brief Perform p9_throttle_sync HWP +/// +/// The purpose of this procedure is to triggers sync command from a 'master' +/// MC to other MCs that have attached memory in a processor. +/// +/// ---------------------------------------------------------------------------- +/// *HWP HWP Owner : Joe McGill <jmcgill@us.ibm.com> +/// *HWP HWP Backup : Mark Pizzutillo <Mark.Pizzutillo@ibm.com> +/// *HWP FW Owner : Thi Tran <thi@us.ibm.com> +/// *HWP Team : Nest +/// *HWP Level : 3 +/// *HWP Consumed by : HB +/// ---------------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <p9a_throttle_sync.H> +#include <fapi2.H> +#include <generic/memory/lib/utils/find.H> +#include <generic/memory/lib/utils/c_str.H> +#include <lib/shared/axone_consts.H> + +/// +/// @brief Program MCMODE0 based on the functional targets +/// +/// @param[in] i_mi_target The MC target to be programmed +/// @param[in] i_mi_targets Other MC targets. +/// +/// @return FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode prog_MCMODE0( + const fapi2::Target<fapi2::TARGET_TYPE_MI>& i_mc_target, + const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MI> >& i_mc_targets) +{ + FAPI_DBG("Entering prog_MCMODE0 on target %s", mss::c_str(i_mc_target)); + // -------------------------------------------------------------- + // Setup MCMODE0 for disabling MC SYNC to other-side and same-side + // partner unit. + // BIT27: set if other-side MC is non-functional, 0<->2, 1<->3 + // BIT28: set if same-side MC is non-functional, 0<->1, 2<->3 + // -------------------------------------------------------------- + fapi2::buffer<uint64_t> l_scomData(0); + fapi2::buffer<uint64_t> l_scomMask(0); + bool l_other_side_functional = false; + bool l_same_side_functional = false; + uint8_t l_current_pos = 0; + uint8_t l_other_side_pos = 0; + uint8_t l_same_side_pos = 0; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_mc_target, l_current_pos), + "Error getting ATTR_CHIP_UNIT_POS on %s", mss::c_str(i_mc_target)); + + // Calculate the peer MC in the other side and in the same side. + l_other_side_pos = (l_current_pos + MAX_MC_PER_SIDE) % MAX_MC_PER_PROC; + l_same_side_pos = ((l_current_pos / MAX_MC_SIDES_PER_PROC) * MAX_MC_PER_SIDE) + + ((l_current_pos % MAX_MC_PER_SIDE) + 1) % MAX_MC_PER_SIDE; + + FAPI_DBG("Current pos: %i, other side pos: %i, same side pos: %i", + l_current_pos, l_other_side_pos, l_same_side_pos); + + // Determine side functionality + for (const auto& l_mc : i_mc_targets) + { + uint8_t l_tmp_pos = 0; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mc, l_tmp_pos), + "Error getting ATTR_CHIP_UNIT_POS on %s", mss::c_str(l_mc)); + + // The other side + if (l_tmp_pos == l_other_side_pos) + { + l_other_side_functional = true; + } + + // The same side + if (l_tmp_pos == l_same_side_pos) + { + l_same_side_functional = true; + } + } + + l_scomData.flush<0>(); + l_scomMask.flush<0>(); + + if (!l_other_side_functional) + { + l_scomData.setBit<P9A_MI_MCMODE0_DISABLE_MC_SYNC>(); + l_scomMask.setBit<P9A_MI_MCMODE0_DISABLE_MC_SYNC>(); + } + else + { + l_scomData.clearBit<P9A_MI_MCMODE0_DISABLE_MC_SYNC>(); + l_scomMask.setBit<P9A_MI_MCMODE0_DISABLE_MC_SYNC>(); + } + + if (!l_same_side_functional) + { + l_scomData.setBit<P9A_MI_MCMODE0_DISABLE_MC_PAIR_SYNC>(); + l_scomMask.setBit<P9A_MI_MCMODE0_DISABLE_MC_PAIR_SYNC>(); + } + else + { + l_scomData.clearBit<P9A_MI_MCMODE0_DISABLE_MC_PAIR_SYNC>(); + l_scomMask.setBit<P9A_MI_MCMODE0_DISABLE_MC_PAIR_SYNC>(); + } + + FAPI_DBG("Writing MCS_MCMODE0 reg 0x%016llX: Mask 0x%016llX , Data 0x%016llX", + P9A_MI_MCMODE0, l_scomMask, l_scomData); + + FAPI_TRY(fapi2::putScomUnderMask(i_mc_target, P9A_MI_MCMODE0, l_scomData, l_scomMask), + "putScomUnderMask() returns an error, P9A_MI_MCMODE0 reg 0x%016llX", P9A_MI_MCMODE0); + +fapi_try_exit: + FAPI_DBG("Exiting prog_MCMODE0"); + return fapi2::current_err; +} + +/// +/// @brief Programming master MCS +/// Writes P9A_MI_MCSYNC reg to set the input MCS as the master. +/// +/// @param[in] i_mcsTarget The MCS target to be programmed as master. +/// @return FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode prog_master(const fapi2::Target<fapi2::TARGET_TYPE_MI>& i_mc_target) +{ + FAPI_DBG("Entering progMaster with target %s", mss::c_str(i_mc_target)); + fapi2::buffer<uint64_t> l_scomData(0); + fapi2::buffer<uint64_t> l_scomMask(0); + + // ------------------------------------------------------------------- + // 1. Reset sync command + // ------------------------------------------------------------------- + + // Clear GO bit + l_scomMask.flush<0>().setBit<P9A_MI_MCSYNC_SYNC_GO>(); + l_scomData.flush<0>(); + FAPI_TRY(fapi2::putScomUnderMask(i_mc_target, P9A_MI_MCSYNC, l_scomData, l_scomMask), + "putScomUnderMask() returns an error (Reset), P9A_MI_MCSYNC reg 0x%016llX", P9A_MI_MCSYNC); + + // -------------------------------------------------------------- + // 2. Setup MC Sync Command Register data for master MCS or MI + // -------------------------------------------------------------- + + // Clear buffers + l_scomData.flush<0>(); + l_scomMask.flush<0>(); + + // Force bit set in case cleared from last procedure run + l_scomData.setBit<EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_REF_EN>(); + l_scomMask.setBit<EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_REF_EN>(); + + // Iterate through OCMBs to make sure refresh SYNC bit is set + for (const auto& l_ocmb : mss::find_targets<fapi2::TARGET_TYPE_OCMB_CHIP>(i_mc_target)) + { + FAPI_DBG("Writing EXPLR_SRQ_MBA_SYNCCNTLQ reg 0x%016llX: Data 0x%016llX Mask 0x%016llX", + EXPLR_SRQ_MBA_SYNCCNTLQ, l_scomData, l_scomMask); + + FAPI_TRY(fapi2::putScomUnderMask(l_ocmb, EXPLR_SRQ_MBA_SYNCCNTLQ, l_scomData, l_scomMask), + "Error writing to REG 0x%016llX of %s", EXPLR_SRQ_MBA_SYNCCNTLQ, mss::c_str(l_ocmb)); + } + + // Clear buffers + l_scomData.flush<0>(); + l_scomMask.flush<0>(); + + // Setup MCSYNC_CHANNEL_SELECT + // Set ALL channels with or without DIMMs (bits 0:7) + l_scomData.setBit<P9A_MI_MCSYNC_CHANNEL_SELECT, + P9A_MI_MCSYNC_CHANNEL_SELECT_LEN>(); + l_scomMask.setBit<P9A_MI_MCSYNC_CHANNEL_SELECT, + P9A_MI_MCSYNC_CHANNEL_SELECT_LEN>(); + + // Setup MCSYNC_SYNC_TYPE for SYNC ALL + l_scomData.setBit<P9A_MI_MCSYNC_SYNC_TYPE>(); + l_scomMask.setBit<P9A_MI_MCSYNC_SYNC_TYPE>(); + + // Setup SYNC_GO (bit 16 is now used for both channels) + l_scomMask.setBit<P9A_MI_MCSYNC_SYNC_GO>(); + l_scomData.setBit<P9A_MI_MCSYNC_SYNC_GO>(); + + // -------------------------------------------------------------- + // 3. Write to MC Sync Command Register of master MCS or MI + // -------------------------------------------------------------- + // Write to MCSYNC reg + FAPI_DBG("Writing P9A_MI_MCSYNC reg 0x%016llX: Mask 0x%016llX , Data 0x%016llX", + P9A_MI_MCSYNC, l_scomMask, l_scomData); + + FAPI_TRY(fapi2::putScomUnderMask(i_mc_target, P9A_MI_MCSYNC, l_scomData, l_scomMask), + "putScomUnderMask() returns an error (Sync), P9A_MI_MCSYNC reg 0x%016llX", P9A_MI_MCSYNC); + + // Note: No need to read Sync replay count and retry in P9. + + // -------------------------------------------------------------- + // 4. Clear refresh sync bit + // -------------------------------------------------------------- + l_scomData.flush<0>(); + l_scomMask.flush<0>().setBit<EXPLR_SRQ_MBA_SYNCCNTLQ_SYNC_REF_EN>(); + + // Iterate through OCMBs to clear refresh sync bit + for (const auto& l_ocmb : mss::find_targets<fapi2::TARGET_TYPE_OCMB_CHIP>(i_mc_target)) + { + FAPI_DBG("Writing EXPLR_SRQ_MBA_SYNCCNTLQ reg 0x%016llX: Mask 0x%016llX , Data 0x%016llX on %s", + EXPLR_SRQ_MBA_SYNCCNTLQ, l_scomMask, l_scomData, mss::c_str(l_ocmb)); + + FAPI_TRY(fapi2::putScomUnderMask(l_ocmb, EXPLR_SRQ_MBA_SYNCCNTLQ, l_scomData, l_scomMask), + "putScomUnderMask() returns an error (Sync), EXPLR_SRQ_MBA_SYNCCNTLQ reg 0x%016llX", + EXPLR_SRQ_MBA_SYNCCNTLQ); + } + +fapi_try_exit: + FAPI_DBG("Exiting progMaster"); + return fapi2::current_err; +} + +/// +/// @brief Perform throttle sync on the Memory Controllers +/// +/// @param[in] i_mc_targets vector of reference of MC targets (MCS or MI) +/// @return FAPI2_RC_SUCCESS if success, else error code. +/// +fapi2::ReturnCode throttle_sync( + const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MI> >& i_mc_targets) +{ + mc_side_info_t l_mcSide[MAX_MC_SIDES_PER_PROC]; + uint8_t l_sideNum = 0; + uint8_t l_pos = 0; + uint8_t l_numMasterProgrammed = 0; + + // Initialization + for (l_sideNum = 0; l_sideNum < MAX_MC_SIDES_PER_PROC; l_sideNum++) + { + l_mcSide[l_sideNum].master_mc_found = false; + } + + // --------------------------------------------------------------------- + // 1. Pick the first MCS/MI with DIMMS as potential master + // for both MC sides (MC01/MC23) + // --------------------------------------------------------------------- + for (const auto& l_mc : i_mc_targets) + { + uint8_t l_num_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(l_mc).size(); + + if (l_num_dimms > 0) + { + // This MCS or MI has DIMMs attached, find out which MC side it + // belongs to: + // l_sideNum = 0 --> MC01 + // 1 --> MC23 + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mc, l_pos), + "Error getting ATTR_CHIP_UNIT_POS on %s", mss::c_str(l_mc)); + l_sideNum = l_pos / MAX_MC_SIDES_PER_PROC; + + FAPI_INF("MCS %u has DIMMs", l_pos); + + // If there's no master MCS or MI marked for this side yet, mark + // this MCS as master + if (l_mcSide[l_sideNum].master_mc_found == false) + { + FAPI_INF("Mark MCS %u as master for MC side %u", + l_pos, l_sideNum); + l_mcSide[l_sideNum].master_mc_found = true; + l_mcSide[l_sideNum].master_mc = l_mc; + } + } + + prog_MCMODE0(l_mc, i_mc_targets); + } + + // -------------------------------------------------------------- + // 2. Program the master MI + // -------------------------------------------------------------- + for (l_sideNum = 0; l_sideNum < MAX_MC_SIDES_PER_PROC; l_sideNum++) + { + // If there is a potential master MI found for this side + if (l_mcSide[l_sideNum].master_mc_found == true) + { + // No master MI programmed for either side yet, + // go ahead and program this MI as master. + if (l_numMasterProgrammed == 0) + { + FAPI_TRY(prog_master(l_mcSide[l_sideNum].master_mc), + "programMaster() returns error on %s", mss::c_str(l_mcSide[l_sideNum].master_mc)); + l_numMasterProgrammed++; + } + } + } + +fapi_try_exit: + FAPI_DBG("Exiting"); + return fapi2::current_err; +} + +extern "C" +{ + /// + /// @brief p9a_throttle_sync procedure + /// + /// @param[in] i_target TARGET_TYPE_PROC_CHIP target + /// @return FAPI2_RC_SUCCESS if success, else error code. + /// + fapi2::ReturnCode p9a_throttle_sync( + const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) + { + FAPI_DBG("Executing p9a_throttle_sync on %s", mss::c_str(i_target)); + + const auto l_miChiplets = i_target.getChildren<fapi2::TARGET_TYPE_MI>(); + + if (l_miChiplets.size() > 0) + { + FAPI_TRY(throttle_sync(l_miChiplets), "Error calling throttle_sync() with vector of MI Chiplets"); + } + + fapi_try_exit: + FAPI_DBG("Exiting"); + return fapi2::current_err; + } + +} // extern "C" diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.H b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.H new file mode 100644 index 000000000..c87312b23 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.H @@ -0,0 +1,78 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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_throttle_sync.H +/// +/// @brief p9a_throttle_sync HWP +/// +/// The purpose of this procedure is to triggers sync command from a 'master' +/// MC to other MCs that have attached memory in a processor. +/// +/// ---------------------------------------------------------------------------- +/// *HWP HWP Owner : Joe McGill <jmcgill@us.ibm.com> +/// *HWP HWP Backup : Mark Pizzutillo <Mark.Pizzutillo@ibm.com> +/// *HWP FW Owner : Thi Tran <thi@us.ibm.com> +/// *HWP Team : Nest +/// *HWP Level : 3 +/// *HWP Consumed by : HB +/// ---------------------------------------------------------------------------- +#ifndef _P9A_THROTTLE_SYNC_H_ +#define _P9A_THROTTLE_SYNC_H_ + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <fapi2.H> +#include <p9a_mc_scom_addresses_fld.H> +#include <p9a_misc_scom_addresses_fld.H> +#include <p9a_misc_scom_addresses.H> +#include <explorer_scom_addresses.H> +#include <explorer_scom_addresses_fld.H> + +// Function pointer typedef definition for HWP call support +typedef fapi2::ReturnCode (*p9a_throttle_sync_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&); + +/// +/// @brief Structure that holds the potential master MI for a MC side (MC01/MC23) +/// +struct mc_side_info_t +{ + bool master_mc_found = false; + fapi2::Target<fapi2::TARGET_TYPE_MI> master_mc; // Master MC for this MC side +}; + +extern "C" +{ + /// + /// @brief p9a_throttle_sync procedure + /// + /// @param[in] i_target TARGET_TYPE_PROC_CHIP target + /// @return FAPI2_RC_SUCCESS if success, else error code. + /// + fapi2::ReturnCode p9a_throttle_sync(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target); + +} // extern "C" + +#endif // _P9A_THROTTLE_SYNC_H_ diff --git a/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.mk b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.mk new file mode 100644 index 000000000..cf235b53d --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.mk @@ -0,0 +1,30 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/import/chips/p9/procedures/hwp/nest/p9a_throttle_sync.mk $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 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_throttle_sync +$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)/chips/p9a/procedures/hwp/memory/) + +$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(ROOTPATH)) +$(call BUILD_PROCEDURE) |