// ---------------------------------------------------------------------------- // IStepDispatcher::writeIstepControl() // ---------------------------------------------------------------------------- errlHndl_t AST2400BootConfig::writeIstepControl( istepControl_t i_istepCtl ) { errlHndl_t l_err = NULL; size_t l_len = sizeof(uint8_t); // read istep control from 0x2a TRACFCOMP( g_bc_trace, "AST2400BootConfig:: Write istep control %x", i_istepCtl.istepControl); do { //write status l_err = deviceOp( DeviceFW::WRITE, TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, &(i_istepCtl.istepStatus), l_len, DEVICE_SIO_ADDRESS(SIO::DONT_CARE, ISTEP_STATUS_REG)); if(l_err) { break; } //write command/control l_err = deviceOp( DeviceFW::WRITE, TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, &(i_istepCtl.istepControl), l_len, DEVICE_SIO_ADDRESS(SIO::DONT_CARE, ISTEP_HOST_CTL_REG)); if(l_err) { break; } } while(0); return l_err; }
// ---------------------------------------------------------------------------- // readIstepControl() // ---------------------------------------------------------------------------- errlHndl_t AST2400BootConfig::readIstepControl( istepControl_t &o_stepInfo ) { errlHndl_t l_err = NULL; size_t l_len = sizeof(uint8_t); do { // read istep control from 0x2a l_err = deviceOp( DeviceFW::READ, TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, &(o_stepInfo.istepControl), l_len, DEVICE_SIO_ADDRESS(SIO::DONT_CARE, ISTEP_CONTROL_REG)); if(l_err) { break; } // read major number from 0x2b l_err = deviceOp( DeviceFW::READ, TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, &(o_stepInfo.istepMajorNumber), l_len, DEVICE_SIO_ADDRESS(SIO::DONT_CARE, ISTEP_MAJOR_REG)); if(l_err) { break; } // read minor number from 0x2c l_err = deviceOp( DeviceFW::READ, TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, &(o_stepInfo.istepMinorNumber), l_len, DEVICE_SIO_ADDRESS(SIO::DONT_CARE, ISTEP_MINOR_REG)); } while(0); return l_err; }
errlHndl_t gpioWrite ( TARGETING::Target * i_target, void * i_buffer, size_t i_buflen, gpioAddr_t & i_gpioInfo) { errlHndl_t err = NULL; size_t cmdlen = GPIO_ADDR_SIZE + i_buflen; uint8_t cmd[cmdlen]; cmd[0] = i_gpioInfo.portAddr; memcpy(&(cmd[GPIO_ADDR_SIZE]), i_buffer, i_buflen); err = deviceOp( DeviceFW::WRITE, i_target, &cmd, cmdlen, DEVICE_I2C_ADDRESS ( i_gpioInfo.i2cPort, i_gpioInfo.engine, i_gpioInfo.i2cDeviceAddr, i_gpioInfo.i2cMuxBusSelector, &(i_gpioInfo.i2cMuxPath) ) ); if(err) { err->collectTrace( GPIO_COMP_NAME ); } return err; }
errlHndl_t gpioRead( TARGETING::Target * i_target, void * o_buffer, size_t & io_buflen, gpioAddr_t & i_gpioInfo) { errlHndl_t err = NULL; // This i2c interface writes the gpio portAddr to the device // then reads the value of the port w/o a stop bit in between ops err = deviceOp( DeviceFW::READ, i_target, o_buffer, io_buflen, DEVICE_I2C_ADDRESS_OFFSET ( i_gpioInfo.i2cPort, i_gpioInfo.engine, i_gpioInfo.i2cDeviceAddr, GPIO_ADDR_SIZE, reinterpret_cast<uint8_t*>(&(i_gpioInfo.portAddr)), i_gpioInfo.i2cMuxBusSelector, &(i_gpioInfo.i2cMuxPath) ) ); if(err) { err->collectTrace( GPIO_COMP_NAME ); } return err; }
/// /// @brief Receive - get bits off the block-transfer interface /// errlHndl_t BTMessage::recv(void) { // Check to make sure we are in the right state (coding error) assert(iv_data == NULL); // Go down to the device and read. Note the driver is BT specific // and we're BT specific so we can send down a BTMessage object. size_t unused_length; errlHndl_t err = deviceOp(DeviceFW::READ, TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, static_cast<void*>(this), unused_length, DeviceFW::IPMIBT); if (err) { delete[] iv_data; // If the reading the response fails, the caller may still call // delete[] on the pointer we return to them. This makes sure that // for this case, they're just deleting NULL. iv_data = NULL; iv_len = 0; } // For BT messages, the sequence number is the key - for other xports // it might be different. Note the sequence number is a reference to // our base's iv_key, so we're done. return err; }
errlHndl_t mboxddShutDown(TARGETING::Target* i_target) { size_t scom_len = sizeof(uint64_t); uint64_t scom_data = 0; errlHndl_t err = mboxddMaskInterrupts(i_target); if(!err) { // Clear the status reg //Turn off Permission to Send //Turn off everything possible err = deviceOp(DeviceFW::WRITE, i_target, reinterpret_cast<void*>(&scom_data), scom_len, DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1)); } // Clear any pending stuff if(!err) { err = deviceOp(DeviceFW::READ, i_target, reinterpret_cast<void*>(&scom_data), scom_len, DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_REG_PIB)); } if(!err) { err = deviceOp(DeviceFW::WRITE, i_target, reinterpret_cast<void*>(&scom_data), scom_len, DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_REG_PIB)); } // Others? return err; }
/// /// @brief Transimit - send the data out the device interface /// errlHndl_t BTMessage::phy_xmit(void) { // When a uint8_t is constructed, it's initialied to 0. So, // this initializes the sequence counter to 0. static Util::Lockfree::Counter<uint8_t> seq; // Assign a "unique" sequence number. Note that we don't // leverage the network function to create a sequence // number, we just keep an 8 bit counter. This *should* // be ok - it means we will get back the response to any // particular message before we send another 254 messages. // This seems safe. iv_seq = seq.next(); // Initialize the error state of the message iv_state = 0; size_t unused_size; errlHndl_t err = deviceOp(DeviceFW::WRITE, TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, static_cast<void*>(this), unused_size, DeviceFW::IPMIBT); // If we're not going to remain on the i_sendq, we need to delete // the data. if ((err) || (iv_state != EAGAIN)) { delete[] iv_data; iv_data = NULL; } if (!err) { // If there wasn't an error, and we don't see EAGAIN, we need to // queue up for a response. Note we queue up both synchronus and // asynchronous messages, and let the subclasses handle what // happens when the response arrives (because it will.) if (iv_state != EAGAIN) { Singleton<IpmiRP>::instance().queueForResponse(*this); } // Otherwise we had no error, but were told EAGAIN, which means the // interface was busy. else { IPMI_TRAC(INFO_MRK "busy, queue head %x:%x", iv_netfun, iv_cmd); } } return err; }
errlHndl_t mboxddEnableInterrupts(TARGETING::Target * i_target) { errlHndl_t err = NULL; size_t scom_len = sizeof(uint64_t); // Setup mailbox intr mask reg // Set bits 2,1,0 // assume we always use mailbox 1 uint64_t scom_data = (static_cast<uint64_t>(MBOX_DOORBELL_ERROR) | static_cast<uint64_t>(MBOX_HW_ACK) | static_cast<uint64_t>(MBOX_DATA_PENDING)) << 32; err = deviceOp(DeviceFW::WRITE, i_target, reinterpret_cast<void*>(&scom_data), scom_len, DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_MASK_PIB_RS)); return err; }
errlHndl_t mboxddMaskInterrupts(TARGETING::Target * i_target) { errlHndl_t err = NULL; // Mask off all interrupts // Reset intr enable bits by setting the bits in MBOX_DB_INT_MASK_PIB_RC uint64_t scom_data = (static_cast<uint64_t>(MBOX_DOORBELL_ERROR) | static_cast<uint64_t>(MBOX_HW_ACK) | static_cast<uint64_t>(MBOX_DATA_PENDING)) << 32; size_t scom_len = sizeof(uint64_t); err = deviceOp(DeviceFW::WRITE, i_target, reinterpret_cast<void*>(&scom_data), scom_len, DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_MASK_PIB_RC)); return err; }
/** * @brief Reads the mailbox PIB error status register */ errlHndl_t mboxGetErrStat(TARGETING::Target* i_target,uint64_t &o_status) { errlHndl_t l_err = NULL; uint32_t l_64bitBuf[2] = {0}; size_t l_64bitSize = sizeof(uint64_t); do { l_err = deviceOp(DeviceFW::READ,i_target, l_64bitBuf,l_64bitSize, DEVICE_XSCOM_ADDRESS(MBOX_DB_ERR_STAT_PIB)); if (l_err) { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxGetErrStat> Unable to read PIB Error Status"); break; } else { //Check for Illegal Op if ((l_64bitBuf[0] & MBOX_ILLEGAL_OP) == MBOX_ILLEGAL_OP) { o_status |= MBOX_ILLEGAL_OP; } //Check for Write Full if ((l_64bitBuf[0] & MBOX_DATA_WRITE_ERR) == MBOX_DATA_WRITE_ERR) { o_status |= MBOX_DATA_WRITE_ERR; } //Check for Read Empty if ((l_64bitBuf[0] & MBOX_DATA_READ_ERR) == MBOX_DATA_READ_ERR) { o_status |= MBOX_DATA_READ_ERR; } //Check for Parity Error & add address of parity error if ((l_64bitBuf[0] & MBOX_PARITY_ERR) == MBOX_PARITY_ERR) { o_status |= MBOX_PARITY_ERR; uint64_t l_temp = (l_64bitBuf[0] & 0x00FF0000); o_status |= (l_temp << 40); } } //Write '1' to Clear Status(16) l_64bitBuf[0] = 0x00010000; l_err = deviceOp(DeviceFW::WRITE,i_target, l_64bitBuf,l_64bitSize, DEVICE_XSCOM_ADDRESS(MBOX_DB_ERR_STAT_PIB)); if (l_err) { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxGetErrStat> Unable to clear PIB Error Status"); break; } } while(0); return l_err; }
/** * @brief Performs a mailbox write operation */ errlHndl_t mboxWrite(TARGETING::Target* i_target,void* i_buffer, size_t& i_buflen) { errlHndl_t l_err = NULL; uint32_t l_64bitBuf[2] = {0}; size_t l_64bitSize = sizeof(uint64_t); do { //If the expected siZe in bytes is bigger than the max data allowed // send back an error. if (i_buflen > MBOX_MAX_DATA_BYTES) { TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Invalid data length : i_buflen=%d", i_buflen); /*@ * @errortype * @moduleid MBOX::MOD_MBOXDD_WRITE * @reasoncode MBOX::RC_INVALID_LENGTH * @userdata1 Target ID String... * @userdata2 Data Length * @devdesc MboxDD::write> Invalid data length (> msg_t size) * @custdesc A problem occurred during the * IPL of the system. */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MBOX::MOD_MBOXDD_WRITE, MBOX::RC_INVALID_LENGTH, TARGETING::get_huid(i_target), TO_UINT64(i_buflen), true /*Add HB Software Callout*/); l_err->collectTrace(MBOX_TRACE_NAME,1024); // Set the i_buflen to 0 to indicate no write occured i_buflen = 0; break; } // read the DB_STATUS_1A_REG: doorbell status and control 1a l_err = deviceOp(DeviceFW::READ,i_target, l_64bitBuf,l_64bitSize, DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1)); if (l_err) { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxWrite> Unable to read Doorbell Status/Control Register"); break; } /* * DB_STATUS_1A_REG: doorbell status and control 1a * Bit31(MSB) : Permission to Send Doorbell 1 * Bit30 : Abort Doorbell 1 * Bit29 : LBUS Slave B Pending Doorbell 1 * Bit28 : PIB Slave A Pending Doorbell 1 * Bit27 : Reserved * Bit26 : Xdn Doorbell 1 * Bit25 : Xup Doorbell 1 * Bit24 : Reserved * Bit23-20 : Header Count PIB Slave A Doorbell 1 * Bit19-12 : Data Count PIB Slave A Doorbell 1 * Bit11-8 : Header Count LBUS Slave B Doorbell 1 * Bit7-0 : Data Count LBUS Slave B Doorbell 1 */ //Verify There is no LBUS Pending, if ((l_64bitBuf[0] & (MBOX_LBUS_SLAVE_B_PND | MBOX_HDR_PIB_SLAVE_A | MBOX_DATA_PIB_SLAVE_A)) == 0) { // Current register counter indicating which of the mbox registers // to write to uint32_t cur_reg_cntr = 0; uint32_t l_data[2] = {0}; // Total number of registers to read to get all the data. uint8_t l_numRegsToWrite = (i_buflen*sizeof(uint8_t))/sizeof(uint32_t); uint8_t l_numBytesLeft = (i_buflen*sizeof(uint8_t))%sizeof(uint32_t); if (l_numBytesLeft != 0) { l_numRegsToWrite++; } uint32_t *l_buf = static_cast<uint32_t *>(i_buffer); // For the write we put the data into the MBOX data registers. // MBOX_DATA_PIB_START = 0x00050040 and the end address is // MBOX_DATA_PIB_END = 0x0005004F // each address inbetween increments by 1. //Write Data registers. Start at the first and increment through //the registers until all the data has been written. while (cur_reg_cntr < l_numRegsToWrite) { // If this is the last register we need to write and are not word aligned if (((cur_reg_cntr + 1) == l_numRegsToWrite) && (l_numBytesLeft != 0)) { // zero out the data reg. l_data[0] = 0; // Only copy the number of bytes remaining.. memcpy(&l_data[0], l_buf+cur_reg_cntr,l_numBytesLeft); } else { // point to the next 32bits of data in the buffer. l_data[0] = *(l_buf+cur_reg_cntr); } l_err = deviceOp(DeviceFW::WRITE,i_target, l_data,l_64bitSize, DEVICE_XSCOM_ADDRESS(MBOX_DATA_PIB_START+cur_reg_cntr)); if (l_err) { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxWrite> Unable to write Data Area Register 0x%X",MBOX_DATA_PIB_START+cur_reg_cntr); break; } //increment counter so we are at the next register cur_reg_cntr++; } if (l_err) { break; } //Write LBUS Pending(28) and Data Count bits(11-0) to indicate // data has been written. l_64bitBuf[0] = MBOX_LBUS_SLAVE_B_PND | (MBOX_DATA_PIB_SLAVE_A & (i_buflen << 12)); l_err = deviceOp(DeviceFW::WRITE,i_target, l_64bitBuf,l_64bitSize, DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1)); if (l_err) { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxWrite> Unable to set Doorbell Status/Control Register"); break; } } else { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxWrite> Message still pending : MBOX_DB_STAT_CNTRL_1=%X", l_64bitBuf[0]); /*@ * @errortype * @moduleid MBOX::MOD_MBOXDD_WRITE * @reasoncode MBOX::RC_MSG_PENDING * @userdata1 Target ID String... * @userdata2 Status/Control Register * @devdesc MboxDD::write> Message still pending * @custdesc A problem occurred during the * IPL of the system. */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, MBOX::MOD_MBOXDD_WRITE, MBOX::RC_MSG_PENDING, TARGETING::get_huid(i_target), reinterpret_cast<uint64_t>(l_64bitBuf), true /*Add HB Software Callout*/); // Set the i_buflen to 0 to indicate no write occured i_buflen = 0; l_err->collectTrace(MBOX_TRACE_NAME,1024); break; } } while(0); return l_err; }
/** * @brief Performs a mailbox read operation */ errlHndl_t mboxRead(TARGETING::Target* i_target,void *o_buffer, size_t &io_buflen,uint64_t* o_status) { uint64_t l_stat = 0; errlHndl_t l_err = NULL; uint32_t l_64bitBuf[2] = {0}; uint32_t l_StatusReg[2] = {0}; uint32_t l_IntReg[2] = {0}; size_t l_64bitSize = sizeof(uint64_t); size_t input_buflen = io_buflen; io_buflen = 0; do { // no longer check for buffer length.. MBox DD will pass back the max // allowed data if the buflen is > the max size. This is done prior // to reading the data from the mbox registers. // Read the Int Reg B l_err = deviceOp(DeviceFW::READ,i_target, l_IntReg,l_64bitSize, DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_REG_PIB)); if (l_err) { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxRead> Unable to read PIB Interrupt Register"); break; } /*if nothing on in the interrupt reg -- nothing for this function to do*/ if(!(l_IntReg[0])) { break; } // Check to see if there is an error bit set. if ((l_IntReg[0] & MBOX_DOORBELL_ERROR) == MBOX_DOORBELL_ERROR) { TRACFCOMP(g_trac_mbox, INFO_MRK "mboxRead> Found interrupt on error status register"); // Go get the error info l_err = mboxGetErrStat(i_target,l_stat); if (l_err) { break; } } #if defined(__DESTRUCTIVE_MBOX_TEST__) if(g_forceError) { TRACFCOMP(g_trac_mbox,"MBOXDD> forcing error!"); g_forceError = false; l_stat |= MBOX_DOORBELL_ERROR | MBOX_DATA_WRITE_ERR; } #endif // No errors so read the doorbell status and control 1a register l_err = deviceOp(DeviceFW::READ,i_target, l_64bitBuf,l_64bitSize, DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1)); if (l_err) { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxRead> Unable to read Doorbell Status/Control Register"); break; } /* * DB_STATUS_1A_REG: doorbell status and control 1a * Bit31(MSB) : Permission to Send Doorbell 1 * Bit30 : Abort Doorbell 1 * Bit29 : LBUS Slave B Pending Doorbell 1 * Bit28 : PIB Slave A Pending Doorbell 1 * Bit27 : Reserved * Bit26 : Xdn Doorbell 1 * Bit25 : Xup Doorbell 1 * Bit24 : Reserved * Bit23-20 : Header Count PIB Slave A Doorbell 1 * Bit19-12 : Data Count PIB Slave A Doorbell 1 * Bit11-8 : Header Count LBUS Slave B Doorbell 1 * Bit7-0 : Data Count LBUS Slave B Doorbell 1 */ //If the Acknowledge bit is on and the Xup bit is on if ((l_IntReg[0] & MBOX_HW_ACK) == MBOX_HW_ACK && (l_64bitBuf[0] & MBOX_XUP) == MBOX_XUP) { l_stat |= MBOX_HW_ACK; l_StatusReg[0] |= MBOX_XUP; } //Check for PIB Pending. If PIB pending is found then we need // to go read the data from the mailbox registers. if ((l_IntReg[0] & MBOX_DATA_PENDING) == MBOX_DATA_PENDING && (l_64bitBuf[0] & MBOX_PIB_SLAVE_A_PND) == MBOX_PIB_SLAVE_A_PND) { l_stat |= MBOX_DATA_PENDING; //Set the io_buflen to the number of bytes of data available to // be read. io_buflen = (l_64bitBuf[0] & MBOX_DATA_LBUS_SLAVE_B); // If the buffer length passed in is less than the data size read, // then set the buffer length to the passed in size and only read // that much data. (truncate the data to fit into the buffer) // Conversely, if the input_buflen is greater than the size of the // data read, the io_buflen returned to the user becomes the size // of the data read. if (input_buflen < io_buflen) { TRACFCOMP(g_trac_mbox, INFO_MRK "mboxRead> Data truncated, input buffer length less than number of significant bytes"); // set the io_buflen to the size of the buffer passed in. // which will only read enough data to fill the buffer. io_buflen = input_buflen; } // Current register counter indicating which of the mbox registers // we are currently reading from. uint32_t cur_reg_cntr = 0; uint32_t l_data[2]; // Total number of registers to read to get all the data. uint8_t l_numRegsToRead = (io_buflen*sizeof(uint8_t))/sizeof(uint32_t); uint8_t l_numBytesLeft = (io_buflen*sizeof(uint8_t))%sizeof(uint32_t); if (l_numBytesLeft != 0) { l_numRegsToRead++; } uint32_t *local_buf = static_cast<uint32_t *>(o_buffer); // For the read we extract the data from the MBOX data registers. // MBOX_DATA_LBUS_START = 0x00050080 and the end address is // MBOX_DATA_LBUS_END = 0x0005008F // each address inbetween increments by 1. //Loop through the mbox registers until all the data to be read has // been extracted from the mbox registers. while (cur_reg_cntr < l_numRegsToRead) { l_err = deviceOp(DeviceFW::READ,i_target, l_data,l_64bitSize, DEVICE_XSCOM_ADDRESS(MBOX_DATA_LBUS_START+cur_reg_cntr)); if (l_err) { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxRead> Unable to read Data Area Register 0x%X",MBOX_DATA_LBUS_START+cur_reg_cntr); break; } // Need to check here to make sure we are not overrunning our // buffer. // If this is the last register we need to read and we are not word aligned if (((cur_reg_cntr + 1) == l_numRegsToRead) && (l_numBytesLeft != 0)) { // Only copy the number of bytes remaining.. memcpy( local_buf + cur_reg_cntr, &l_data[0], l_numBytesLeft); } // normal copy path.. copy the entire word. else { memcpy( local_buf + cur_reg_cntr, &l_data[0], sizeof(uint32_t)); } cur_reg_cntr++; } if (l_err) { break; } //Write-to-Clear Xup,and bits 20-32 (data and header count) //Write to set Xup (by setting PIB_SLAVE_PND) //Write the Xdn to indicate read is done l_StatusReg[0] |= MBOX_PIB_SLAVE_A_PND | MBOX_XDN | MBOX_HDR_LBUS_SLAVE_B | MBOX_DATA_LBUS_SLAVE_B; } //Write to clear PIB Pending, Abort, and XUP (all that apply) if(l_StatusReg[0]) { l_err = deviceOp(DeviceFW::WRITE,i_target, l_StatusReg,l_64bitSize, DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1)); if (l_err) { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxRead> Unable to clear Doorbell Status/Control Register"); break; } } //Write-to-Clear 'on' bits of interrupt reg if(l_IntReg[0]) { l_err = deviceOp(DeviceFW::WRITE,i_target, l_IntReg,l_64bitSize, DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_REG_PIB)); if (l_err) { TRACFCOMP(g_trac_mbox, ERR_MRK "mboxRead> Unable to clear PIB Interrupt Register"); break; } } } while(0); (*o_status) = l_stat; return l_err; }
errlHndl_t doScomOp(DeviceFW::OperationType i_opType, TARGETING::Target* i_target, void* io_buffer, size_t& io_buflen, int64_t i_accessType, uint64_t i_addr) { errlHndl_t l_err = NULL; do{ TARGETING::ScomSwitches scomSetting; scomSetting.useXscom = true; //Default to Xscom supported. if(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL != i_target) { scomSetting = i_target->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); } //Always XSCOM the Master Sentinel if((TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL == i_target) || (scomSetting.useXscom)) { //do XSCOM l_err = deviceOp(i_opType, i_target, io_buffer, io_buflen, DEVICE_XSCOM_ADDRESS(i_addr)); break; } else if(scomSetting.useInbandScom) { //do IBSCOM l_err = deviceOp(i_opType, i_target, io_buffer, io_buflen, DEVICE_IBSCOM_ADDRESS(i_addr)); if( l_err ) { break; } } else if(scomSetting.useFsiScom) { //do FSISCOM l_err = deviceOp(i_opType, i_target, io_buffer, io_buflen, DEVICE_FSISCOM_ADDRESS(i_addr)); if( l_err ) { break; } } else { assert(0,"SCOM::scomPerformOp> ATTR_SCOM_SWITCHES does not indicate Xscom, Ibscom, or FSISCOM is supported. i_target=0x%.8x", get_huid(i_target)); break; } }while(0); //Look for special retry codes if( l_err && (0xFFFFFFFF != i_accessType) && (l_err->reasonCode() == IBSCOM::IBSCOM_RETRY_DUE_TO_ERROR) ) { delete l_err; TRACFCOMP(g_trac_scom, "Forcing retry of Scom to %.16X on %.8X", i_addr, TARGETING::get_huid(i_target)); // use the unused i_accessType parameter to avoid an infinite recursion int64_t accessType_flag = 0xFFFFFFFF; l_err = doScomOp( i_opType, i_target, io_buffer, io_buflen, accessType_flag, i_addr ); } //Add some additional FFDC based on the specific operation if( l_err ) { addScomFailFFDC( l_err, i_target, i_addr ); } return l_err; }
// ---------------------------------------------------------------------------- // readAndProcessBootConfig() // ---------------------------------------------------------------------------- errlHndl_t AST2400BootConfig::readAndProcessBootConfig() { TRACDCOMP(g_bc_trace, ENTER_MRK"readAndProcessBootConfig()"); errlHndl_t l_err = NULL; uint8_t register_data = 0; size_t l_len = sizeof(uint8_t); do { // read the register holding the agreed upon magic // number to indicate registers have been configured // Registers below 0x30 do not belong to any particular SIO device. // Device field advised to be set to SUART1 or iLPC2AHB as these are the // only two devices currently in use and will thereby save additional // SIO before and after this call. l_err = deviceOp( DeviceFW::READ, TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, &(register_data), l_len, DEVICE_SIO_ADDRESS(SIO::DONT_CARE, BOOT_FLAGS_VERSION_REG)); if( l_err ) { TRACFCOMP(g_bc_trace,"Failed reading the boot flags version, skip processing"); break; } if( register_data != BOOT_FLAGS_VERSION_1 ) { TRACFCOMP(g_bc_trace,"WRN>>readAndProcessBootConfig() - " "boot flags not correct version" " 0x%x!=0x%x", register_data, BOOT_FLAGS_VERSION_1 ); #ifdef CONFIG_CONSOLE CONSOLE::displayf(NULL, "Ignoring boot flags, incorrect version 0x%x", register_data); CONSOLE::flush(); #endif break; } // read the SIO register holding the boot flags l_err = deviceOp( DeviceFW::READ, TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, &(register_data), l_len, DEVICE_SIO_ADDRESS(SIO::DONT_CARE, BOOT_FLAGS_REG)); if( l_err ) { TRACFCOMP(g_bc_trace,"Failed reading the boot flags, leave" " settings at default values"); break; } processBootFlagsV1( register_data ); }while(0); TRACDCOMP(g_bc_trace, EXIT_MRK"readAndProcessBootConfig()"); return l_err; }