📄 except.cc
字号:
// ---------------------------------------------------------------------- case SOFT_SL_REPL: case SOFT_SL_COHE: case SOFT_LIMBO: // this is a soft exception -- an inplace flush // (used for speculative load exceptions, for example proc->graduates++; proc->graduation_count++; // statistics: add cycle count and instruction count proc->cycles[SOFT_LIMBO] += (long long)YS__Simtime + proc->DELAY - proc->start_cycle[SOFT_LIMBO]; proc->graduated[SOFT_LIMBO] += proc->graduates - proc->start_graduated[SOFT_LIMBO]; proc->start_graduated[SOFT_LIMBO] = 0; proc->reset_lists(); proc->pc = icopy.pc; // we need to restart the instruction proc->npc = icopy.npc; if (!PSTATE_GET_PRIV(proc->pstate)) { proc->start_graduated[OK] = proc->graduates; proc->start_cycle[OK] = proc->curr_cycle; } return(0); break; // ---------------------------------------------------------------------- // Simulator Trap case SYSTRAP_02: proc->reset_lists(); proc->pc = icopy.npc; proc->npc = proc->pc+SIZE_OF_SPARC_INSTRUCTION; if (!SimTrapHandle(&icopy, proc)) { FatalException(&icopy, proc); return -1; } proc->graduates++; proc->graduation_count++; // statistics: add cycle count and instruction count proc->cycles[SYSTRAP_02] += (long long)YS__Simtime + proc->DELAY - proc->start_cycle[SYSTRAP_02]; proc->graduated[SYSTRAP_02] += proc->graduates - proc->start_graduated[SYSTRAP_02]; proc->start_graduated[SYSTRAP_02] = 0; if (!PSTATE_GET_PRIV(proc->pstate)) { proc->start_graduated[OK] = proc->graduates; proc->start_cycle[OK] = proc->curr_cycle; } return 0; break; // ---------------------------------------------------------------------- // copy offending PC into BADADDR register, copy page number of // offending PC into index register (not used for fully assoc. TLB) // and into lower bits of context register case ITLB_MISS: addr = icopy.pc; proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TLB_BADADDR)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TLB_BADADDR)]] = addr; proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TLB_INDEX)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TLB_INDEX)]] = proc->itlb->MissEntry(addr); proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TLB_TAG)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TLB_TAG)]] = (addr & ~(PAGE_SIZE-1)) | 0x1; break; // ---------------------------------------------------------------------- // copy offending address into BADADDR register, copy page number of // offending address into index register (not used for fully assoc. TLB) // and into lower bits of context register case DTLB_MISS: proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TLB_BADADDR)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TLB_BADADDR)]] = (unsigned int)icopy.addr; proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TLB_INDEX)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TLB_INDEX)]] = proc->dtlb->MissEntry(icopy.addr); proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TLB_TAG)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TLB_TAG)]] = (icopy.addr & ~(PAGE_SIZE-1)) | 0x1; break; // ---------------------------------------------------------------------- case INSTR_FAULT: proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TLB_BADADDR)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TLB_BADADDR)]] = icopy.pc; PrintInstrFault(&icopy, proc); break; // ---------------------------------------------------------------------- case DATA_FAULT: proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TLB_BADADDR)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TLB_BADADDR)]] = (unsigned int)icopy.addr; PrintDataFault(&icopy, proc); break; //----------------------------------------------------------------------- case FPERR: take_fp_exception(proc, inst); break; // external interrupt: clear interrupt bit ------------------------------ case INTERRUPT_00: case INTERRUPT_01: case INTERRUPT_02: case INTERRUPT_03: case INTERRUPT_04: case INTERRUPT_05: case INTERRUPT_06: case INTERRUPT_07: case INTERRUPT_08: case INTERRUPT_09: case INTERRUPT_0A: case INTERRUPT_0B: case INTERRUPT_0C: case INTERRUPT_0D: case INTERRUPT_0E: case INTERRUPT_0F: proc->interrupt_pending &= ~(0x00000001 << (INTERRUPT_00 - icopy.exception_code)); break; } proc->reset_lists(); SaveCPUState(&icopy, proc); if (icopy.exception_code == CLEANWINDOW) {#ifdef TRACE if (YS__Simtime > TRACE) YS__logmsg(proc->proc_id / ARCH_cpus, " [%i] Clean Window %i - saving %i\n", proc->proc_id, proc->cwp, (proc->cwp + 1) % NUM_WINS);#endif proc->cwp = (proc->cwp + 1) % NUM_WINS; } if ((icopy.code.instruction == iFLUSHW) && (icopy.exception_code == WINOVERFLOW)) {#ifdef TRACE if (YS__Simtime > TRACE) YS__logmsg(proc->proc_id / ARCH_cpus, " [%i] Flush Window - saving %i\n", proc->proc_id, (proc->cwp + proc->cansave + 2) % NUM_WINS);#endif proc->cwp = (proc->cwp + proc->cansave + 2) % NUM_WINS; } if ((icopy.code.instruction == iSAVE) && (icopy.exception_code == WINOVERFLOW)) {#ifdef TRACE if (YS__Simtime > TRACE) YS__logmsg(proc->proc_id / ARCH_cpus, " [%i] Overflow Window %i - saving %i\n", proc->proc_id, proc->cwp, (proc->cwp + 2) % NUM_WINS);#endif proc->cwp = (proc->cwp + 2) % NUM_WINS; } if (icopy.exception_code == WINUNDERFLOW) {#ifdef TRACE if (YS__Simtime > TRACE) YS__logmsg(proc->proc_id / ARCH_cpus, " [%i] Underflow Window %i - restoring %i\n", proc->proc_id, proc->cwp, (proc->cwp + NUM_WINS -1) % NUM_WINS);#endif proc->cwp = (proc->cwp + NUM_WINS - 1) % NUM_WINS; } //--------------------------------------------------------------------------- // jump to trap table if ((icopy.exception_code <= OK) || (icopy.exception_code >= MAX_EXCEPT)) YS__errmsg(proc->proc_id / ARCH_cpus, "Invalid exception code %i at PC 0x%08X\n", icopy.exception_code, icopy.pc); proc->pc = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TBA)]] | icopy.exception_code << 5; proc->npc = proc->pc+SIZE_OF_SPARC_INSTRUCTION; return 0;}//-----------------------------------------------------------------------------void SaveCPUState(instance *inst, ProcState *proc){#ifdef TRACE if (YS__Simtime > TRACE) { YS__logmsg(proc->proc_id / ARCH_cpus, " [%i] Save PC: 0x%X NPC: 0x%X PState: 0x%X ICC: 0x%X\n", proc->proc_id, inst->pc, inst->npc, proc->pstate, proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, COND_ICC)]]); YS__logmsg(proc->proc_id / ARCH_cpus, " [%i] CWP: %i CanSave: %i CanRestore: %i Otherwin: %i Cleanwin: %i\n", proc->proc_id, proc->cwp, proc->cansave, proc->canrestore, proc->otherwin, proc->cleanwin); }#endif // increment trap level proc->tl++; if (proc->tl >= NUM_TRAPS) YS__errmsg(proc->proc_id / ARCH_cpus, "Maximum Trap Level %i exceeded at 0x%08X\n", NUM_TRAPS, inst->pc); // save pc into tpc proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TPC)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc,proc->cwp, PRIV_TPC)]] = inst->pc; // save npc into tnpc proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TNPC)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc,proc->cwp, PRIV_TNPC)]] = inst->npc; // save pstate into tstate proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TSTATE)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TSTATE)]] = proc->pstate | proc-> phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, COND_ICC)]] << 24 | proc->cwp << 16; // set trap type proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_TT)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_TT)]] = inst->exception_code; // set pstate to privileged with alternate globals, disable interrupts // disable instruction TLB, disable data TLB for memory traps, // enable otherwise PSTATE_SET_PRIV(proc->pstate); PSTATE_SET_AG(proc->pstate); PSTATE_CLR_IE(proc->pstate); PSTATE_CLR_ITE(proc->pstate); if ((inst->exception_code == ITLB_MISS) || (inst->exception_code == DTLB_MISS) || (inst->exception_code == INSTR_FAULT) || (inst->exception_code == DATA_FAULT)) PSTATE_CLR_DTE(proc->pstate); else PSTATE_SET_DTE(proc->pstate);} /*--------------------------------------------------------------------------*/ static void FatalException(instance *inst, ProcState *proc){ #ifdef COREFILE if (proc->curr_cycle > DEBUG_TIME) fprintf(corefile, "Non returnable FATAL error!\n"); #endif YS__logmsg(proc->proc_id / ARCH_cpus, "Processor %d dying with FATAL error %i (%s) at time %g\n", proc->proc_id, inst->exception_code, enames[inst->exception_code], YS__Simtime); YS__logmsg(proc->proc_id / ARCH_cpus, "pc = 0x%08X, tag = %lld, %s \n", inst->pc, inst->tag, inames[inst->code.instruction]); YS__logmsg(proc->proc_id / ARCH_cpus, "lrs1 = %d, prs1 = %d \n", inst->lrs1, inst->prs1); YS__logmsg(proc->proc_id / ARCH_cpus, "lrs2 = %d, prs2 = %d \n", inst->lrs2, inst->prs2); YS__logmsg(proc->proc_id / ARCH_cpus, "lrd = %d, prd = %d \n", inst->lrd, inst->prd); switch (inst->code.rs1_regtype) { case REG_INT: YS__logmsg(proc->proc_id / ARCH_cpus, "rs1i = 0x%08X, ", inst->rs1vali); break; case REG_FP: YS__logmsg(proc->proc_id / ARCH_cpus, "rs1f = %f, ", inst->rs1valf); break; case REG_FPHALF: YS__logmsg(proc->proc_id / ARCH_cpus, "rs1fh = %f, ", double(inst->rs1valfh)); break; case REG_INTPAIR: YS__logmsg(proc->proc_id / ARCH_cpus, "rs1p = 0x%08X/0x%08X, ", inst->rs1valipair.a,inst->rs1valipair.b); break; case REG_INT64: YS__logmsg(proc->proc_id / ARCH_cpus, "rs1ll = %016llX, ", inst->rs1valll); break; default: YS__logmsg(proc->proc_id / ARCH_cpus, "rs1X = XXX, "); break; } switch (inst->code.rs2_regtype) { case REG_INT: YS__logmsg(proc->proc_id / ARCH_cpus, "rs2i = 0x%08X, ", inst->rs2vali); break; case REG_FP: YS__logmsg(proc->proc_id / ARCH_cpus, "rs2f = %f, ", inst->rs2valf); break; case REG_FPHALF: YS__logmsg(proc->proc_id / ARCH_cpus, "rs2fh = %f, ", double(inst->rs2valfh)); break; case REG_INTPAIR: YS__logmsg(proc->proc_id / ARCH_cpus, "rs2pair unsupported"); break; case REG_INT64: YS__logmsg(proc->proc_id / ARCH_cpus, "rs2ll = %80llX, ", inst->rs2valll); break; default: YS__logmsg(proc->proc_id / ARCH_cpus, "rs2X = XXX, "); break; } YS__logmsg(proc->proc_id / ARCH_cpus, "rsccvali = 0x%08X \n", inst->rsccvali); YS__logmsg(proc->proc_id / ARCH_cpus, "addr = 0x%08X\n", inst->addr); proc->exit = -1; YS__logmsg(proc->proc_id / ARCH_cpus, "Processor %d forcing grinding halt with code %d\n", proc->proc_id, inst->rs1vali); for (int n = 0; n < ARCH_mynodes * ARCH_cpus; n++) DoExit(); exit(1); // no graceful end -- abort all processors immediately}/*---------------------------------------------------------------------------*/ static int ProcessSerializedInstruction(instance *inst, ProcState *proc){ switch (inst->code.instruction) { //----------------------------------------------------------------------- case iarithSPECIAL1: // e.g. RD from special regs. if (inst->code.rs1 == STATE_TICK) proc->log_int_reg_file[arch_to_log(proc, proc->cwp, STATE_TICK)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, STATE_TICK)]] = (unsigned int)((long long)YS__Simtime - proc->tick_base); if (inst->code.rs1 == STATE_PC) proc->log_int_reg_file[arch_to_log(proc, proc->cwp, STATE_PC)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, STATE_PC)]] = inst->pc; proc->phy_int_reg_file[proc->intmapper[inst->lrd]] = proc->log_int_reg_file[inst->lrd] = proc->log_int_reg_file[inst->lrs1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -