// ------------------------------------------------------------------ // i2cEnableSensorCache // ------------------------------------------------------------------ errlHndl_t i2cEnableSensorCache ( TARGETING::Target * i_target ) { errlHndl_t err = NULL; TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cEnableSensorCache()" ); // There must be a 2ms window where the cache is disabled to avoid // some thrashing in the Centaur logic. TRACDCOMP( g_trac_i2c, "Delaying 2ms before enable" ); nanosleep(0,2 * NS_PER_MSEC); uint64_t scacData = SCAC_ENABLE_MSK; size_t dataSize = sizeof(scacData); // Write the scac set reg to enable the sensor cache err = DeviceFW::deviceOp( DeviceFW::WRITE, i_target, &scacData, dataSize, DEVICE_SCOM_ADDRESS(SCAC_CONFIG_SET) ); TRACDCOMP( g_trac_i2c, EXIT_MRK"i2cEnableSensorCache()" ); return err; } // end i2cEnableSensorCache
void Settings::_init() { errlHndl_t l_errl = NULL; size_t size = sizeof(iv_regValue); // Read / cache security switch setting from processor. l_errl = deviceRead(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, &iv_regValue, size, DEVICE_SCOM_ADDRESS(SECURITY_SWITCH_REGISTER)); // If this errors, we're in bad shape and shouldn't trust anything. assert(NULL == l_errl); }
void Daemon::writeScratchReg(uint64_t i_value) { size_t l_size = sizeof(uint64_t); errlHndl_t l_errl = deviceWrite(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, &i_value, l_size, DEVICE_SCOM_ADDRESS(MB_SCRATCH_REGISTER_1)); if (l_errl) { errlCommit(l_errl, TRACE_COMP_ID); } }
//****************************************************************************** //todGetScom() //****************************************************************************** errlHndl_t todGetScom(const TARGETING::Target * i_target, const uint64_t i_address, fapi2::variable_buffer & o_data) { errlHndl_t l_err = NULL; // Perform SCOM read uint64_t l_data = 0; size_t l_size = sizeof(uint64_t); l_err = deviceRead((TARGETING::Target *)i_target, &l_data, l_size, DEVICE_SCOM_ADDRESS(i_address)); return l_err; }
uint64_t Daemon::readScratchReg() { size_t l_size = sizeof(uint64_t); uint64_t value = 0; errlHndl_t l_errl = deviceRead(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, &value, l_size, DEVICE_SCOM_ADDRESS(MB_SCRATCH_REGISTER_1)); if (l_errl) { errlCommit(l_errl, TRACE_COMP_ID); } return value; }
/// @brief Platform-level implementation called by getScom() ReturnCode platGetScom(const Target<TARGET_TYPE_ALL>& i_target, const uint64_t i_address, buffer<uint64_t>& o_data) { ReturnCode l_rc; errlHndl_t l_err = NULL; FAPI_DBG(ENTER_MRK "platGetScom"); // Note: Trace is placed here in plat code because PPE doesn't support // trace in common fapi2_hw_access.H bool l_traceit = platIsScanTraceEnabled(); // Extract the component pointer TARGETING::Target* l_target = reinterpret_cast<TARGETING::Target*>(i_target.get()); // Grab the name of the target TARGETING::ATTR_FAPI_NAME_type l_targName = {0}; fapi2::toString(i_target, l_targName, sizeof(l_targName)); // Perform SCOM read size_t l_size = sizeof(uint64_t); l_err = deviceRead(l_target, &o_data(), l_size, DEVICE_SCOM_ADDRESS(i_address, opMode)); //If an error occured durring the device read and a pib_err_mask is set, // then we will check if the err matches the mask, if it does we // ignore the error if(l_err && (pib_err_mask != 0x00)) { checkPibMask(l_err); } if (l_err) { if(opMode & fapi2::IGNORE_HW_ERROR) { delete l_err; l_err = nullptr; } else { FAPI_ERR("platGetScom: deviceRead returns error!"); FAPI_ERR("fapiGetScom failed - Target %s, Addr %.16llX", l_targName, i_address); l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); } } if (l_traceit) { uint64_t l_data = (uint64_t)o_data; FAPI_SCAN("TRACE : GETSCOM : %s : %.16llX %.16llX", l_targName, i_address, l_data); } FAPI_DBG(EXIT_MRK "platGetScom"); return l_rc; }
/// @brief Platform-level implementation called by putScomUnderMask() ReturnCode platPutScomUnderMask(const Target<TARGET_TYPE_ALL>& i_target, const uint64_t i_address, const buffer<uint64_t> i_data, const buffer<uint64_t> i_mask) { ReturnCode l_rc; errlHndl_t l_err = NULL; FAPI_DBG(ENTER_MRK "platPutScomUnderMask"); // Note: Trace is placed here in plat code because PPE doesn't support // trace in common fapi2_hw_access.H bool l_traceit = platIsScanTraceEnabled(); // Grab the name of the target TARGETING::ATTR_FAPI_NAME_type l_targName = {0}; fapi2::toString(i_target, l_targName, sizeof(l_targName)); do { // Extract the component pointer TARGETING::Target* l_target = reinterpret_cast<TARGETING::Target*>(i_target.get()); // Get current value from HW uint64_t l_data = 0; size_t l_size = sizeof(uint64_t); l_err = deviceRead(l_target, &l_data, l_size, DEVICE_SCOM_ADDRESS(i_address,opMode)); if (l_err && !(opMode & fapi2::IGNORE_HW_ERROR)) { FAPI_ERR("platPutScomUnderMask: deviceRead returns error!"); l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); break; } else if(l_err) { delete l_err; l_err = nullptr; break; } // Calculate new value to write to reg uint64_t l_inMaskInverted = ~i_mask; // Write mask inverted uint64_t l_newMask = (i_data & i_mask); // Retain set data bits // l_data = current data set bits l_data &= l_inMaskInverted; // l_data = current data set bit + set mask bits l_data |= l_newMask; // Write new value l_err = deviceWrite(l_target, &l_data, l_size, DEVICE_SCOM_ADDRESS(i_address,opMode)); if (l_err && !(opMode & fapi2::IGNORE_HW_ERROR)) { FAPI_ERR("platPutScomUnderMask: deviceWrite returns error!"); l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err)); break; } else if (l_err) { delete l_err; l_err = nullptr; break; } } while (0); if(l_err && (pib_err_mask != 0x00)) { checkPibMask(l_err); } if (l_rc != fapi2::FAPI2_RC_SUCCESS) { FAPI_ERR("platPutScomUnderMask failed - Target %s, Addr %.16llX", l_targName, i_address); } if( l_traceit ) { uint64_t l_data = i_data; uint64_t l_mask = i_mask; FAPI_SCAN( "TRACE : PUTSCOMMASK : %s : %.16llX %.16llX %.16llX", l_targName, i_address, l_data, l_mask); } FAPI_DBG(EXIT_MRK "platPutScomUnderMask"); return l_rc; }
/* * @brief Initialize any attributes that need to be set early on */ static void initializeAttributes(TargetService& i_targetService) { #define TARG_FN "initializeAttributes()...)" TARG_ENTER(); bool l_isMpipl = false; Target* l_pTopLevel = NULL; i_targetService.getTopLevelTarget(l_pTopLevel); if(l_pTopLevel) { Target* l_pMasterProcChip = NULL; i_targetService.masterProcChipTargetHandle(l_pMasterProcChip); if(l_pMasterProcChip) { // Master uses xscom by default, needs to be set before // doing any other scom accesses ScomSwitches l_switches = l_pMasterProcChip->getAttr<ATTR_SCOM_SWITCHES>(); l_switches.useXscom = 1; l_switches.useFsiScom = 0; l_pMasterProcChip->setAttr<ATTR_SCOM_SWITCHES>(l_switches); errlHndl_t l_errl = NULL; size_t l_size = sizeof(uint64_t); uint64_t l_data; // Scratch register 2 is defined as 0x00050039.. accessing // directly to avoid confusion as the Literals set have // 0x00050039 mapped to MBOX_SCRATCH1 which is confusing. l_errl = DeviceFW::deviceRead(l_pMasterProcChip, &(l_data), l_size, DEVICE_SCOM_ADDRESS(0x00050039)); if(l_errl) { TARG_INF("Read of scratch register failed"); errlCommit(l_errl,TARG_COMP_ID); } else { // bit 0 on indicates MPIPL if(l_data & 0x8000000000000000ull) { l_isMpipl = true; } } } if(l_isMpipl) { l_pTopLevel->setAttr<ATTR_IS_MPIPL_HB>(1); } else { l_pTopLevel->setAttr<ATTR_IS_MPIPL_HB>(0); } } else // top level is NULL - never expected { TARG_INF("Top level target is NULL"); } TARG_EXIT(); #undef TARG_FN }
void addScomFailFFDC( errlHndl_t i_err, TARGETING::Target* i_target, uint64_t i_addr ) { // Read some error regs from scom ERRORLOG::ErrlUserDetailsLogRegister l_scom_data(i_target); bool addit = false; TARGETING::TYPE l_type = TARGETING::TYPE_NA; if( i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL ) { l_type = TARGETING::TYPE_PROC; } else { l_type = i_target->getAttr<TARGETING::ATTR_TYPE>(); } //PBA scoms on the processor if( ((i_addr & 0xFFFFF000) == 0x00064000) && (TARGETING::TYPE_PROC == l_type) ) { addit = true; //look for hung operations on the PBA uint64_t ffdc_regs[] = { //grab the PBA buffers in case something is hung 0x02010850, //PBARBUFVAL0 0x02010851, //PBARBUFVAL1 0x02010852, //PBARBUFVAL2 0x02010858, //PBAWBUFVAL0 0x02010859, //PBAWBUFVAL1 0x020F0012, //PB_GP3 (has fence information) }; for( size_t x = 0; x < (sizeof(ffdc_regs)/sizeof(ffdc_regs[0])); x++ ) { l_scom_data.addData(DEVICE_SCOM_ADDRESS(ffdc_regs[x])); } } //EX scoms on the processor (not including PCB slave regs) else if( ((i_addr & 0xF0000000) == 0x10000000) && ((i_addr & 0x00FF0000) != 0x000F0000) && (TARGETING::TYPE_PROC == l_type) ) { addit = true; uint64_t ex_offset = 0xFF000000 & i_addr; //grab some data related to the PCB slave state uint64_t ffdc_regs[] = { 0x0F010B, //Special Wakeup 0x0F0012, //GP3 0x0F0100, //PowerManagement GP0 0x0F0106, //PFET Status Core 0x0F010E, //PFET Status ECO 0x0F0111, //PM State History }; for( size_t x = 0; x < (sizeof(ffdc_regs)/sizeof(ffdc_regs[0])); x++ ) { l_scom_data.addData(DEVICE_SCOM_ADDRESS(ex_offset|ffdc_regs[x])); } } //Any non-PCB Slave and non TP reg on the processor if( ((i_addr & 0x00FF0000) != 0x000F0000) && ((i_addr & 0xFF000000) != 0x00000000) && (TARGETING::TYPE_PROC == l_type) ) { addit = true; uint64_t chiplet_offset = 0xFF000000 & i_addr; //grab some data related to the PCB slave state uint64_t ffdc_regs[] = { 0x0F0012, //GP3 0x0F001F, //Error capture reg }; for( size_t x = 0; x < (sizeof(ffdc_regs)/sizeof(ffdc_regs[0])); x++ ) { l_scom_data.addData( DEVICE_SCOM_ADDRESS( chiplet_offset|ffdc_regs[x]) ); } //grab the clock/osc regs l_scom_data.addData(DEVICE_SCOM_ADDRESS(0x00050019)); l_scom_data.addData(DEVICE_SCOM_ADDRESS(0x0005001A)); //grab the clock regs via FSI too, just in case TARGETING::Target* mproc = NULL; TARGETING::targetService().masterProcChipTargetHandle(mproc); if( (i_target != TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) && (i_target != mproc) ) { l_scom_data.addData(DEVICE_FSI_ADDRESS(0x2864));//==2819 l_scom_data.addData(DEVICE_FSI_ADDRESS(0x2868));//==281A } } if( addit ) { l_scom_data.addToLog(i_err); } }
// ------------------------------------------------------------------ // i2cDisableSensorCache // ------------------------------------------------------------------ errlHndl_t i2cDisableSensorCache ( TARGETING::Target * i_target, bool & o_disabled ) { errlHndl_t err = NULL; o_disabled = false; TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cDisableSensorCache()" ); do { // There must be a 30ms window between the last time the cache // was enabled and the next time it is disabled. Since we // have no way to easily track the last enablement, we will // just take the hit inside every disable call. TRACDCOMP( g_trac_i2c, "Delaying 30ms before disable" ); nanosleep(0,30 * NS_PER_MSEC); uint64_t scacData = 0x0; size_t dataSize = sizeof(scacData); // Read the scac config reg to get the enabled/disabled bit err = DeviceFW::deviceOp( DeviceFW::READ, i_target, &scacData, dataSize, DEVICE_SCOM_ADDRESS(SCAC_CONFIG_REG) ); if ( err ) { break; } // Disable SCAC if it's enabled if( scacData & SCAC_ENABLE_MSK ) { o_disabled = true; // Enable SCAC again after op completes scacData = SCAC_ENABLE_MSK; // Write the scac clear reg to disable the sensor cache err = DeviceFW::deviceOp( DeviceFW::WRITE, i_target, &scacData, dataSize, DEVICE_SCOM_ADDRESS(SCAC_CONFIG_CLR) ); if ( err ) { break; } // Wait 30 msec for outstanding sensor cache // operations to complete nanosleep(0,30 * NS_PER_MSEC); } } while( 0 ); TRACDCOMP( g_trac_i2c, EXIT_MRK"i2cDisableSensorCache()" ); return err; } // end i2cDisableSensorCache