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 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; }
errlHndl_t MemOps::resolve( TargetHandle_t i_proc, AttentionList & o_attentions) { errlHndl_t err = 0; uint64_t gp1ScomData = 0; do { // get the nest gp1 register content and decode // (get a list of membufs reporting attentions) err = getScom(i_proc, GP1::address, gp1ScomData); if(err) { break; } ResolveMcsArgs args; args.proc = i_proc; args.list = &o_attentions; args.ops = this; GP1::forEach(gp1ScomData, &args, &resolveMcs); } while(0); return err; }
void resolveMcs(uint64_t i_mcs, void * i_data) { ResolveMcsArgs * args = static_cast<ResolveMcsArgs *>(i_data); uint64_t mciFirScomData; TargetHandle_t mcs = getTargetService().getMcs(args->proc, i_mcs); // read the MCI fir to determine what type of attention // centaur reporting errlHndl_t err = getScom(mcs, MCI::address, mciFirScomData); if(err) { errlCommit(err, ATTN_COMP_ID); } else { // pick the highest priority attention for(uint64_t type = INVALID_ATTENTION_TYPE; type != END_ATTENTION_TYPE; ++type) { uint64_t mask; if(!MCI::getCheckbits(type, mask)) { // this object doesn't support // this attention type continue; } if(mask & mciFirScomData) { AttnData d; d.targetHndl = getTargetService().getMembuf(mcs); if(!d.targetHndl) { // this membuf not functional // or nothing is attached to this MCS break; } d.attnType = static_cast<ATTENTION_VALUE_TYPE>(type); args->list->add(Attention(d, args->ops)); break; } } } }
fapi2::ReturnCode ppe_isHalted( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const uint64_t i_base_address, bool* o_halted) { fapi2::buffer<uint64_t> l_data64; FAPI_TRY(getScom ( i_target, i_base_address + PPE_XIRAMDBG, l_data64 ), "Failed reading XIRAMDBG register!" ); *o_halted = l_data64.getBit<0>(); fapi_try_exit: return fapi2::current_err; }
errlHndl_t MemOps::resolve( TargetHandle_t i_proc, AttentionList & o_attentions) { errlHndl_t err = 0; //@TODO: RTC:150944 // Don't need this for now as this is Centaur Chip related ATTN_TRACE("MemOps::resolve - P9 Noop"); #if 0 uint64_t gp1ScomData = 0; do { // get the nest gp1 register content and decode // (get a list of membufs reporting attentions) err = getScom(i_proc, GP1::address, gp1ScomData); if(err) { break; } ResolveMcsArgs args; args.proc = i_proc; args.list = &o_attentions; args.ops = this; GP1::forEach(gp1ScomData, &args, &resolveMcs); } while(0); #endif return err; }
void Service::processIntrQMsgPreAck(const msg_t & i_msg) { // this function should do as little as possible // since the hw can't generate additional interrupts // until the msg is acknowledged TargetHandle_t proc = NULL; INTR::XISR_t xisr; xisr.u32 = i_msg.data[0]; TargetHandleList procs; getTargetService().getAllChips(procs, TYPE_PROC); TargetHandleList::iterator it = procs.begin(); // resolve the xisr to a proc target while(it != procs.end()) { uint64_t node = 0, chip = 0; getTargetService().getAttribute(ATTR_FABRIC_NODE_ID, *it, node); getTargetService().getAttribute(ATTR_FABRIC_CHIP_ID, *it, chip); if(node == xisr.node && chip == xisr.chip) { proc = *it; break; } ++it; } uint64_t hostMask = HostMask::host(); uint64_t nonHostMask = HostMask::nonHost(); uint64_t data = 0; // do the minimum that is required // for sending EOI without getting // another interrupt. for host attentions // this is clearing the gpio interrupt // type status register // and for xstp,rec,spcl this is // masking the appropriate bit in // ipoll mask // read the ipoll status register // to determine the interrupt was // caused by host attn or something // else (xstp,rec,spcl) errlHndl_t err = getScom(proc, IPOLL_STATUS_REG, data); if(err) { errlCommit(err, ATTN_COMP_ID); // assume everything is on data = hostMask | nonHostMask; } if(data & hostMask) { // if host attention, clear the ITR macro gpio interrupt // type status register. err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0); if(err) { errlCommit(err, ATTN_COMP_ID); } } if(data & nonHostMask) { // mask local proc xstp,rec and/or special attns if on. // the other thread might be trying to unmask // on the same target. The mutex ensures // neither thread corrupts the register. mutex_lock(&iv_mutex); err = modifyScom(proc, IPOLL::address, data & nonHostMask, SCOM_OR); mutex_unlock(&iv_mutex); if(err) { errlCommit(err, ATTN_COMP_ID); } } }
fapi2::ReturnCode ppe_single_step( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target, const uint64_t i_base_address, const uint16_t i_Rs, uint64_t i_step_count) { fapi2::buffer<uint64_t> l_data64; fapi2::buffer<uint64_t> l_dbcr_save; fapi2::buffer<uint32_t> l_gpr31_save; fapi2::buffer<uint64_t> l_sprg0_save; FAPI_TRY(ppe_pollHaltState(i_target, i_base_address)); // Save SPRG0 i_Rs before getting dbcr FAPI_DBG("Save SPRG0"); FAPI_TRY(getScom(i_target, i_base_address + PPE_XIRAMDBG, l_data64), "Error in GETSCOM"); l_data64.extractToRight(l_sprg0_save, 32, 32); FAPI_DBG("Saved SPRG0 value : 0x%08llX", l_sprg0_save ); FAPI_DBG("Save i_Rs"); l_data64.flush<0>().insertFromRight(ppe_getMtsprInstruction(i_Rs, SPRG0), 0, 32); FAPI_DBG("getMtsprInstruction(%d, SPRG0): 0x%16llX", R31, l_data64 ); FAPI_TRY(ppe_RAMRead(i_target, i_base_address, l_data64, l_gpr31_save)); FAPI_DBG("Saved GPR31 value : 0x%08llX", l_gpr31_save ); FAPI_INF(" Read and Save DBCR"); FAPI_DBG("Move DBCR to i_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)); FAPI_DBG("Move i_Rs to SPRG0 : so now SPRG0 has DBCR value"); l_data64.flush<0>().insertFromRight(ppe_getMtsprInstruction(i_Rs, SPRG0), 0, 32); FAPI_DBG("getMtsprInstruction(%d, SPRG0): 0x%16llX", i_Rs, l_data64 ); FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMEDR, l_data64)); FAPI_DBG("Save SPRG0 i.e. DBCR"); FAPI_TRY(getScom(i_target, i_base_address + PPE_XIRAMDBG, l_data64), "Error in GETSCOM"); l_data64.extractToRight(l_dbcr_save, 32, 32); FAPI_DBG("Saved DBCR value : 0x%08llX", l_dbcr_save ); FAPI_DBG("clear DBCR[8] IACE and DBCR[12:13] DACE"); FAPI_TRY(ppe_update_dbcr(i_target, i_base_address, ANDIS_CONST, 0x0F73, R31)); //Restore i_Rs and SPRG0 before single step FAPI_DBG("Restore i_Rs"); l_data64.flush<0>().insertFromRight(ppe_getMfsprInstruction(i_Rs, SPRG0), 0, 32); FAPI_DBG("getMfsprInstruction(R31, SPRG0): 0x%16llX", l_data64 ); l_data64.insertFromRight(l_gpr31_save, 32, 32); FAPI_DBG("Final Instr + SPRG0: 0x%16llX", l_data64 ); //write sprg0 with address and ram mfsprg0 to i_Rs FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMGA, l_data64 )); FAPI_DBG("Restore SPRG0"); FAPI_TRY(ppe_pollHaltState(i_target, i_base_address)); FAPI_TRY(putScom(i_target, i_base_address + PPE_XIRAMDBG , l_sprg0_save), "Error in PUTSCOM"); while(i_step_count != 0) { FAPI_DBG(" Send Single step command via XCR...step count = 0x%16llx", i_step_count); l_data64.flush<0>().insertFromRight(p9hcd::SINGLE_STEP, 1, 3); FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64), "Error in PUTSCOM in XCR to generate Single Step condition"); --i_step_count; //Decrement step count FAPI_TRY(ppe_pollHaltState(i_target, i_base_address)); } // Save SPRG0 i_Rs before getting dbcr FAPI_DBG("Save SPRG0"); FAPI_TRY(getScom(i_target, i_base_address + PPE_XIRAMDBG, l_data64), "Error in GETSCOM"); l_data64.extractToRight(l_sprg0_save, 32, 32); FAPI_DBG("Saved SPRG0 value : 0x%08llX", l_sprg0_save ); FAPI_DBG("Save i_Rs"); l_data64.flush<0>().insertFromRight(ppe_getMtsprInstruction(i_Rs, SPRG0), 0, 32); FAPI_DBG("getMtsprInstruction(%d, SPRG0): 0x%16llX", R31, l_data64 ); FAPI_TRY(ppe_RAMRead(i_target, i_base_address, l_data64, l_gpr31_save)); FAPI_DBG("Saved GPR31 value : 0x%08llX", l_gpr31_save ); FAPI_INF(" Restore DBCR"); FAPI_INF(" Write orig. DBCR into SPRG0"); l_data64.flush<0>().insertFromRight(ppe_getMfsprInstruction(i_Rs, SPRG0), 0, 32); FAPI_DBG("getMfsprInstruction(%d, SPRG0): 0x%16llX", i_Rs, l_data64 ); l_data64.insertFromRight(l_dbcr_save, 32, 32); FAPI_DBG("Final Instr + SPRG0: 0x%16llX", l_data64 ); //write sprg0 with address and ram mfsprg0 to i_Rs FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMGA, l_data64 )); //then mtDBCR from i_Rs 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)); //Restore i_Rs and SPRG0 after dbcr updates FAPI_DBG("Restore i_Rs"); l_data64.flush<0>().insertFromRight(ppe_getMfsprInstruction(i_Rs, SPRG0), 0, 32); FAPI_DBG("getMfsprInstruction(R31, SPRG0): 0x%16llX", l_data64 ); l_data64.insertFromRight(l_gpr31_save, 32, 32); FAPI_DBG("Final Instr + SPRG0: 0x%16llX", l_data64 ); //write sprg0 with address and ram mfsprg0 to i_Rs FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMGA, l_data64 )); FAPI_DBG("Restore SPRG0"); FAPI_TRY(ppe_pollHaltState(i_target, i_base_address)); FAPI_TRY(putScom(i_target, i_base_address + PPE_XIRAMDBG , l_sprg0_save), "Error in GETSCOM"); fapi_try_exit: return fapi2::current_err; }
fapi2::ReturnCode p9_hcd_core_stopclocks( const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target, const bool i_sync_stop_quad_clk) { FAPI_INF(">>p9_hcd_core_stopclocks"); fapi2::ReturnCode l_rc; fapi2::buffer<uint64_t> l_ccsr; fapi2::buffer<uint64_t> l_data64; fapi2::buffer<uint64_t> l_temp64; uint32_t l_loops1ms; uint8_t l_attr_chip_unit_pos; uint8_t l_attr_vdm_enabled; uint8_t l_attr_sdisn_setup; const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> l_sys; auto l_quad = i_target.getParent<fapi2::TARGET_TYPE_EQ>(); auto l_perv = i_target.getParent<fapi2::TARGET_TYPE_PERV>(); auto l_chip = i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>(); auto l_ex_vector = l_quad.getChildren<fapi2::TARGET_TYPE_EX> (fapi2::TARGET_STATE_FUNCTIONAL); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_SDISN_SETUP, l_chip, l_attr_sdisn_setup)); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDM_ENABLED, l_chip, l_attr_vdm_enabled)); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_perv, l_attr_chip_unit_pos)); l_attr_chip_unit_pos = (l_attr_chip_unit_pos - p9hcd::PERV_TO_CORE_POS_OFFSET) % 4; //Check if EQ is powered off; if so, return FAPI_TRY(fapi2::getScom(l_quad, EQ_PPM_PFSNS, l_data64), "Error reading data from EQ_PPM_PFSNS"); if (l_data64.getBit<EQ_PPM_PFSNS_VDD_PFETS_DISABLED_SENSE>()) { FAPI_DBG("Set core as stopped in STOP history register"); FAPI_TRY(putScom(i_target, C_PPM_SSHSRC, BIT64(0))); return fapi2::current_err; } //Check if core is powered off; if so, return FAPI_TRY(fapi2::getScom(i_target, C_PPM_PFSNS, l_data64), "Error reading data from C_PPM_PFSNS"); if (l_data64.getBit<C_PPM_PFSNS_VDD_PFETS_DISABLED_SENSE>()) { FAPI_DBG("Set core as stopped in STOP history register"); FAPI_TRY(putScom(i_target, C_PPM_SSHSRC, BIT64(0))); return fapi2::current_err; } // ---------------------------- // Prepare to stop core clocks // ---------------------------- FAPI_DBG("Check PM_RESET_STATE_INDICATOR via GPMMR[15]"); FAPI_TRY(getScom(i_target, C_PPM_GPMMR_SCOM, l_data64)); if (!l_data64.getBit<15>()) { FAPI_DBG("Gracefully turn off power management, continue anyways if fail"); /// @todo RTC158181 suspend_pm() } FAPI_DBG("Check core clock controller status"); l_rc = p9_common_clk_ctrl_state<fapi2::TARGET_TYPE_CORE>(i_target); if (l_rc) { FAPI_INF("Clock controller of this core chiplet is inaccessible, return"); goto fapi_try_exit; } FAPI_DBG("Check cache clock controller status"); l_rc = p9_common_clk_ctrl_state<fapi2::TARGET_TYPE_EQ>(l_quad); if (l_rc) { FAPI_INF("WARNING: core is enabled while cache is not, continue anyways"); } else { FAPI_DBG("Check PERV clock status for access to CME via CLOCK_STAT[4]"); FAPI_TRY(getScom(l_quad, EQ_CLOCK_STAT_SL, l_data64)); FAPI_DBG("Check PERV fence status for access to CME via CPLT_CTRL1[4]"); FAPI_TRY(getScom(l_quad, EQ_CPLT_CTRL1, l_temp64)); if (l_data64.getBit<4>() == 0 && l_temp64.getBit<4>() == 0) { #ifdef DD2 FAPI_DBG("Halting the PGPE ..."); l_rc = ppe_halt(l_chip, PGPE_BASE_ADDRESS); FAPI_ASSERT_NOEXIT(!l_rc, fapi2::CORE_STOPCLKS_PGPE_HALT_TIMEOUT() .set_CHIP(l_chip), "PSTATE GPE Halt timeout"); FAPI_DBG("Halting the SGPE ..."); l_rc = ppe_halt(l_chip, SGPE_BASE_ADDRESS); FAPI_ASSERT_NOEXIT(!l_rc, fapi2::CORE_STOPCLKS_SGPE_HALT_TIMEOUT() .set_CHIP(l_chip), "STOP GPE Halt timeout"); FAPI_DBG("Clear the atomic lock on EQ %d", l_attr_chip_unit_pos); l_rc = p9_clear_atomic_lock(l_quad); FAPI_ASSERT_NOEXIT(!l_rc, fapi2::CORE_STOPCLKS_ATOMIC_LOCK_FAIL() .set_EQ(l_quad), "EQ Atomic Halt timeout"); for ( auto& ex : l_ex_vector ) { fapi2::ATTR_CHIP_UNIT_POS_Type l_cme_id = 0; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, ex, l_cme_id)); FAPI_DBG("Halting CME %d", l_cme_id ); uint64_t l_cme_base_address = getCmeBaseAddress (l_cme_id); l_rc = ppe_halt(l_chip, l_cme_base_address); FAPI_ASSERT_NOEXIT(!l_rc, fapi2::CACHE_STOPCLKS_CME_HALT_TIMEOUT() .set_EX(ex), "CME Halt timeout"); } #endif //if a core is only in special wakeup and asserting pm_exit, //then setting 6,7 of SICR will cause pm_exit to drop and //the core will re-enter a power saving state FAPI_DBG("Prevent Core-L2 Quiesce from removing PM_EXIT CME_SCOM_LMCR[22]"); FAPI_TRY(putScom(l_quad, (l_attr_chip_unit_pos < 2) ? EX_0_CME_SCOM_LMCR_OR : EX_1_CME_SCOM_LMCR_OR, (BIT64(22)))); FAPI_DBG("Assert Core-L2/CC Quiesces via CME_SCOM_SICR[6,8]/[7,9]"); FAPI_TRY(putScom(l_quad, (l_attr_chip_unit_pos < 2) ? EX_0_CME_SCOM_SICR_OR : EX_1_CME_SCOM_SICR_OR, (BIT64(6 + (l_attr_chip_unit_pos % 2)) | BIT64(8 + (l_attr_chip_unit_pos % 2))))); } } FAPI_DBG("Assert pm_mux_disable to get PCB Mux from CME via SLAVE_CONFIG[7]"); FAPI_TRY(getScom(i_target, C_SLAVE_CONFIG_REG, l_data64)); FAPI_TRY(putScom(i_target, C_SLAVE_CONFIG_REG, DATA_SET(7))); FAPI_DBG("Override possible PPM write protection to CME via CPPM_CPMMR[1]"); FAPI_TRY(putScom(i_target, C_CPPM_CPMMR_OR, MASK_SET(1))); FAPI_DBG("Assert chiplet fence via NET_CTRL0[18]"); FAPI_TRY(putScom(i_target, C_NET_CTRL0_WOR, MASK_SET(18))); // ------------------------------- // Stop core clocks // ------------------------------- FAPI_DBG("Clear all SCAN_REGION_TYPE bits"); FAPI_TRY(putScom(i_target, C_SCAN_REGION_TYPE, MASK_ZERO)); if(i_sync_stop_quad_clk) { FAPI_DBG("Stop core clocks(all but pll) via CLK_REGION in SLAVE mode"); l_data64 = (p9hcd::CLK_STOP_CMD_SLAVE | p9hcd::CLK_REGION_ALL_BUT_PLL | p9hcd::CLK_THOLD_ALL); FAPI_TRY(putScom(i_target, C_CLK_REGION, l_data64)); } else { FAPI_DBG("Stop core clocks(all but pll) via CLK_REGION"); l_data64 = (p9hcd::CLK_STOP_CMD | p9hcd::CLK_REGION_ALL_BUT_PLL | p9hcd::CLK_THOLD_ALL); FAPI_TRY(putScom(i_target, C_CLK_REGION, l_data64)); FAPI_DBG("Poll for core clocks stopped via CPLT_STAT0[8]"); l_loops1ms = 1E6 / CORE_CLK_STOP_POLLING_HW_NS_DELAY; do { fapi2::delay(CORE_CLK_STOP_POLLING_HW_NS_DELAY, CORE_CLK_STOP_POLLING_SIM_CYCLE_DELAY); FAPI_TRY(getScom(i_target, C_CPLT_STAT0, l_data64)); } while((l_data64.getBit<8>() != 1) && ((--l_loops1ms) != 0)); FAPI_ASSERT((l_loops1ms != 0), fapi2::PMPROC_CORECLKSTOP_TIMEOUT().set_CORECPLTSTAT(l_data64), "Core Clock Stop Timeout"); FAPI_DBG("Check core clocks stopped via CLOCK_STAT_SL[4-13]"); FAPI_TRY(getScom(i_target, C_CLOCK_STAT_SL, l_data64)); FAPI_ASSERT((((~l_data64) & p9hcd::CLK_REGION_ALL_BUT_PLL) == 0), fapi2::PMPROC_CORECLKSTOP_FAILED().set_CORECLKSTAT(l_data64), "Core Clock Stop Failed"); FAPI_DBG("Core clocks stopped now"); } // ------------------------------- // Disable core clock sync // ------------------------------- FAPI_DBG("Drop core clock sync enable via CPPM_CACCR[15]"); FAPI_TRY(putScom(i_target, C_CPPM_CACCR_CLEAR, MASK_SET(15))); FAPI_DBG("Poll for core clock sync done to drop via CPPM_CACSR[13]"); l_loops1ms = 1E6 / CORE_CLK_SYNC_POLLING_HW_NS_DELAY; do { fapi2::delay(CORE_CLK_SYNC_POLLING_HW_NS_DELAY, CORE_CLK_SYNC_POLLING_SIM_CYCLE_DELAY); FAPI_TRY(getScom(i_target, C_CPPM_CACSR, l_data64)); } while((l_data64.getBit<13>() == 1) && ((--l_loops1ms) != 0)); FAPI_ASSERT((l_loops1ms != 0), fapi2::PMPROC_CORECLKSYNCDROP_TIMEOUT().set_COREPPMCACSR(l_data64), "Core Clock Sync Drop Timeout"); FAPI_DBG("Core clock sync done dropped"); // ------------------------------- // Fence up // ------------------------------- FAPI_DBG("Assert skew sense to skew adjust fence via NET_CTRL0[22]"); FAPI_TRY(putScom(i_target, C_NET_CTRL0_WOR, MASK_SET(22))); FAPI_DBG("Drop ABIST_SRAM_MODE_DC to support ABIST Recovery via BIST[1]"); FAPI_TRY(getScom(i_target, C_BIST, l_data64)); FAPI_TRY(putScom(i_target, C_BIST, DATA_UNSET(1))); FAPI_DBG("Assert vital fence via CPLT_CTRL1[3]"); FAPI_TRY(putScom(i_target, C_CPLT_CTRL1_OR, MASK_SET(3))); FAPI_DBG("Assert regional fences via CPLT_CTRL1[4-14]"); FAPI_TRY(putScom(i_target, C_CPLT_CTRL1_OR, p9hcd::CLK_REGION_ALL)); if (l_attr_sdisn_setup) { FAPI_DBG("DD1 Only: Drop sdis_n(flushing LCBES condition) vai CPLT_CONF0[34]"); FAPI_TRY(putScom(i_target, C_CPLT_CONF0_CLEAR, MASK_SET(34))); } // ------------------------------- // Disable VDM // ------------------------------- if (l_attr_vdm_enabled == fapi2::ENUM_ATTR_VDM_ENABLED_TRUE) { FAPI_DBG("Set VDM Disable via CPPM_VDMCR[1]"); FAPI_TRY(putScom(i_target, C_PPM_VDMCR_OR, MASK_SET(1))); FAPI_DBG("Drop VDM Poweron via CPPM_VDMCR[0]"); FAPI_TRY(putScom(i_target, C_PPM_VDMCR_CLEAR, MASK_SET(0))); } // ------------------------------- // Update stop history // ------------------------------- FAPI_DBG("Set core as stopped in STOP history register"); FAPI_TRY(putScom(i_target, C_PPM_SSHSRC, BIT64(0))); // ------------------------------- // Clean up // ------------------------------- FAPI_DBG("Return possible PPM write protection to CME via CPPM_CPMMR[1]"); FAPI_TRY(putScom(i_target, C_CPPM_CPMMR_CLEAR, MASK_SET(1))); FAPI_DBG("Drop pm_mux_disable to release PCB Mux via SLAVE_CONFIG[7]"); FAPI_TRY(getScom(i_target, C_SLAVE_CONFIG_REG, l_data64)); FAPI_TRY(putScom(i_target, C_SLAVE_CONFIG_REG, DATA_UNSET(7))); fapi_try_exit: FAPI_INF("<<p9_hcd_core_stopclocks"); return fapi2::current_err; }
/** brief handle chip attentions * * @param[in] i_proc - processor chip id at attention * XSCOM chip id based on devtree defn * @param[in] i_ipollStatus - processor chip Ipoll status * @param[in] i_ipollMask - processor chip Ipoll mask * @return 0 on success else return code */ int handleAttns(uint64_t i_proc, uint64_t i_ipollStatus, uint64_t i_ipollMask) { ATTN_SLOW(ENTER_MRK"ATTN_RT::handleAttns RtProc: %llx" ", ipollMask: %llx, ipollStatus: %llx", i_proc, i_ipollMask, i_ipollStatus); int rc = 0; errlHndl_t err = NULL; AttentionList attentions; MemOps & memOps = getMemOps(); uint64_t l_iprScomData = 0; do { // Convert chipIds to HB targets TargetHandle_t proc = NULL; err = RT_TARG::getHbTarget(i_proc, proc); if(err) { ATTN_ERR("ATTN_RT::handleAttns getHbTarget " "returned error for RtProc: %llx", i_proc); rc = EINVAL; break; } err = Singleton<Service>::instance().handleAttentions(proc); if(err) { ATTN_ERR("ATTN_RT::handleAttns service::handleAttentions " "returned error for RtProc: %llx", i_proc); break; } // For host attentions, clear gpio interrupt type register. // If we do not clear gpio register, ipoll status will again // get set and we will end up in infinite loop. uint64_t hostMask = 0; IPOLL::getCheckbits(HOST, hostMask); if( i_ipollMask & hostMask) { // After handling attn, check GP1 for more attns // as there could be additional memory units with attns. attentions.clear(); err = memOps.resolve(proc, attentions); if(err) { ATTN_ERR("RT GP1 Chk:memOps returned error.HUID:0X%08X ", get_huid( proc )); break; } // Save the IPR if any attns still active on Centaurs if (!attentions.empty()) { err = getScom(proc, INTR_TYPE_LCL_ERR_STATUS_REG, l_iprScomData); if(err) { ATTN_ERR("RT SaveIPR returned error.HUID:0X%08X ", get_huid( proc )); break; } } // end if any attentions // Clear the IPR (interrupt presentation register) err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0); if(err) { ATTN_ERR("ATTN_RT::handleAttns putscom failed for " "RtProc: %llx address:0x%08X", i_proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG); break; } // Restore the IPR if any attns still active in Centaurs if (!attentions.empty()) { err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_OR_REG, l_iprScomData); if(err) { ATTN_ERR("RT RestoreIPR returned error.HUID:0X%08X ", get_huid( proc )); break; } } // end if any attentions } // end if i_ipollMask & hostMask) } while(0); if(err) { errlCommit( err, ATTN_COMP_ID ); if(0 == rc) { rc = -1; } } attentions.clear(); ATTN_SLOW(EXIT_MRK"ATTN_RT::handleAttns rc: %d", rc); return rc; }
fapi2::ReturnCode p9_extract_sbe_rc(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip, P9_EXTRACT_SBE_RC::RETURN_ACTION& o_return_action, bool i_set_sdb, bool i_unsecure_mode) { fapi2::buffer<uint64_t> l_data64; fapi2::buffer<uint64_t> l_data64_dbgpro; fapi2::buffer<uint64_t> l_data64_fi2c_status; fapi2::buffer<uint64_t> l_data64_mib_mem_info; fapi2::buffer<uint64_t> l_data64_mib_sib_info; fapi2::buffer<uint32_t> l_data32; fapi2::buffer<uint32_t> l_data32_ir; fapi2::buffer<uint32_t> l_data32_edr; fapi2::buffer<uint32_t> l_data32_iar; bool l_ppe_halt_state = true; bool l_data_mchk = false; bool otprom_addr_range = false; bool pibmem_addr_range = false; bool seeprom_addr_range = false; bool otprom_data_range = false; bool pibmem_data_range = false; bool seeprom_data_range = false; uint32_t HC, MCS, otprom_addr, mem_error, sib_rsp_info; // FAPI_ASSERT condition constant const bool FAIL = false; // Address Range constants const uint32_t OTPROM_MIN_RANGE = 0x000C0000; const uint32_t OTPROM_MAX_RANGE = 0x000C0378; const uint32_t PIBMEM_MIN_RANGE = 0xFFFE8000; const uint32_t PIBMEM_MAX_RANGE = 0xFFFFFFFF; const uint32_t SEEPROM_MIN_RANGE = 0x80000000; const uint32_t SEEPROM_MAX_RANGE = 0x80038E18; // OTPROM Address constants as per the image on 28/Sep/2016 // These values might change on every recomilation of OTPROM binary // Refs : /afs/apd/func/project/tools/cronus/p9/exe/dev/prcd_d/images/sbe_otprom.dis const uint32_t MAGIC_NUMBER_MISMATCH_LOCATION = 0xC0188; const uint32_t OTPROM_IMAGE_END_LOCATION = 0xC016C; FAPI_INF("p9_extract_sbe_rc : Entering ..."); if(i_set_sdb) { // Applying SDB setting FAPI_DBG("p9_extract_sbe_rc: Setting chip in SDB mode"); FAPI_TRY(getCfamRegister(i_target_chip, PERV_SB_CS_FSI, l_data32)); l_data32.setBit<PERV_SB_CS_SECURE_DEBUG_MODE>(); FAPI_TRY(putCfamRegister(i_target_chip, PERV_SB_CS_FSI, l_data32)); } // XSR and IAR FAPI_DBG("p9_extract_sbe_rc : Reading PPE_XIDBGPRO"); FAPI_TRY(getScom(i_target_chip, PU_PPE_XIDBGPRO, l_data64_dbgpro)); l_data64_dbgpro.extractToRight(l_data32_iar, PU_PPE_XIDBGPRO_IAR, (PU_PPE_XIDBGPRO_IAR_LEN + 2)); //To get 32 bits of address FAPI_DBG("p9_extract_sbe_rc : PPE_XIDBGPRO : %#018lX", l_data64_dbgpro); FAPI_DBG("p9_extract_sbe_rc : SBE IAR : %#08lX", l_data32_iar); if (l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_HS>()) { FAPI_INF("p9_extract_sbe_rc : PPE is in HALT state"); l_ppe_halt_state = true; } else { FAPI_INF("p9_extract_sbe_rc : PPE is in RUNNING state, likely infinite loop, recommending restart"); l_ppe_halt_state = false; o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE; FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_RUNNING() .set_TARGET_CHIP(i_target_chip), "SBE is in running state"); } if(l_ppe_halt_state) { // ------- LEVEL 1 ------ // //Extract HC l_data32.flush<0>(); l_data64_dbgpro.extractToRight(l_data32, PU_PPE_XIDBGPRO_XSR_HC, PU_PPE_XIDBGPRO_XSR_HC_LEN); HC = l_data32; switch(HC) { case 0x0 : o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE; FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_NEVER_STARTED() .set_TARGET_CHIP(i_target_chip), "ERROR:Halt Condition is all Zero, SBE engine was probably never started"); break; case 0x1 : FAPI_ERR("p9_extract_sbe_rc : XCR[CMD] written 111 to force-halt the processor."); break; case 0x2 : FAPI_ERR("p9_extract_sbe_rc : A second watchdog timer (WDT) event occurred while TCR[WRC]=11"); break; case 0x3 : FAPI_ERR("p9_extract_sbe_rc : Unmaskable interrupt halt"); break; case 0x4 : FAPI_ERR("p9_extract_sbe_rc : Debug halt"); break; case 0x5 : FAPI_ERR("p9_extract_sbe_rc : DBCR halt"); break; case 0x6 : FAPI_ERR("p9_extract_sbe_rc : The external halt_req input was active."); break; case 0x7 : FAPI_ERR("p9_extract_sbe_rc : Hardware failure"); break; default : FAPI_ERR("p9_extract_sbe_rc : INVALID HALT CONDITION HC=0x%x", HC); break; } //Extract TRAP if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_TRAP>()) { FAPI_DBG("p9_extract_sbe_rc : TRAP Instruction Debug Event Occured"); } //Extract IAC if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_IAC>()) { FAPI_DBG("p9_extract_sbe_rc : Instruction Address Compare Debug Event Occured"); } //Extract DACR if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_DACR>()) { FAPI_DBG("p9_extract_sbe_rc : Data Address Compare (Read) Debug Event Occured"); } //Extract DACW if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_DACW>()) { FAPI_DBG("p9_extract_sbe_rc : Data Address Compare (Write) Debug Event Occured"); } //Extract WS if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_NULL_MSR_WE>()) { FAPI_DBG("p9_extract_sbe_rc : In WAIT STATE"); } //Extract EP if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_EP>()) { FAPI_DBG("p9_extract_sbe_rc : Maskable Event Pending"); } //Extract MFE if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_MFE>()) { FAPI_ERR("p9_extract_sbe_rc : Multiple Fault Error Occured"); } //Extract MCS l_data32.flush<0>(); l_data64_dbgpro.extractToRight(l_data32, PU_PPE_XIDBGPRO_XSR_MCS, PU_PPE_XIDBGPRO_XSR_MCS_LEN); MCS = l_data32; // IR and EDR FAPI_DBG("p9_extract_sbe_rc : Reading PPE_XIRAMEDR"); FAPI_TRY(getScom(i_target_chip, PU_PPE_XIRAMEDR, l_data64)); l_data64.extractToRight(l_data32_ir, PU_PPE_XIRAMEDR_XIRAMGA_IR, PU_PPE_XIRAMEDR_XIRAMGA_IR_LEN); l_data64.extractToRight(l_data32_edr, PU_PPE_XIRAMEDR_EDR, PU_PPE_XIRAMEDR_EDR_LEN); if(MCS == 0x4) { if((OTPROM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= OTPROM_MAX_RANGE)) { FAPI_DBG("p9_extract_sbe_rc : Program Interrupt occured in OTPROM memory program"); } else if((PIBMEM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= PIBMEM_MAX_RANGE)) { FAPI_DBG("p9_extract_sbe_rc : Program Interrupt occured in PIBMEM memory program"); } else if((SEEPROM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= SEEPROM_MAX_RANGE)) { FAPI_DBG("p9_extract_sbe_rc : Program Interrupt occured in SEEPROM memory program"); } else { FAPI_ERR("ERROR: IAR %08lX is out of range when MCS reported a Program Interrupt", l_data32_iar); } o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE; FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_PROGRAM_INTERRUPT() .set_TARGET_CHIP(i_target_chip), "ERROR:Program interrupt promoted for Address=%08lX", l_data32_edr); } else { FAPI_DBG("p9_extract_sbe_rc : Data/Alignment/Data Machine check interrupt for Data=%08lX", l_data32_edr); switch (MCS) { case 0x0 : FAPI_DBG("p9_extract_sbe_rc : Instruction machine check"); break; case 0x1 : FAPI_DBG("p9_extract_sbe_rc : Data machine check - load"); l_data_mchk = true; break; case 0x2 : FAPI_DBG("p9_extract_sbe_rc : Data machine check - precise store"); l_data_mchk = true; break; case 0x3 : FAPI_DBG("p9_extract_sbe_rc : Data machine check - imprecise store"); l_data_mchk = true; break; case 0x5 : FAPI_DBG("p9_extract_sbe_rc : Instruction storage interrupt, promoted"); break; case 0x6 : FAPI_DBG("p9_extract_sbe_rc : Alignment interrupt, promoted"); break; case 0x7 : FAPI_DBG("p9_extract_sbe_rc : Data storage interrupt, promoted"); break; default : FAPI_ERR("p9_extract_sbe_rc : INVALID Machine Check Status MCS=0x%x", MCS); break; } } // ------- LEVEL 2 ------ // if((OTPROM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= OTPROM_MAX_RANGE)) { FAPI_DBG("p9_extract_sbe_rc : IAR contains OTPROM address"); otprom_addr_range = true; } else if((PIBMEM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= PIBMEM_MAX_RANGE)) { FAPI_DBG("p9_extract_sbe_rc : IAR contains PIBMEM address"); pibmem_addr_range = true; } else if((SEEPROM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= SEEPROM_MAX_RANGE)) { FAPI_DBG("p9_extract_sbe_rc : IAR contains SEEPROM address"); seeprom_addr_range = true; } else { o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE; FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_ADDR_NOT_RECOGNIZED() .set_TARGET_CHIP(i_target_chip), "ERROR:Address %08lX is out of range", l_data32_iar); } // ------- LEVEL 3 ------ // if(otprom_addr_range) { if(i_unsecure_mode) { FAPI_DBG("p9_extract_sbe_rc : Reading OTPROM status register"); FAPI_TRY(getScom(i_target_chip, PU_STATUS_REGISTER, l_data64)); FAPI_DBG("p9_extract_sbe_rc : OTPROM status : %#018lX", l_data64); if(l_data64.getBit<PU_STATUS_REGISTER_ADDR_NVLD>()) { FAPI_ERR("p9_extract_sbe_rc : OTPROM::Address invalid bit set"); } if(l_data64.getBit<PU_STATUS_REGISTER_WRITE_NVLD>()) { FAPI_ERR("p9_extract_sbe_rc : OTPROM::Write invalid bit set"); } if(l_data64.getBit<PU_STATUS_REGISTER_READ_NVLD>()) { FAPI_ERR("p9_extract_sbe_rc : OTPROM::Read invalid bit set"); } if(l_data64.getBit<PU_STATUS_REGISTER_INVLD_CMD_ERR>()) { FAPI_ERR("p9_extract_sbe_rc : OTPROM::Invalid command register fields programmed bit set"); } if(l_data64.getBit<PU_STATUS_REGISTER_CORR_ERR>()) { FAPI_ERR("p9_extract_sbe_rc : OTPROM::Correctable error bit set"); } if(l_data64.getBit<PU_STATUS_REGISTER_UNCORR_ERROR>()) { FAPI_ERR("p9_extract_sbe_rc : OTPROM::Uncorrectable error bit set"); } if(l_data64.getBit<PU_STATUS_REGISTER_DCOMP_ERR>()) { FAPI_ERR("p9_extract_sbe_rc : OTPROM::Decompression Engine Error bit set"); } if(l_data64.getBit<PU_STATUS_REGISTER_INVLD_PRGM_ERR>()) { FAPI_ERR("p9_extract_sbe_rc : OTPROM::Invalid Program Operation error bit set"); } //-- FAPI Asserts section for OTPROM --// o_return_action = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION; FAPI_ASSERT(l_data64.getBit<PU_STATUS_REGISTER_UNCORR_ERROR>() != 1, fapi2::EXTRACT_SBE_RC_OTP_ECC_ERR_INSECURE_MODE() .set_TARGET_CHIP(i_target_chip), "ERROR:Uncorrectable error detected in OTPROM memory read"); } // Map the OTPROM address to the known error at that location // the OTPROM is write-once at mfg test, so addresses should remain fixed in this code otprom_addr = l_data32_iar; if(otprom_addr == MAGIC_NUMBER_MISMATCH_LOCATION) { o_return_action = P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM; FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_MAGIC_NUMBER_MISMATCH() .set_TARGET_CHIP(i_target_chip), "ERROR:SEEPROM magic number didn't match"); } else if(otprom_addr == OTPROM_IMAGE_END_LOCATION) { o_return_action = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION; FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_BRANCH_TO_SEEPROM_FAIL() .set_TARGET_CHIP(i_target_chip), "ERROR:Branch to SEEPROM didn't happen"); } else { o_return_action = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION; FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_UNEXPECTED_OTPROM_HALT() .set_TARGET_CHIP(i_target_chip), "ERROR:Halted in OTPROM at address %08lX, but not at an expected halt location", otprom_addr); } } if(pibmem_addr_range) { FAPI_DBG("p9_extract_sbe_rc : Reading PIBMEM status register"); FAPI_TRY(getScom(i_target_chip, PU_PIBMEM_STATUS_REG, l_data64)); FAPI_DBG("p9_extract_sbe_rc : PIBMEM status : %#018lX", l_data64); if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ADDR_INVALID_PIB>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address which PIB is trying to access in PIBMEM is not valid one in PIBMEM"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_WRITE_INVALID_PIB>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address for which PIB is trying to write is not writable"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_READ_INVALID_PIB>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address for which PIB is trying to read is not readable"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_UNCORRECTED_ERROR_PIB>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Uncorrectable error occurred while PIB memory read"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_CORRECTED_ERROR_PIB>()) { FAPI_INF("p9_extract_sbe_rc : PIBMEM::Corrected error in PIB mem read"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_WRITE_RST_INTERRUPT_PIB>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Reset occurred during write operation to PIBMEM from PIB side"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_READ_RST_INTERRUPT_PIB>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Reset occurred during read operation to PIBMEM from PIB side"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ADDR_INVALID_FACES>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address which is given by Fast acesss interface, to access in PIBMEM is not valid one in PIBMEM"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_WRITE_INVALID_FACES>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address which is given by Fast acesss interface, to access in PIBMEM is not valid one in PIBMEM or not writable"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_READ_INVALID_FACES>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address which is given by Fast acesss interface, to access is not readable"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_UNCORRECTED_ERROR_FACES>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Uncorrectable error occurred while fast acess interface read"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_CORRECTED_ERROR_FACES>()) { FAPI_INF("p9_extract_sbe_rc : PIBMEM::Corrected error in fast acess read operation"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_BAD_ARRAY_ADDRESS_FACES>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Wrong address accessd in indirect mode of operation from fast acess interface"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_WRITE_RST_INTERRUPT_FACES>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Reset occurred during write operation to PIBMEM from fast acess side"); } if(l_data64.getBit<PU_PIBMEM_STATUS_REG_READ_RST_INTERRUPT_FACES>()) { FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Reset occurred during read operation to PIBMEM from fast acess side"); } //-- FAPI Asserts section for PIBMEM --// o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE; FAPI_ASSERT(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_UNCORRECTED_ERROR_PIB>() != 1, fapi2::EXTRACT_SBE_RC_PIBMEM_ECC_ERR_INSECURE_MODE() .set_TARGET_CHIP(i_target_chip), "ERROR:Uncorrectable error occurred while PIB memory read"); o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE; FAPI_ASSERT(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_UNCORRECTED_ERROR_FACES>() != 1, fapi2::EXTRACT_SBE_RC_PIBMEM_ECC_ERR_INSECURE_MODE() .set_TARGET_CHIP(i_target_chip), "ERROR:Uncorrectable error occurred while fast access interface read"); } if(seeprom_addr_range) { if(i_unsecure_mode) { FAPI_DBG("p9_extract_sbe_rc : Reading FI2CM mode register"); FAPI_TRY(getScom(i_target_chip, PU_MODE_REGISTER_B, l_data64)); FAPI_DBG("p9_extract_sbe_rc : FI2CM mode : %#018lX", l_data64); l_data32.flush<0>(); l_data64.extractToRight(l_data32, 0, 16); uint32_t i2c_speed = l_data32; if(i2c_speed < 0x0003) { o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE; FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_FI2CM_BIT_RATE_ERR() .set_TARGET_CHIP(i_target_chip), "ERROR:Speed on the I2C bit rate divisor is less than min speed value (0x0003), I2C Speed read is %04lX", i2c_speed); } } if(i_unsecure_mode) { FAPI_DBG("p9_extract_sbe_rc : Reading FI2CM status register"); FAPI_TRY(getScom(i_target_chip, PU_STATUS_REGISTER_B, l_data64_fi2c_status)); FAPI_DBG("p9_extract_sbe_rc : FI2CM status : %#018lX", l_data64_fi2c_status); if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_ADDR_NVLD_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Address invalid bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_WRITE_NVLD_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Write invalid bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_READ_NVLD_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Read invalid bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_ADDR_P_ERR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Address parity error bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_PAR_ERR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Data parity error bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_LB_PARITY_ERROR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Local bus parity error bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_ECC_CORRECTED_ERROR_0>()) { FAPI_INF("p9_extract_sbe_rc : FI2CM::WARN:One bit flip was there in data and been corrected"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_ECC_UNCORRECTED_ERROR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::There are 2 bit flips in read data which cannot be corrected"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_ECC_CONFIG_ERROR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Control register is ecc_enabled for data_length not equal to 8. OR ECC is enabled for the engine where ECC block is not instantiated"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_INVALID_COMMAND_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Invalid command bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_PARITY_ERROR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Parity error bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_BACK_END_OVERRUN_ERROR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Back end overrun error bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_BACK_END_ACCESS_ERROR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Back end access error bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_ARBITRATION_LOST_ERROR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Arbitration lost error bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_NACK_RECEIVED_ERROR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::NACK receieved error bit set"); } if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_STOP_ERROR_0>()) { FAPI_ERR("p9_extract_sbe_rc : FI2CM::Stop error bit set"); } //-- FAPI Asserts section for SEEPROM --// o_return_action = P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM; FAPI_ASSERT((l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_ECC_CONFIG_ERROR_0>() != 1 || l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_INVALID_COMMAND_0>() != 1 || l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_PARITY_ERROR_0>() != 1 || l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_BACK_END_OVERRUN_ERROR_0>() != 1 || l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_BACK_END_ACCESS_ERROR_0>() != 1 || l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_ARBITRATION_LOST_ERROR_0>() != 1 || l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_NACK_RECEIVED_ERROR_0>() != 1 || l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_STOP_ERROR_0>() != 1), fapi2::EXTRACT_SBE_RC_FI2C_ERROR() .set_TARGET_CHIP(i_target_chip), "FI2C I2C Error detected"); o_return_action = P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM; FAPI_ASSERT(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_ECC_UNCORRECTED_ERROR_0>() != 1, fapi2::EXTRACT_SBE_RC_FI2C_ECC_ERR_INSECURE_MODE() .set_TARGET_CHIP(i_target_chip), "ERROR:There are 2 bit flips in read data which cannot be corrected"); } else { // TODO - Read FI2CM status register by performing ramming of local register } } // ------- LEVEL 4 ------ // if(l_data_mchk) { if((OTPROM_MIN_RANGE <= l_data32_edr) && (l_data32_edr <= OTPROM_MAX_RANGE)) { FAPI_DBG("p9_extract_sbe_rc : EDR contains OTPROM address"); otprom_data_range = true; } else if((PIBMEM_MIN_RANGE <= l_data32_edr) && (l_data32_edr <= PIBMEM_MAX_RANGE)) { FAPI_DBG("p9_extract_sbe_rc : EDR contains PIBMEM address"); pibmem_data_range = true; } else if((SEEPROM_MIN_RANGE <= l_data32_edr) && (l_data32_edr <= SEEPROM_MAX_RANGE)) { FAPI_DBG("p9_extract_sbe_rc : EDR contains SEEPROM address"); seeprom_data_range = true; } else { FAPI_DBG("p9_extract_sbe_rc : EDR contains out of scope address = %08lX", l_data32_edr); } if(otprom_data_range || seeprom_data_range) // SIB Info is valid only for Otprom & Seeprom data { //-- MIB External Interface SIB Info FAPI_DBG("p9_extract_sbe_rc : Reading MIB SIB Info register"); FAPI_TRY(getScom(i_target_chip, PU_MIB_XISIB, l_data64_mib_sib_info)); FAPI_DBG("p9_extract_sbe_rc : MIB SIB Info : %#018lX", l_data64_mib_sib_info); l_data32.flush<0>(); l_data64_mib_sib_info.extractToRight(l_data32, PU_MIB_XISIB_PIB_RSP_INFO, PU_MIB_XISIB_PIB_RSP_INFO_LEN); sib_rsp_info = l_data32; } if(otprom_data_range) { o_return_action = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION; FAPI_ASSERT((!(sib_rsp_info == 0x6)), fapi2::EXTRACT_SBE_RC_OTP_ECC_ERR(), "Parity/ECC error detected in OTPROM memory, Check if OTPROM programmed correctly by dumping content"); o_return_action = P9_EXTRACT_SBE_RC::RESTART_CBS; FAPI_ASSERT((!(sib_rsp_info == 0x7)), fapi2::EXTRACT_SBE_RC_OTP_TIMEOUT() .set_TARGET_CHIP(i_target_chip), "PIB Timeout error detected during access to OTPROM"); o_return_action = P9_EXTRACT_SBE_RC::RESTART_CBS; FAPI_ASSERT((!(sib_rsp_info != 0x0)), fapi2::EXTRACT_SBE_RC_OTP_PIB_ERR() .set_TARGET_CHIP(i_target_chip), "Scom error detected"); } if(pibmem_data_range) { //-- MIB External Interface MEM Info FAPI_DBG("p9_extract_sbe_rc : Reading MIB MEM Info register"); FAPI_TRY(getScom(i_target_chip, PU_MIB_XIMEM, l_data64_mib_mem_info)); FAPI_DBG("p9_extract_sbe_rc : MIB MEM Info : %#018lX", l_data64_mib_mem_info); l_data32.flush<0>(); l_data64_mib_mem_info.extractToRight(l_data32, PU_MIB_XIMEM_MEM_ERROR, PU_MIB_XIMEM_MEM_ERROR_LEN); mem_error = l_data32; o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE; FAPI_ASSERT((!(mem_error == 0x6)), fapi2::EXTRACT_SBE_RC_PIBMEM_ECC_ERR(), "ECC error detected during pibmem access, Run PIBMEM REPAIR test.."); o_return_action = P9_EXTRACT_SBE_RC::RESTART_CBS; FAPI_ASSERT((!(mem_error != 0x0)), fapi2::EXTRACT_SBE_RC_PIBMEM_PIB_ERR() .set_TARGET_CHIP(i_target_chip), "Error detected during pibmem access"); } if(seeprom_data_range) { o_return_action = P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM; FAPI_ASSERT((!(sib_rsp_info == 0x7)), fapi2::EXTRACT_SBE_RC_FI2C_TIMEOUT() .set_TARGET_CHIP(i_target_chip), "FI2C Timeout error detected"); o_return_action = P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM; FAPI_ASSERT((!(sib_rsp_info == 0x6)), fapi2::EXTRACT_SBE_RC_FI2C_ECC_ERR() .set_TARGET_CHIP(i_target_chip), "FI2C SEEPROM uncorrectable ECC error detected"); o_return_action = P9_EXTRACT_SBE_RC::RESTART_CBS; FAPI_ASSERT((!(sib_rsp_info == 0x4)), fapi2::EXTRACT_SBE_RC_FI2C_SPRM_CFG_ERR() .set_TARGET_CHIP(i_target_chip), "FI2C SEEPROM config error detected"); o_return_action = P9_EXTRACT_SBE_RC::RESTART_CBS; FAPI_ASSERT((!(sib_rsp_info != 0x0)), fapi2::EXTRACT_SBE_RC_FI2C_PIB_ERR() .set_TARGET_CHIP(i_target_chip), "FI2C PIB error detected"); } } //Unknown FAPI_ERR("Halted due to unknown error at IAR location %08lX", l_data32_iar); o_return_action = P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM; FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_UNKNOWN_ERROR() .set_TARGET_CHIP(i_target_chip), "SBE halted due to unknown error"); } FAPI_INF("p9_extract_sbe_rc : Exiting ..."); fapi_try_exit: return fapi2::current_err; }
void ServiceCommon::processAttnPreAck(const TargetHandle_t i_proc) { uint64_t hostMask = HostMask::host(); uint64_t nonHostMask = HostMask::nonHost(); uint64_t data = 0; // do the minimum that is required // for sending EOI without getting // another interrupt. for host attentions // this is clearing the gpio interrupt // type status register // and for xstp,rec,spcl this is // masking the appropriate bit in // ipoll mask // read the ipoll status register // to determine the interrupt was // caused by host attn or something // else (xstp,rec,spcl) errlHndl_t err = getScom(i_proc, IPOLL_STATUS_REG, data); if(err) { errlCommit(err, ATTN_COMP_ID); // assume everything is on data = hostMask | nonHostMask; } if(data & hostMask) { // if host attention, clear the ITR macro gpio interrupt // type status register. err = putScom(i_proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0); if(err) { errlCommit(err, ATTN_COMP_ID); } } if(data & nonHostMask) { // mask local proc xstp,rec and/or special attns if on. // the other thread might be trying to unmask // on the same target. The mutex ensures // neither thread corrupts the register. mutex_lock(&iv_mutex); err = modifyScom(i_proc, IPOLL::address, data & nonHostMask, SCOM_OR); mutex_unlock(&iv_mutex); if(err) { errlCommit(err, ATTN_COMP_ID); } } }