📄 memprocess.cc
字号:
return; if (req->d.proc_data.inst_tag != inst->tag) return; // to handle times when reused by exception, prediction, etc if (inst->vsbfwd) { if (inst->memprogress == -1) { // standard for when issued inst->memprogress = req->d.proc_data.inst->vsbfwd; inst->vsbfwd = 0; inst->global_perform = 1; } else { // if instruction got killed, don't reset memprogress inst->vsbfwd = 0; inst->global_perform = 1; } } else /* Call the instruction function in funcs.cc */ DoMemFunc(inst, AllProcs[req->d.proc_data.proc_id]);}/*****************************************************************************//*****************************************************************************/extern "C" void PerformIFetch(REQ * req){ int count, max_count; unsigned pc; ProcState *proc = AllProcs[req->d.proc_instruction.proc_id]; fetch_queue_entry fqe; instr *instruction; if (proc->pstate != req->d.proc_instruction.pstate) { proc->fetch_done = 1; return; } if (proc->fetch_pc != req->vaddr) return; instruction = (instr*)req->d.proc_instruction.instructions; max_count = min(req->d.proc_instruction.count, proc->fetch_queue_size - proc->fetch_queue->NumItems()); count = 0; pc = req->vaddr; while (count < max_count) { fqe.inst = NewInstance(instruction, proc); fqe.exception_code = OK; fqe.pc = pc; proc->fetch_queue->Enqueue(fqe); count ++; instruction ++; pc += SIZE_OF_SPARC_INSTRUCTION; } proc->fetch_done = 1; proc->fetch_pc = pc;}/*****************************************************************************//* SpecLoadBufCohe: Called in systems with speculative loads whenever *//* a coherence comes to the L1 cache (whether an invalidation or a *//* replacement from L2). This function checks the coherence message *//* against outstanding speculative loads to determine if any needs to *//* be rolled back. *//*****************************************************************************/extern "C" int SpecLoadBufCohe(int proc_id, int paddr, SLBFailType fail){ ProcState *proc = AllProcs[proc_id]; except e_code; MemQLink < instance * >*slbindex; extern int block_mask; if (fail == SLB_Cohe) e_code = SOFT_SL_COHE; else if (fail == SLB_Repl) e_code = SOFT_SL_REPL; else YS__errmsg(proc_id / ARCH_cpus, "Unknown speculative load type");#ifdef STORE_ORDERING // skip the first element, since this is the active one by SC/PC standards slbindex = proc->MemQueue.GetNext(NULL); /* this indicates whether the operations being investigated are speculative or not. In the case of SC, all reads other than the head of the queue are speculative. In PC, all reads after some other read are speculative */ int specstart; if (Processor_Consistency) { specstart = 0; if (slbindex && (!IsStore(slbindex->d) || IsRMW(slbindex->d))) specstart = 1; } else// SC specstart = 1; while ((slbindex = proc->MemQueue.GetNext(slbindex)) != NULL) { instance *d = slbindex->d; if (d->memprogress && specstart && paddr == (d->addr & block_mask1)) { if (d->exception_code == OK || d->exception_code == SERIALIZE) d->exception_code = e_code; d->exception_code = e_code; proc->active_list.flag_exception(d->tag, e_code); } if (Processor_Consistency && !specstart && (!IsStore(d) || IsRMW(d))) specstart = 1; }#else // RC // in RC you might need to even look at the first load, since you // might just be waiting on previous stores slbindex = NULL; long long minspec = -1; if (proc->LLtag >= 0) minspec = proc->LLtag; else if (proc->SLtag >= 0 && proc->SLtag < minspec) minspec = proc->SLtag; if (minspec == -1) /* no way we're speculating */ return 0; while ((slbindex = proc->LoadQueue.GetNext(slbindex)) != NULL) { instance *d = slbindex->d; if (d->memprogress && (d->tag > minspec) && paddr == (d->addr & block_mask1d)) { if (d->exception_code == OK || d->exception_code == SERIALIZE) d->exception_code = e_code; d->exception_code = e_code; proc->active_list.flag_exception(d->tag, e_code); } }#endif return 0;}/*****************************************************************************//* Wrapper functions to interface to the various MemSys routines *//*****************************************************************************/extern "C" void FreeAMemUnit(int proc_id, long long tag){ ProcState *proc = AllProcs[proc_id]; // do this when you commit a request from the L1 ports#ifdef COREFILE if (YS__Simtime > DEBUG_TIME) fprintf(proc->corefile, "Freeing memunit for tag %lld\n", tag);#endif proc->FreeingUnits.insert(proc->curr_cycle, uMEM);}extern "C" void AckWriteToWBUF(instance *inst, int proc_id){ ProcState *proc = AllProcs[proc_id]; proc->active_list.mark_done_in_active_list(inst->tag, inst->exception_code, proc->curr_cycle - 1);}/*****************************************************************************/extern "C" void ReplaceAddr(instance *inst, unsigned addr){ inst->addr = addr;}/*****************************************************************************//* Signal I/O interrupt to processor: set pending interrupt bit and clear *//* halt-flag. Also, subtract the halted time from the cycle count for the *//* current exception level, and add halted time to total time CPU was halted.*//*****************************************************************************/extern "C" void ExternalInterrupt(int proc_id, int int_num){ ProcState *proc = AllProcs[proc_id]; int n; long long halted; if (proc == NULL) return; if (int_num < 0 || int_num > 15) YS__errmsg(proc_id / ARCH_cpus, "Invalid Interrupt Type %i\n", int_num); proc->interrupt_pending |= 0x00000001 << int_num; YS__logmsg(proc_id / ARCH_cpus, "%.0f Interrupt %i CPU %i\n", YS__Simtime, int_num, proc_id % ARCH_cpus); if (proc->halt != 0) { halted = (long long)YS__Simtime - proc->start_halted; for (n = 0; n < MAX_EXCEPT; n++) if (proc->start_graduated[n] != 0) proc->start_cycle[n] += halted; proc->total_halted += halted; proc->halt = 0; }}/*****************************************************************************//* Halt processor: set PIL to specified value and set halt-flag. *//* Remember current cycle for acconting. *//*****************************************************************************/extern "C" void ProcessorHalt(int proc_id, int pil){ ProcState *proc = AllProcs[proc_id]; if (proc == NULL) return; proc->halt = 1; proc->start_halted = (long long)YS__Simtime; proc->pil = pil; proc->log_int_reg_file[arch_to_log(proc, proc->cwp, PRIV_PIL)] = proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, PRIV_PIL)]] = pil;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -