fapi2::ReturnCode pm_occ_fir_reset( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_IMP("pm_occ_fir_reset Enter"); uint8_t firinit_done_flag = 0; p9pmFIR::PMFir <p9pmFIR::FIRTYPE_OCC_LFIR> l_occFir(i_target); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PM_FIRINIT_DONE_ONCE_FLAG, i_target, firinit_done_flag), "ERROR: Failed to fetch the entry status of FIRINIT"); if (firinit_done_flag == 1) { FAPI_TRY(l_occFir.get(p9pmFIR::REG_FIRMASK), "ERROR: Failed to get the OCC FIR MASK value"); /* Fetch the OCC FIR MASK; Save it to HWP attribute; clear its contents */ FAPI_TRY(l_occFir.saveMask(), "ERROR: Failed to save the OCC FIR Mask to the attribute"); } FAPI_TRY(l_occFir.setAllRegBits(p9pmFIR::REG_FIRMASK), "ERROR: Faled to set the OCC FIR MASK"); FAPI_TRY(l_occFir.put(), "ERROR:Failed to write to the OCC FIR MASK"); fapi_try_exit: return fapi2::current_err; }
fapi2::ReturnCode pm_cme_fir_init( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_IMP("pm_cme_fir_init start"); auto l_exChiplets = i_target.getChildren<fapi2::TARGET_TYPE_EX> (fapi2::TARGET_STATE_FUNCTIONAL); for (auto l_ex_chplt : l_exChiplets) { p9pmFIR::PMFir <p9pmFIR::FIRTYPE_CME_LFIR> l_cmeFir(l_ex_chplt); /* Clear the FIR Register */ FAPI_TRY(l_cmeFir.clearAllRegBits(p9pmFIR::REG_FIR), "ERROR: Failed to clear CME FIR"); // Always restore from the scan init values FAPI_TRY(l_cmeFir.restoreSavedMask(), "ERROR: Failed to restore the CME mask saved"); FAPI_TRY(l_cmeFir.put(), "ERROR:Failed to write to the CME FIR MASK"); } fapi_try_exit: return fapi2::current_err; }
/// /// @brief Checks to make sure ATTR_MSS_MRW_TEMP_REFRESH_MODE and ATTR_MSS_MRW_FINE_REFRESH_MODE are set correctly /// @return fapi2::FAPI2_RC_SUCCESS if okay /// @note from DDR4 DRAM Spec (79-4B) 4.9.4 page 48 /// fapi2::ReturnCode temp_refresh_mode() { uint8_t l_temp_refresh = 0; uint8_t l_refresh_mode = 0; FAPI_TRY( mrw_fine_refresh_mode (l_refresh_mode)); FAPI_TRY( mrw_temp_refresh_mode (l_temp_refresh)); // If the temperature refresh mode is enabled, only the normal mode (Fixed 1x mode; MRS4 A8:A7:A6= 000) is allowed for the fine refresh mode // Per JEDEC DDR4 DRAM spec from 07-2016 page 48 section 4.9.4 if ( l_temp_refresh == fapi2::ENUM_ATTR_MSS_MRW_TEMP_REFRESH_MODE_ENABLE) { FAPI_ASSERT( (l_refresh_mode == fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL), fapi2::MSS_INVALID_FINE_REFRESH_MODE_WITH_TEMP_REFRESH_MODE_ENABLED() .set_FINE_REF_MODE(l_refresh_mode) .set_TEMP_REF_MODE(l_temp_refresh), "Incorrect setting for ATTR_MSS_MRW_FINE_REFRESH_MODE (%d) if ATTR_MSS_MRW_TEMP_REFRESH_MODE is enabled", l_refresh_mode); } return fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: return fapi2::current_err; };
/// /// @brief p9_build_smp procedure entry point /// See doxygen in p9_build_smp.H /// fapi2::ReturnCode p9_build_smp(std::vector<fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>>& i_chips, const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_master_chip_sys_next, const p9_build_smp_operation i_op) { FAPI_DBG("Start"); // process HWP input vector of chips p9_build_smp_system l_smp; FAPI_TRY(p9_build_smp_insert_chips(i_chips, i_master_chip_sys_next, i_op, l_smp), "Error from p9_build_smp_insert_chips"); // check topology before continuing FAPI_TRY(p9_build_smp_check_topology(i_op, l_smp), "Error from p9_build_smp_check_topology"); // activate new SMP configuration if (i_op == SMP_ACTIVATE_PHASE1) { // set fabric configuration registers (hotplug, switch CD set) FAPI_TRY(p9_build_smp_set_fbc_cd(l_smp), "Error from p9_build_smp_set_fbc_cd"); } // set fabric configuration registers (hotplug, switch AB set) FAPI_TRY(p9_build_smp_set_fbc_ab(l_smp, i_op), "Error from p9_build_smp_set_fbc_ab"); fapi_try_exit: FAPI_DBG("End"); return fapi2::current_err; }
// NOTE: see doxygen comments in header fapi2::ReturnCode p9_fbc_eff_config() { FAPI_DBG("Start"); fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; fapi2::ATTR_PROC_FABRIC_CORE_FLOOR_RATIO_Type l_core_floor_ratio; fapi2::ATTR_PROC_FABRIC_CORE_CEILING_RATIO_Type l_core_ceiling_ratio; fapi2::ATTR_FREQ_PB_MHZ_Type l_freq_fbc; fapi2::ATTR_FREQ_CORE_CEILING_MHZ_Type l_freq_core_ceiling; FAPI_TRY(p9_fbc_eff_config_process_freq_attributes( FAPI_SYSTEM, l_core_floor_ratio, l_core_ceiling_ratio, l_freq_fbc, l_freq_core_ceiling), "Error from p9_fbc_eff_config_process_freq_attributes"); FAPI_TRY(p9_fbc_eff_config_calc_epsilons( FAPI_SYSTEM, l_core_floor_ratio, l_core_ceiling_ratio, l_freq_fbc, l_freq_core_ceiling), "Error from p9_fbc_eff_config_calc_epsilons"); fapi_try_exit: FAPI_DBG("End"); return fapi2::current_err; }
/// @brief Enable Drivers/Recievers of O, PCIE, MC chiplets /// /// @param[in] i_target_chiplet Reference to TARGET_TYPE_PERV target /// @return FAPI2_RC_SUCCESS if success, else error code. static fapi2::ReturnCode p9_chiplet_enable_ridi_net_ctrl_action_function( const fapi2::Target<fapi2::TARGET_TYPE_PERV>& i_target_chiplet) { bool l_read_reg = false; fapi2::buffer<uint64_t> l_data64; FAPI_DBG("Entering ..."); FAPI_INF("Check for chiplet enable"); //Getting NET_CTRL0 register value FAPI_TRY(fapi2::getScom(i_target_chiplet, PERV_NET_CTRL0, l_data64)); l_read_reg = l_data64.getBit<0>(); //l_read_reg = NET_CTRL0.CHIPLET_ENABLE if ( l_read_reg ) { FAPI_INF("Enable Recievers, Drivers DI1 & DI2"); //Setting NET_CTRL0 register value l_data64.flush<0>(); l_data64.setBit<19>(); //NET_CTRL0.RI_N = 1 l_data64.setBit<20>(); //NET_CTRL0.DI1_N = 1 l_data64.setBit<21>(); //NET_CTRL0.DI2_N = 1 FAPI_TRY(fapi2::putScom(i_target_chiplet, PERV_NET_CTRL0_WOR, l_data64)); } FAPI_DBG("Exiting ..."); fapi_try_exit: return fapi2::current_err; }
// ----------------------------------------------------------------------------- // Function definition // ----------------------------------------------------------------------------- fapi2::ReturnCode p9_pm_pba_init( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const p9pm::PM_FLOW_MODE i_mode) { FAPI_IMP("> p9_pm_pba_init"); if (i_mode == p9pm::PM_INIT) { FAPI_TRY(pba_init(i_target), " pba_init() failed."); } else if (i_mode == p9pm::PM_RESET) { FAPI_TRY(pba_reset(i_target), " pba_reset() failed."); } else { FAPI_ASSERT(false, fapi2::P9_PMPROC_PBA_INIT_INCORRECT_MODE() .set_PM_MODE(i_mode), "Unknown mode 0x%08llx passed to p9_pm_pba_init.", i_mode); } fapi_try_exit: FAPI_IMP("< p9_pm_pba_init"); return fapi2::current_err; }
/// @brief FW Team Utility function that sets the Bad DQ Bitmap. /// @param[in] i_mba Reference to MBA Chiplet /// @param[in] i_port MBA port number (0-(MAX_PORTS_PER_MBA - 1)) /// @param[in] i_dimm MBA port DIMM number (0-(MAX_DIMM_PER_PORT - 1)) /// @param[in] i_rank DIMM rank number (0-(MAX_RANKS_PER_DIMM -1)) /// @param[in] i_data Reference to data where Bad DQ bitmap is copied from /// @return FAPI2_RC_SUCCESS fapi2::ReturnCode dimmSetBadDqBitmap(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, const uint8_t (&i_data)[DIMM_DQ_RANK_BITMAP_SIZE]) { FAPI_INF(">>dimmSetBadDqBitmap. %s:%d:%d:%d", mss::c_str(i_mba), i_port, i_dimm, i_rank); // Check parameters and find the DIMM fapi2::Target<fapi2::TARGET_TYPE_MBA> fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm; // Get the Bad DQ bitmap by querying ATTR_BAD_DQ_BITMAP. // Use a heap based array to avoid large stack alloc uint8_t (&l_dqBitmap)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE] = *(reinterpret_cast<uint8_t(*)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE]> (new uint8_t[MAX_RANKS_PER_DIMM * DIMM_DQ_RANK_BITMAP_SIZE])); FAPI_TRY(dimmBadDqCheckParamFindDimm(i_mba, i_port, i_dimm, i_rank, l_dimm)); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_BAD_DQ_BITMAP, l_dimm, l_dqBitmap)); // Add the rank bitmap to the DIMM bitmap and write the bitmap memcpy(l_dqBitmap[i_rank], i_data, DIMM_DQ_RANK_BITMAP_SIZE); FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_BAD_DQ_BITMAP, l_dimm, l_dqBitmap)); delete [] &l_dqBitmap; FAPI_INF("<<dimmSetBadDqBitmap"); fapi_try_exit: return fapi2::current_err; }
/// /// @brief Setup the OCMB for enterprise and half-DIMM modes as desired /// @param[in] i_target the OCMB target to operate on /// @return FAPI2_RC_SUCCESS iff ok /// fapi2::ReturnCode exp_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) { mss::display_git_commit_info("exp_omi_setup"); // Declares variables fapi2::buffer<uint64_t> l_data; bool l_is_enterprise = false; bool l_is_half_dimm = false; // Gets the configuration information from attributes FAPI_TRY(mss::enterprise_mode(i_target, l_is_enterprise)); FAPI_TRY(mss::half_dimm_mode(i_target, l_is_half_dimm)); // Prints out the data FAPI_INF("%s %s enterprise mode %s-DIMM mode", mss::c_str(i_target), l_is_enterprise ? "is" : "isn't", l_is_half_dimm ? "half" : "full"); // Sets up the register mss::exp::omi::set_enterprise_set_bit(l_data, l_is_enterprise); mss::exp::omi::set_half_dimm_mode(l_data, l_is_half_dimm); // Writes the data to the register FAPI_TRY(mss::exp::omi::write_enterprise_config(i_target, l_data)); // Checks that the chip is configured correctly FAPI_TRY(mss::exp::omi::read_enterprise_config(i_target, l_data)); FAPI_TRY(mss::exp::omi::check_enterprise_mode(i_target, l_is_enterprise, l_data)); fapi_try_exit: return fapi2::current_err; }
fapi2::ReturnCode ppe_update_dbcr( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const uint64_t i_base_address, const uint64_t i_inst_op, const uint16_t i_immed_16, const uint16_t i_Rs) { fapi2::buffer<uint64_t> l_data64; //Modify DBCR using read modify write //Move DBCR to Rs l_data64.flush<0>().insertFromRight(ppe_getMfsprInstruction(i_Rs, DBCR), 0, 32); FAPI_DBG("getMfsprInstruction(%d, DBCR): 0x%16llX", i_Rs, l_data64 ); FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMEDR, l_data64)); //Modify Rs l_data64.flush<0>().insertFromRight(ppe_getInstruction(i_inst_op, i_Rs, i_Rs, i_immed_16), 0, 32); FAPI_DBG("getInstruction(Immed %X: 0x%16llX", i_immed_16, l_data64 ); FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMEDR, l_data64)); //MOVE new Rs into DBCR l_data64.flush<0>().insertFromRight(ppe_getMtsprInstruction(i_Rs, DBCR), 0, 32); FAPI_DBG("getMtsprInstruction(%d, DBCR): 0x%16llX", i_Rs, l_data64 ); FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMEDR, l_data64)); fapi_try_exit: return fapi2::current_err; }
/// /// @brief Change VREG_COARSE for failed DLLs /// @param[in] i_target the fapi2 target /// @param[in] i_failed_dll_map failed DLL VREG COARSE map /// @return FAPI2_RC_SUCCESS iff ok /// fapi2::ReturnCode change_vreg_coarse(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const std::map< fapi2::buffer<uint64_t>, fapi2::buffer<uint64_t> >& i_failed_dll_map) { for( const auto& map : i_failed_dll_map) { // Little renaming to help clarify map fields const auto FAILING_COARSE_REG = map.first; const auto NEIGHBOR_DATA = map.second; fapi2::buffer<uint64_t> l_data; // Read DAC coarse from failed DLL FAPI_TRY( mss::getScom(i_target, FAILING_COARSE_REG, l_data), "Failed getScom() operation on %s reg 0x%016llx", mss::c_str(i_target), FAILING_COARSE_REG ); FAPI_DBG("%s Read DLL_VREG_COARSE reg 0x%016llx, data 0x%016llx", mss::c_str(i_target), FAILING_COARSE_REG, l_data); l_data.insertFromRight< dll_map::REGS_RXDLL_DAC_COARSE, dll_map::REGS_RXDLL_DAC_COARSE_LEN>(NEIGHBOR_DATA); FAPI_INF("%s Writing to DLL_VREG_COARSE reg 0x%016llx, data 0x%016llx, value 0x%llx", mss::c_str(i_target), FAILING_COARSE_REG, l_data, NEIGHBOR_DATA); // Write DAC coarse from failed DLL with DAC coarse from neighboring DLL FAPI_TRY( mss::putScom(i_target, FAILING_COARSE_REG, l_data), "Failed putScom() operation on %s reg 0x%016llx", mss::c_str(i_target), FAILING_COARSE_REG ); } fapi_try_exit: return fapi2::current_err; }
fapi2::ReturnCode ppe_resume( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const uint64_t i_base_address) { fapi2::buffer<uint64_t> l_data64; static const uint32_t RESUME_TRIES = 10; uint32_t l_timeout_count = RESUME_TRIES; //Before reume always clear debug status (Michael's comment) FAPI_INF(" Clear debug status via XCR..."); l_data64.flush<0>(); FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64), "Error in PUTSCOM in XCR to clear dbg status"); FAPI_INF(" Send RESUME command via XCR..."); l_data64.flush<0>().insertFromRight(p9hcd::RESUME, 1, 3); FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64), "Error in PUTSCOM in XCR to resume condition"); do { FAPI_TRY(getScom(i_target, i_base_address + PPE_XIRAMEDR, l_data64)); FAPI_DBG(" Poll content: XSR: 0x%16llX", l_data64); } while((l_data64.getBit<p9hcd::HALTED_STATE>() != 0) && (--l_timeout_count != 0)); fapi_try_exit: return fapi2::current_err; }
fapi2::ReturnCode eff_memory_size( const fapi2::Target<fapi2::TARGET_TYPE_DMI>& i_target, uint64_t& o_size ) { o_size = 0; for (const auto& mba : mss::find_targets<fapi2::TARGET_TYPE_MBA>(i_target)) { uint8_t l_sizes[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {}; uint8_t l_func_dimms_bitmap = 0; FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CEN_MSS_EFF_DIMM_FUNCTIONAL_VECTOR, mba, l_func_dimms_bitmap), "Failed to access attribute ATTR_CEN_MSS_EFF_DIMM_FUNCTIONAL_VECTOR for %s", mss::c_str(mba) ); FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DIMM_SIZE, mba, l_sizes), "Failed to access attribute ATTR_CEN_EFF_DIMM_SIZE for %s", mss::c_str(mba) ); for( size_t p = 0; p < MAX_PORTS_PER_MBA; ++p) { for( size_t d = 0; d < MAX_DIMM_PER_PORT; ++d) { if( is_dimm_functional(l_func_dimms_bitmap, p, d) ) { o_size += l_sizes[p][d]; } }// dimm }// port }// mba fapi_try_exit: return fapi2::current_err; }
/// /// @brief Helper function to set DAC_COARSE reg /// @param[in] i_target the fapi2 target /// @param[in] i_failed_dll_dac failed DLL VREG COARSE /// @param[in] i_value the value to set /// @return FAPI2_RC_SUCCESS iff ok /// static fapi2::ReturnCode dll_dac_helper(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const fapi2::buffer<uint64_t>& i_failed_dll_dac, const uint64_t i_value) { constexpr uint64_t SOURCE_START = dll_map::REGS_RXDLL_VREG; // Read DAC coarse from failed DLL fapi2::buffer<uint64_t> l_data; FAPI_TRY( mss::getScom(i_target, i_failed_dll_dac, l_data), "Failed getScom() operation on %s reg 0x%016llx", mss::c_str(i_target), i_failed_dll_dac ); l_data.insert<dll_map::REGS_RXDLL_VREG, dll_map::REGS_RXDLL_VREG_LEN, SOURCE_START>(i_value); FAPI_INF("%s Writing to DAC_REG 0x%016llx, data 0x%016llx, value 0x%llx", mss::c_str(i_target), i_failed_dll_dac, l_data, i_value); // Write DAC coarse from failed DLL with DAC coarse from neighboring DLL FAPI_TRY( mss::putScom(i_target, i_failed_dll_dac, l_data), "Failed putScom() operation on %s reg 0x%016llx", mss::c_str(i_target), i_failed_dll_dac ); fapi_try_exit: return fapi2::current_err; }
fapi2::ReturnCode p9_pm_cme_firinit( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const p9pm::PM_FLOW_MODE i_mode) { FAPI_IMP("p9_pm_cme_firinit start"); if(i_mode == p9pm::PM_RESET) { FAPI_TRY(pm_cme_fir_reset(i_target), "ERROR: Failed to reset the CME FIRs"); } else if(i_mode == p9pm::PM_INIT) { FAPI_TRY(pm_cme_fir_init(i_target), "ERROR: Failed to initialize the CME FIRs"); } else { FAPI_ASSERT(false, fapi2::PM_CME_FIRINIT_BAD_MODE().set_BADMODE(i_mode), "ERROR; Unknown mode passed to p9_pm_cme_firinit. Mode %x", i_mode); } fapi_try_exit: FAPI_INF("p9_pm_cme_firinit end"); return fapi2::current_err; }
// ----------------------------------------------------------------------------- // pba_reset -- mode = PM_RESET // ----------------------------------------------------------------------------- fapi2::ReturnCode pba_reset( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { std::vector<uint64_t> v_pba_reset_regs = { PU_BCDE_PBADR_SCOM, PU_BCDE_OCIBAR_SCOM, PU_BCUE_CTL_SCOM, PU_BCUE_SET_SCOM, PU_BCUE_PBADR_SCOM, PU_BCUE_OCIBAR_SCOM, PU_PBAXSHBR0_SCOM, PU_PBAXSHBR1_SCOM, PU_PBAXSHCS0_SCOM, PU_PBAXSHCS1_SCOM, PU_PBASLVCTL0_SCOM, PU_PBASLVCTL1_SCOM, PU_PBASLVCTL2_SCOM, PU_PBAFIR, PU_PBACFG, PU_PBAERRRPT0 }; FAPI_IMP(">> pba_reset ..."); fapi2::buffer<uint64_t> l_data64; // Stop the BCDE and BCUE FAPI_TRY(pba_bc_stop(i_target), "pba_bc_stop() detected an error"); // Reset each slave and wait for completion. FAPI_TRY(pba_slave_reset(i_target), "pba_slave_reset() failed."); for (auto it : v_pba_reset_regs) { FAPI_DBG("Resetting PBA register 0x%08llX", it); FAPI_TRY(fapi2::putScom(i_target, it, 0), "Failed to reset register 0x%08llX", it); } // Perform non-zero reset operations // Reset PBAX errors via Configuration Register // Bit 2: PBAXCFG_SND_RESET // Bit 3: PBAXCFG_RCV_RESET l_data64.setBit<2, 2>(); FAPI_INF("Resetting PBAX errors via PBAX config register 0x%08llX with " "value = 0x%16llX", PU_PBAXCFG_SCOM, uint64_t(l_data64)); FAPI_TRY(fapi2::putScom(i_target, PU_PBAXCFG_SCOM, l_data64)); // Perform PBA Slave setup to prepare for the boot phase. FAPI_TRY(pba_slave_setup_boot_phase(i_target), "pba_slave_setup_boot_phase() failed. "); fapi_try_exit: FAPI_IMP("<< pba_reset ..."); return fapi2::current_err; }
/// /// @brief Check the omi status in Axone side /// @param[in] i_target the OMIC target to operate on /// @return FAPI2_RC_SUCCESS iff ok /// fapi2::ReturnCode p9a_omi_train_check( const fapi2::Target<fapi2::TARGET_TYPE_OMI>& i_target) { mss::display_git_commit_info("p9a_omi_train_check"); FAPI_INF("%s Start p9a_omi_train_check", mss::c_str(i_target)); // Const constexpr uint8_t STATE_MACHINE_SUCCESS = 0b111; // This value is from Lonny Lambrecht constexpr uint8_t MAX_LOOP_COUNT = 20; // Retry times // Declares variables fapi2::buffer<uint64_t> l_omi_status; fapi2::buffer<uint64_t> l_omi_training_status; uint8_t l_state_machine_state = 0; uint8_t l_tries = 0; FAPI_TRY(mss::mc::omi_train_status(i_target, l_state_machine_state, l_omi_status)); while (l_tries < MAX_LOOP_COUNT && l_state_machine_state != STATE_MACHINE_SUCCESS) { // Delay fapi2::delay(mss::DELAY_100US, 10 * mss::DELAY_1MS); // Check OMI training status FAPI_TRY(mss::mc::omi_train_status(i_target, l_state_machine_state, l_omi_status)); // Note: this is very useful debug information while trying to debug training during polling FAPI_TRY(mss::getScom(i_target, P9A_MC_REG2_DL0_TRAINING_STATUS, l_omi_training_status)); l_tries++; } FAPI_TRY(mss::getScom(i_target, P9A_MC_REG2_DL0_TRAINING_STATUS, l_omi_training_status)); FAPI_ASSERT(l_state_machine_state == STATE_MACHINE_SUCCESS, fapi2::P9A_OMI_TRAIN_ERR() .set_TARGET(i_target) .set_EXPECTED_SM_STATE(STATE_MACHINE_SUCCESS) .set_ACTUAL_SM_STATE(l_state_machine_state) .set_DL0_STATUS(l_omi_status) .set_DL0_TRAINING_STATUS(l_omi_training_status), "%s OMI Training Failure, expected state:%d/actual state:%d", mss::c_str(i_target), STATE_MACHINE_SUCCESS, l_state_machine_state ); FAPI_INF("%s End p9a_omi_train_check, expected state:%d/actual state:%d, DL0_STATUS:0x%016llx, DL0_TRAINING_STATUS:0x%016llx", mss::c_str(i_target), STATE_MACHINE_SUCCESS, l_state_machine_state, l_omi_status, l_omi_training_status); return fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: return fapi2::current_err; }// p9a_omi_train_check
static fapi2::ReturnCode setup_pcie_work_around_attributes( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const fapi2::buffer<uint64_t>& i_ecid_part) { uint8_t l_version = 0; i_ecid_part.extractToRight<DD_LEVEL, DD_LEVEL_LEN>(l_version); { // Workarounds for DD1.00 modulues fapi2::ATTR_CHIP_EC_FEATURE_PCIE_LOCK_PHASE_ROTATOR_Type l_ec_feature_pcie_lock_phase_rotator = 0; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_PCIE_LOCK_PHASE_ROTATOR, i_target, l_ec_feature_pcie_lock_phase_rotator), "Error from FAPI_ATTR_GET (ATTR_CHIP_EC_FEATURE_PCIE_LOCK_PHASE_ROTATOR)"); uint8_t l_value = 0; if (l_ec_feature_pcie_lock_phase_rotator && (l_version < ddLevelPciePart)) { FAPI_DBG("seeing version 1.00 (0x%x) setting ATTR_PROC_PCIE_PCS_RX_ROT_EXTEL", l_version); l_value = 1; } for (auto& l_pec_trgt : i_target.getChildren<fapi2::TARGET_TYPE_PEC>(fapi2::TARGET_STATE_FUNCTIONAL)) { FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PROC_PCIE_PCS_RX_ROT_EXTEL, l_pec_trgt, l_value), "Error from FAPI_ATTR_SET (ATTR_PROC_PCIE_PCS_RX_ROT_EXTEL)"); } } { // Workarounds for DD1.01/DD1.02 modules fapi2::ATTR_CHIP_EC_FEATURE_PCIE_DISABLE_FDDC_Type l_ec_feature_pcie_disable_fddc = 0; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_PCIE_DISABLE_FDDC, i_target, l_ec_feature_pcie_disable_fddc), "Error from FAPI_ATTR_GET (ATTR_CHIP_EC_FEATURE_PCIE_DISABLE_FDDC)"); uint8_t l_value = 1; if (l_ec_feature_pcie_disable_fddc && (l_version >= ddLevelPciePart)) { FAPI_DBG("seeing version >= 1.01 (0x%x) clearing ATTR_PROC_PCIE_PCS_RX_DFE_FDDC", l_version); l_value = 0; } for (auto& l_pec_trgt : i_target.getChildren<fapi2::TARGET_TYPE_PEC>(fapi2::TARGET_STATE_FUNCTIONAL)) { FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PROC_PCIE_PCS_RX_DFE_FDDC, l_pec_trgt, l_value), "Error from FAPI_ATTR_SET (ATTR_PROC_PCIE_PCS_RX_DFE_FDDC)"); } } return fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: return fapi2::current_err; }
/// /// @brief mrs05_data ctor /// @param[in] a fapi2::TARGET_TYPE_DIMM target /// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok /// mrs05_data::mrs05_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ): iv_ca_parity_latency(fapi2::ENUM_ATTR_EFF_CA_PARITY_LATENCY_DISABLE), iv_crc_error_clear(fapi2::ENUM_ATTR_EFF_CRC_ERROR_CLEAR_CLEAR), iv_ca_parity_error_status(fapi2::ENUM_ATTR_EFF_CA_PARITY_ERROR_STATUS_CLEAR), iv_odt_input_buffer(fapi2::ENUM_ATTR_EFF_ODT_INPUT_BUFF_DEACTIVATED), iv_ca_parity(fapi2::ENUM_ATTR_EFF_CA_PARITY_DISABLE), iv_data_mask(fapi2::ENUM_ATTR_EFF_DATA_MASK_DISABLE), iv_write_dbi(fapi2::ENUM_ATTR_EFF_WRITE_DBI_DISABLE), iv_read_dbi(fapi2::ENUM_ATTR_EFF_READ_DBI_DISABLE) { FAPI_TRY( mss::eff_ca_parity_latency(i_target, iv_ca_parity_latency), "Error in mrs05_data()" ); FAPI_TRY( mss::eff_crc_error_clear(i_target, iv_crc_error_clear), "Error in mrs05_data()" ); FAPI_TRY( mss::eff_ca_parity_error_status(i_target, iv_ca_parity_error_status), "Error in mrs05_data()" ); FAPI_TRY( mss::eff_odt_input_buff(i_target, iv_odt_input_buffer), "Error in mrs05_data()" ); FAPI_TRY( mss::eff_dram_rtt_park(i_target, &(iv_rtt_park[0])), "Error in mrs05_data()" ); FAPI_TRY( mss::eff_ca_parity(i_target, iv_ca_parity), "Error in mrs05_data()" ); FAPI_TRY( mss::eff_data_mask(i_target, iv_data_mask), "Error in mrs05_data()" ); FAPI_TRY( mss::eff_write_dbi(i_target, iv_write_dbi), "Error in mrs05_data()" ); FAPI_TRY( mss::eff_read_dbi(i_target, iv_read_dbi), "Error in mrs05_data()" ); o_rc = fapi2::FAPI2_RC_SUCCESS; return; fapi_try_exit: o_rc = fapi2::current_err; FAPI_ERR("%s unable to get attributes for mrs05", mss::c_str(i_target)); return; }
/// /// @brief Utility function to check parameters and find a DIMM target /// @param[in] i_mba mba target /// @param[in] i_port Port number /// @param[in] i_dimm Dimm number /// @param[in] i_rank Rank number /// @param[out] o_dimm Dimm target /// @return FAPI2_RC_SUCCESS iff okay /// fapi2::ReturnCode dimmBadDqCheckParamFindDimm(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, fapi2::Target<fapi2::TARGET_TYPE_DIMM>& o_dimm) { uint8_t l_port = 0; uint8_t l_dimm = 0; std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_dimms; std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>::const_iterator dimmIter; FAPI_ASSERT((i_port < MAX_PORTS_PER_MBA) && (i_dimm < MAX_DIMM_PER_PORT) && (i_rank < MAX_RANKS_PER_DIMM), fapi2::CEN_BAD_DQ_DIMM_BAD_PARAM(). set_MBA(i_mba). set_FFDC_PORT(i_port). set_FFDC_DIMM(i_dimm). set_FFDC_RANK(i_rank), "dimmBadDqCheckParamFindDimm: %s Bad parameter. %d:%d:%d", mss::c_str(i_mba), i_port, i_dimm, i_rank); // Get the functional DIMMs associated with the MBA chiplet l_dimms = i_mba.getChildren<fapi2::TARGET_TYPE_DIMM>(); // Find the DIMM with the correct MBA port/dimm for (dimmIter = l_dimms.begin(); dimmIter != l_dimms.end(); ++dimmIter) { FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MBA_PORT, *dimmIter, l_port)); if (l_port == i_port) { FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MBA_DIMM, *dimmIter, l_dimm)); if (l_dimm == i_dimm) { o_dimm = *dimmIter; break; } } } FAPI_ASSERT(dimmIter != l_dimms.end(), fapi2::CEN_BAD_DQ_DIMM_NOT_FOUND(). set_MBA(i_mba). set_FFDC_PORT(i_port). set_FFDC_DIMM(i_dimm), "dimmBadDqCheckParamFindDimm: " "Did not find DIMM for %s:%d:%d", mss::c_str(i_mba), i_port, i_dimm); fapi_try_exit: return fapi2::current_err; }
/// /// @brief Configure the ARR0 of the CCS instruction for mrs05 /// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM> /// @param[in,out] io_inst the instruction to fixup /// @param[in] i_rank the rank in question /// @return FAPI2_RC_SUCCESS iff OK /// fapi2::ReturnCode mrs05(const fapi2::Target<TARGET_TYPE_DIMM>& i_target, ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst, const uint64_t i_rank) { // Check to make sure our ctor worked ok mrs05_data l_data( i_target, fapi2::current_err ); FAPI_TRY( fapi2::current_err, "%s Unable to construct MRS05 data from attributes", mss::c_str(i_target) ); FAPI_TRY( mrs05(i_target, l_data, io_inst, i_rank) ); fapi_try_exit: return fapi2::current_err; }
/// /// @brief Apply an additional PHY Phase Rotator Offset if we are in MFG Mode. /// /// @param[in] i_target Reference to processor chip target /// @param[in] i_phy_target Phy endpoint target /// @param[in] i_pr_offset Phase Rotator Offset /// @param[in] i_even True=process even half-link, False=process odd half-link /// /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. /// fapi2::ReturnCode p9_smp_phy_mfg_stress( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const fapi2::Target<fapi2::TARGET_TYPE_OBUS>& i_phy_target, const uint8_t i_pr_offset, const bool i_even) { FAPI_DBG("Start"); for (uint8_t l_lane = 0; l_lane < LANES_PER_HALF_LINK; l_lane++) { // set PHY TX lane address, start at: // - PHY lane 0 for even (work up) // - PHY lane 23 for odd (work down) uint64_t l_phy_rx_bit_cntl3_eo_pl_addr = OBUS_RX0_RXPACKS0_SLICE0_RX_BIT_CNTL3_EO_PL; if (i_even) { l_phy_rx_bit_cntl3_eo_pl_addr |= ((uint64_t) l_lane << 32); } else { l_phy_rx_bit_cntl3_eo_pl_addr |= ((uint64_t) (23 - l_lane) << 32); } FAPI_DBG("Adding PR Offset(%d) to lane %d", i_pr_offset, l_lane); fapi2::buffer<uint64_t> l_phy_rx_bit_cntl3_eo_pl; FAPI_TRY(fapi2::getScom(i_phy_target, l_phy_rx_bit_cntl3_eo_pl_addr, l_phy_rx_bit_cntl3_eo_pl), "Error from getScom (0x%08X)", l_phy_rx_bit_cntl3_eo_pl_addr); l_phy_rx_bit_cntl3_eo_pl.insertFromRight < OBUS_RX0_RXPACKS0_SLICE0_RX_BIT_CNTL3_EO_PL_PR_DATA_A_OFFSET, OBUS_RX0_RXPACKS0_SLICE0_RX_BIT_CNTL3_EO_PL_PR_DATA_A_OFFSET_LEN > (i_pr_offset); l_phy_rx_bit_cntl3_eo_pl.insertFromRight < OBUS_RX0_RXPACKS0_SLICE0_RX_BIT_CNTL3_EO_PL_PR_DATA_B_OFFSET, OBUS_RX0_RXPACKS0_SLICE0_RX_BIT_CNTL3_EO_PL_PR_DATA_B_OFFSET_LEN > (i_pr_offset); FAPI_TRY(fapi2::putScom(i_phy_target, l_phy_rx_bit_cntl3_eo_pl_addr, l_phy_rx_bit_cntl3_eo_pl), "Error from putScom (0x%08X)", l_phy_rx_bit_cntl3_eo_pl_addr); } fapi_try_exit: FAPI_DBG("End"); return fapi2::current_err; }
/// /// @brief p9_htm_reset procedure entry point /// See doxygen in p9_htm_reset.H /// fapi2::ReturnCode p9_htm_reset( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_DBG("Entering"); fapi2::ReturnCode l_rc; uint8_t l_corePos = 0; auto l_modeRegList = std::vector<uint64_t>(); auto l_coreChiplets = i_target.getChildren<fapi2::TARGET_TYPE_CORE>(); uint8_t l_nhtmType; uint8_t l_chtmType[NUM_CHTM_ENGINES]; // Get ATTR_NHTM_TRACE_TYPE FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_NHTM_TRACE_TYPE, i_target, l_nhtmType), "p9_htm_reset: Error getting ATTR_NHTM_TRACE_TYPE, l_rc 0x%.8X", (uint64_t)fapi2::current_err); // Get ATTR_CHTM_TRACE_TYPE FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHTM_TRACE_TYPE, i_target, l_chtmType), "p9_htm_reset: Error getting ATTR_CHTM_TRACE_TYPE, l_rc 0x%.8X", (uint64_t)fapi2::current_err); // Reset NHTM trace // Note: reset NHTM0 will also reset NHTM1 in global mode if (l_nhtmType != fapi2::ENUM_ATTR_NHTM_TRACE_TYPE_DISABLE) { FAPI_TRY( resetHTM(i_target, 0), "p9_htm_reset: resetHTM() returns error NHTM" "l_rc 0x%.8X", (uint64_t)fapi2::current_err ); } // Reset CHTM for (auto l_core : l_coreChiplets) { // Get the core position FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_core, l_corePos), "Error getting ATTR_CHIP_UNIT_POS"); FAPI_DBG("Reset HTM on core %u....", l_corePos); if (l_chtmType[l_corePos] != fapi2::ENUM_ATTR_CHTM_TRACE_TYPE_DISABLE) { FAPI_TRY(resetHTM(l_core, l_corePos), "p9_htm_reset: resetHTM() returns error: CHTM %u, " "l_rc 0x%.8X", l_corePos, (uint64_t)fapi2::current_err ); } } fapi_try_exit: FAPI_DBG("Exiting"); return fapi2::current_err; }
fapi2::ReturnCode p9_pm_occ_firinit( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const p9pm::PM_FLOW_MODE i_mode) { FAPI_IMP("p9_pm_occ_firinit Enter"); fapi2::buffer<uint64_t> l_data64; fapi2::buffer<uint64_t> l_mask64; uint64_t l_fir; uint64_t l_mask; uint64_t l_unmaskedErrors; FAPI_DBG("Checking OCC FIRs"); FAPI_TRY(fapi2::getScom(i_target, PERV_TP_OCC_SCOM_OCCLFIR, l_data64), "ERROR: Failed to fetch OCC FIR"); FAPI_TRY(fapi2::getScom(i_target, PERV_TP_OCC_SCOM_OCCLFIRMASK, l_mask64), "ERROR: Failed to fetch OCC FIRMASK"); l_data64.extractToRight<0, 64>(l_fir); l_mask64.extractToRight<0, 64>(l_mask); l_unmaskedErrors = l_fir & l_mask; if(l_unmaskedErrors) { FAPI_INF("WARNING: OCC has active errors"); } if(i_mode == p9pm::PM_RESET) { FAPI_TRY(pm_occ_fir_reset(i_target), "ERROR: Failed to reset the OCC FIRs"); } else if(i_mode == p9pm::PM_INIT) { FAPI_TRY(pm_occ_fir_init(i_target), "ERROR: Failed to initialize the OCC FIRs"); } else { FAPI_ASSERT(false, fapi2::PM_OCC_FIRINIT_BAD_MODE().set_BADMODE(i_mode), "ERROR; Unknown mode passed to p9_pm_occ_firinit. Mode %x", i_mode); } fapi_try_exit: FAPI_IMP("p9_pm_occ_firinit Exit"); return fapi2::current_err; }
fapi2::ReturnCode ppe_pollHaltState( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const uint64_t i_base_address) { fapi2::buffer<uint64_t> l_data64; // Halt state entry should be very fast on PPEs (eg nanoseconds) // Try only using the SCOM access time to delay. static const uint32_t HALT_TRIES = 10; uint32_t l_timeout_count = HALT_TRIES; do { FAPI_TRY(getScom(i_target, i_base_address + PPE_XIRAMDBG, l_data64), "Error in GETSCOM"); } while (! l_data64.getBit<0>() && --l_timeout_count != 0); FAPI_ASSERT(l_data64.getBit<0>(), fapi2::P9_PPE_STATE_HALT_TIMEOUT_ERR(), "PPE Halt Timeout"); fapi_try_exit: return fapi2::current_err; }
fapi2::ReturnCode p9_i2ctest_puti2c_fail( fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { // This will fail because PROC_CHIP not supported type FAPI_INF("Entering p9_i2ctest_puti2c_fail..."); std::vector<uint8_t> l_i2cdata; l_i2cdata.push_back(1); l_i2cdata.push_back(2); l_i2cdata.push_back(3); l_i2cdata.push_back(4); l_i2cdata.push_back(5); FAPI_INF( "Do putI2c on proc target" ); FAPI_TRY(fapi2::putI2c(i_target, l_i2cdata)); fapi_try_exit: FAPI_INF( "Exiting p9_i2ctest_puti2c_fail... rc = 0x%.8X", (uint64_t)fapi2::current_err ); return fapi2::current_err; }
/** * @brief A HWP that runs Restore eRepair. This procedure should update the * bad lane vector and power down the bad lanes. The rx bad lanes will update * the bad lane vector of the passed target. The lanes specified in the * i_rx_bad_lanes and in the i_tx_bad_lanes vectors will be powered down on the * target that is passed in. Note: This procedure does not power down any * bad lanes on the connected target. * @param[in] i_target FAPI2 Target * @param[in] i_rx_bad_lanes Vector of Rx Bad Lanes * @param[in] i_tx_bad_lanes Vector of Tx Bad Lanes * @retval ReturnCode */ fapi2::ReturnCode p9_io_dmi_restore_erepair( const fapi2::Target< fapi2::TARGET_TYPE_DMI >& i_target, const std::vector< uint8_t >& i_rx_bad_lanes, const std::vector< uint8_t >& i_tx_bad_lanes) { FAPI_IMP("Entering..."); FAPI_DBG("Rx Bad Lanes Size: %d", i_rx_bad_lanes.size()); FAPI_DBG("Tx Bad Lanes Size: %d", i_tx_bad_lanes.size()); if(!i_rx_bad_lanes.empty()) { FAPI_TRY(set_rx_bad_lane_vectors(i_target, i_rx_bad_lanes), "Setting Rx Bad Lane Vectors Failed"); } // This function will power down the rx & tx lanes specified in the vectors // on the target that is passed in. FAPI_EXEC_HWP(fapi2::current_err, p9_io_dmi_pdwn_lanes, i_target, i_rx_bad_lanes, i_tx_bad_lanes); fapi_try_exit: FAPI_IMP("Exiting..."); return fapi2::current_err; }
/// /// @brief Scominit for Explorer /// @param[in] i_target the OCMB target to operate on /// @return FAPI2_RC_SUCCESS iff ok /// fapi2::ReturnCode exp_scominit( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) { mss::display_git_commit_info("exp_scominit"); if (mss::count_dimm(i_target) == 0) { FAPI_INF("... skipping mss_scominit %s - no DIMM ...", mss::c_str(i_target)); return fapi2::FAPI2_RC_SUCCESS; } // We need to make sure we hit all ports const auto& l_port_targets = mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target); fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; const auto& l_mc = i_target.getParent<fapi2::TARGET_TYPE_OMI>() .getParent<fapi2::TARGET_TYPE_MCC>() .getParent<fapi2::TARGET_TYPE_MI>() .getParent<fapi2::TARGET_TYPE_MC>(); for(const auto& l_port : l_port_targets) { fapi2::ReturnCode l_rc; FAPI_INF("phy scominit for %s", mss::c_str(l_port)); FAPI_EXEC_HWP(l_rc, explorer_scom, i_target, l_port, FAPI_SYSTEM, l_mc); FAPI_TRY(l_rc, "Error from explorer.scom.initfile %s", mss::c_str(l_port)); } return fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: FAPI_INF("End MSS SCOM init"); return fapi2::current_err; }
/// /// @brief Checks for DLL error status /// @param[in] i_target the fapi2 target /// @param[in] i_failed_dll_cntrl vector of failed DLLs /// @return FAPI2_RC_SUCCESS iff ok /// fapi2::ReturnCode check_status(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const std::vector< uint64_t >& i_failed_dll_cntrl) { for( const auto& reg : i_failed_dll_cntrl ) { fapi2::buffer<uint64_t> l_dll_cntrl_data; FAPI_TRY( mss::getScom(i_target, reg, l_dll_cntrl_data), "Failed getScom() operation on %s reg 0x%016llx", mss::c_str(i_target), reg ); FAPI_DBG("Checking status on %s, DLL CNTRL reg 0x%016llx", mss::c_str(i_target), reg); FAPI_ASSERT( did_cal_fail(l_dll_cntrl_data) == false, fapi2::MSS_DLL_FAILED_TO_CALIBRATE() .set_MCA_IN_ERROR(i_target), "%s DLL failed to calibrate", mss::c_str(i_target) ) } return fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: return fapi2::current_err; }
fapi2::ReturnCode ppe_halt( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const uint64_t i_base_address) { fapi2::buffer<uint64_t> l_data64; FAPI_INF(" Send HALT command via XCR..."); l_data64.flush<0>().insertFromRight(p9hcd::HALT, 1, 3); FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64), "Error in PUTSCOM in XCR to generate Halt condition"); FAPI_TRY(ppe_pollHaltState(i_target, i_base_address)); fapi_try_exit: return fapi2::current_err; }