/** * @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; }
fapi2::ReturnCode p9_pm_pba_firinit( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const p9pm::PM_FLOW_MODE i_mode) { FAPI_IMP("p9_pm_pba_firinit Enter"); if(i_mode == p9pm::PM_RESET) { FAPI_TRY(pm_pba_fir_reset(i_target), "ERROR: Failed to reset the PBA FIRs"); } else if(i_mode == p9pm::PM_INIT) { FAPI_TRY(pm_pba_fir_init(i_target), "ERROR: Failed to initialize the PBA FIRs"); } else { FAPI_ASSERT(false, fapi2::PM_PBA_FIRINIT_BAD_MODE().set_BADMODE(i_mode), "ERROR; Unknown mode passed to p9_pm_pba_firinit. Mode %x", i_mode); } fapi_try_exit: FAPI_IMP("p9_pm_pba_firinit 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; }
// ----------------------------------------------------------------------------- // 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 A HWP that runs Read eRepair. This procedure reads the current bad * lanes and passes by reference the lane numbers in a vector. The rx vectors * will return to the caller ( PRD or e-repair ) the bad lane numbers on this * endpoint. The caller will duplicate the found rx bad lanes to the * corresponding tx bad lanes on the connected target. * @param[in] i_target Reference to Target * @param[in] i_clock_group Clock Group of Target * @param[out] o_bad_lanes Vector of bad lanes * @retval ReturnCode */ fapi2::ReturnCode p9_io_xbus_read_erepair( const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target, const uint8_t& i_clock_group, std::vector< uint8_t >& o_bad_lanes ) { FAPI_IMP("p9_io_xbus_read_erepair: Entering."); const uint8_t LANE_00 = 0; const uint16_t BAD_LANES_3PLUS = 3; const uint16_t BAD_LANES_2 = 2; const uint16_t BAD_LANES_1 = 1; const uint16_t BAD_LANES_0 = 0; uint64_t l_data = 0; o_bad_lanes.clear(); FAPI_TRY(io::read( EDIP_RX_GLBSM_STAT9_E_PG, i_target, i_clock_group, LANE_00, l_data), "Reading Bad Lane Code Failed."); FAPI_DBG( "Bad Lane Code: %d", io::get( EDIP_RX_BAD_LANE_CODE, l_data ) ); switch( io::get( EDIP_RX_BAD_LANE_CODE, l_data ) ) { case BAD_LANES_3PLUS: FAPI_DBG( "Bad Lane: Three or more bad lanes found." ); // We will intentionally fall through to collect bad lane 1 & 2. case BAD_LANES_2: FAPI_DBG( "Bad Lane 2: %d", io::get( EDIP_RX_BAD_LANE2, l_data ) ); o_bad_lanes.push_back( (uint8_t)io::get( EDIP_RX_BAD_LANE2, l_data ) ); // We will intentionally fall through to collect bad lane 1. case BAD_LANES_1: FAPI_DBG( "Bad Lane 1: %d", io::get( EDIP_RX_BAD_LANE1, l_data ) ); o_bad_lanes.push_back( (uint8_t)io::get( EDIP_RX_BAD_LANE1, l_data ) ); break; case BAD_LANES_0: FAPI_DBG( "No Bad Lanes" ); default: break; } fapi_try_exit: FAPI_IMP("p9_io_xbus_read_erepair: 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 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; }
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; }
/** * @brief A HWP that runs Read eRepair. This procedure reads the current bad * lanes and passes by reference the lane numbers in a vector. The rx vectors * will return to the caller (PRD or e-repair) the bad lane numbers on this * endpoint. The caller will duplicate the found rx bad lanes to the * corresponding tx bad lanes on the connected target. * @param[in] i_target Reference to Target * @param[out] o_bad_lanes Vector of bad lanes * @retval ReturnCode */ fapi2::ReturnCode p9_io_cen_read_erepair( const fapi2::Target < fapi2::TARGET_TYPE_MEMBUF_CHIP >& i_target, std::vector< uint8_t >& o_bad_lanes) { FAPI_IMP("p9_io_cen_read_erepair: Entering."); const uint8_t GRP0 = 0; const uint8_t LN0 = 0; const uint16_t BAD_LANES_3PLUS = 3; const uint16_t BAD_LANES_2 = 2; const uint16_t BAD_LANES_1 = 1; const uint16_t BAD_LANES_0 = 0; uint64_t l_data = 0; o_bad_lanes.clear(); FAPI_TRY(io::read(EDI_RX_BAD_LANE_ENC_GCRMSG_PG, i_target, GRP0, LN0, l_data), "Reading Bad Lane Code Failed."); FAPI_DBG("Bad Lane Code: %d", io::get(EDI_RX_BAD_LANE_CODE_GCRMSG, l_data)); switch(io::get(EDI_RX_BAD_LANE_CODE_GCRMSG, l_data)) { case BAD_LANES_3PLUS: FAPI_DBG("Bad Lane: Three or more bad lanes found."); // We will intentionally fall through to collect bad lane 1 & 2. case BAD_LANES_2: FAPI_DBG("Bad Lane 2: %d", io::get(EDI_RX_BAD_LANE2_GCRMSG, l_data)); o_bad_lanes.push_back((uint8_t)io::get(EDI_RX_BAD_LANE2_GCRMSG, l_data)); // We will intentionally fall through to collect bad lane 1. case BAD_LANES_1: FAPI_DBG("Bad Lane 1: %d", io::get(EDI_RX_BAD_LANE1_GCRMSG, l_data)); o_bad_lanes.push_back((uint8_t)io::get(EDI_RX_BAD_LANE1_GCRMSG, l_data)); break; case BAD_LANES_0: FAPI_DBG("No Bad Lanes"); default: break; } fapi_try_exit: FAPI_IMP("p9_io_cen_read_erepair: Exiting."); return fapi2::current_err; }
// ---------------------------------------------------------------------- // Function definitions // ---------------------------------------------------------------------- fapi2::ReturnCode p9_pm_firinit( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const p9pm::PM_FLOW_MODE i_mode) { FAPI_IMP("p9_pm_firinit start"); fapi2::ReturnCode l_rc; uint8_t l_pm_firinit_flag; fapi2::buffer<uint64_t> l_data64; // CHECKING FOR FIRS BEFORE RESET and INIT FAPI_DBG("Checking PBA FIRs"); FAPI_TRY(fapi2::getScom(i_target, PU_PBAFIR , l_data64), "ERROR: Failed to fetch PBA FIR"); if(l_data64) { FAPI_INF("WARNING: PBA has active error(s)"); } // Handle PBA FIRs, Masks and actions FAPI_DBG("Calling PBA firinit ..."); FAPI_EXEC_HWP(l_rc, p9_pm_pba_firinit, i_target, i_mode); FAPI_TRY(l_rc); // Handle Core and Quad errors FAPI_DBG("Calling PPM firinit ..."); FAPI_EXEC_HWP(l_rc, p9_pm_ppm_firinit, i_target, i_mode); FAPI_TRY(l_rc); // Handle CME FIRs, Masks and actions FAPI_DBG("Calling CME firinit ..."); FAPI_EXEC_HWP(l_rc, p9_pm_cme_firinit, i_target, i_mode); FAPI_TRY(l_rc); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PM_FIRINIT_DONE_ONCE_FLAG, i_target, l_pm_firinit_flag), "ERROR: Failed to fetch the firinit call status flag"); // Set the ATTR_PM_FIRINIT_DONE_ONCE_FLAG attribute if (i_mode == p9pm::PM_INIT) { if (l_pm_firinit_flag != 1) { l_pm_firinit_flag = 1; FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PM_FIRINIT_DONE_ONCE_FLAG, i_target, l_pm_firinit_flag), "ERROR: Failed to set firinit call status after init"); } } fapi_try_exit: FAPI_INF("p9_pm_firinit end"); return fapi2::current_err; } // END p9_pm_firinit
fapi2::ReturnCode p9_pm_ocb_indir_setup_circular( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const p9ocb::PM_OCB_CHAN_NUM i_ocb_chan, const p9ocb::PM_OCB_CHAN_TYPE i_ocb_type, const uint32_t i_ocb_bar, const uint8_t i_ocb_q_len, const p9ocb::PM_OCB_CHAN_OUFLOW i_ocb_flow, const p9ocb::PM_OCB_ITPTYPE i_ocb_itp) { FAPI_IMP("p9_pm_ocb_indir_setup_circular Enter"); FAPI_DBG("Channel: %d; Mode: %d; OCB BAR: 0x%08X; Queue length: %d;", i_ocb_chan, i_ocb_type, i_ocb_bar, i_ocb_q_len); FAPI_DBG("Flow Notification Mode: %d; Interrupt Behaviour: %d", i_ocb_flow, i_ocb_itp); fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; FAPI_EXEC_HWP(l_rc, p9_pm_ocb_init, i_target, p9pm::PM_SETUP_ALL, i_ocb_chan, i_ocb_type, i_ocb_bar, i_ocb_q_len, i_ocb_flow, i_ocb_itp); if (l_rc == fapi2::FAPI2_RC_SUCCESS) { FAPI_INF("Circular setup of channel %d successful.", i_ocb_chan); } else { FAPI_ERR("ERROR: Failed to setup channel %d to circular mode.", i_ocb_chan); } FAPI_IMP("p9_pm_ocb_indir_setup_circular Exit"); return l_rc; }
fapi2::ReturnCode p9_pm_pss_init( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const p9pm::PM_FLOW_MODE i_mode) { FAPI_IMP(">> p9_pm_pss_init"); // Initialization: perform order or dynamic operations to initialize // the PMC using necessary Platform or Feature attributes. if (i_mode == p9pm::PM_INIT) { FAPI_TRY(pm_pss_init(i_target), "Failed to initialize the PSS logic"); } // Reset: perform reset of PSS else if (i_mode == p9pm::PM_RESET) { FAPI_TRY(pm_pss_reset(i_target), "Failed to reset PSS logic."); } fapi_try_exit: FAPI_IMP("<< p9_pm_pss_init"); return fapi2::current_err; }
/** * @brief Sets the rx bad lane vector * @param[in] i_rx_target FAPI2 Rx Target * @param[in] i_rx_bad_lanes Vector of Bad Lanes */ fapi2::ReturnCode set_rx_bad_lane_vectors( const fapi2::Target< fapi2::TARGET_TYPE_DMI >& i_target, const std::vector< uint8_t >& i_bad_lanes) { FAPI_IMP("Entering..."); const uint8_t GRP3 = 3; const uint8_t LN0 = 0; const uint8_t IO_GCR_REG_WIDTH = 16; uint8_t bad_lane = 0; uint64_t l_data = 0; char target_string[fapi2::MAX_ECMD_STRING_LEN]; fapi2::toString(i_target, target_string, fapi2::MAX_ECMD_STRING_LEN); for(uint8_t index = 0; index < i_bad_lanes.size(); ++index) { bad_lane = i_bad_lanes[index]; FAPI_DBG("Setting Bad Lane[%d/%d]:%d Target(%s:g%d)", index, i_bad_lanes.size() - 1, bad_lane, target_string, GRP3); // For each group, the bad lane vector is split up into 2 registers due // to GCR registers only being 16 bits wide. if(i_bad_lanes[index] < IO_GCR_REG_WIDTH) { FAPI_TRY(io::read(EDIP_RX_LANE_BAD_VEC_0_15, i_target, GRP3, LN0, l_data), "RMW rx_bad_lane_0_15_reg failed"); l_data |= (0x8000 >> bad_lane); FAPI_TRY(io::write(EDIP_RX_LANE_BAD_VEC_0_15, i_target, GRP3, LN0, l_data), "RMW rx_bad_lane_0_15_reg failed"); } else {
fapi2::ReturnCode p9_io_obus_firmask_restore(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip, const std::vector<fapi2::Target<fapi2::TARGET_TYPE_OBUS>> i_obus_targets) { FAPI_IMP("p9_io_obus_firmask_restore: Entering..."); uint64_t l_restoreValue; // Read the proc's obus firmask value we stored previously FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_PB_IOOFIR_MASK, i_target_chip, l_restoreValue), "failed to get attribute ATTR_IO_PB_IOOFIR_MASK"); // If ATTR_IO_PB_IOOFIR_MASK is zero that indicates that firmask_save has not been // called yet so we will not restore this firmask // Note: it was decided to keep these attribute checks seperate to allow // attribute overrides of these attributes to take effect on HBRT reset if(l_restoreValue) { // Write the stored value back to the scom register FAPI_TRY(fapi2::putScom(i_target_chip, PU_IOE_PB_IOO_FIR_MASK_REG, l_restoreValue), "putScom of PU_IOE_PB_IOO_FIR_MASK_REG failed"); // Need to write 0 to ATTR_IO_PB_IOOFIR_MASK to ensure // we do not re-write the obus firmask values on HBRT // reboots or MPIPLs l_restoreValue = 0; FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_PB_IOOFIR_MASK, i_target_chip, l_restoreValue), "failed to set attribute ATTR_IO_PB_IOOFIR_MASK"); } else { FAPI_IMP("p9_io_obus_firmask_restore: Skipping restore of PU_IOE_PB_IOO_FIR_MASK_REG because ATTR_IO_PB_IOOFIR_MASK is 0"); } // Loop through obus targets and restore the IOO LFIR value if necessary for(const auto& l_obusTarget : i_obus_targets) { // Read the obus's obus firmask value we stored previously FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_OLLFIR_MASK, l_obusTarget, l_restoreValue), "failed to get attribute ATTR_IO_OLLFIR_MASK"); // If ATTR_IO_OLLFIR_MASK is zero that indicates that firmask_save has not been // called yet so we will not restore this firmask // Note: it was decided to keep these attribute checks seperate to allow // attribute overrides of these attributes to take effect on HBRT reset if(l_restoreValue) { // Write the stored value back to the scom register FAPI_TRY(fapi2::putScom(l_obusTarget, OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG, l_restoreValue), "putScom of OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG failed"); // Need to write 0 to ATTR_IO_OLLFIR_MASK to ensure // we do not re-write the obus firmask values on HBRT // reboots or MPIPLs l_restoreValue = 0; FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_OLLFIR_MASK, l_obusTarget, l_restoreValue), "failed to set attribute ATTR_IO_OLLFIR_MASK"); } else { FAPI_IMP("p9_io_obus_firmask_restore: Skipping restore of OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG because ATTR_IO_OLLFIR_MASK is 0"); } } fapi_try_exit: FAPI_IMP("p9_io_obus_firmask_restore: Exiting..."); return fapi2::current_err; }
fapi2::ReturnCode p9_io_obus_firmask_save(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip, const std::vector<fapi2::Target<fapi2::TARGET_TYPE_OBUS>> i_obus_targets) { FAPI_IMP("p9_io_obus_firmask_save: Entering..."); fapi2::buffer<uint64_t> l_scomBuffer = 0; fapi2::buffer<uint64_t> l_action0Buffer = 0; fapi2::buffer<uint64_t> l_action1Buffer = 0; // First read the PB IOO fir mask register FAPI_TRY(fapi2::getScom(i_target_chip, PU_IOE_PB_IOO_FIR_MASK_REG, l_scomBuffer), "getScom of PU_IOE_PB_IOO_FIR_MASK_REG failed"); // Save off scom value we read into ATTR_IO_PB_IOOFIR_MASK FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_PB_IOOFIR_MASK, i_target_chip, l_scomBuffer), "failed to set attribute ATTR_IO_PB_IOOFIR_MASK"); // Apply mask required for Hostboot IPL time // Set bits 28-35 (see above for more details) l_scomBuffer.insertFromRight<PU_IOE_PB_IOO_FIR_MASK_REG_PARSER00_ATTN, SET_LENGTH_8>(SET_BYTE); // Set bits 52-59 (see above for more details) l_scomBuffer.insertFromRight<PU_IOE_PB_IOO_FIR_MASK_REG_DOB01_ERR, SET_LENGTH_8>(SET_BYTE); // Write modified mask back to scom register FAPI_TRY(fapi2::putScom(i_target_chip, PU_IOE_PB_IOO_FIR_MASK_REG, l_scomBuffer), "putScom of PU_IOE_PB_IOO_FIR_MASK_REG failed"); // Loop through obus targets and save off IOO LFIR for(const auto& l_obusTarget : i_obus_targets) { // For each obus target read the IOOL FIR mask and store it in // the ATTR_IO_OLLFIR_MASK attribute for later FAPI_TRY(fapi2::getScom(l_obusTarget, OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG, l_scomBuffer), "getScom of OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG failed"); FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_OLLFIR_MASK, l_obusTarget, l_scomBuffer), "failed to set attribute ATTR_IO_OLLFIR_MASK"); // For each obus target read the IOOL FIR action registers FAPI_TRY(fapi2::getScom(l_obusTarget, OBUS_LL0_PB_IOOL_FIR_ACTION0_REG, l_action0Buffer), "getScom of OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG failed"); FAPI_TRY(fapi2::getScom(l_obusTarget, OBUS_LL0_PB_IOOL_FIR_ACTION1_REG, l_action1Buffer), "getScom of OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG failed"); // Apply mask required for Hostboot IPL time, we must mask additional // bits during IPL time because Hostboot does not know about OBUS // peer targets yet. When PRD attempts to handle some of these FIRs // it will expect the PEER_TARGET information to be there. // Set bits 42-47 if the action register indicate the error as recoverable for(uint64_t i = PB_IOOL_FIR_MASK_REG_FIR_LINK0_NO_SPARE_MASK; i <= OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG_LINK1_TOO_MANY_CRC_ERRORS; i++) { if(l_action0Buffer.getBit(i) == 0 && l_action1Buffer.getBit(i) == 1 ) { l_scomBuffer.setBit(i); } } // Set bits 52-59 if the action register indicate the error as recoverable for(uint64_t i = OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG_LINK0_CORRECTABLE_ARRAY_ERROR; i <= OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG_LINK1_TOO_MANY_CRC_ERRORS; i++) { if(l_action0Buffer.getBit(i) == 0 && l_action1Buffer.getBit(i) == 1 ) { l_scomBuffer.setBit(i); } } // Write modified mask back to scom register FAPI_TRY(fapi2::putScom(l_obusTarget, OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG, l_scomBuffer), "putScom of OBUS_LL0_LL0_LL0_PB_IOOL_FIR_MASK_REG failed"); } fapi_try_exit: FAPI_IMP("p9_io_obus_firmask_restore: Exiting..."); return fapi2::current_err; }
// ----------------------------------------------------------------------------- // pba_bc_stop // ----------------------------------------------------------------------------- fapi2::ReturnCode pba_bc_stop( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_IMP(">>> pba_bc_stop..."); fapi2::buffer<uint64_t> l_data64; bool l_bcde_stop_complete = false; bool l_bcue_stop_complete = false; uint32_t l_pollCount; l_data64.setBit<0>(); // Stopping Block Copy Download Engine FAPI_TRY(fapi2::putScom(i_target, PU_BCDE_CTL_SCOM, l_data64), "Failed to set the BCDE control register"); // Stopping Block Copy Upload Engine FAPI_TRY(fapi2::putScom(i_target, PU_BCUE_CTL_SCOM, l_data64), "Failed to set the BCUE control register"); // Polling on, to verify that BCDE & BCUE are indeed stopped. for (l_pollCount = 0; l_pollCount < p9pba::MAX_PBA_BC_STOP_POLLS; l_pollCount++) { // Read the BCDE Status register to check for a stopped condition FAPI_TRY(fapi2::getScom(i_target, PU_BCDE_STAT_SCOM, l_data64)); FAPI_DBG("BCDE Status = 0x%016llX", uint64_t(l_data64)); if (! l_data64.getBit<p9pba::PBA_BC_STAT_RUNNING>() ) { FAPI_INF("BCDE Running Bit clear to indicate the stop condition"); l_bcde_stop_complete = true; } // Read the BCUE Status register to check for stop condition FAPI_TRY(fapi2::getScom(i_target, PU_BCUE_STAT_SCOM, l_data64)); FAPI_DBG("BCUE Status = 0x%016llX", uint64_t(l_data64)); if(! l_data64.getBit<p9pba::PBA_BC_STAT_RUNNING>()) { FAPI_INF("BCUE Running Bit is clear, indicates the stop condition"); l_bcue_stop_complete = true; } // If both engines are stopped , exit polling loop if (l_bcde_stop_complete && l_bcue_stop_complete) { break; } else { FAPI_TRY(fapi2::delay(p9pba::MAX_PBA_BC_STOP_POLLS * 1000, 2000000), " fapi2::delay Failed "); // In microseconds } } // Assert, if BCDE did not stop if (!l_bcde_stop_complete) { FAPI_ASSERT(false, fapi2::P9_PROCPM_PBA_BCDE_STOP_TIMEOUT() .set_POLLCOUNT( p9pba::MAX_PBA_BC_STOP_POLLS) .set_POLLVALUE(p9pba::MAX_PBA_BC_STOP_POLLS) .set_CHIP(i_target), "PBA BCDE Stop Timeout"); } // Assert, if BCUE did not stop if (!l_bcue_stop_complete) { FAPI_ASSERT(false, fapi2::P9_PROCPM_PBA_BCUE_STOP_TIMEOUT() .set_POLLCOUNT( p9pba::MAX_PBA_BC_STOP_POLLS) .set_POLLVALUE( p9pba::MAX_PBA_BC_STOP_POLLS) .set_CHIP(i_target), "PBA BCUE Stop Timeout"); } FAPI_INF("Clear the BCDE and BCUE stop bits."); l_data64.flush<0>(); FAPI_TRY(fapi2::putScom(i_target, PU_BCDE_CTL_SCOM, l_data64)); FAPI_TRY(fapi2::putScom(i_target, PU_BCUE_CTL_SCOM, l_data64)); fapi_try_exit: FAPI_IMP("<<< pba_bc_stop..."); return fapi2::current_err; }
//------------------------------------------------------------------------------ // name: proc_mpipl_chip_cleanup //------------------------------------------------------------------------------ // purpose: // To enable MCD recovery // // Note: PHBs are left in ETU reset state after executing proc_mpipl_nest_cleanup, which runs before this procedure. PHYP releases PHBs from ETU reset post HostBoot IPL. // // SCOM regs // // 1) MCD even recovery control register // 0000000002013410 (SCOM) // bit 0 (MCD_REC_EVEN_ENABLE): 0 to 1 transition needed to start, reset to 0 at end of request. // bit 5 (MCD_REC_EVEN_REQ_PEND) // // // 2) MCD odd recovery control register // 0000000002013411 (SCOM) // bit 0 (MCD_REC_ODD_ENABLE): 0 to 1 transition needed to start, reset to 0 at end of request. // bit 5 (MCD_REC_ODD_REQ_PEND) // // 3) Clear PCI Nest FIR registers // 02012000 (SCOM) // 02012400 (SCOM) // 02012800 (SCOM) // // parameters: // 'i_target' is reference to chip target // // returns: // FAPI_RC_SUCCESS (success, MCD recovery enabled for odd and even slices) // // RC_MCD_RECOVERY_NOT_DISABLED_RC (MCD recovery for even or odd slice is not disabled; therefore can't re-enable MCD recovery) // (Note: refer to file eclipz/chips/p8/working/procedures/xml/error_info/proc_mpipl_chip_cleanup_errors.xml) // // getscom/putscom fapi errors // fapi error assigned from eCMD function failure // //------------------------------------------------------------------------------ fapi::ReturnCode proc_mpipl_chip_cleanup(const fapi::Target &i_target){ const char *procedureName = "proc_mpipl_chip_cleanup"; //Name of this procedure fapi::ReturnCode rc; //fapi return code value uint32_t rc_ecmd = 0; //ecmd return code value const uint32_t data_size = 64; //Size of data buffer const int MAX_MCD_DIRS = 2; //Max of 2 MCD Directories (even and odd) ecmdDataBufferBase fsi_data[MAX_MCD_DIRS]; const uint64_t ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[MAX_MCD_DIRS] = { 0x0000000002013410, //MCD even recovery control register address 0x0000000002013411 //MCD odd recovery control register address }; const uint32_t MCD_RECOVERY_CTRL_REG_BIT_POS0 = 0; //Bit 0 of MCD even and odd recovery control regs const char *ARY_MCD_DIR_STRS[MAX_MCD_DIRS] = { "Even", //Ptr to char string "Even" for even MCD "Odd" //Ptr to char string "Odd" for odd MCD }; const int MAX_PHBS = 3; const uint64_t PCI_NEST_FIR_REG_ADDRS[MAX_PHBS] = { 0x02012000, 0x02012400, 0x02012800 }; do { //Set bit length for 64-bit buffers rc_ecmd = fsi_data[0].setBitLength(data_size); rc_ecmd |= fsi_data[1].setBitLength(data_size); if(rc_ecmd) { rc.setEcmdError(rc_ecmd); break; } //Verify MCD recovery was previously disabled for even and odd slices //If not, this is an error condition for (int counter = 0; counter < MAX_MCD_DIRS; counter++) { FAPI_DBG("Verifying MCD %s Recovery is disabled, target=%s", ARY_MCD_DIR_STRS[counter], i_target.toEcmdString()); //Get data from MCD Even or Odd Recovery Ctrl reg rc = fapiGetScom(i_target, ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter], fsi_data[counter]); if (!rc.ok()) { FAPI_ERR("%s: fapiGetScom error (addr: 0x%08llX), target=%s", procedureName, ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter], i_target.toEcmdString()); break; } //Check whether bit 0 is 0, meaning MCD recovery is disabled as expected if( fsi_data[counter].getBit(MCD_RECOVERY_CTRL_REG_BIT_POS0) ) { FAPI_ERR("%s: MCD %s Recovery not disabled as expected, target=%s", procedureName, ARY_MCD_DIR_STRS[counter], i_target.toEcmdString()); const fapi::Target & CHIP_TARGET = i_target; const uint64_t & MCD_RECOV_CTRL_REG_ADDR = ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter]; ecmdDataBufferBase & MCD_RECOV_CTRL_REG_DATA = fsi_data[counter]; FAPI_SET_HWP_ERROR(rc, RC_MPIPL_MCD_RECOVERY_NOT_DISABLED_RC); break; } } if(!rc.ok()) { break; } //Assert bit 0 of MCD Recovery Ctrl regs to enable MCD recovery for (int counter = 0; counter < MAX_MCD_DIRS; counter++) { FAPI_DBG("Enabling MCD %s Recovery, target=%s", ARY_MCD_DIR_STRS[counter], i_target.toEcmdString()); //Assert bit 0 of MCD Even or Odd Recovery Control reg to enable recovery rc_ecmd = fsi_data[counter].setBit(MCD_RECOVERY_CTRL_REG_BIT_POS0 ); if(rc_ecmd) { FAPI_ERR("%s: Error (%u) asserting bit pos %u in ecmdDataBufferBase that stores value of MCD %s Recovery Control reg (addr: 0x%08llX), target=%s", procedureName, rc_ecmd, MCD_RECOVERY_CTRL_REG_BIT_POS0, ARY_MCD_DIR_STRS[counter], ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter], i_target.toEcmdString()); rc.setEcmdError(rc_ecmd); break; } //Write data to MCD Even or Odd Recovery Control reg rc = fapiPutScom(i_target, ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter], fsi_data[counter]); if (!rc.ok()) { FAPI_ERR("%s: fapiPutScom error (addr: 0x%08llX), target=%s", procedureName, ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter], i_target.toEcmdString()); break; } } if(!rc.ok()) { break; } // SW227429: clear PCI Nest FIR registers // hostboot is blindly sending EOIs in order to ensure no interrupts are pending when PHYP starts up again // with ETU held in reset, these get trapped in PCI and force a freeze to occur (PCI Nest FIR(14)) // clearing the FIR should remove the freeze condition rc_ecmd = fsi_data[0].flushTo0(); if (rc_ecmd) { FAPI_ERR("%s: Error (%u) forming PCI Nest FIR clear data buffer, target=%s", procedureName, rc_ecmd, i_target.toEcmdString()); rc.setEcmdError(rc_ecmd); break; } for (int counter = 0; counter < MAX_PHBS; counter++) { FAPI_DBG("Clearing PCI%d Nest FIR, target=%s", counter, i_target.toEcmdString()); rc = fapiPutScom(i_target, PCI_NEST_FIR_REG_ADDRS[counter], fsi_data[0]); if (!rc.ok()) { FAPI_ERR("%s: fapiPutScom error (addr: 0x%08llX), target=%s", procedureName, PCI_NEST_FIR_REG_ADDRS[counter], i_target.toEcmdString()); break; } } } while(0); FAPI_IMP("Exiting %s", procedureName); return rc; }
fapi2::ReturnCode pm_pba_fir_init( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_IMP("pm_pba_fir_init Enter"); uint8_t firinit_done_flag; p9pmFIR::PMFir <p9pmFIR::FIRTYPE_PBA_LFIR> l_pbaFir(i_target); FAPI_TRY(l_pbaFir.get(p9pmFIR::REG_ALL), "ERROR: Failed to get the PBA FIR values"); /* Clear the FIR and action buffers */ FAPI_TRY(l_pbaFir.clearAllRegBits(p9pmFIR::REG_FIR), "ERROR: Failed to clear PBA FIR"); FAPI_TRY(l_pbaFir.clearAllRegBits(p9pmFIR::REG_ACTION0), "ERROR: Failed to clear PBA FIR"); FAPI_TRY(l_pbaFir.clearAllRegBits(p9pmFIR::REG_ACTION1), "ERROR: Failed to clear PBA FIR"); FAPI_TRY(l_pbaFir.setAllRegBits(p9pmFIR::REG_FIRMASK), "ERROR: Faled to set the PBA FIR MASK"); /* Set the action and mask for the PBA LFIR bits */ FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_OCI_APAR_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_PB_RDADRERR_FW), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_PB_RDDATATO_FW), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_PB_SUE_FW), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_PB_UE_FW), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_PB_CE_FW), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_OCI_SLAVE_INIT), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_OCI_WRPAR_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_SPARE), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_PB_UNEXPCRESP), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_PB_UNEXPDATA), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_PB_PARITY_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_PB_WRADRERR_FW), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_PB_BADCRESP), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_PB_ACKDEAD_FW_RD), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_PB_CRESPTO), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCUE_SETUP_ERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCUE_PB_ACK_DEAD), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCUE_PB_ADRERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCUE_OCI_DATERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCDE_SETUP_ERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCDE_PB_ACK_DEAD), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCDE_PB_ADRERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCDE_RDDATATO_ERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCDE_SUE_ERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCDE_UE_ERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCDE_CE), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_BCDE_OCI_DATERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_INTERNAL_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_ILLEGAL_CACHE_OP), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.setRecvAttn(PBAFIR_OCI_BAD_REG_ADDR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_AXPUSH_WRERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_AXRCV_DLO_ERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_AXRCV_DLO_TO), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_AXRCV_RSVDATA_TO), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_AXFLOW_ERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_AXSND_DHI_RTYTO), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_AXSND_DLO_RTYTO), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_AXSND_RSVTO), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_AXSND_RSVERR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_PB_ACKDEAD_FW_WR), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_RESERVED_41), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_RESERVED_42), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_RESERVED_43), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_FIR_PARITY_ERR2), FIR_MASK_ERROR); FAPI_TRY(l_pbaFir.mask(PBAFIR_FIR_PARITY_ERR), FIR_MASK_ERROR); 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"); FAPI_DBG("firinit_done_flag for PBA = %d", firinit_done_flag); if (firinit_done_flag) { FAPI_TRY(l_pbaFir.restoreSavedMask(), "ERROR: Failed to restore the mask saved"); } FAPI_TRY(l_pbaFir.put(), "ERROR:Failed to write to the PBA FIR MASK"); fapi_try_exit: return fapi2::current_err; }
fapi2::ReturnCode pm_occ_fir_init( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_IMP("pm_occ_fir_init 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"); FAPI_TRY(l_occFir.get(p9pmFIR::REG_ALL), "ERROR: Failed to get the OCC FIR values"); /* Clear all the FIR and action buffers */ FAPI_TRY(l_occFir.clearAllRegBits(p9pmFIR::REG_FIR), "ERROR: Failed to clear OCC FIR"); FAPI_TRY(l_occFir.clearAllRegBits(p9pmFIR::REG_ACTION0), "ERROR: Failed to clear OCC action 0"); FAPI_TRY(l_occFir.clearAllRegBits(p9pmFIR::REG_ACTION1), "ERROR: Failed to clear OCC action 1"); /* Set the action and mask for the OCC LFIR bits */ FAPI_TRY(l_occFir.mask(OCC_FW0), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(OCC_FW1), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(CME_ERR_NOTIFY), FIR_MASK_ERROR); FAPI_TRY(l_occFir.setRecvAttn(STOP_RCV_NOTIFY_PRD), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.mask(OCC_HB_NOTIFY), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(GPE0_WD_TIMEOUT), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(GPE1_WD_TIMEOUT), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(GPE2_WD_TIMEOUT), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(GPE3_WD_TIMEOUT), FIR_MASK_ERROR); FAPI_TRY(l_occFir.setRecvAttn(GPE0_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(GPE1_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.mask(GPE2_ERR), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(GPE3_ERR), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(OCB_ERR), FIR_MASK_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_UE), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_CE), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_READ_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_WRITE_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_DATAOUT_PERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_OCI_WDATA_PARITY), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_OCI_BE_PARITY_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_OCI_ADDR_PARITY_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.mask(GPE0_HALTED), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(GPE1_HALTED), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(GPE2_HALTED), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(GPE3_HALTED), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(EXT_TRAP), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(PPC405_CORE_RESET), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(PPC405_CHIP_RESET), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(PPC405_SYS_RESET), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(PPC405_WAIT_STATE), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(PPC405_DBGSTOPACK), FIR_MASK_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCB_DB_OCI_TIMEOUT), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCB_DB_OCI_RDATA_PARITY), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCB_DB_OCI_SLVERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCB_PIB_ADDR_PARITY_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCB_DB_PIB_DATA_PARITY_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCB_IDC0_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCB_IDC1_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCB_IDC2_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCB_IDC3_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRT_FSM_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(JTAGACC_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.mask(SPARE_ERR_38), FIR_MASK_ERROR); FAPI_TRY(l_occFir.setRecvAttn(C405_ECC_UE), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(C405_ECC_CE), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(C405_OCI_MC_CHK), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_SPARE_DIRERR0), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_SPARE_DIRERR1), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_SPARE_DIRERR2), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(SRAM_SPARE_DIRERR3), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(GPE0_OCISLV_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(GPE1_OCISLV_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(GPE2_OCISLV_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(GPE3_OCISLV_ERR), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.mask(C405ICU_M_TIMEOUT), FIR_MASK_ERROR); FAPI_TRY(l_occFir.setRecvAttn(C405DCU_M_TIMEOUT), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCC_CMPLX_FAULT), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.setRecvAttn(OCC_CMPLX_NOTIFY), FIR_REC_ATTN_ERROR); FAPI_TRY(l_occFir.mask(SPARE_59), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(SPARE_60), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(SPARE_61), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(FIR_PARITY_ERR_DUP), FIR_MASK_ERROR); FAPI_TRY(l_occFir.mask(FIR_PARITY_ERR), FIR_MASK_ERROR); if (firinit_done_flag) { FAPI_TRY(l_occFir.restoreSavedMask(), "ERROR: Failed to restore the mask saved"); } FAPI_TRY(l_occFir.put(), "ERROR: Failed to write the OCC FIR values"); fapi_try_exit: return fapi2::current_err; }
fapi2::ReturnCode pm_pss_init( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_IMP(">> pm_pss_init Enter"); fapi2::buffer<uint64_t> l_data64; const uint8_t l_default_apss_chip_select = 0; const uint8_t l_default_spipss_frame_size = 0x20; const uint8_t l_default_spipss_in_delay = 0; const uint8_t l_default_spipss_clock_polarity = 0; const uint8_t l_default_spipss_clock_phase = 0; const uint16_t l_default_attr_pm_spipss_clock_divider = 0xA; uint32_t l_attr_proc_pss_init_nest_frequency; uint8_t l_attr_pm_apss_chip_select; uint8_t l_attr_pm_spipss_frame_size; uint8_t l_attr_pm_spipss_in_delay; uint8_t l_attr_pm_spipss_clock_polarity; uint8_t l_attr_pm_spipss_clock_phase; uint16_t l_attr_pm_spipss_clock_divider; uint32_t l_attr_pm_spipss_inter_frame_delay; uint32_t l_spipss_100ns_value; uint8_t l_p2s_fsm_enable; uint8_t l_p2s_nr_of_frames; uint8_t l_hwctrl_fsm_enable; uint8_t l_hwctrl_nr_of_frames; const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> l_sysTarget = i_target.getParent<fapi2::TARGET_TYPE_SYSTEM>(); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_PB_MHZ, l_sysTarget, l_attr_proc_pss_init_nest_frequency), "Error: Could not fetch the system Frequency") GETATTR_DEFAULT(fapi2::ATTR_PM_APSS_CHIP_SELECT, "ATTR_PM_APSS_CHIP_SELECT", i_target, l_attr_pm_apss_chip_select, l_default_apss_chip_select); GETATTR_DEFAULT(fapi2::ATTR_PM_SPIPSS_FRAME_SIZE, "ATTR_PM_SPIPSS_FRAME_SIZE", i_target, l_attr_pm_spipss_frame_size, l_default_spipss_frame_size); GETATTR_DEFAULT(fapi2::ATTR_PM_SPIPSS_IN_DELAY, "ATTR_PM_SPIPSS_IN_DELAY", i_target, l_attr_pm_spipss_in_delay, l_default_spipss_in_delay ); GETATTR_DEFAULT(fapi2::ATTR_PM_SPIPSS_CLOCK_POLARITY, "ATTR_PM_SPIPSS_CLOCK_POLARITY", i_target, l_attr_pm_spipss_clock_polarity, l_default_spipss_clock_polarity ); GETATTR_DEFAULT(fapi2::ATTR_PM_SPIPSS_CLOCK_PHASE, "ATTR_PM_SPIPSS_CLOCK_PHASE", i_target, l_attr_pm_spipss_clock_phase, l_default_spipss_clock_phase ); GETATTR_DEFAULT(fapi2::ATTR_PM_SPIPSS_CLOCK_DIVIDER, "ATTR_PM_SPIPSS_CLOCK_DIVIDER", i_target, l_attr_pm_spipss_clock_divider, l_default_attr_pm_spipss_clock_divider); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PM_SPIPSS_INTER_FRAME_DELAY_SETTING, i_target, l_attr_pm_spipss_inter_frame_delay), "Error: Could not fetch inter frame delay"); // ------------------------------------------ // -- Init procedure // ------------------------------------------ // ****************************************************************** // - set SPIPSS_ADC_CTRL_REG0 with the values read from attributes // ****************************************************************** FAPI_TRY(fapi2::getScom(i_target, PU_SPIMPSS_ADC_CTRL_REG0, l_data64)); l_data64.insertFromRight<0, 6>(l_attr_pm_spipss_frame_size); l_data64.insertFromRight<12, 6>(l_attr_pm_spipss_in_delay); FAPI_TRY(fapi2::putScom(i_target, PU_SPIMPSS_ADC_CTRL_REG0, l_data64), "Error: failed to set the SPIPSS ADC CTRL REG 0 configuration"); // ****************************************************************** // - set SPIPSS_ADC_CTRL_REG1 // adc_fsm_enable = disable // adc_device = APSS // adc_cpol = 0 // adc_cpha = 0 // adc_clock_divider = set to 10Mhz // adc_nr_of_frames = 0x16 (for auto 2 mode) // ****************************************************************** FAPI_TRY(fapi2::getScom(i_target, PU_SPIPSS_ADC_CTRL_REG1, l_data64)); l_hwctrl_fsm_enable = 0x1; l_hwctrl_nr_of_frames = 0x10; l_data64.insertFromRight<0, 1>(l_hwctrl_fsm_enable); l_data64.insertFromRight<1, 1>(l_attr_pm_apss_chip_select); l_data64.insertFromRight<2, 1>(l_attr_pm_spipss_clock_polarity); l_data64.insertFromRight<3, 1>(l_attr_pm_spipss_clock_phase); l_data64.insertFromRight<4, 10>(l_attr_pm_spipss_clock_divider); l_data64.insertFromRight<14, 4>(l_hwctrl_nr_of_frames); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_ADC_CTRL_REG1, l_data64), "Error: failed to set the SPIPSS ADC CTRL REG 1 configuration"); // ****************************************************************** // - set SPIPSS_ADC_CTRL_REG2 // ****************************************************************** FAPI_TRY(fapi2::getScom(i_target, PU_SPIPSS_ADC_CTRL_REG2, l_data64)); l_data64.insertFromRight<0, 17>(l_attr_pm_spipss_inter_frame_delay); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_ADC_CTRL_REG2, l_data64), "Error: failed to set the SPIPSS ADC CTRL REG 2 configuration"); // ****************************************************************** // - clear SPIPSS_ADC_Wdata_REG // ****************************************************************** l_data64.flush<0>(); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_ADC_WDATA_REG, l_data64), "Error: Failed to clear SPIPSS ADC WDATA"); // ****************************************************************** // - set SPIPSS_P2S_CTRL_REG0 // ****************************************************************** FAPI_TRY(fapi2::getScom(i_target, PU_SPIPSS_P2S_CTRL_REG0, l_data64)); l_data64.insertFromRight<0, 6>(l_attr_pm_spipss_frame_size); l_data64.insertFromRight<12, 6>(l_attr_pm_spipss_in_delay); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_P2S_CTRL_REG0, l_data64), "Error: Failed to set SPIPSS P2S CTRL REG 0"); // ****************************************************************** // - set SPIPSS_P2S_CTRL_REG1 // p2s_fsm_enable = disable // p2s_device = APSS // p2s_cpol = 0 // p2s_cpha = 0 // p2s_clock_divider = set to 10Mhz // p2s_nr_of_frames = 1 (for auto 2 mode) // ****************************************************************** FAPI_TRY(fapi2::getScom(i_target, PU_SPIPSS_P2S_CTRL_REG1, l_data64)); l_p2s_fsm_enable = 0x1; l_p2s_nr_of_frames = 0x1; l_data64.insertFromRight<0, 1>(l_p2s_fsm_enable); l_data64.insertFromRight<1, 1>(l_attr_pm_apss_chip_select); l_data64.insertFromRight<2, 1>(l_attr_pm_spipss_clock_polarity); l_data64.insertFromRight<3, 1>(l_attr_pm_spipss_clock_phase); l_data64.insertFromRight<4, 10>(l_attr_pm_spipss_clock_divider); l_data64.insertFromRight<17, 1>(l_p2s_nr_of_frames); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_P2S_CTRL_REG1, l_data64), "Error: Failed to set SPIPSS P2S CTRL REG 1"); // ****************************************************************** // - set SPIPSS_P2S_CTRL_REG2 // ****************************************************************** FAPI_TRY(fapi2::getScom(i_target, PU_SPIPSS_P2S_CTRL_REG2, l_data64)); l_data64.insertFromRight<0, 17>(l_attr_pm_spipss_inter_frame_delay); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_P2S_CTRL_REG2, l_data64), "Error: Failed to set SPIPSS P2S CTRL REG 2"); // ****************************************************************** // - clear SPIPSS_P2S_Wdata_REG // ****************************************************************** l_data64.flush<0>(); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_P2S_WDATA_REG, l_data64), "Error: Failed to clear SPI PSS P2S WDATA"); // ****************************************************************** // - Set 100ns Register for Interframe delay // ****************************************************************** l_spipss_100ns_value = l_attr_proc_pss_init_nest_frequency / 40; FAPI_TRY(fapi2::getScom(i_target, PU_SPIPSS_100NS_REG, l_data64)); l_data64.insertFromRight<0, 32>(l_spipss_100ns_value); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_100NS_REG, l_data64), "Error: Failed to set 100ns clear SPI PSS P2S WDATA"); fapi_try_exit: FAPI_IMP("<< pm_pss_init"); return fapi2::current_err; }
fapi2::ReturnCode pm_pss_reset( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_IMP(">> pm_pss_reset"); fapi2::buffer<uint64_t> l_data64; uint32_t l_pollcount = 0; uint32_t l_max_polls; // timeout period is 10 millisecond. (Far longer than needed) const uint32_t l_pss_timeout_us = 10000; const uint32_t l_pss_poll_interval_us = 10; // ****************************************************************** // - Poll status register for ongoing or no errors to give the // chance for on-going operations to complete // ****************************************************************** FAPI_INF("Polling for ADC on-going to go low ... "); l_max_polls = l_pss_timeout_us / l_pss_poll_interval_us; for (l_pollcount = 0; l_pollcount < l_max_polls; l_pollcount++) { FAPI_TRY(fapi2::getScom(i_target, PU_SPIPSS_ADC_STATUS_REG, l_data64)); // ADC on-going complete if (l_data64.getBit<0>() == 0) { FAPI_INF("All frames sent from ADC to the APSS device."); break; } // ADC error FAPI_ASSERT(l_data64.getBit<7>() != 1, fapi2::PM_PSS_ADC_ERROR() .set_CHIP(i_target) .set_POLLCOUNT(l_pollcount), "Error while sending the frames from ADC to APSS device"); FAPI_DBG("Delay before next poll"); fapi2::delay(l_pss_poll_interval_us * 1000, 1000); } // Write attempted while Bridge busy if(l_data64.getBit<5>() == 1) { FAPI_INF("SPIP2S Write While Bridge Busy bit asserted. May cause " "undefined bridge behavior. Will be cleared during reset"); } // Polling timeout if (l_pollcount >= l_max_polls) { FAPI_INF("WARNING: SPI ADC did not go to idle in at least %d us. " "Reset of PSS macro is commencing anyway", l_pss_timeout_us); } // ****************************************************************** // - Poll status register for ongoing or errors to give the // chance for on-going operations to complete // ****************************************************************** FAPI_INF("Polling for P2S on-going to go low ... "); for (l_pollcount = 0; l_pollcount < l_max_polls; l_pollcount++) { FAPI_TRY(fapi2::getScom(i_target, PU_SPIPSS_P2S_STATUS_REG, l_data64)); //P2S On-going complete if (l_data64.getBit<0>() == 0) { FAPI_INF("All frames sent from P2S to the APSS device."); break; } // P2S error FAPI_ASSERT(l_data64.getBit<7>() != 1, fapi2::PM_PSS_P2S_ERROR() .set_CHIP(i_target) .set_POLLCOUNT(l_pollcount), "Error while sending the frames from P2S to APSS device"); FAPI_DBG("Delay before next poll"); fapi2::delay(l_pss_poll_interval_us * 1000, 1000); } // write attempted while bridge busy if (l_data64.getBit<5>() == 1) { FAPI_INF("SPIP2S Write While Bridge Busy bit asserted. " "Will be cleared with coming reset"); } // Poll timeout if (l_pollcount >= l_max_polls) { FAPI_INF("WARNING: SPI P2S did not go to idle in at least %d us. " "Reset of PSS macro is commencing anyway", l_pss_timeout_us); } // ****************************************************************** // - Resetting both ADC and P2S bridge // ****************************************************************** FAPI_INF("Resetting P2S and ADC bridges."); l_data64.flush<0>(); l_data64.setBit<1>(); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_ADC_RESET_REGISTER, l_data64), "Error: Could not reset ADC bridge"); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_P2S_RESET_REGISTER, l_data64), "Error: Could not reset P2S bridge"); // Clearing reset for cleanliness l_data64.flush<0>(); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_ADC_RESET_REGISTER, l_data64), "Error: Could not clear the ADC reset register"); FAPI_TRY(fapi2::putScom(i_target, PU_SPIPSS_P2S_RESET_REGISTER, l_data64), "Error: Could not clear the P2S reset register"); fapi_try_exit: FAPI_IMP("<< pm_pss_reset"); return fapi2::current_err; }
fapi2::ReturnCode pm_cme_fir_reset( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_IMP("pm_cme_fir_reset start"); auto l_eqChiplets = i_target.getChildren<fapi2::TARGET_TYPE_EQ> (fapi2::TARGET_STATE_FUNCTIONAL); uint8_t firinit_done_flag; 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"); for (auto l_eq_chplt : l_eqChiplets) { //We cannot rely on the HWAS state because during an MPIPL //the cores get stopped and the SP doesnt know until an //attr sync occurs with the platform. We must use the //query_cache_state to safely determine if we can scom //the ex targets fapi2::ReturnCode l_rc; bool l_l2_is_scanable[MAX_L2_PER_QUAD]; bool l_l2_is_scomable[MAX_L2_PER_QUAD]; bool l_l3_is_scanable[MAX_L3_PER_QUAD]; bool l_l3_is_scomable[MAX_L3_PER_QUAD]; for (auto cnt = 0; cnt < MAX_L2_PER_QUAD; ++cnt) { l_l2_is_scomable[cnt] = false; l_l2_is_scanable[cnt] = false; } for (auto cnt = 0; cnt < MAX_L3_PER_QUAD; ++cnt) { l_l3_is_scanable[cnt] = false; l_l3_is_scomable[cnt] = false; } uint8_t l_chip_unit_pos; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_eq_chplt, l_chip_unit_pos), "ERROR: Failed to get the chip unit pos attribute from the eq"); FAPI_EXEC_HWP(l_rc, p9_query_cache_access_state, l_eq_chplt, l_l2_is_scomable, l_l2_is_scanable, l_l3_is_scomable, l_l3_is_scanable); FAPI_TRY(l_rc, "ERROR: failed to query cache access state for EQ %d", l_chip_unit_pos); auto l_exChiplets = l_eq_chplt.getChildren<fapi2::TARGET_TYPE_EX> (fapi2::TARGET_STATE_FUNCTIONAL); for(auto l_ex_chplt : l_exChiplets) { FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_ex_chplt, l_chip_unit_pos), "ERROR: Failed to get the chip unit pos attribute from the ex"); //look ex is scommable l_chip_unit_pos = l_chip_unit_pos % 2; if ((!(l_l2_is_scomable[l_chip_unit_pos]) && !(l_l3_is_scomable[l_chip_unit_pos]))) { continue; } p9pmFIR::PMFir <p9pmFIR::FIRTYPE_CME_LFIR> l_cmeFir(l_ex_chplt); /* Only save off the FIR masks if they have been initialized */ if ( firinit_done_flag != fapi2::ENUM_ATTR_PM_FIRINIT_DONE_ONCE_FLAG_FIRS_RESET_IN_HB ) { FAPI_TRY(l_cmeFir.get(p9pmFIR::REG_FIRMASK), "ERROR: Failed to get the PBA FIR MASK value"); /* Fetch the CME FIR MASK; Save it to HWP attribute; clear it */ FAPI_TRY(l_cmeFir.saveMask(), "ERROR: Failed to save CME FIR Mask to the attribute"); FAPI_TRY(l_cmeFir.setAllRegBits(p9pmFIR::REG_FIRMASK), "ERROR: Faled to set the CME FIR MASK"); FAPI_TRY(l_cmeFir.put(), "ERROR:Failed to write to the CME FIR MASK"); } } } if (firinit_done_flag == fapi2::ENUM_ATTR_PM_FIRINIT_DONE_ONCE_FLAG_NO_INIT) { firinit_done_flag = fapi2::ENUM_ATTR_PM_FIRINIT_DONE_ONCE_FLAG_FIRS_RESET_IN_HB; FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PM_FIRINIT_DONE_ONCE_FLAG, i_target, firinit_done_flag ), "ERROR: Failed to set attribute PM_FIRINIT_DONE_ONCE_FLAG to RESET_IN_HB in pm_cme_fir_reset"); } fapi_try_exit: return fapi2::current_err; }
// ----------------------------------------------------------------------------- // pba_slave_reset // ----------------------------------------------------------------------------- fapi2::ReturnCode pba_slave_reset( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_IMP(">> pba_slave_reset"); fapi2::buffer<uint64_t> l_data64; bool l_poll_failure = false; uint32_t l_pollCount; // Slave to be reset. Note: Slave 3 is not reset as it is owned by SBE std::vector<uint32_t> v_slave_resets = {0, 1, 2}; for (auto sl : v_slave_resets) { FAPI_INF("Reseting PBA Slave %x", sl); l_poll_failure = true; for (l_pollCount = 0; l_pollCount < p9pba::MAX_PBA_RESET_POLLS; l_pollCount++) { // Reset the selected slave l_data64.insert<0, 64>(p9pba::PBA_SLVRESETs[sl] ); FAPI_TRY(fapi2::putScom(i_target, PU_PBASLVRST_SCOM, l_data64)); // Read the reset register to check for reset completion FAPI_TRY(fapi2::getScom(i_target, PU_PBASLVRST_SCOM, l_data64)); FAPI_DBG("Slave %x reset poll l_data64 = 0x%016llX", sl, l_data64); // If slave reset in progress, wait and then poll if (l_data64 & 0x0000000000000001 << (63 - ( 4 + sl)) ) { FAPI_TRY(fapi2::delay(p9pba::PBA_RESET_POLL_DELAY * 1000, 200000), " fapi2::delay Failed. "); // In microseconds } else { FAPI_INF("PBA Reset complete for Slave %d", sl); l_poll_failure = false; break; } } // Error exit from above loop if (l_poll_failure) { const uint64_t& l_BUFFCONT = uint64_t(l_data64); FAPI_ASSERT(false, fapi2::P9_PMPROC_PBA_SLAVE_RESET_TIMEOUT() .set_POLLCOUNT(l_pollCount) .set_SLAVENUM(sl) .set_PBASLVREG(l_BUFFCONT) .set_CHIP(i_target), "PBA Slave Reset Timout"); } // Check if the slave is still actually busy. if ( l_data64 & 0x0000000000000001 << (63 - ( 8 + sl)) ) { const uint64_t& l_BUFFCONT = uint64_t(l_data64); FAPI_ASSERT(false, fapi2::P9_PMPROC_PBA_SLAVE_BUSY_AFTER_RESET() .set_POLLCOUNT(l_pollCount) .set_SLAVENUM(sl) .set_PBASLVREG( l_BUFFCONT) .set_CHIP(i_target), "Slave 0x%x still busy after reset", sl); } } fapi_try_exit: FAPI_IMP("<< pba_slave_reset"); return fapi2::current_err; }
//------------------------------------------------------------------------------ // HWP entry point //------------------------------------------------------------------------------ fapi::ReturnCode proc_fab_iovalid( std::vector<proc_fab_iovalid_proc_chip>& i_proc_chips, bool i_set_not_clear) { // return code fapi::ReturnCode rc; // iterator for HWP input vector std::vector<proc_fab_iovalid_proc_chip>::const_iterator iter; // partial good attributes uint8_t abus_enable_attr; uint8_t xbus_enable_attr; bool x_changed = false; bool a_changed = false; // mark HWP entry FAPI_IMP("proc_fab_iovalid: Entering ..."); do { // loop over all chips in input vector for (iter = i_proc_chips.begin(); iter != i_proc_chips.end(); iter++) { // process X links if (iter->x0 || iter->x1 || iter->x2 || iter->x3) { // query XBUS partial good attribute rc = FAPI_ATTR_GET(ATTR_PROC_X_ENABLE, &(iter->this_chip), xbus_enable_attr); if (!rc.ok()) { FAPI_ERR("proc_fab_iovalid: Error querying ATTR_PROC_X_ENABLE"); break; } if (xbus_enable_attr != fapi::ENUM_ATTR_PROC_X_ENABLE_ENABLE) { FAPI_ERR("proc_fab_iovalid: Partial good attribute error"); const fapi::Target & TARGET = iter->this_chip; FAPI_SET_HWP_ERROR(rc, RC_PROC_FAB_IOVALID_X_PARTIAL_GOOD_ERR); break; } rc = proc_fab_iovalid_manage_x_links(*iter, i_set_not_clear); if (!rc.ok()) { FAPI_ERR("proc_fab_iovalid: Error from proc_fab_iovalid_manage_x_links"); break; } rc = proc_fab_iovalid_manage_x_fir(*iter, i_set_not_clear); if (!rc.ok()) { FAPI_ERR("proc_fab_iovalid: Error from proc_fab_iovalid_manage_x_fir"); break; } x_changed = true; } // process A links if (iter->a0 || iter->a1 || iter->a2) { // query ABUS partial good attribute rc = FAPI_ATTR_GET(ATTR_PROC_A_ENABLE, &(iter->this_chip), abus_enable_attr); if (!rc.ok()) { FAPI_ERR("proc_fab_iovalid: Error querying ATTR_PROC_A_ENABLE"); break; } if (abus_enable_attr != fapi::ENUM_ATTR_PROC_A_ENABLE_ENABLE) { FAPI_ERR("proc_fab_iovalid: Partial good attribute error"); const fapi::Target & TARGET = iter->this_chip; FAPI_SET_HWP_ERROR(rc, RC_PROC_FAB_IOVALID_A_PARTIAL_GOOD_ERR); break; } rc = proc_fab_iovalid_manage_a_links(*iter, i_set_not_clear); if (!rc.ok()) { FAPI_ERR("proc_fab_iovalid: Error from proc_fab_iovalid_manage_a_links"); break; } rc = proc_fab_iovalid_manage_a_fir(*iter, i_set_not_clear); if (!rc.ok()) { FAPI_ERR("proc_fab_iovalid: Error from proc_fab_iovalid_manage_a_fir"); break; } a_changed = true; } if (x_changed || a_changed) { rc = proc_fab_iovalid_manage_ras_fir(*iter, i_set_not_clear); if (!rc.ok()) { FAPI_ERR("proc_fab_iovalid: Error from proc_fab_iovalid_manage_ras_fir"); break; } } } } while(0); // log function exit FAPI_IMP("proc_fab_iovalid: Exiting ..."); return rc; }
// ----------------------------------------------------------------------------- // pba_slave_setup_runtime_phase // ----------------------------------------------------------------------------- fapi2::ReturnCode pba_slave_setup_runtime_phase( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { pba_mode_t pm; pba_slvctln_t ps; fapi2::buffer<uint64_t> l_data64(64); FAPI_IMP(">> pba_slave_setup_runtime_phase"); // Set the PBA_MODECTL register. It's not yet clear how PBA BCE // transaction size will affect performance - for now we go with the // largest size. The HTM marker space is enabled and configured. Slave // fairness is enabled. The setting 'dis_slvmatch_order' ensures that PBA // will correctly flush write data before allowing a read of the same // address from a different master on a different slave. The second write // buffer is enabled. pm.value = 0; pm.fields.pba_region = PBA_OCI_REGION; pm.fields.bcde_ocitrans = PBA_BCE_OCI_TRANSACTION_64_BYTES; pm.fields.bcue_ocitrans = PBA_BCE_OCI_TRANSACTION_64_BYTES; pm.fields.en_marker_ack = 1; pm.fields.oci_marker_space = (PBA_OCI_MARKER_BASE >> 16) & 0x7; pm.fields.en_slv_fairness = 1; pm.fields.en_second_wrbuf = 1; l_data64 = pm.value; // write the prepared value FAPI_TRY(fapi2::putScom(i_target, PU_PBAMODE_SCOM, l_data64), "Failed to set PBA MODE register"); FAPI_INF("Initialize PBA Slave 0 for SGPE STOP use ..."); // Slave 0 (SGPE STOP). This is a read/write slave in the event that // the STOP functions needs to write to memory.. ps.value = 0; ps.fields.enable = 1; ps.fields.mid_match_value = OCI_MASTER_ID_SGPE; ps.fields.mid_care_mask = OCI_MASTER_ID_MASK_ALL; ps.fields.read_ttype = PBA_READ_TTYPE_CL_RD_NC; ps.fields.read_prefetch_ctl = PBA_READ_PREFETCH_NONE; ps.fields.write_ttype = PBA_WRITE_TTYPE_DMA_PR_WR; ps.fields.wr_gather_timeout = PBA_WRITE_GATHER_TIMEOUT_2_PULSES; ps.fields.buf_alloc_a = 1; ps.fields.buf_alloc_b = 1; ps.fields.buf_alloc_c = 1; ps.fields.buf_alloc_w = 1; l_data64 = ps.value; FAPI_TRY(fapi2::putScom(i_target, PU_PBASLVCTL0_SCOM, l_data64), "Failed to set Slave 0 control register"); FAPI_INF("Initialize PBA Slave 1 for PPC405 booting use ..."); // Slave 1 (GPE 1). This is a read/write slave. Write gathering is // allowed, but with the shortest possible timeout. ps.value = 0; ps.fields.enable = 1; ps.fields.mid_match_value = OCI_MASTER_ID_ICU & OCI_MASTER_ID_DCU; ps.fields.mid_care_mask = OCI_MASTER_ID_ICU & OCI_MASTER_ID_DCU; ps.fields.read_ttype = PBA_READ_TTYPE_CL_RD_NC; ps.fields.read_prefetch_ctl = PBA_READ_PREFETCH_NONE; ps.fields.write_ttype = PBA_WRITE_TTYPE_DMA_PR_WR; ps.fields.wr_gather_timeout = PBA_WRITE_GATHER_TIMEOUT_2_PULSES; ps.fields.buf_alloc_a = 1; ps.fields.buf_alloc_b = 1; ps.fields.buf_alloc_c = 1; ps.fields.buf_alloc_w = 1; l_data64 = ps.value; FAPI_TRY(fapi2::putScom(i_target, PU_PBASLVCTL1_SCOM, l_data64), "Failed to set Slave 1 control register"); FAPI_INF("Initialize PBA Slave 2 for PGPE Pstates/WOF use ..."); // Slave 2 (PGPE Boot). This is a read/write slave. Write gethering is // allowed, but with the shortest possible timeout. This slave is // effectively disabled soon after IPL. ps.value = 0; ps.fields.enable = 1; ps.fields.mid_match_value = OCI_MASTER_ID_PGPE; ps.fields.mid_care_mask = OCI_MASTER_ID_MASK_ALL; ps.fields.read_ttype = PBA_READ_TTYPE_CL_RD_NC; ps.fields.read_prefetch_ctl = PBA_READ_PREFETCH_NONE; ps.fields.write_ttype = PBA_WRITE_TTYPE_DMA_PR_WR; ps.fields.wr_gather_timeout = PBA_WRITE_GATHER_TIMEOUT_2_PULSES; ps.fields.buf_alloc_a = 1; ps.fields.buf_alloc_b = 1; ps.fields.buf_alloc_c = 1; ps.fields.buf_alloc_w = 1; l_data64 = ps.value; FAPI_TRY(fapi2::putScom(i_target, PU_PBASLVCTL2_SCOM, l_data64), "Failed to set Slave 2 control register"); // Slave 3 is not modified by this function FAPI_INF("Skipping PBA Slave 3 as this is owned by SBE ..."); fapi_try_exit: FAPI_IMP("<< pba_slave_setup_runtime_phase"); return fapi2::current_err; } // end pba_slave_setup_runtime_phase
// ----------------------------------------------------------------------------- // pba_init -- mode = PM_INIT // ----------------------------------------------------------------------------- fapi2::ReturnCode pba_init( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target) { FAPI_IMP(">> pba_init ..."); fapi2::buffer<uint64_t> l_data64 = 0; uint8_t l_attr_pbax_groupid; uint8_t l_attr_pbax_chipid; uint8_t l_attr_pbax_broadcast_vector; // Clear PBA CONFIG. This register is cleared as there are no chicken // switches that need to be disabled. All other bits are set by OCC Firmware FAPI_TRY(fapi2::putScom(i_target, PU_PBACFG, l_data64), "Failed to clear PBA_CONFIG"); // Clear the PBA FIR FAPI_TRY(fapi2::putScom(i_target, PU_PBAFIR, l_data64), "Failed to clear PBA_FIR"); // No action required for the following registers: // PBARBUFVAL[n] (PBA Read Buffer Valid Status Registers) : They are ROX // PBAPBOCR[n] (PBA PowerBus OverCommit Rate Registers) : They are read-only // PBABAR[n] (PBA Base Address Range Registers) : Handled outside this FAPI // PBABARMSK[n] (PBA BAR Mask Register) : Handled outside this FAPI // (Thus, during a reset, the BARS/MASKS are retained.) // ---------------------------------------------------------- // Get attributes // ---------------------------------------------------------- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_PBAX_GROUPID, i_target, l_attr_pbax_groupid), "Error getting ATTR_PBAX_GROUPID"); FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_PBAX_CHIPID, i_target, l_attr_pbax_chipid), "Error getting ATTR_PBAX_CHIPID"); FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_PBAX_BRDCST_ID_VECTOR, i_target, l_attr_pbax_broadcast_vector), "Error getting ATTR_PBAX_BRDCST_ID_VECTOR"); FAPI_INF("Initialize PBAX Configuration ..."); l_data64.insertFromRight<PU_PBAXCFG_RCV_GROUPID, PU_PBAXCFG_RCV_GROUPID_LEN> (l_attr_pbax_groupid); l_data64.insertFromRight<PU_PBAXCFG_RCV_CHIPID, PU_PBAXCFG_RCV_CHIPID_LEN> (l_attr_pbax_chipid); l_data64.insertFromRight<PU_PBAXCFG_RCV_BRDCST_GROUP, PU_PBAXCFG_RCV_BRDCST_GROUP_LEN> (l_attr_pbax_broadcast_vector); FAPI_INF("PBAX Topology Configuration - GroupID: 0x%02X, ChipID: 0x%02X, BroadcastVector: 0x%02X", l_attr_pbax_groupid, l_attr_pbax_chipid, l_attr_pbax_broadcast_vector); // 20:24 - l_pbax_data_timeout // 27 - l_pbax_snd_retry_commit_overcommit // 28:35 - l_pbax_snd_retry_threshold // 36:40 - l_pbax_snd_timeout l_data64.insertFromRight<PU_PBAXCFG_RCV_DATATO_DIV, PU_PBAXCFG_RCV_DATATO_DIV_LEN> (PBAX_DATA_TIMEOUT); l_data64.insertFromRight<PU_PBAXCFG_SND_RETRY_COUNT_OVERCOM, 1> (PBAX_SND_RETRY_COMMIT_OVERCOMMIT); l_data64.insertFromRight<PU_PBAXCFG_SND_RETRY_THRESH, PU_PBAXCFG_SND_RETRY_THRESH_LEN> (PBAX_SND_RETRY_THRESHOLD); l_data64.insertFromRight<PU_PBAXCFG_SND_RSVTO_DIV, PU_PBAXCFG_SND_RSVTO_DIV_LEN> (PBAX_SND_TIMEOUT); FAPI_TRY(fapi2::putScom(i_target, PU_PBAXCFG_SCOM, l_data64), "Failed to set PBAX Config"); // Perform PBA Slave setup to prepare for the runtime phase. FAPI_TRY(pba_slave_setup_runtime_phase(i_target), "pba_slave_setup_runtime_phase() failed. "); fapi_try_exit: FAPI_IMP("<< pba_init ..."); return fapi2::current_err; }
fapi2::ReturnCode p9_pm_occ_control (const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const p9occ_ctrl::PPC_CONTROL i_ppc405_reset_ctrl, const p9occ_ctrl::PPC_BOOT_CONTROL i_ppc405_boot_ctrl, const uint64_t i_ppc405_jump_to_main_instr) { FAPI_IMP("Entering p9_pm_occ_control ...."); fapi2::buffer<uint64_t> l_data64; fapi2::buffer<uint64_t> l_firMask; fapi2::buffer<uint64_t> l_occfir; fapi2::buffer<uint64_t> l_jtagcfg; // Set up Boot Vector Registers in SRAM // - set bv0-2 to all 0's (illegal instructions) // - set bv3 to proper branch instruction if (i_ppc405_boot_ctrl != p9occ_ctrl::PPC405_BOOT_NULL) { FAPI_DBG("Writing to Boot Vector 0-2 Registers"); FAPI_TRY(fapi2::putScom(i_target, PU_SRAM_SRBV0_SCOM, l_data64)); FAPI_TRY(fapi2::putScom(i_target, PU_SRAM_SRBV1_SCOM, l_data64)); FAPI_TRY(fapi2::putScom(i_target, PU_SRAM_SRBV2_SCOM, l_data64)); if (i_ppc405_boot_ctrl == p9occ_ctrl::PPC405_BOOT_SRAM) { FAPI_DBG("Writing to Boot Vector 3 Register"); l_data64.flush<0>().insertFromRight(PPC405_BRANCH_SRAM_INSTR, 0, 32); } else if (i_ppc405_boot_ctrl == p9occ_ctrl::PPC405_BOOT_MEM) { FAPI_INF("Setting up for memory boot"); FAPI_TRY(bootMemory(i_target, l_data64), "Booting from Memory Failed"); } else if(i_ppc405_boot_ctrl == p9occ_ctrl::PPC405_BOOT_WITHOUT_BL) { FAPI_DBG("Setting up for boot without bootloader"); l_data64.flush<0>().insertFromRight(i_ppc405_jump_to_main_instr, 0, 64); } else { l_data64.flush<0>().insertFromRight(PPC405_BRANCH_OLD_INSTR, 0, 32); } FAPI_TRY(fapi2::putScom(i_target, PU_SRAM_SRBV3_SCOM, l_data64)); } // Handle the i_ppc405_reset_ctrl parameter switch (i_ppc405_reset_ctrl) { case p9occ_ctrl::PPC405_RESET_NULL: FAPI_INF("No action to be taken for PPC405"); break; case p9occ_ctrl::PPC405_RESET_OFF: FAPI_TRY(fapi2::putScom(i_target, PU_OCB_PIB_OCR_CLEAR, ~BIT(OCB_PIB_OCR_CORE_RESET_BIT))); break; case p9occ_ctrl::PPC405_RESET_ON: FAPI_TRY(fapi2::putScom(i_target, PU_OCB_PIB_OCR_OR, BIT(OCB_PIB_OCR_CORE_RESET_BIT))); break; case p9occ_ctrl::PPC405_HALT_OFF: FAPI_TRY(fapi2::putScom(i_target, PU_JTG_PIB_OJCFG_AND, ~BIT(OCB_PIB_OCR_OCR_DBG_HALT_BIT))); break; case p9occ_ctrl::PPC405_HALT_ON: FAPI_TRY(fapi2::putScom(i_target, PU_JTG_PIB_OJCFG_OR, BIT(OCB_PIB_OCR_OCR_DBG_HALT_BIT))); break; case p9occ_ctrl::PPC405_RESET_SEQUENCE: /// It is unsafe in general to simply reset the 405, as this is an /// asynchronous reset that can leave OCI slaves in unrecoverable /// states. /// This is a "safe" reset-entry sequence that includes /// halting the 405 (a synchronous operation) before issuing the /// reset. Since this sequence halts/unhalts the 405 and modifies /// FIRs it is called apart from the simple PPC405_RESET_OFF /// that simply sets the 405 reset bit. /// /// The sequence: /// /// 1. Mask the "405 halted" FIR bit to avoid FW thinking the halt /// we are about to inject on the 405 is an error. /// /// 2. Halt the 405. If the 405 does not halt in 1ms we note that /// but press on, hoping (probably in vain) that any subsequent /// reset actions will clear up the issue. /// To check if the 405 halted we must clear the FIR and verify /// that the FIR is set again. /// /// 3. Put the 405 into reset. /// /// 4. Clear the halt bit. /// /// 5. Restore the original FIR mask /// Save the FIR mask, and mask the halted FIR FAPI_DBG("Performing the RESET SEQUENCE"); FAPI_TRY(fapi2::getScom(i_target, PERV_TP_OCC_SCOM_OCCLFIRMASK, l_firMask)); FAPI_TRY(fapi2::putScom(i_target, PERV_TP_OCC_SCOM_OCCLFIRMASK_OR, BIT(OCCLFIR_PPC405_DBGSTOPACK_BIT))); // Halt the 405 and verify that it is halted FAPI_TRY(fapi2::putScom(i_target, PU_OCB_PIB_OCR_OR, BIT(OCB_PIB_OCR_OCR_DBG_HALT_BIT))); FAPI_TRY(fapi2::delay(NS_DELAY, SIM_CYCLE_DELAY)); FAPI_TRY(fapi2::putScom(i_target, PERV_TP_OCC_SCOM_OCCLFIR_AND, ~BIT(OCCLFIR_PPC405_DBGSTOPACK_BIT))); FAPI_TRY(fapi2::getScom(i_target, PERV_TP_OCC_SCOM_OCCLFIR, l_occfir)); if (!(l_occfir & BIT(OCCLFIR_PPC405_DBGSTOPACK_BIT))) { FAPI_ERR("OCC will not halt. Pressing on, hoping for the best."); } // Put 405 into reset, unhalt 405 and clear the halted FIR bit. FAPI_TRY(fapi2::putScom(i_target, PU_OCB_PIB_OCR_OR, BIT(OCB_PIB_OCR_CORE_RESET_BIT))); FAPI_TRY(fapi2::putScom(i_target, PU_OCB_PIB_OCR_CLEAR, BIT(OCB_PIB_OCR_OCR_DBG_HALT_BIT))); FAPI_TRY(fapi2::putScom(i_target, PERV_TP_OCC_SCOM_OCCLFIR_AND, ~BIT(OCCLFIR_PPC405_DBGSTOPACK_BIT))); // Restore the original FIR mask FAPI_TRY(fapi2::putScom(i_target, PERV_TP_OCC_SCOM_OCCLFIRMASK, l_firMask)); break; case p9occ_ctrl::PPC405_START: // Check the JTAG Halt bit is off as the the PPC405 won't actually start // if this bit is on (controlled by RiscWatch) FAPI_TRY(fapi2::getScom(i_target, PU_JTG_PIB_OJCFG, l_jtagcfg)); FAPI_ASSERT (!(l_jtagcfg.getBit<JTG_PIB_OJCFG_DBG_HALT_BIT>()), fapi2::OCC_CONTROL_NONSTART_DUE_TO_RISCWATCH() .set_JTAGCFG(l_jtagcfg) .set_TARGET(i_target), "OCC will not start as the JTAG halt from RiscWatch is currently set"); FAPI_INF("Starting the PPC405"); // Clear the halt bit FAPI_TRY(fapi2::putScom(i_target, PU_OCB_PIB_OCR_CLEAR, BIT(OCB_PIB_OCR_OCR_DBG_HALT_BIT))); // Set the reset bit FAPI_TRY(fapi2::putScom(i_target, PU_OCB_PIB_OCR_OR, BIT(OCB_PIB_OCR_CORE_RESET_BIT))); // Clear the reset bit FAPI_TRY(fapi2::putScom(i_target, PU_OCB_PIB_OCR_CLEAR, BIT(OCB_PIB_OCR_CORE_RESET_BIT))); break; default: break; } fapi_try_exit: FAPI_IMP("Exiting p9_pm_occ_control ...."); return fapi2::current_err; }