diff options
author | Steve Reinhardt <stever@eecs.umich.edu> | 2003-10-23 19:09:18 -0700 |
---|---|---|
committer | Steve Reinhardt <stever@eecs.umich.edu> | 2003-10-23 19:09:18 -0700 |
commit | cc9a838f4c5a5bf5e8951bdb351fc7d4b74661fb (patch) | |
tree | 1bae8b1b09fcc39d04631c84beaf51f830938372 /cpu/simple_cpu/simple_cpu.cc | |
parent | 320540829d62f9c5a5290a8c9bd991fda297a210 (diff) | |
parent | 6e2fc8ce766d1f9cb601b4a2a15d1ba294ce97a5 (diff) | |
download | gem5-cc9a838f4c5a5bf5e8951bdb351fc7d4b74661fb.tar.xz |
Merge stever@zizzer:/bk/m5 into isabel.reinhardt.house:/z/stever/bk/m5
--HG--
extra : convert_revision : b0f93bd35d767fd3a520a9fed70a71d40b0056db
Diffstat (limited to 'cpu/simple_cpu/simple_cpu.cc')
-rw-r--r-- | cpu/simple_cpu/simple_cpu.cc | 152 |
1 files changed, 88 insertions, 64 deletions
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index 3c9be172f..c96e31cb0 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -103,11 +103,11 @@ SimpleCPU::SimpleCPU(const string &_name, FunctionalMemory *mem, MemInterface *icache_interface, MemInterface *dcache_interface, - int cpu_id, Tick freq) + Tick freq) : BaseCPU(_name, /* number_of_threads */ 1, max_insts_any_thread, max_insts_all_threads, max_loads_any_thread, max_loads_all_threads, - _system, cpu_id, freq), + _system, freq), #else SimpleCPU::SimpleCPU(const string &_name, Process *_process, Counter max_insts_any_thread, @@ -122,61 +122,23 @@ SimpleCPU::SimpleCPU(const string &_name, Process *_process, #endif tickEvent(this), xc(NULL), cacheCompletionEvent(this) { + _status = Idle; #ifdef FULL_SYSTEM - xc = new ExecContext(this, 0, system, itb, dtb, mem, cpu_id); + xc = new ExecContext(this, 0, system, itb, dtb, mem); - _status = Running; - if (cpu_id != 0) { + TheISA::initCPU(&xc->regs); - xc->setStatus(ExecContext::Unallocated); + IntReg *ipr = xc->regs.ipr; + ipr[TheISA::IPR_MCSR] = 0x6; - //Open a GDB debug session on port (7000 + the cpu_id) - (new GDBListener(new RemoteGDB(system, xc), 7000 + cpu_id))->listen(); - - AlphaISA::init(system->physmem, &xc->regs); - - fault = Reset_Fault; - - IntReg *ipr = xc->regs.ipr; - ipr[TheISA::IPR_MCSR] = 0x6; - - AlphaISA::swap_palshadow(&xc->regs, true); - - xc->regs.pc = - ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; - xc->regs.npc = xc->regs.pc + sizeof(MachInst); - - _status = Idle; - } - else { - system->init(xc); - - // Reset the system - // - AlphaISA::init(system->physmem, &xc->regs); - - fault = Reset_Fault; - - IntReg *ipr = xc->regs.ipr; - ipr[TheISA::IPR_MCSR] = 0x6; - - AlphaISA::swap_palshadow(&xc->regs, true); - - xc->regs.pc = ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; - xc->regs.npc = xc->regs.pc + sizeof(MachInst); - - _status = Running; - tickEvent.schedule(0); - } + AlphaISA::swap_palshadow(&xc->regs, true); + fault = Reset_Fault; + xc->regs.pc = ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; + xc->regs.npc = xc->regs.pc + sizeof(MachInst); #else xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0); fault = No_Fault; - if (xc->status() == ExecContext::Active) { - _status = Running; - tickEvent.schedule(0); - } else - _status = Idle; #endif // !FULL_SYSTEM icacheInterface = icache_interface; @@ -193,13 +155,61 @@ SimpleCPU::SimpleCPU(const string &_name, Process *_process, lastIcacheStall = 0; lastDcacheStall = 0; - contexts.push_back(xc); + execContexts.push_back(xc); } SimpleCPU::~SimpleCPU() { } + +void +SimpleCPU::registerExecContexts() +{ + BaseCPU::registerExecContexts(); + + // if any of this CPU's ExecContexts are active, mark the CPU as + // running and schedule its tick event. + for (int i = 0; i < execContexts.size(); ++i) { + ExecContext *xc = execContexts[i]; + if (xc->status() == ExecContext::Active && _status != Running) { + _status = Running; + // this should only happen at initialization time + assert(curTick == 0); + tickEvent.schedule(0); + } + } +} + + +void +SimpleCPU::switchOut() +{ + _status = SwitchedOut; + if (tickEvent.scheduled()) + tickEvent.squash(); +} + + +void +SimpleCPU::takeOverFrom(BaseCPU *oldCPU) +{ + BaseCPU::takeOverFrom(oldCPU); + + assert(!tickEvent.scheduled()); + + // if any of this CPU's ExecContexts are active, mark the CPU as + // running and schedule its tick event. + for (int i = 0; i < execContexts.size(); ++i) { + ExecContext *xc = execContexts[i]; + if (xc->status() == ExecContext::Active && _status != Running) { + _status = Running; + tickEvent.schedule(curTick + 1); + } + } +} + + void SimpleCPU::regStats() { @@ -488,6 +498,11 @@ SimpleCPU::processCacheCompletion() dcacheStallCycles += curTick - lastDcacheStall; setStatus(Running); break; + case SwitchedOut: + // If this CPU has been switched out due to sampling/warm-up, + // ignore any further status changes (e.g., due to cache + // misses outstanding at the time of the switch). + return; default: panic("SimpleCPU::processCacheCompletion: bad state"); break; @@ -693,7 +708,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) SimObjectParam<AlphaDtb *> dtb; SimObjectParam<FunctionalMemory *> mem; SimObjectParam<System *> system; - Param<int> cpu_id; Param<int> mult; #else SimObjectParam<Process *> workload; @@ -702,6 +716,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) SimObjectParam<BaseMem *> icache; SimObjectParam<BaseMem *> dcache; + Param<bool> defer_registration; + END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU) @@ -724,39 +740,47 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU) INIT_PARAM(dtb, "Data TLB"), INIT_PARAM(mem, "memory"), INIT_PARAM(system, "system object"), - INIT_PARAM_DFLT(cpu_id, "CPU identification number", 0), INIT_PARAM_DFLT(mult, "system clock multiplier", 1), #else INIT_PARAM(workload, "processes to run"), #endif // FULL_SYSTEM INIT_PARAM_DFLT(icache, "L1 instruction cache object", NULL), - INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL) + INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL), + INIT_PARAM_DFLT(defer_registration, "defer registration with system " + "(for sampling)", false) END_INIT_SIM_OBJECT_PARAMS(SimpleCPU) CREATE_SIM_OBJECT(SimpleCPU) { + SimpleCPU *cpu; #ifdef FULL_SYSTEM if (mult != 1) panic("processor clock multiplier must be 1\n"); - return new SimpleCPU(getInstanceName(), system, - max_insts_any_thread, max_insts_all_threads, - max_loads_any_thread, max_loads_all_threads, - itb, dtb, mem, - (icache) ? icache->getInterface() : NULL, - (dcache) ? dcache->getInterface() : NULL, - cpu_id, ticksPerSecond * mult); + cpu = new SimpleCPU(getInstanceName(), system, + max_insts_any_thread, max_insts_all_threads, + max_loads_any_thread, max_loads_all_threads, + itb, dtb, mem, + (icache) ? icache->getInterface() : NULL, + (dcache) ? dcache->getInterface() : NULL, + ticksPerSecond * mult); #else - return new SimpleCPU(getInstanceName(), workload, - max_insts_any_thread, max_insts_all_threads, - max_loads_any_thread, max_loads_all_threads, - icache->getInterface(), dcache->getInterface()); + cpu = new SimpleCPU(getInstanceName(), workload, + max_insts_any_thread, max_insts_all_threads, + max_loads_any_thread, max_loads_all_threads, + icache->getInterface(), dcache->getInterface()); #endif // FULL_SYSTEM + + if (!defer_registration) { + cpu->registerExecContexts(); + } + + return cpu; } REGISTER_SIM_OBJECT("SimpleCPU", SimpleCPU) |