void PacketPB::build(string& strPb, unsigned int length) { Head h; h.xcode[0] = 0xA1; h.xcode[1] = 0xB2; h.xcode[2] = 0xC3; //长度必须要在计算 CRC 前面赋值,否则影响收到包以后的 CRC 校验 //长度 = Body + CRC h.len = length + sizeof(crc); //总长 = Head + Body + CRC len = sizeof(Head) + h.len; memset(data, 0, sizeof(data)); memcpy(data, (char*)&h, sizeof(Head)); ptrHead = (HeadPtr)data; memcpy(data + sizeof(Head), strPb.c_str(), length); //计算 CRC 时,计算的是 Head + Body 的 CRC crc = protocol::createCRC(data, len - sizeof(crc)); memcpy(data + sizeof(Head) + length, (char*)&crc, sizeof(crc)); printDetail(); }
int PacketPB::parseBody(string& strPb) { // LOG_DEBUG("PB parseBody : " << common::printByHex(&data[sizeof(Head)], ptrHead->len)); len += ptrHead->len; strPb.assign(&data[sizeof(Head)], ptrHead->len - sizeof(crc)); memcpy(&crc, &data[len - sizeof(crc)], sizeof(crc)); if(crc != protocol::createCRC(data, len - sizeof(crc))) { LOG_DEBUG("PB : crc verify error!"); return -1; } printDetail(); return 0; }
//************************************************************************** void control_inst_t::Retire( abstract_pc_t *a ) { #ifdef DEBUG_DYNAMIC_RET DEBUG_OUT("control_inst_t:Retire BEGIN, proc[%d]\n",m_proc); #endif #ifdef DEBUG_DYNAMIC char buf[128]; s->printDisassemble(buf); DEBUG_OUT("\tcontrol_inst_t::Retire BEGIN %s seq_num[ %lld ] cycle[ %lld ] fetchPC[ 0x%llx ] fetchNPC[ 0x%llx ] PredictedPC[ 0x%llx ] PredictedNPC[ 0x%llx ]\n", buf, seq_num, m_pseq->getLocalCycle(), m_actual.pc, m_actual.npc, m_predicted.pc, m_predicted.npc); for(int i=0; i < SI_MAX_DEST; ++i){ reg_id_t & dest = getDestReg(i); reg_id_t & tofree = getToFreeReg(i); if( !dest.isZero() ){ DEBUG_OUT("\tDest[ %d ] Vanilla[ %d ] Physical[ %d ] Arf[ %s ] ToFree: Vanilla[ %d ] physical[ %d ] Arf[ %s ]\n", i, dest.getVanilla(), dest.getPhysical(), dest.rid_type_menomic( dest.getRtype() ), tofree.getVanilla(), tofree.getPhysical(), tofree.rid_type_menomic( tofree.getRtype() ) ); } } #endif ASSERT( !getEvent( EVENT_FINALIZED ) ); STAT_INC( m_pseq->m_stat_control_retired[m_proc] ); // Need this bc we place fetch barrier on retry instead of stxa: if ( (s->getOpcode() == i_retry) || (s->getFlag( SI_FETCH_BARRIER)) ) { // if we have a branch misprediction, we already unstalled the fetch in partialSquash(): if(getEvent(EVENT_BRANCH_MISPREDICT) == false){ m_pseq->unstallFetch(m_proc); } } STAT_INC( m_pseq->m_branch_seen_stat[s->getBranchType()][2] ); STAT_INC( m_pseq->m_branch_seen_stat[s->getBranchType()][m_priv? 1:0] ); // record when execution takes place m_event_times[EVENT_TIME_RETIRE] = m_pseq->getLocalCycle() - m_fetch_cycle; // update dynamic branch prediction (predicated) instruction statistics static_inst_t *s_instr = getStaticInst(); if (s_instr->getType() == DYN_CONTROL) { uint32 inst; int op2; int pred; switch (s_instr->getBranchType()) { case BRANCH_COND: // conditional branch STAT_INC( m_pseq->m_nonpred_retire_count_stat[m_proc] ); break; case BRANCH_PCOND: // predictated conditional inst = s_instr->getInst(); op2 = maskBits32( inst, 22, 24 ); pred = maskBits32( inst, 19, 19 ); if ( op2 == 3 ) { // integer register w/ predication STAT_INC( m_pseq->m_pred_reg_retire_count_stat[m_proc] ); if (pred) { STAT_INC( m_pseq->m_pred_reg_retire_taken_stat[m_proc] ); } else { STAT_INC( m_pseq->m_pred_reg_retire_nottaken_stat[m_proc] ); } } else { STAT_INC( m_pseq->m_pred_retire_count_stat[m_proc] ); if (pred) { STAT_INC( m_pseq->m_pred_retire_count_taken_stat[m_proc] ); } else { STAT_INC( m_pseq->m_pred_retire_count_nottaken_stat[m_proc] ); } } if (pred == true && m_isTaken == false || pred == false && m_isTaken == true) { STAT_INC( m_pseq->m_branch_wrong_static_stat ); } break; default: ; // ignore non-predictated branches } } #ifdef DEBUG_RETIRE m_pseq->out_info("## Control Retire Stage\n"); printDetail(); m_pseq->printPC( &m_actual ); #endif bool mispredict = (m_events & EVENT_BRANCH_MISPREDICT); if (mispredict) { // incorrect branch prediction STAT_INC( m_pseq->m_branch_wrong_stat[s->getBranchType()][2] ); STAT_INC( m_pseq->m_branch_wrong_stat[s->getBranchType()][m_priv? 1:0] ); //train BRANCH_PRIV predictor if( (s->getBranchType() == BRANCH_PRIV) ){ if (m_predicted.cwp != m_actual.cwp) { m_pseq->getRegstatePred()->update(getVPC(), CONTROL_CWP, m_actual.cwp, m_predicted.cwp); } if (m_predicted.tl != m_actual.tl) { m_pseq->getRegstatePred()->update(getVPC(), CONTROL_TL, m_actual.tl, m_predicted.tl); } if (m_predicted.pstate != m_actual.pstate) { m_pseq->getRegstatePred()->update(getVPC(), CONTROL_PSTATE, m_actual.pstate, m_predicted.pstate); } } //****************************** print out mispredicted inst ***************** if(s->getBranchType() == BRANCH_PRIV){ char buf[128]; s->printDisassemble( buf ); bool imm = s->getFlag(SI_ISIMMEDIATE); #if 0 if(m_predicted.pc != m_actual.pc){ m_pseq->out_info("CONTROLOP: PC mispredict: predicted[ 0x%llx ] actual[ 0x%llx ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n", m_predicted.pc, m_actual.pc, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf); } #endif #if 0 if(m_predicted.npc != m_actual.npc){ m_pseq->out_info("CONTROLOP: NPC mispredict: predicted[ 0x%llx ] actual[ 0x%llx ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n", m_predicted.npc, m_actual.npc, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf); } #endif #if 0 if (m_predicted.cwp != m_actual.cwp) { m_pseq->out_info("CONTROLOP: CWP mispredict: predicted[ %d ] actual[ %d ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n", m_predicted.cwp, m_actual.cwp, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf); } #endif #if 0 if (m_predicted.tl != m_actual.tl) { m_pseq->out_info("CONTROLOP: TL mispredict: predicted[ %d ] actual[ %d ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n", m_predicted.tl, m_actual.tl, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf); } #endif #if 0 if (m_predicted.pstate != m_actual.pstate) { m_pseq->out_info("CONTROLOP: PSTATE mispredict: predicted[ 0x%0x ] actual[ 0x%0x ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n", m_predicted.pstate, m_actual.pstate, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf); } #endif } //************************************************************************** // train ras's exception table if (ras_t::EXCEPTION_TABLE && s->getBranchType() == BRANCH_RETURN) { my_addr_t tos; ras_t *ras = m_pseq->getRAS(m_proc); ras->getTop(&(m_pred_state.ras_state), &tos); if(tos == m_actual.npc) { ras->markException(m_predicted.npc); // update RAS state ras->pop(&(m_pred_state.ras_state)); m_pseq->setSpecBPS(m_pred_state); if (ras_t::DEBUG_RAS) m_pseq->out_info("*********** DEBUG_RAS ***********\n"); } else { ras->unmarkException(m_actual.npc); } } // XU DEBUG if (0 && s->getBranchType() == BRANCH_RETURN) { m_pseq->out_info("**** %c:mispred 0x%llx, pred 0x%llx target 0x%llx, " "next %d TOS %d\n", m_priv? 'K':'U', getVPC(), m_predicted.npc, m_actual.npc, m_pred_state.ras_state.next_free, m_pred_state.ras_state.TOS); // print 5 instr after mis-pred generic_address_t addr = m_predicted.npc-8; for(uint32 i = 0; i < 5; i++, addr+=4) { //get the actual seq number for the pointer to m_state: int32 seq_num = m_pseq->getID() / CONFIG_LOGICAL_PER_PHY_PROC; assert(seq_num >= 0 && seq_num < system_t::inst->m_numSMTProcs); tuple_int_string_t *disassemble = SIM_disassemble((processor_t *) system_t::inst->m_state[seq_num]->getSimicsProcessor(m_proc), addr, /* logical */ 1); if (disassemble) m_pseq->out_info(" %s\n", disassemble->string); } } } else { // correct or no prediction STAT_INC( m_pseq->m_branch_right_stat[s->getBranchType()][2] ); STAT_INC( m_pseq->m_branch_right_stat[s->getBranchType()][m_priv? 1:0] ); } /* update branch predictor tables at retirement */ if (s->getBranchType() == BRANCH_COND || s->getBranchType() == BRANCH_PCOND) { m_pseq->getDirectBP()->Update(getVPC(), (m_pseq->getArchBPS()->cond_state), s->getFlag( SI_STATICPRED ), m_isTaken, m_proc); } else if (s->getBranchType() == BRANCH_INDIRECT || (s->getBranchType() == BRANCH_CALL && s->getOpcode() != i_call) ) { // m_actual.npc is the indirect target m_pseq->getIndirectBP()->Update( getVPC(), &(m_pseq->getArchBPS()->indirect_state), m_actual.npc, m_proc ); } m_pseq->setArchBPS(m_pred_state); // no need to update call&return, since we used checkpointed RAS // no update on traps right now SetStage(RETIRE_STAGE); /* retire any register overwritten by link register */ retireRegisters(); #if 0 if(m_actual.pc == (my_addr_t) -1){ char buf[128]; s->printDisassemble(buf); ERROR_OUT("\tcontrol_inst_t::Retire %s seq_num[ %lld ] cycle[ %lld ] fetchPC[ 0x%llx ] fetchNPC[ 0x%llx ] fetched[ %lld ] executed[ %lld ]\n", buf, seq_num, m_pseq->getLocalCycle(), m_actual.pc, m_actual.npc, m_fetch_cycle, m_fetch_cycle+getEventTime(EVENT_TIME_EXECUTE_DONE)); //print out writer cycle for(int i=0; i < SI_MAX_SOURCE; ++i){ reg_id_t & source = getSourceReg(i); if(!source.isZero()){ uint64 written_cycle = source.getARF()->getWrittenCycle( source, m_proc ); uint64 writer_seqnum = source.getARF()->getWriterSeqnum( source, m_proc ); ERROR_OUT("\tSource[ %d ] Vanilla[ %d ] Physical[ %d ] Arf[ %s ] written_cycle[ %lld ] writer_seqnum[ %lld ]\n", i, source.getVanilla(), source.getPhysical(), source.rid_type_menomic( source.getRtype() ), written_cycle, writer_seqnum); } } } #endif ASSERT( m_actual.pc != (my_addr_t) -1 ); /* return pc, npc pair which are the results of execution */ a->pc = m_actual.pc; a->npc = m_actual.npc; markEvent( EVENT_FINALIZED ); #ifdef DEBUG_DYNAMIC_RET DEBUG_OUT("control_inst_t:Retire END, proc[%d]\n",m_proc); #endif }