// send the sync complete message errlHndl_t AttributeSync::sendSyncCompleteMessage( ) { TARG_INF("sending sync complete message"); errlHndl_t l_err = NULL; msg_t * msg = msg_allocate(); // initialize msg buffer memset( msg, 0, sizeof(msg_t) ); msg->type = ATTR_SYNC_COMPLETE_TO_FSP; ATTR_SYNC_ADD_PAGE_COUNT( iv_total_pages, msg->data[0] ); l_err = sendMboxMessage( SYNCHRONOUS, msg ); if( l_err == NULL ) { // see if there was an error on the other end ATTR_SYNC_RC return_code = ATTR_SYNC_GET_RC( msg->data[0] ); if ( return_code ) { TARG_ERR("Attribute sync failed with return code: 0x%x", return_code ); TARG_ERR("Failed syncing iv_total_pages: 0x%x from iv_section_to_sync: 0x%x", iv_total_pages,iv_section_to_sync ); /*@ * @errortype * @moduleid TARG_MOD_ATTR_SYNC * @reasoncode TARG_RC_ATTR_SYNC_TO_FSP_FAIL * @userdata1 return code from FSP attribute sync * @userdata2[0:31] page count for this section * @userdata2[31:63] section ID of for section being sync'd * * @devdesc The attribute synchronization code on the * FSP side was unable to complete the sync * operation successfully. * * @custdesc A problem occurred during the IPL of the * system: Attributes were not fully * syncronized between the host firmware and * service processor. * */ l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, TARG_MOD_ATTR_SYNC, TARG_RC_ATTR_SYNC_TO_FSP_FAIL, return_code, TWO_UINT32_TO_UINT64( iv_total_pages,iv_section_to_sync)); } } // for a syncronous message we need to free the message msg_free( msg ); return l_err; }
// send a request to FSP to sync to Hostboot errlHndl_t AttributeSync::sendSyncToHBRequestMessage() { TARG_INF( ENTER_MRK "AttributeSync::sendSyncToHBRequestMessage" ); errlHndl_t l_err = NULL; // allocate message buffer // buffer will be initialized to zero by msg_allocate() msg_t * l_pMsg = msg_allocate(); l_pMsg->type = ATTR_SYNC_REQUEST_TO_HB; ATTR_SYNC_ADD_SECTION_ID( iv_section_to_sync, l_pMsg->data[0] ); l_err = sendMboxMessage( SYNCHRONOUS, l_pMsg ); if( l_err == NULL ) { // see if there was an error on the other end ATTR_SYNC_RC return_code = ATTR_SYNC_GET_RC( l_pMsg->data[0] ); if ( return_code ) { TARG_ERR( "rc 0x%x received from FSP for Sync to HB request", return_code ); /*@ * @errortype * @moduleid TARG_MOD_ATTR_SYNC * @reasoncode TARG_RC_ATTR_SYNC_REQUEST_TO_HB_FAIL * @userdata1 return code from FSP * @userdata2 section to sync * @devdesc The attribute synchronization code on the * FSP side was unable to fulfill the sync to * HostBoot request. */ l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, TARG_MOD_ATTR_SYNC, TARG_RC_ATTR_SYNC_REQUEST_TO_HB_FAIL, return_code, iv_section_to_sync); } } else { TARG_ERR( "Failed to send request to FSP to sync section type %u " "to Hostboot.", iv_section_to_sync ); } // for a syncronous message we need to free the message msg_free( l_pMsg ); l_pMsg = NULL; TARG_INF( EXIT_MRK "AttributeSync::sendSyncToHBRequestMessage" ); return l_err; }
Message::Message(MessageType i_type, size_t i_len, uint8_t* i_data, MessageMode i_mode): iv_msg(msg_allocate()), iv_errl(NULL), iv_len(i_len), iv_mode(i_mode), iv_data(i_data) { iv_msg->type = i_type; iv_msg->extra_data = static_cast<void*>(this); }
// send the sync complete message errlHndl_t AttributeSync::sendSyncCompleteMessage( ) { TRACFCOMP(g_trac_targeting, "sending sync complete message"); errlHndl_t l_err = NULL; msg_t * msg = msg_allocate(); // initialize msg buffer memset( msg, 0, sizeof(msg_t) ); msg->type = ATTR_SYNC_COMPLETE_TO_FSP; ATTR_SYNC_ADD_PAGE_COUNT( iv_total_pages, msg->data[0] ); l_err = sendMboxMessage( SYNCHRONOUS, msg ); if( l_err == NULL ) { // see if there was an error on the other end ATTR_SYNC_RC return_code = ATTR_SYNC_GET_RC( msg->data[0] ); if ( return_code ) { TRACFCOMP(g_trac_targeting, "return code: 0x%x", return_code ); /*@ * @errortype * @moduleid TARG_MOD_ATTR_SYNC * @reasoncode TARG_RC_ATTR_SYNC_TO_FSP_FAIL * @userdata1 return code from FSP attribute sync * @userdata2 section ID of for section being sync'd * * @devdesc The Attribute synchronization code on the * FSP side was unable to complete the sync * operation successfully. */ l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, TARG_MOD_ATTR_SYNC, TARG_RC_ATTR_SYNC_TO_FSP_FAIL, return_code, (uint64_t)iv_section_to_sync); } } // for a syncronous message we need to free the message msg_free( msg ); return l_err; }
void sendESEL(uint8_t* i_eselData, uint32_t i_dataSize, uint32_t i_eid, uint8_t i_eventDirType, uint8_t i_eventOffset, uint8_t i_sensorType, uint8_t i_sensorNumber ) { IPMI_TRAC(ENTER_MRK "sendESEL()"); #ifdef __HOSTBOOT_RUNTIME // HBRT doesn't send a msg, but use the msg structure to pass the data msg_t l_msg; msg_t *msg = &l_msg; memset(msg, 0, sizeof(msg_t)); #else msg_t *msg = msg_allocate(); #endif msg->type = MSG_SEND_ESEL; msg->data[0] = i_eid; // create the sel record of information selRecord l_sel; l_sel.record_type = record_type_system_event; l_sel.generator_id = generator_id_ami; l_sel.evm_format_version = format_ipmi_version_2_0; l_sel.sensor_type = i_sensorType; l_sel.sensor_number = i_sensorNumber; l_sel.event_dir_type = i_eventDirType; l_sel.event_data1 = i_eventOffset; eselInitData *eselData = new eselInitData(&l_sel, i_eselData, i_dataSize); msg->extra_data = eselData; #ifdef __HOSTBOOT_RUNTIME process_esel(msg); #else // one message queue to the SEL thread static msg_q_t mq = Singleton<IpmiSEL>::instance().msgQueue(); //Send the msg to the sel thread int rc = msg_send(mq,msg); if(rc) { IPMI_TRAC(ERR_MRK "Failed (rc=%d) to send message",rc); delete eselData; } #endif IPMI_TRAC(EXIT_MRK "sendESEL"); return; } // sendESEL
/////////////////////////////////////////////////////////////////////////////// // ErrlManager::sendErrLogToFSP() /////////////////////////////////////////////////////////////////////////////// void ErrlManager::sendErrLogToFSP ( errlHndl_t& io_err ) { msg_t *msg = NULL; TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendErrLogToFSP" ); do { //Create a mailbox message to send to FSP msg = msg_allocate(); msg->type = ERRLOG_SEND_TO_FSP_TYPE; uint32_t l_msgSize = io_err->flattenedSize(); //Data[0] will be hostboot error log ID so Hostboot can //keep track of the error log when FSP responses back. msg->data[0] = io_err->eid(); msg->data[1] = l_msgSize; void * temp_buff = MBOX::allocate( l_msgSize ); io_err->flatten ( temp_buff, l_msgSize ); msg->extra_data = temp_buff; TRACDCOMP( g_trac_errl, INFO_MRK"Send msg to FSP for errlogId %.8x", io_err->eid() ); errlHndl_t l_err = MBOX::send( MBOX::FSP_ERROR_MSGQ, msg ); if( !l_err ) { // clear this - we're done with the message; // the receiver will free the storage when it's done msg = NULL; } else { TRACFCOMP(g_trac_errl, ERR_MRK"Failed sending error log to FSP"); //Free the extra data due to the error MBOX::deallocate( msg->extra_data ); msg_free( msg ); msg = NULL; delete l_err; l_err = NULL; } } while (0); TRACFCOMP( g_trac_errl, EXIT_MRK"ErrlManager::sendErrLogToFSP" ); } // sendErrLogToFSP
/// /// @brief msg ctor /// @param[in] i_cmd, the network function & command /// @param[in] i_len, the length of the data /// @param[in] i_data, the data (new'd space) /// Message::Message(const command_t& i_cmd, const uint8_t i_len, uint8_t* i_data): iv_msg(msg_allocate()), iv_key(0), iv_len(i_len), iv_netfun(i_cmd.first), iv_seq(iv_key), iv_cmd(i_cmd.second), iv_cc(0), iv_state(0), iv_errl(NULL), iv_data(i_data) { iv_timeout.tv_sec = 0; iv_timeout.tv_nsec = 0; }
errlHndl_t Service::stop() { ATTN_SLOW("shutting down..."); mutex_lock(&iv_mutex); tid_t intrTask = iv_intrTask; tid_t prdTask = iv_prdTask; msg_q_t q = iv_intrTaskQ; iv_intrTask = 0; iv_prdTask = 0; mutex_unlock(&iv_mutex); if(intrTask) { errlHndl_t err = configureInterrupts(q, DOWN); if(err) { errlCommit(err, ATTN_COMP_ID); } msg_t * shutdownMsg = msg_allocate(); shutdownMsg->type = SHUTDOWN; msg_sendrecv(q, shutdownMsg); msg_free(shutdownMsg); task_wait_tid(intrTask, 0, 0); msg_q_destroy(q); } if(prdTask) { sync_cond_signal(&iv_cond); task_wait_tid(prdTask, 0, 0); } ATTN_SLOW("..shutdown complete"); return 0; }
void ErrlManager::sendResourcesMsg(errlManagerNeeds i_needs) { TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendResourcesMsg %d", i_needs); //Create a message to send to Host boot error message queue. msg_t *msg = msg_allocate(); switch (i_needs) { case PNOR: msg->type = ERRORLOG::ErrlManager::ERRLOG_ACCESS_PNOR_TYPE; break; case TARG: msg->type = ERRORLOG::ErrlManager::ERRLOG_ACCESS_TARG_TYPE; break; case MBOX: msg->type = ERRORLOG::ErrlManager::ERRLOG_ACCESS_MBOX_TYPE; break; case IPMI: msg->type = ERRORLOG::ErrlManager::ERRLOG_ACCESS_IPMI_TYPE; break; case ERRLDISP: msg->type = ERRORLOG::ErrlManager::ERRLOG_ACCESS_ERRLDISP_TYPE; break; default: { TRACFCOMP( g_trac_errl, ERR_MRK "bad msg!!"); assert(0); } } //Send the msg asynchronously to error message queue to handle. int rc = msg_send ( ERRORLOG::ErrlManager::iv_msgQ, msg ); //Return code is non-zero when the message queue is invalid //or the message type is invalid. if ( rc ) { TRACFCOMP( g_trac_errl, ERR_MRK "Failed (rc=%d) to send %d message.", rc, i_needs); } return; }
void Daemon::sendExtractBuffer(void* i_buffer, size_t i_size) { // Send buffer message. // We don't need to check for mailbox attributes or readiness // because we should only be sending this message if we were // requested to by the SP. msg_t* msg = msg_allocate(); msg->type = DaemonIf::TRACE_BUFFER; msg->data[1] = i_size; msg->extra_data = i_buffer; errlHndl_t l_errl = MBOX::send(MBOX::FSP_TRACE_MSGQ, msg); if (l_errl) { errlCommit(l_errl, TRACE_COMP_ID); MBOX::deallocate(i_buffer); msg_free(msg); } }
/////////////////////////////////////////////////////////////////////////////// // ErrlManager::sendErrlogToMessageQueue() /////////////////////////////////////////////////////////////////////////////// void ErrlManager::sendErrlogToMessageQueue ( errlHndl_t& io_err, compId_t i_committerComp ) { msg_t * msg = NULL; TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendErrlogToMessageQueue" ); do { //Create a message to send to Host boot error message queue. msg = msg_allocate(); msg->type = ERRLOG_NEEDS_TO_BE_COMMITTED_TYPE; //Pass along the component id in the message msg->data[0] = i_committerComp; //Pass along the error log handle in the message msg->data[1] = 8; msg->extra_data = io_err; TRACFCOMP( g_trac_errl, INFO_MRK"Send an error log to message queue" " to commit. eid=%.8X", io_err->eid() ); //Send the error log to error message queue to handle. //Message is sent as asynchronous. int rc = msg_send ( iv_msgQ, msg ); //Return code is non-zero when the message queue is invalid //or the message type is invalid. if ( rc ) { TRACFCOMP( g_trac_errl, ERR_MRK "Failed to send mailbox message" "to message queue. eid=%.8X", io_err->eid() ); break; } } while (0); TRACFCOMP( g_trac_errl, EXIT_MRK"ErrlManager::sendErrlogToMessageQueue" ); return; } // sendErrlogToMessageQueue
void ErrlManager::sendAckErrorlog(uint32_t i_eid) { TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendAddErrorlog 0x%.8X", i_eid); //Create a message to send to Host boot error message queue. msg_t *msg = msg_allocate(); msg->type = ERRLOG_COMMITTED_ACK_RESPONSE_TYPE; //Pass along the eid of the error, shifted up to the first word msg->data[0] = static_cast<uint64_t>(i_eid) << 32; //Send the msg asynchronously to error message queue to handle. int rc = msg_send ( ERRORLOG::ErrlManager::iv_msgQ, msg ); //Return code is non-zero when the message queue is invalid //or the message type is invalid. if ( rc ) { TRACFCOMP( g_trac_errl, ERR_MRK "Failed (rc=%d) to send ack 0x%.8X message.", rc, i_eid); } return; }
// ------------------------------------------------------------------ // sendMboxWriteMsg // ------------------------------------------------------------------ errlHndl_t sendMboxWriteMsg ( size_t i_numBytes, void * i_data, TARGETING::Target * i_target, VPD_MSG_TYPE i_type, VpdWriteMsg_t& i_record ) { errlHndl_t l_err = NULL; msg_t* msg = NULL; TRACSSCOMP( g_trac_vpd, ENTER_MRK"sendMboxWriteMsg()" ); do { //Create a mailbox message to send to FSP msg = msg_allocate(); msg->type = i_type; msg->data[0] = i_record.data0; msg->data[1] = i_numBytes; //Copy the data into the message msg->extra_data = malloc( i_numBytes ); memcpy( msg->extra_data, i_data, i_numBytes ); TRACFCOMP( g_trac_vpd, INFO_MRK"sendMboxWriteMsg: Send msg to FSP to write VPD type %.8X, record %d, offset 0x%X", i_type, i_record.rec_num, i_record.offset ); //We only send VPD update when we have SP Base Services if( !INITSERVICE::spBaseServicesEnabled() ) { TRACFCOMP(g_trac_vpd, INFO_MRK "No SP Base Services, skipping VPD write"); TRACFBIN( g_trac_vpd, "msg=", msg, sizeof(msg_t) ); TRACFBIN( g_trac_vpd, "extra=", msg->extra_data, i_numBytes ); free (msg->extra_data); msg_free( msg ); break; } l_err = MBOX::send( MBOX::FSP_VPD_MSGQ, msg ); if( l_err ) { TRACFCOMP(g_trac_vpd, ERR_MRK "Failed sending VPD to FSP for %.8X", TARGETING::get_huid(i_target)); ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog(l_err); l_err->collectTrace("VPD",1024); if( VPD_WRITE_DIMM == i_type ) { l_err->collectTrace("SPD",1024); } // just commit the log and move on, nothing else to do errlCommit( l_err, VPD_COMP_ID ); l_err = NULL; free( msg->extra_data ); msg->extra_data = NULL; msg_free( msg ); } } while( 0 ); TRACSSCOMP( g_trac_vpd, EXIT_MRK"sendMboxWriteMsg()" ); return l_err; }
enum fsm_event e2e_event(struct port *p, int fd_index) { int cnt, fd = p->fda.fd[fd_index]; enum fsm_event event = EV_NONE; struct ptp_message *msg, *dup; switch (fd_index) { case FD_ANNOUNCE_TIMER: case FD_SYNC_RX_TIMER: pr_debug("port %hu: %s timeout", portnum(p), fd_index == FD_SYNC_RX_TIMER ? "rx sync" : "announce"); if (p->best) { fc_clear(p->best); } port_set_announce_tmo(p); return EV_ANNOUNCE_RECEIPT_TIMEOUT_EXPIRES; case FD_DELAY_TIMER: pr_debug("port %hu: delay timeout", portnum(p)); port_set_delay_tmo(p); delay_req_prune(p); tc_prune(p); if (!clock_free_running(p->clock)) { switch (p->state) { case PS_UNCALIBRATED: case PS_SLAVE: if (port_delay_request(p)) { event = EV_FAULT_DETECTED; } break; default: break; }; } return event; case FD_QUALIFICATION_TIMER: pr_debug("port %hu: qualification timeout", portnum(p)); return EV_QUALIFICATION_TIMEOUT_EXPIRES; case FD_MANNO_TIMER: case FD_SYNC_TX_TIMER: case FD_UNICAST_REQ_TIMER: case FD_UNICAST_SRV_TIMER: pr_err("unexpected timer expiration"); return EV_NONE; case FD_RTNL: pr_debug("port %hu: received link status notification", portnum(p)); rtnl_link_status(fd, p->name, port_link_status, p); if (p->link_status == (LINK_UP|LINK_STATE_CHANGED)) { return EV_FAULT_CLEARED; } else if ((p->link_status == (LINK_DOWN|LINK_STATE_CHANGED)) || (p->link_status & TS_LABEL_CHANGED)) { return EV_FAULT_DETECTED; } else { return EV_NONE; } } msg = msg_allocate(); if (!msg) { return EV_FAULT_DETECTED; } msg->hwts.type = p->timestamping; cnt = transport_recv(p->trp, fd, msg); if (cnt <= 0) { pr_err("port %hu: recv message failed", portnum(p)); msg_put(msg); return EV_FAULT_DETECTED; } if (msg_sots_valid(msg)) { ts_add(&msg->hwts.ts, -p->rx_timestamp_offset); } if (msg_unicast(msg)) { pl_warning(600, "cannot handle unicast messages!"); msg_put(msg); return EV_NONE; } dup = msg_duplicate(msg, cnt); if (!dup) { msg_put(msg); return EV_NONE; } if (tc_ignore(p, dup)) { msg_put(dup); dup = NULL; } switch (msg_type(msg)) { case SYNC: if (tc_fwd_sync(p, msg)) { event = EV_FAULT_DETECTED; break; } if (dup) { process_sync(p, dup); } break; case DELAY_REQ: if (tc_fwd_request(p, msg)) { event = EV_FAULT_DETECTED; } break; case PDELAY_REQ: break; case PDELAY_RESP: break; case FOLLOW_UP: if (tc_fwd_folup(p, msg)) { event = EV_FAULT_DETECTED; break; } if (dup) { process_follow_up(p, dup); } break; case DELAY_RESP: if (tc_fwd_response(p, msg)) { event = EV_FAULT_DETECTED; } if (dup) { process_delay_resp(p, dup); } break; case PDELAY_RESP_FOLLOW_UP: break; case ANNOUNCE: if (tc_forward(p, msg)) { event = EV_FAULT_DETECTED; break; } if (dup && process_announce(p, dup)) { event = EV_STATE_DECISION_EVENT; } break; case SIGNALING: case MANAGEMENT: if (tc_forward(p, msg)) { event = EV_FAULT_DETECTED; } break; } msg_put(msg); if (dup) { msg_put(dup); } return event; }
void Daemon::sendContBuffer(void* i_buffer, size_t i_size) { // Write debug structure with buffer information. g_debugSettings.bufferSize = i_size; g_debugSettings.bufferPage = i_buffer; // Signal for simics. asm volatile("mr 4, %0; mr 5, %1" :: "r" (i_buffer), "r" (i_size) : "4", "5"); MAGIC_INSTRUCTION(MAGIC_CONTINUOUS_TRACE); TARGETING::Target* sys = NULL; TARGETING::targetService().getTopLevelTarget(sys); TARGETING::HbSettings hbSettings = sys->getAttr<TARGETING::ATTR_HB_SETTINGS>(); // Determine if continuous trace is currently enabled. bool contEnabled = hbSettings.traceContinuous; if (g_debugSettings.contTraceOverride != DebugSettings::CONT_TRACE_USE_ATTR) { contEnabled = (g_debugSettings.contTraceOverride >= DebugSettings::CONT_TRACE_FORCE_ENABLE); } if(contEnabled) { //Only send via debugComm if tool has explicitly enabled //otherwise this will "hang" hostboot while it waits for the tool if(g_debugSettings.contTraceOverride == DebugSettings::CONT_TRACE_FORCE_ENABLE_DEBUG_COMM) { // Write scratch register indicating is available. uint64_t l_addr = reinterpret_cast<uint64_t>(i_buffer); Util::writeDebugCommRegs(Util::MSG_TYPE_TRACE, l_addr, i_size); } //Always attempt to send to FSP if enabled if (MBOX::mailbox_enabled()) { msg_t* msg = msg_allocate(); msg->type = DaemonIf::TRACE_CONT_TRACE_BUFFER; msg->data[1] = i_size; msg->extra_data = MBOX::allocate(i_size); memcpy(msg->extra_data,i_buffer,i_size); errlHndl_t l_errl = MBOX::send(MBOX::FSP_TRACE_MSGQ, msg); if (l_errl) { errlCommit(l_errl, TRACE_COMP_ID); msg_free(msg); } } } //Always free the buf free(i_buffer); }
errlHndl_t AttributeSync::syncSectionToFsp( TARGETING::SECTION_TYPE i_section_to_sync ) { errlHndl_t l_errl = NULL; msg_t * msg = NULL; iv_section_to_sync = i_section_to_sync; do{ // set up the pointers to the data area getSectionData(); for( iv_current_page = 0; iv_current_page < iv_total_pages; iv_current_page++ ) { msg = msg_allocate(); msg->type = ATTR_SYNC_SECTION_TO_FSP; msg->data[0] = 0; ATTR_SYNC_ADD_SECTION_ID( iv_section_to_sync, msg->data[0] ); ATTR_SYNC_ADD_PAGE_NUMBER( iv_current_page, msg->data[0] ); // set the 2nd data word to the buffer size msg->data[1] = PAGESIZE; // allocated storage will always be 4k msg->extra_data = MBOX::allocate( PAGESIZE ); // copy the attributes from mem to our buffer. memcpy( msg->extra_data, iv_pages[iv_current_page].dataPtr, PAGESIZE ); TARG_INF("syncSectionToFsp() - copy %d bytes from %p to %p", PAGESIZE, iv_pages[iv_current_page].dataPtr, msg->extra_data); // mailbox code will free both the msg and the extra data // we allocated above for an async message. l_errl = sendMboxMessage( ASYNCHRONOUS, msg ); if( l_errl ) { TARG_ERR("failed sending sync message"); break; } } if(( l_errl == NULL ) && ( iv_total_pages != 0 )) { // tell fsp to commit the last section of data we sent l_errl = sendSyncCompleteMessage(); if( l_errl ) { TARG_ERR("failed sending sync complete message"); } } }while(0); return l_errl; }
void Daemon::sendContBuffer(void* i_buffer, size_t i_size) { // Write debug structure with buffer information. g_debugSettings.bufferSize = i_size; g_debugSettings.bufferPage = i_buffer; // Write scratch register indicating continuous trace is available. writeScratchReg(1ull << 32); // Signal for simics. asm volatile("mr 4, %0; mr 5, %1" :: "r" (i_buffer), "r" (i_size) : "4", "5"); MAGIC_INSTRUCTION(MAGIC_CONTINUOUS_TRACE); TARGETING::Target* sys = NULL; TARGETING::targetService().getTopLevelTarget(sys); TARGETING::HbSettings hbSettings = sys->getAttr<TARGETING::ATTR_HB_SETTINGS>(); // Determine if continuous trace is currently enabled. bool contEnabled = hbSettings.traceContinuous; if (g_debugSettings.contTraceOverride != DebugSettings::CONT_TRACE_USE_ATTR) { contEnabled = (g_debugSettings.contTraceOverride == DebugSettings::CONT_TRACE_FORCE_ENABLE); } if (!contEnabled) { // Trace isn't enabled so just discard the buffer. free(i_buffer); } else { if (MBOX::mailbox_enabled()) { msg_t* msg = msg_allocate(); msg->type = DaemonIf::TRACE_CONT_TRACE_BUFFER; msg->data[1] = i_size; msg->extra_data = MBOX::allocate(i_size); memcpy(msg->extra_data,i_buffer,i_size); free(i_buffer); errlHndl_t l_errl = MBOX::send(MBOX::FSP_TRACE_MSGQ, msg); if (l_errl) { errlCommit(l_errl, TRACE_COMP_ID); msg_free(msg); } } else { // Wait for tools to extract the buffer. while(0 != readScratchReg()) { task_yield(); } free(i_buffer); } } }