blob: fe2c8e708ecdc0f8d0854d297ea19f07e7132dee [file] [log] [blame]
Korey Sewell973d8b82009-02-10 15:49:29 -08001/*
2 * Copyright (c) 2007 MIPS Technologies, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Korey Sewell
29 *
30 */
31
Nathan Binkert47877cf2009-05-26 09:23:13 -070032#include <algorithm>
Steve Reinhardt14808ec2009-04-17 16:54:58 -070033
Korey Sewell973d8b82009-02-10 15:49:29 -080034#include "arch/utility.hh"
Nathan Binkert47877cf2009-05-26 09:23:13 -070035#include "config/full_system.hh"
Nathan Binkertd9f39c82009-09-23 08:34:21 -070036#include "config/the_isa.hh"
Korey Sewell973d8b82009-02-10 15:49:29 -080037#include "cpu/activity.hh"
Korey Sewell973d8b82009-02-10 15:49:29 -080038#include "cpu/base.hh"
Nathan Binkertd9f39c82009-09-23 08:34:21 -070039#include "cpu/exetrace.hh"
40#include "cpu/inorder/cpu.hh"
41#include "cpu/inorder/first_stage.hh"
Korey Sewell973d8b82009-02-10 15:49:29 -080042#include "cpu/inorder/inorder_dyn_inst.hh"
Nathan Binkertd9f39c82009-09-23 08:34:21 -070043#include "cpu/inorder/pipeline_traits.hh"
44#include "cpu/inorder/resource_pool.hh"
45#include "cpu/inorder/resources/resource_list.hh"
Korey Sewell973d8b82009-02-10 15:49:29 -080046#include "cpu/inorder/thread_context.hh"
47#include "cpu/inorder/thread_state.hh"
Nathan Binkertd9f39c82009-09-23 08:34:21 -070048#include "cpu/simple_thread.hh"
49#include "cpu/thread_context.hh"
Korey Sewell973d8b82009-02-10 15:49:29 -080050#include "mem/translating_port.hh"
Nathan Binkertd9f39c82009-09-23 08:34:21 -070051#include "params/InOrderCPU.hh"
Korey Sewell973d8b82009-02-10 15:49:29 -080052#include "sim/process.hh"
Korey Sewell973d8b82009-02-10 15:49:29 -080053#include "sim/stat_control.hh"
Korey Sewell973d8b82009-02-10 15:49:29 -080054
Korey Sewellbadb2382009-09-15 01:44:48 -040055#if FULL_SYSTEM
56#include "cpu/quiesce_event.hh"
57#include "sim/system.hh"
58#endif
59
60#if THE_ISA == ALPHA_ISA
61#include "arch/alpha/osfpal.hh"
62#endif
63
Korey Sewell973d8b82009-02-10 15:49:29 -080064using namespace std;
65using namespace TheISA;
66using namespace ThePipeline;
67
68InOrderCPU::TickEvent::TickEvent(InOrderCPU *c)
69 : Event(CPU_Tick_Pri), cpu(c)
70{ }
71
72
73void
74InOrderCPU::TickEvent::process()
75{
76 cpu->tick();
77}
78
79
80const char *
81InOrderCPU::TickEvent::description()
82{
83 return "InOrderCPU tick event";
84}
85
86InOrderCPU::CPUEvent::CPUEvent(InOrderCPU *_cpu, CPUEventType e_type,
Korey Sewell4a945aa2010-01-31 18:26:26 -050087 Fault fault, ThreadID _tid, DynInstPtr inst,
88 unsigned event_pri_offset)
89 : Event(Event::Priority((unsigned int)CPU_Tick_Pri + event_pri_offset)),
90 cpu(_cpu)
Korey Sewell973d8b82009-02-10 15:49:29 -080091{
Korey Sewelld8e09352010-01-31 18:26:03 -050092 setEvent(e_type, fault, _tid, inst);
Korey Sewell973d8b82009-02-10 15:49:29 -080093}
94
Korey Sewell3a057bd2009-05-12 15:01:16 -040095
96std::string InOrderCPU::eventNames[NumCPUEvents] =
97{
98 "ActivateThread",
Korey Sewelle1fcc642010-01-31 18:26:32 -050099 "ActivateNextReadyThread",
100 "DeactivateThread",
Korey Sewell5e0b8332010-01-31 18:28:05 -0500101 "HaltThread",
Korey Sewell3a057bd2009-05-12 15:01:16 -0400102 "SuspendThread",
Korey Sewell3a057bd2009-05-12 15:01:16 -0400103 "Trap",
104 "InstGraduated",
Korey Sewelld9eaa2f2010-01-31 18:26:40 -0500105 "SquashFromMemStall",
Korey Sewell3a057bd2009-05-12 15:01:16 -0400106 "UpdatePCs"
107};
108
Korey Sewell973d8b82009-02-10 15:49:29 -0800109void
110InOrderCPU::CPUEvent::process()
111{
112 switch (cpuEventType)
113 {
114 case ActivateThread:
115 cpu->activateThread(tid);
116 break;
117
Korey Sewelle1fcc642010-01-31 18:26:32 -0500118 case ActivateNextReadyThread:
119 cpu->activateNextReadyThread();
120 break;
121
122 case DeactivateThread:
123 cpu->deactivateThread(tid);
124 break;
125
Korey Sewell5e0b8332010-01-31 18:28:05 -0500126 case HaltThread:
127 cpu->haltThread(tid);
Korey Sewell973d8b82009-02-10 15:49:29 -0800128 break;
129
Korey Sewelld9eaa2f2010-01-31 18:26:40 -0500130 case SuspendThread:
131 cpu->suspendThread(tid);
Korey Sewell973d8b82009-02-10 15:49:29 -0800132 break;
133
Korey Sewelleac5eac2010-01-31 18:26:13 -0500134 case SquashFromMemStall:
135 cpu->squashDueToMemStall(inst->squashingStage, inst->seqNum, tid);
136 break;
137
Korey Sewell973d8b82009-02-10 15:49:29 -0800138 case Trap:
Gabe Black6833ca72010-09-13 19:26:03 -0700139 cpu->trapCPU(fault, tid, inst);
Korey Sewell973d8b82009-02-10 15:49:29 -0800140 break;
141
142 default:
Korey Sewell5e0b8332010-01-31 18:28:05 -0500143 fatal("Unrecognized Event Type %s", eventNames[cpuEventType]);
Korey Sewell973d8b82009-02-10 15:49:29 -0800144 }
Korey Sewell7b3b3622010-01-31 17:18:15 -0500145
Korey Sewell973d8b82009-02-10 15:49:29 -0800146 cpu->cpuEventRemoveList.push(this);
147}
148
Korey Sewell7b3b3622010-01-31 17:18:15 -0500149
150
Korey Sewell973d8b82009-02-10 15:49:29 -0800151const char *
152InOrderCPU::CPUEvent::description()
153{
154 return "InOrderCPU event";
155}
156
157void
158InOrderCPU::CPUEvent::scheduleEvent(int delay)
159{
Steve Reinhardtd60c2932011-01-07 21:50:29 -0800160 assert(!scheduled() || squashed());
Steve Reinhardt6f118792011-01-07 21:50:29 -0800161 cpu->reschedule(this, cpu->nextCycle(curTick() + cpu->ticks(delay)), true);
Korey Sewell973d8b82009-02-10 15:49:29 -0800162}
163
164void
165InOrderCPU::CPUEvent::unscheduleEvent()
166{
167 if (scheduled())
168 squash();
169}
170
171InOrderCPU::InOrderCPU(Params *params)
172 : BaseCPU(params),
173 cpu_id(params->cpu_id),
Korey Sewell9e1dc7f2009-03-04 22:37:45 -0500174 coreType("default"),
175 _status(Idle),
Korey Sewell973d8b82009-02-10 15:49:29 -0800176 tickEvent(this),
Korey Sewell973d8b82009-02-10 15:49:29 -0800177 timeBuffer(2 , 2),
178 removeInstsThisCycle(false),
179 activityRec(params->name, NumStages, 10, params->activity),
Korey Sewellbadb2382009-09-15 01:44:48 -0400180#if FULL_SYSTEM
181 system(params->system),
182 physmem(system->physmem),
183#endif // FULL_SYSTEM
Korey Sewell7b3b3622010-01-31 17:18:15 -0500184#ifdef DEBUG
185 cpuEventNum(0),
186 resReqCount(0),
187#endif // DEBUG
Korey Sewell973d8b82009-02-10 15:49:29 -0800188 switchCount(0),
189 deferRegistration(false/*params->deferRegistration*/),
Korey Sewell0b29c2d2010-01-31 18:28:59 -0500190 stageTracing(params->stageTracing),
191 instsPerSwitch(0)
Korey Sewell0e967982010-01-31 18:25:13 -0500192{
Korey Sewellbadb2382009-09-15 01:44:48 -0400193 ThreadID active_threads;
Korey Sewell973d8b82009-02-10 15:49:29 -0800194 cpu_params = params;
195
196 resPool = new ResourcePool(this, params);
Korey Sewell973d8b82009-02-10 15:49:29 -0800197
Korey Sewell973d8b82009-02-10 15:49:29 -0800198 // Resize for Multithreading CPUs
199 thread.resize(numThreads);
200
Korey Sewellbadb2382009-09-15 01:44:48 -0400201#if FULL_SYSTEM
202 active_threads = 1;
203#else
204 active_threads = params->workload.size();
Korey Sewell973d8b82009-02-10 15:49:29 -0800205
206 if (active_threads > MaxThreads) {
207 panic("Workload Size too large. Increase the 'MaxThreads'"
208 "in your InOrder implementation or "
209 "edit your workload size.");
210 }
Korey Sewell0e967982010-01-31 18:25:13 -0500211
Korey Sewell1a89e8f2010-01-31 18:29:59 -0500212
Korey Sewell0e967982010-01-31 18:25:13 -0500213 if (active_threads > 1) {
214 threadModel = (InOrderCPU::ThreadModel) params->threadModel;
Korey Sewelle1fcc642010-01-31 18:26:32 -0500215
216 if (threadModel == SMT) {
217 DPRINTF(InOrderCPU, "Setting Thread Model to SMT.\n");
218 } else if (threadModel == SwitchOnCacheMiss) {
219 DPRINTF(InOrderCPU, "Setting Thread Model to "
220 "Switch On Cache Miss\n");
221 }
222
Korey Sewell0e967982010-01-31 18:25:13 -0500223 } else {
224 threadModel = Single;
225 }
226
227
228
Korey Sewellbadb2382009-09-15 01:44:48 -0400229#endif
Korey Sewell973d8b82009-02-10 15:49:29 -0800230
231 // Bind the fetch & data ports from the resource pool.
232 fetchPortIdx = resPool->getPortIdx(params->fetchMemPort);
233 if (fetchPortIdx == 0) {
Korey Sewell1c8dfd92009-05-12 15:01:13 -0400234 fatal("Unable to find port to fetch instructions from.\n");
Korey Sewell973d8b82009-02-10 15:49:29 -0800235 }
236
237 dataPortIdx = resPool->getPortIdx(params->dataMemPort);
238 if (dataPortIdx == 0) {
Korey Sewell1c8dfd92009-05-12 15:01:13 -0400239 fatal("Unable to find port for data.\n");
Korey Sewell973d8b82009-02-10 15:49:29 -0800240 }
241
Nathan Binkert47877cf2009-05-26 09:23:13 -0700242 for (ThreadID tid = 0; tid < numThreads; ++tid) {
Korey Sewellbadb2382009-09-15 01:44:48 -0400243#if FULL_SYSTEM
244 // SMT is not supported in FS mode yet.
Korey Sewellf09f84d2009-10-01 09:35:06 -0400245 assert(numThreads == 1);
246 thread[tid] = new Thread(this, 0);
Korey Sewellbadb2382009-09-15 01:44:48 -0400247#else
Nathan Binkert6faf3772009-06-04 23:21:12 -0700248 if (tid < (ThreadID)params->workload.size()) {
Korey Sewell30cd2d22009-03-04 13:17:08 -0500249 DPRINTF(InOrderCPU, "Workload[%i] process is %#x\n",
Korey Sewellf09f84d2009-10-01 09:35:06 -0400250 tid, params->workload[tid]->prog_fname);
251 thread[tid] =
Gabe Blackc9a27d82009-07-08 23:02:22 -0700252 new Thread(this, tid, params->workload[tid]);
Korey Sewell973d8b82009-02-10 15:49:29 -0800253 } else {
254 //Allocate Empty thread so M5 can use later
255 //when scheduling threads to CPU
Korey Sewell30cd2d22009-03-04 13:17:08 -0500256 Process* dummy_proc = params->workload[0];
Korey Sewellf09f84d2009-10-01 09:35:06 -0400257 thread[tid] = new Thread(this, tid, dummy_proc);
Korey Sewell973d8b82009-02-10 15:49:29 -0800258 }
Korey Sewell1a89e8f2010-01-31 18:29:59 -0500259
260 // Eventually set this with parameters...
261 asid[tid] = tid;
Korey Sewellbadb2382009-09-15 01:44:48 -0400262#endif
Korey Sewell973d8b82009-02-10 15:49:29 -0800263
264 // Setup the TC that will serve as the interface to the threads/CPU.
265 InOrderThreadContext *tc = new InOrderThreadContext;
266 tc->cpu = this;
Nathan Binkert47877cf2009-05-26 09:23:13 -0700267 tc->thread = thread[tid];
Korey Sewell973d8b82009-02-10 15:49:29 -0800268
269 // Give the thread the TC.
Nathan Binkert47877cf2009-05-26 09:23:13 -0700270 thread[tid]->tc = tc;
271 thread[tid]->setFuncExeInst(0);
272 globalSeqNum[tid] = 1;
Korey Sewell973d8b82009-02-10 15:49:29 -0800273
274 // Add the TC to the CPU's list of TC's.
275 this->threadContexts.push_back(tc);
276 }
277
278 // Initialize TimeBuffer Stage Queues
Korey Sewell973d8b82009-02-10 15:49:29 -0800279 for (int stNum=0; stNum < NumStages - 1; stNum++) {
280 stageQueue[stNum] = new StageQueue(NumStages, NumStages);
Korey Sewell846f9532009-03-04 13:16:49 -0500281 stageQueue[stNum]->id(stNum);
Korey Sewell973d8b82009-02-10 15:49:29 -0800282 }
283
284
285 // Set Up Pipeline Stages
286 for (int stNum=0; stNum < NumStages; stNum++) {
287 if (stNum == 0)
288 pipelineStage[stNum] = new FirstStage(params, stNum);
289 else
290 pipelineStage[stNum] = new PipelineStage(params, stNum);
291
292 pipelineStage[stNum]->setCPU(this);
293 pipelineStage[stNum]->setActiveThreads(&activeThreads);
294 pipelineStage[stNum]->setTimeBuffer(&timeBuffer);
295
296 // Take Care of 1st/Nth stages
297 if (stNum > 0)
298 pipelineStage[stNum]->setPrevStageQueue(stageQueue[stNum - 1]);
Korey Sewellf69b0182009-03-04 13:17:07 -0500299 if (stNum < NumStages - 1)
300 pipelineStage[stNum]->setNextStageQueue(stageQueue[stNum]);
Korey Sewell973d8b82009-02-10 15:49:29 -0800301 }
302
303 // Initialize thread specific variables
Nathan Binkert47877cf2009-05-26 09:23:13 -0700304 for (ThreadID tid = 0; tid < numThreads; tid++) {
Korey Sewell973d8b82009-02-10 15:49:29 -0800305 archRegDepMap[tid].setCPU(this);
306
307 nonSpecInstActive[tid] = false;
308 nonSpecSeqNum[tid] = 0;
309
310 squashSeqNum[tid] = MaxAddr;
311 lastSquashCycle[tid] = 0;
312
Gabe Blacka480ba02009-07-08 23:02:20 -0700313 memset(intRegs[tid], 0, sizeof(intRegs[tid]));
Gabe Black0cb180e2009-07-08 23:02:20 -0700314 memset(floatRegs.i[tid], 0, sizeof(floatRegs.i[tid]));
Gabe Black32daf6f2009-07-08 23:02:20 -0700315 isa[tid].clear();
Korey Sewell973d8b82009-02-10 15:49:29 -0800316
Korey Sewelld9eaa2f2010-01-31 18:26:40 -0500317 isa[tid].expandForMultithreading(numThreads, 1/*numVirtProcs*/);
Korey Sewell1a89e8f2010-01-31 18:29:59 -0500318
319 // Define dummy instructions and resource requests to be used.
320 dummyInst[tid] = new InOrderDynInst(this,
321 thread[tid],
322 0,
323 tid,
324 asid[tid]);
325
326 dummyReq[tid] = new ResourceRequest(resPool->getResource(0),
327 dummyInst[tid],
328 0,
329 0,
330 0,
331 0);
Korey Sewell973d8b82009-02-10 15:49:29 -0800332 }
333
Korey Sewell9357e352010-01-31 18:30:48 -0500334 dummyReqInst = new InOrderDynInst(this, NULL, 0, 0, 0);
335 dummyReqInst->setSquashed();
336
337 dummyBufferInst = new InOrderDynInst(this, NULL, 0, 0, 0);
338 dummyBufferInst->setSquashed();
339
Steve Reinhardt6f118792011-01-07 21:50:29 -0800340 lastRunningCycle = curTick();
Korey Sewell973d8b82009-02-10 15:49:29 -0800341
Korey Sewell973d8b82009-02-10 15:49:29 -0800342 // Reset CPU to reset state.
343#if FULL_SYSTEM
344 Fault resetFault = new ResetFault();
345 resetFault->invoke(tcBase());
346#else
347 reset();
348#endif
349
Korey Sewell9357e352010-01-31 18:30:48 -0500350 dummyBufferInst->resetInstCount();
351
Korey Sewell973d8b82009-02-10 15:49:29 -0800352 // Schedule First Tick Event, CPU will reschedule itself from here on out.
353 scheduleTickEvent(0);
354}
355
Korey Sewellf3bc2df2010-01-31 18:30:08 -0500356InOrderCPU::~InOrderCPU()
357{
358 delete resPool;
359}
360
Korey Sewell973d8b82009-02-10 15:49:29 -0800361
362void
363InOrderCPU::regStats()
364{
365 /* Register the Resource Pool's stats here.*/
366 resPool->regStats();
367
Korey Sewellffa9ecb2010-01-31 18:28:51 -0500368 /* Register for each Pipeline Stage */
369 for (int stage_num=0; stage_num < ThePipeline::NumStages; stage_num++) {
370 pipelineStage[stage_num]->regStats();
371 }
372
Korey Sewell973d8b82009-02-10 15:49:29 -0800373 /* Register any of the InOrderCPU's stats here.*/
Korey Sewell0b29c2d2010-01-31 18:28:59 -0500374 instsPerCtxtSwitch
375 .name(name() + ".instsPerContextSwitch")
376 .desc("Instructions Committed Per Context Switch")
377 .prereq(instsPerCtxtSwitch);
378
379 numCtxtSwitches
380 .name(name() + ".contextSwitches")
381 .desc("Number of context switches");
Korey Sewell9f0d8f22010-06-23 18:18:20 -0400382
383 comLoads
384 .name(name() + ".comLoads")
385 .desc("Number of Load instructions committed");
386
387 comStores
388 .name(name() + ".comStores")
389 .desc("Number of Store instructions committed");
390
391 comBranches
392 .name(name() + ".comBranches")
393 .desc("Number of Branches instructions committed");
394
395 comNops
396 .name(name() + ".comNops")
397 .desc("Number of Nop instructions committed");
398
399 comNonSpec
400 .name(name() + ".comNonSpec")
401 .desc("Number of Non-Speculative instructions committed");
402
403 comInts
404 .name(name() + ".comInts")
405 .desc("Number of Integer instructions committed");
406
407 comFloats
408 .name(name() + ".comFloats")
409 .desc("Number of Floating Point instructions committed");
Korey Sewell0b29c2d2010-01-31 18:28:59 -0500410
Korey Sewell973d8b82009-02-10 15:49:29 -0800411 timesIdled
412 .name(name() + ".timesIdled")
413 .desc("Number of times that the entire CPU went into an idle state and"
414 " unscheduled itself")
415 .prereq(timesIdled);
416
417 idleCycles
418 .name(name() + ".idleCycles")
Korey Sewellea890992010-01-31 18:30:24 -0500419 .desc("Number of cycles cpu's stages were not processed");
420
421 runCycles
422 .name(name() + ".runCycles")
423 .desc("Number of cycles cpu stages are processed.");
424
425 activity
426 .name(name() + ".activity")
427 .desc("Percentage of cycles cpu is active")
428 .precision(6);
429 activity = (runCycles / numCycles) * 100;
Korey Sewell973d8b82009-02-10 15:49:29 -0800430
431 threadCycles
432 .init(numThreads)
433 .name(name() + ".threadCycles")
434 .desc("Total Number of Cycles A Thread Was Active in CPU (Per-Thread)");
435
436 smtCycles
437 .name(name() + ".smtCycles")
Korey Sewell7b3b3622010-01-31 17:18:15 -0500438 .desc("Total number of cycles that the CPU was in SMT-mode");
Korey Sewell973d8b82009-02-10 15:49:29 -0800439
440 committedInsts
441 .init(numThreads)
442 .name(name() + ".committedInsts")
443 .desc("Number of Instructions Simulated (Per-Thread)");
444
445 smtCommittedInsts
446 .init(numThreads)
447 .name(name() + ".smtCommittedInsts")
448 .desc("Number of SMT Instructions Simulated (Per-Thread)");
449
450 totalCommittedInsts
451 .name(name() + ".committedInsts_total")
452 .desc("Number of Instructions Simulated (Total)");
453
454 cpi
455 .name(name() + ".cpi")
456 .desc("CPI: Cycles Per Instruction (Per-Thread)")
457 .precision(6);
Korey Sewell9f0d8f22010-06-23 18:18:20 -0400458 cpi = numCycles / committedInsts;
Korey Sewell973d8b82009-02-10 15:49:29 -0800459
460 smtCpi
461 .name(name() + ".smt_cpi")
462 .desc("CPI: Total SMT-CPI")
463 .precision(6);
464 smtCpi = smtCycles / smtCommittedInsts;
465
466 totalCpi
467 .name(name() + ".cpi_total")
468 .desc("CPI: Total CPI of All Threads")
469 .precision(6);
Korey Sewelle4aa4ca2009-03-04 13:16:48 -0500470 totalCpi = numCycles / totalCommittedInsts;
Korey Sewell973d8b82009-02-10 15:49:29 -0800471
472 ipc
473 .name(name() + ".ipc")
474 .desc("IPC: Instructions Per Cycle (Per-Thread)")
475 .precision(6);
Korey Sewell9f0d8f22010-06-23 18:18:20 -0400476 ipc = committedInsts / numCycles;
Korey Sewell973d8b82009-02-10 15:49:29 -0800477
478 smtIpc
479 .name(name() + ".smt_ipc")
480 .desc("IPC: Total SMT-IPC")
481 .precision(6);
482 smtIpc = smtCommittedInsts / smtCycles;
483
484 totalIpc
485 .name(name() + ".ipc_total")
486 .desc("IPC: Total IPC of All Threads")
487 .precision(6);
Korey Sewelle4aa4ca2009-03-04 13:16:48 -0500488 totalIpc = totalCommittedInsts / numCycles;
Korey Sewell973d8b82009-02-10 15:49:29 -0800489
490 BaseCPU::regStats();
491}
492
493
494void
495InOrderCPU::tick()
496{
497 DPRINTF(InOrderCPU, "\n\nInOrderCPU: Ticking main, InOrderCPU.\n");
498
499 ++numCycles;
500
Korey Sewellea890992010-01-31 18:30:24 -0500501 bool pipes_idle = true;
502
Korey Sewell973d8b82009-02-10 15:49:29 -0800503 //Tick each of the stages
504 for (int stNum=NumStages - 1; stNum >= 0 ; stNum--) {
505 pipelineStage[stNum]->tick();
Korey Sewellea890992010-01-31 18:30:24 -0500506
507 pipes_idle = pipes_idle && pipelineStage[stNum]->idle;
Korey Sewell973d8b82009-02-10 15:49:29 -0800508 }
509
Korey Sewellea890992010-01-31 18:30:24 -0500510 if (pipes_idle)
511 idleCycles++;
512 else
513 runCycles++;
514
Korey Sewell973d8b82009-02-10 15:49:29 -0800515 // Now advance the time buffers one tick
516 timeBuffer.advance();
517 for (int sqNum=0; sqNum < NumStages - 1; sqNum++) {
518 stageQueue[sqNum]->advance();
519 }
520 activityRec.advance();
Korey Sewellea890992010-01-31 18:30:24 -0500521
Korey Sewell973d8b82009-02-10 15:49:29 -0800522 // Any squashed requests, events, or insts then remove them now
523 cleanUpRemovedReqs();
524 cleanUpRemovedEvents();
525 cleanUpRemovedInsts();
526
527 // Re-schedule CPU for this cycle
528 if (!tickEvent.scheduled()) {
529 if (_status == SwitchedOut) {
530 // increment stat
Steve Reinhardt6f118792011-01-07 21:50:29 -0800531 lastRunningCycle = curTick();
Korey Sewell973d8b82009-02-10 15:49:29 -0800532 } else if (!activityRec.active()) {
533 DPRINTF(InOrderCPU, "sleeping CPU.\n");
Steve Reinhardt6f118792011-01-07 21:50:29 -0800534 lastRunningCycle = curTick();
Korey Sewell973d8b82009-02-10 15:49:29 -0800535 timesIdled++;
536 } else {
Steve Reinhardt6f118792011-01-07 21:50:29 -0800537 //Tick next_tick = curTick() + cycles(1);
Korey Sewell973d8b82009-02-10 15:49:29 -0800538 //tickEvent.schedule(next_tick);
Steve Reinhardt6f118792011-01-07 21:50:29 -0800539 schedule(&tickEvent, nextCycle(curTick() + 1));
Korey Sewell7b3b3622010-01-31 17:18:15 -0500540 DPRINTF(InOrderCPU, "Scheduled CPU for next tick @ %i.\n",
Steve Reinhardt6f118792011-01-07 21:50:29 -0800541 nextCycle(curTick() + 1));
Korey Sewell973d8b82009-02-10 15:49:29 -0800542 }
543 }
544
545 tickThreadStats();
546 updateThreadPriority();
547}
548
549
550void
551InOrderCPU::init()
552{
553 if (!deferRegistration) {
554 registerThreadContexts();
555 }
556
557 // Set inSyscall so that the CPU doesn't squash when initially
558 // setting up registers.
Nathan Binkert47877cf2009-05-26 09:23:13 -0700559 for (ThreadID tid = 0; tid < numThreads; ++tid)
560 thread[tid]->inSyscall = true;
Korey Sewell973d8b82009-02-10 15:49:29 -0800561
Steve Reinhardt14808ec2009-04-17 16:54:58 -0700562#if FULL_SYSTEM
Nathan Binkert47877cf2009-05-26 09:23:13 -0700563 for (ThreadID tid = 0; tid < numThreads; tid++) {
Steve Reinhardt14808ec2009-04-17 16:54:58 -0700564 ThreadContext *src_tc = threadContexts[tid];
565 TheISA::initCPU(src_tc, src_tc->contextId());
Korey Sewell973d8b82009-02-10 15:49:29 -0800566 }
Steve Reinhardt14808ec2009-04-17 16:54:58 -0700567#endif
Korey Sewell973d8b82009-02-10 15:49:29 -0800568
569 // Clear inSyscall.
Nathan Binkert47877cf2009-05-26 09:23:13 -0700570 for (ThreadID tid = 0; tid < numThreads; ++tid)
571 thread[tid]->inSyscall = false;
Korey Sewell973d8b82009-02-10 15:49:29 -0800572
573 // Call Initializiation Routine for Resource Pool
574 resPool->init();
575}
576
577void
Korey Sewell973d8b82009-02-10 15:49:29 -0800578InOrderCPU::reset()
579{
Gabe Black32daf6f2009-07-08 23:02:20 -0700580 for (int i = 0; i < numThreads; i++) {
581 isa[i].reset(coreType, numThreads,
Korey Sewelld9eaa2f2010-01-31 18:26:40 -0500582 1/*numVirtProcs*/, dynamic_cast<BaseCPU*>(this));
Gabe Black32daf6f2009-07-08 23:02:20 -0700583 }
Korey Sewell973d8b82009-02-10 15:49:29 -0800584}
585
586Port*
587InOrderCPU::getPort(const std::string &if_name, int idx)
588{
589 return resPool->getPort(if_name, idx);
590}
591
Korey Sewellbadb2382009-09-15 01:44:48 -0400592#if FULL_SYSTEM
593Fault
594InOrderCPU::hwrei(ThreadID tid)
595{
596 panic("hwrei: Unimplemented");
597
598 return NoFault;
599}
600
601
602bool
603InOrderCPU::simPalCheck(int palFunc, ThreadID tid)
604{
605 panic("simPalCheck: Unimplemented");
606
607 return true;
608}
609
610
611Fault
612InOrderCPU::getInterrupts()
613{
614 // Check if there are any outstanding interrupts
615 return this->interrupts->getInterrupt(this->threadContexts[0]);
616}
617
618
619void
620InOrderCPU::processInterrupts(Fault interrupt)
621{
622 // Check for interrupts here. For now can copy the code that
623 // exists within isa_fullsys_traits.hh. Also assume that thread 0
624 // is the one that handles the interrupts.
625 // @todo: Possibly consolidate the interrupt checking code.
626 // @todo: Allow other threads to handle interrupts.
627
628 assert(interrupt != NoFault);
629 this->interrupts->updateIntrInfo(this->threadContexts[0]);
630
631 DPRINTF(InOrderCPU, "Interrupt %s being handled\n", interrupt->name());
Gabe Blackab8d7ee2010-09-20 02:46:42 -0700632 static StaticInstPtr dummyStatic(TheISA::NoopMachInst, 0);
633 static DynInstPtr dummyDyn = new Impl::DynInst(dummyStatic);
634 this->trap(interrupt, dummyDyn);
Korey Sewellbadb2382009-09-15 01:44:48 -0400635}
636
637
638void
639InOrderCPU::updateMemPorts()
640{
641 // Update all ThreadContext's memory ports (Functional/Virtual
642 // Ports)
643 ThreadID size = thread.size();
644 for (ThreadID i = 0; i < size; ++i)
645 thread[i]->connectMemPorts(thread[i]->getTC());
646}
647#endif
648
Korey Sewell973d8b82009-02-10 15:49:29 -0800649void
Gabe Black6833ca72010-09-13 19:26:03 -0700650InOrderCPU::trap(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
Korey Sewell973d8b82009-02-10 15:49:29 -0800651{
Korey Sewelldb2b7212009-05-12 15:01:16 -0400652 //@ Squash Pipeline during TRAP
Gabe Black6833ca72010-09-13 19:26:03 -0700653 scheduleCpuEvent(Trap, fault, tid, inst, delay);
Korey Sewell973d8b82009-02-10 15:49:29 -0800654}
655
656void
Gabe Black6833ca72010-09-13 19:26:03 -0700657InOrderCPU::trapCPU(Fault fault, ThreadID tid, DynInstPtr inst)
Korey Sewell973d8b82009-02-10 15:49:29 -0800658{
Gabe Black6833ca72010-09-13 19:26:03 -0700659 fault->invoke(tcBase(tid), inst->staticInst);
Korey Sewell973d8b82009-02-10 15:49:29 -0800660}
661
Korey Sewelleac5eac2010-01-31 18:26:13 -0500662void
663InOrderCPU::squashFromMemStall(DynInstPtr inst, ThreadID tid, int delay)
664{
665 scheduleCpuEvent(SquashFromMemStall, NoFault, tid, inst, delay);
666}
667
668
669void
Korey Sewellf95430d2010-06-24 15:34:12 -0400670InOrderCPU::squashDueToMemStall(int stage_num, InstSeqNum seq_num,
671 ThreadID tid)
Korey Sewelleac5eac2010-01-31 18:26:13 -0500672{
673 DPRINTF(InOrderCPU, "Squashing Pipeline Stages Due to Memory Stall...\n");
674
675 // Squash all instructions in each stage including
676 // instruction that caused the squash (seq_num - 1)
677 // NOTE: The stage bandwidth needs to be cleared so thats why
678 // the stalling instruction is squashed as well. The stalled
679 // instruction is previously placed in another intermediate buffer
680 // while it's stall is being handled.
681 InstSeqNum squash_seq_num = seq_num - 1;
682
683 for (int stNum=stage_num; stNum >= 0 ; stNum--) {
684 pipelineStage[stNum]->squashDueToMemStall(squash_seq_num, tid);
685 }
686}
687
Korey Sewell973d8b82009-02-10 15:49:29 -0800688void
689InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault,
Korey Sewelld8e09352010-01-31 18:26:03 -0500690 ThreadID tid, DynInstPtr inst,
Korey Sewell4a945aa2010-01-31 18:26:26 -0500691 unsigned delay, unsigned event_pri_offset)
Korey Sewell973d8b82009-02-10 15:49:29 -0800692{
Korey Sewell4a945aa2010-01-31 18:26:26 -0500693 CPUEvent *cpu_event = new CPUEvent(this, c_event, fault, tid, inst,
694 event_pri_offset);
Korey Sewell973d8b82009-02-10 15:49:29 -0800695
Steve Reinhardt6f118792011-01-07 21:50:29 -0800696 Tick sked_tick = nextCycle(curTick() + ticks(delay));
Korey Sewell973d8b82009-02-10 15:49:29 -0800697 if (delay >= 0) {
Korey Sewell4a945aa2010-01-31 18:26:26 -0500698 DPRINTF(InOrderCPU, "Scheduling CPU Event (%s) for cycle %i, [tid:%i].\n",
Steve Reinhardt6f118792011-01-07 21:50:29 -0800699 eventNames[c_event], curTick() + delay, tid);
Steve Reinhardt214cc0f2011-01-07 21:50:29 -0800700 schedule(cpu_event, sked_tick);
Korey Sewell973d8b82009-02-10 15:49:29 -0800701 } else {
702 cpu_event->process();
703 cpuEventRemoveList.push(cpu_event);
704 }
705
706 // Broadcast event to the Resource Pool
Korey Sewelle1fcc642010-01-31 18:26:32 -0500707 // Need to reset tid just in case this is a dummy instruction
708 inst->setTid(tid);
Korey Sewelld8e09352010-01-31 18:26:03 -0500709 resPool->scheduleEvent(c_event, inst, 0, 0, tid);
Korey Sewell973d8b82009-02-10 15:49:29 -0800710}
711
Korey Sewell96b493d2010-01-31 18:26:47 -0500712bool
Nathan Binkert47877cf2009-05-26 09:23:13 -0700713InOrderCPU::isThreadActive(ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -0800714{
Nathan Binkert47877cf2009-05-26 09:23:13 -0700715 list<ThreadID>::iterator isActive =
716 std::find(activeThreads.begin(), activeThreads.end(), tid);
Korey Sewell973d8b82009-02-10 15:49:29 -0800717
718 return (isActive != activeThreads.end());
719}
720
Korey Sewell96b493d2010-01-31 18:26:47 -0500721bool
722InOrderCPU::isThreadReady(ThreadID tid)
723{
724 list<ThreadID>::iterator isReady =
725 std::find(readyThreads.begin(), readyThreads.end(), tid);
726
727 return (isReady != readyThreads.end());
728}
729
730bool
731InOrderCPU::isThreadSuspended(ThreadID tid)
732{
733 list<ThreadID>::iterator isSuspended =
734 std::find(suspendedThreads.begin(), suspendedThreads.end(), tid);
735
736 return (isSuspended != suspendedThreads.end());
737}
Korey Sewell973d8b82009-02-10 15:49:29 -0800738
739void
Korey Sewelle1fcc642010-01-31 18:26:32 -0500740InOrderCPU::activateNextReadyThread()
741{
742 if (readyThreads.size() >= 1) {
743 ThreadID ready_tid = readyThreads.front();
744
745 // Activate in Pipeline
746 activateThread(ready_tid);
747
748 // Activate in Resource Pool
749 resPool->activateAll(ready_tid);
750
751 list<ThreadID>::iterator ready_it =
752 std::find(readyThreads.begin(), readyThreads.end(), ready_tid);
753 readyThreads.erase(ready_it);
754 } else {
755 DPRINTF(InOrderCPU,
Korey Sewell96b493d2010-01-31 18:26:47 -0500756 "Attempting to activate new thread, but No Ready Threads to"
757 "activate.\n");
Korey Sewell90d3b452010-01-31 18:27:38 -0500758 DPRINTF(InOrderCPU,
759 "Unable to switch to next active thread.\n");
Korey Sewelle1fcc642010-01-31 18:26:32 -0500760 }
761}
762
763void
Nathan Binkert47877cf2009-05-26 09:23:13 -0700764InOrderCPU::activateThread(ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -0800765{
Korey Sewell96b493d2010-01-31 18:26:47 -0500766 if (isThreadSuspended(tid)) {
767 DPRINTF(InOrderCPU,
768 "Removing [tid:%i] from suspended threads list.\n", tid);
769
770 list<ThreadID>::iterator susp_it =
771 std::find(suspendedThreads.begin(), suspendedThreads.end(),
772 tid);
773 suspendedThreads.erase(susp_it);
774 }
775
Korey Sewelle1fcc642010-01-31 18:26:32 -0500776 if (threadModel == SwitchOnCacheMiss &&
777 numActiveThreads() == 1) {
778 DPRINTF(InOrderCPU,
Korey Sewell96b493d2010-01-31 18:26:47 -0500779 "Ignoring activation of [tid:%i], since [tid:%i] is "
780 "already running.\n", tid, activeThreadId());
781
Korey Sewell90d3b452010-01-31 18:27:38 -0500782 DPRINTF(InOrderCPU,"Placing [tid:%i] on ready threads list\n",
Korey Sewell96b493d2010-01-31 18:26:47 -0500783 tid);
Korey Sewelle1fcc642010-01-31 18:26:32 -0500784
785 readyThreads.push_back(tid);
786
Korey Sewell96b493d2010-01-31 18:26:47 -0500787 } else if (!isThreadActive(tid)) {
Nathan Binkert47877cf2009-05-26 09:23:13 -0700788 DPRINTF(InOrderCPU,
Korey Sewell96b493d2010-01-31 18:26:47 -0500789 "Adding [tid:%i] to active threads list.\n", tid);
Korey Sewell973d8b82009-02-10 15:49:29 -0800790 activeThreads.push_back(tid);
Korey Sewell96b493d2010-01-31 18:26:47 -0500791
Korey Sewell90d3b452010-01-31 18:27:38 -0500792 activateThreadInPipeline(tid);
Korey Sewell069b38c2010-01-31 18:27:58 -0500793
Steve Reinhardt6f118792011-01-07 21:50:29 -0800794 thread[tid]->lastActivate = curTick();
Korey Sewell069b38c2010-01-31 18:27:58 -0500795
Korey Sewellb4e0ef72010-01-31 18:28:12 -0500796 tcBase(tid)->setStatus(ThreadContext::Active);
797
Korey Sewell973d8b82009-02-10 15:49:29 -0800798 wakeCPU();
Korey Sewell0b29c2d2010-01-31 18:28:59 -0500799
800 numCtxtSwitches++;
Korey Sewell973d8b82009-02-10 15:49:29 -0800801 }
802}
803
804void
Korey Sewell90d3b452010-01-31 18:27:38 -0500805InOrderCPU::activateThreadInPipeline(ThreadID tid)
806{
807 for (int stNum=0; stNum < NumStages; stNum++) {
808 pipelineStage[stNum]->activateThread(tid);
809 }
810}
811
812void
Korey Sewelld9eaa2f2010-01-31 18:26:40 -0500813InOrderCPU::deactivateContext(ThreadID tid, int delay)
814{
815 DPRINTF(InOrderCPU,"[tid:%i]: Deactivating ...\n", tid);
816
Korey Sewell1a89e8f2010-01-31 18:29:59 -0500817 scheduleCpuEvent(DeactivateThread, NoFault, tid, dummyInst[tid], delay);
Korey Sewelld9eaa2f2010-01-31 18:26:40 -0500818
819 // Be sure to signal that there's some activity so the CPU doesn't
820 // deschedule itself.
821 activityRec.activity();
822
823 _status = Running;
824}
825
826void
Nathan Binkert47877cf2009-05-26 09:23:13 -0700827InOrderCPU::deactivateThread(ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -0800828{
829 DPRINTF(InOrderCPU, "[tid:%i]: Calling deactivate thread.\n", tid);
830
831 if (isThreadActive(tid)) {
832 DPRINTF(InOrderCPU,"[tid:%i]: Removing from active threads list\n",
833 tid);
Nathan Binkert47877cf2009-05-26 09:23:13 -0700834 list<ThreadID>::iterator thread_it =
835 std::find(activeThreads.begin(), activeThreads.end(), tid);
Korey Sewell973d8b82009-02-10 15:49:29 -0800836
837 removePipelineStalls(*thread_it);
838
Korey Sewell973d8b82009-02-10 15:49:29 -0800839 activeThreads.erase(thread_it);
Korey Sewellb4e0ef72010-01-31 18:28:12 -0500840
841 // Ideally, this should be triggered from the
842 // suspendContext/Thread functions
843 tcBase(tid)->setStatus(ThreadContext::Suspended);
Korey Sewell973d8b82009-02-10 15:49:29 -0800844 }
Korey Sewell96b493d2010-01-31 18:26:47 -0500845
846 assert(!isThreadActive(tid));
Korey Sewell973d8b82009-02-10 15:49:29 -0800847}
848
849void
Nathan Binkert47877cf2009-05-26 09:23:13 -0700850InOrderCPU::removePipelineStalls(ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -0800851{
852 DPRINTF(InOrderCPU,"[tid:%i]: Removing all pipeline stalls\n",
853 tid);
854
855 for (int stNum = 0; stNum < NumStages ; stNum++) {
856 pipelineStage[stNum]->removeStalls(tid);
857 }
858
859}
Korey Sewell973d8b82009-02-10 15:49:29 -0800860
Korey Sewell973d8b82009-02-10 15:49:29 -0800861void
Korey Sewell973d8b82009-02-10 15:49:29 -0800862InOrderCPU::updateThreadPriority()
863{
864 if (activeThreads.size() > 1)
865 {
866 //DEFAULT TO ROUND ROBIN SCHEME
867 //e.g. Move highest priority to end of thread list
Nathan Binkert47877cf2009-05-26 09:23:13 -0700868 list<ThreadID>::iterator list_begin = activeThreads.begin();
869 list<ThreadID>::iterator list_end = activeThreads.end();
Korey Sewell973d8b82009-02-10 15:49:29 -0800870
871 unsigned high_thread = *list_begin;
872
873 activeThreads.erase(list_begin);
874
875 activeThreads.push_back(high_thread);
876 }
877}
878
879inline void
880InOrderCPU::tickThreadStats()
881{
882 /** Keep track of cycles that each thread is active */
Nathan Binkert47877cf2009-05-26 09:23:13 -0700883 list<ThreadID>::iterator thread_it = activeThreads.begin();
Korey Sewell973d8b82009-02-10 15:49:29 -0800884 while (thread_it != activeThreads.end()) {
885 threadCycles[*thread_it]++;
886 thread_it++;
887 }
888
889 // Keep track of cycles where SMT is active
890 if (activeThreads.size() > 1) {
891 smtCycles++;
892 }
893}
894
895void
Nathan Binkert47877cf2009-05-26 09:23:13 -0700896InOrderCPU::activateContext(ThreadID tid, int delay)
Korey Sewell973d8b82009-02-10 15:49:29 -0800897{
898 DPRINTF(InOrderCPU,"[tid:%i]: Activating ...\n", tid);
899
Korey Sewell1a89e8f2010-01-31 18:29:59 -0500900
901 scheduleCpuEvent(ActivateThread, NoFault, tid, dummyInst[tid], delay);
Korey Sewell973d8b82009-02-10 15:49:29 -0800902
903 // Be sure to signal that there's some activity so the CPU doesn't
904 // deschedule itself.
905 activityRec.activity();
906
907 _status = Running;
908}
909
Korey Sewelle1fcc642010-01-31 18:26:32 -0500910void
911InOrderCPU::activateNextReadyContext(int delay)
912{
913 DPRINTF(InOrderCPU,"Activating next ready thread\n");
914
915 // NOTE: Add 5 to the event priority so that we always activate
916 // threads after we've finished deactivating, squashing,etc.
917 // other threads
Korey Sewell1a89e8f2010-01-31 18:29:59 -0500918 scheduleCpuEvent(ActivateNextReadyThread, NoFault, 0/*tid*/, dummyInst[0],
Korey Sewelle1fcc642010-01-31 18:26:32 -0500919 delay, 5);
920
921 // Be sure to signal that there's some activity so the CPU doesn't
922 // deschedule itself.
923 activityRec.activity();
924
925 _status = Running;
926}
Korey Sewell973d8b82009-02-10 15:49:29 -0800927
928void
Korey Sewelld9eaa2f2010-01-31 18:26:40 -0500929InOrderCPU::haltContext(ThreadID tid, int delay)
930{
Korey Sewell5e0b8332010-01-31 18:28:05 -0500931 DPRINTF(InOrderCPU, "[tid:%i]: Calling Halt Context...\n", tid);
932
Korey Sewell1a89e8f2010-01-31 18:29:59 -0500933 scheduleCpuEvent(HaltThread, NoFault, tid, dummyInst[tid], delay);
Korey Sewell5e0b8332010-01-31 18:28:05 -0500934
935 activityRec.activity();
936}
937
938void
939InOrderCPU::haltThread(ThreadID tid)
940{
941 DPRINTF(InOrderCPU, "[tid:%i]: Placing on Halted Threads List...\n", tid);
942 deactivateThread(tid);
943 squashThreadInPipeline(tid);
944 haltedThreads.push_back(tid);
945
Korey Sewellb4e0ef72010-01-31 18:28:12 -0500946 tcBase(tid)->setStatus(ThreadContext::Halted);
947
Korey Sewell5e0b8332010-01-31 18:28:05 -0500948 if (threadModel == SwitchOnCacheMiss) {
949 activateNextReadyContext();
950 }
Korey Sewelld9eaa2f2010-01-31 18:26:40 -0500951}
952
953void
Nathan Binkert47877cf2009-05-26 09:23:13 -0700954InOrderCPU::suspendContext(ThreadID tid, int delay)
Korey Sewell973d8b82009-02-10 15:49:29 -0800955{
Korey Sewell1a89e8f2010-01-31 18:29:59 -0500956 scheduleCpuEvent(SuspendThread, NoFault, tid, dummyInst[tid], delay);
Korey Sewell973d8b82009-02-10 15:49:29 -0800957}
958
959void
Nathan Binkert47877cf2009-05-26 09:23:13 -0700960InOrderCPU::suspendThread(ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -0800961{
Korey Sewellf95430d2010-06-24 15:34:12 -0400962 DPRINTF(InOrderCPU, "[tid:%i]: Placing on Suspended Threads List...\n",
963 tid);
Korey Sewell973d8b82009-02-10 15:49:29 -0800964 deactivateThread(tid);
Korey Sewelle1fcc642010-01-31 18:26:32 -0500965 suspendedThreads.push_back(tid);
Steve Reinhardt6f118792011-01-07 21:50:29 -0800966 thread[tid]->lastSuspend = curTick();
Korey Sewellb4e0ef72010-01-31 18:28:12 -0500967
968 tcBase(tid)->setStatus(ThreadContext::Suspended);
Korey Sewell973d8b82009-02-10 15:49:29 -0800969}
970
971void
Nathan Binkert47877cf2009-05-26 09:23:13 -0700972InOrderCPU::squashThreadInPipeline(ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -0800973{
974 //Squash all instructions in each stage
975 for (int stNum=NumStages - 1; stNum >= 0 ; stNum--) {
976 pipelineStage[stNum]->squash(0 /*seq_num*/, tid);
977 }
978}
979
Korey Sewell1c8dfd92009-05-12 15:01:13 -0400980PipelineStage*
981InOrderCPU::getPipeStage(int stage_num)
982{
983 return pipelineStage[stage_num];
984}
985
Korey Sewell973d8b82009-02-10 15:49:29 -0800986uint64_t
Nathan Binkert47877cf2009-05-26 09:23:13 -0700987InOrderCPU::readIntReg(int reg_idx, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -0800988{
Gabe Blacka480ba02009-07-08 23:02:20 -0700989 return intRegs[tid][reg_idx];
Korey Sewell973d8b82009-02-10 15:49:29 -0800990}
991
992FloatReg
Gabe Black25884a82009-07-08 23:02:20 -0700993InOrderCPU::readFloatReg(int reg_idx, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -0800994{
Gabe Black0cb180e2009-07-08 23:02:20 -0700995 return floatRegs.f[tid][reg_idx];
Korey Sewell973d8b82009-02-10 15:49:29 -0800996}
997
998FloatRegBits
Gabe Black25884a82009-07-08 23:02:20 -0700999InOrderCPU::readFloatRegBits(int reg_idx, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001000{;
Gabe Black0cb180e2009-07-08 23:02:20 -07001001 return floatRegs.i[tid][reg_idx];
Korey Sewell973d8b82009-02-10 15:49:29 -08001002}
1003
1004void
Nathan Binkert47877cf2009-05-26 09:23:13 -07001005InOrderCPU::setIntReg(int reg_idx, uint64_t val, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001006{
Gabe Blacka480ba02009-07-08 23:02:20 -07001007 intRegs[tid][reg_idx] = val;
Korey Sewell973d8b82009-02-10 15:49:29 -08001008}
1009
1010
1011void
Gabe Black25884a82009-07-08 23:02:20 -07001012InOrderCPU::setFloatReg(int reg_idx, FloatReg val, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001013{
Gabe Black0cb180e2009-07-08 23:02:20 -07001014 floatRegs.f[tid][reg_idx] = val;
Korey Sewell973d8b82009-02-10 15:49:29 -08001015}
1016
1017
1018void
Gabe Black25884a82009-07-08 23:02:20 -07001019InOrderCPU::setFloatRegBits(int reg_idx, FloatRegBits val, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001020{
Gabe Black0cb180e2009-07-08 23:02:20 -07001021 floatRegs.i[tid][reg_idx] = val;
Korey Sewell973d8b82009-02-10 15:49:29 -08001022}
1023
1024uint64_t
Nathan Binkert47877cf2009-05-26 09:23:13 -07001025InOrderCPU::readRegOtherThread(unsigned reg_idx, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001026{
1027 // If Default value is set, then retrieve target thread
Nathan Binkert47877cf2009-05-26 09:23:13 -07001028 if (tid == InvalidThreadID) {
Korey Sewell973d8b82009-02-10 15:49:29 -08001029 tid = TheISA::getTargetThread(tcBase(tid));
1030 }
1031
Korey Sewell7b3b3622010-01-31 17:18:15 -05001032 if (reg_idx < FP_Base_DepTag) {
1033 // Integer Register File
Korey Sewell973d8b82009-02-10 15:49:29 -08001034 return readIntReg(reg_idx, tid);
Korey Sewell7b3b3622010-01-31 17:18:15 -05001035 } else if (reg_idx < Ctrl_Base_DepTag) {
1036 // Float Register File
Korey Sewell973d8b82009-02-10 15:49:29 -08001037 reg_idx -= FP_Base_DepTag;
1038 return readFloatRegBits(reg_idx, tid);
1039 } else {
1040 reg_idx -= Ctrl_Base_DepTag;
1041 return readMiscReg(reg_idx, tid); // Misc. Register File
1042 }
1043}
1044void
Nathan Binkert47877cf2009-05-26 09:23:13 -07001045InOrderCPU::setRegOtherThread(unsigned reg_idx, const MiscReg &val,
1046 ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001047{
1048 // If Default value is set, then retrieve target thread
Nathan Binkert47877cf2009-05-26 09:23:13 -07001049 if (tid == InvalidThreadID) {
Korey Sewell973d8b82009-02-10 15:49:29 -08001050 tid = TheISA::getTargetThread(tcBase(tid));
1051 }
1052
1053 if (reg_idx < FP_Base_DepTag) { // Integer Register File
1054 setIntReg(reg_idx, val, tid);
1055 } else if (reg_idx < Ctrl_Base_DepTag) { // Float Register File
1056 reg_idx -= FP_Base_DepTag;
1057 setFloatRegBits(reg_idx, val, tid);
1058 } else {
1059 reg_idx -= Ctrl_Base_DepTag;
1060 setMiscReg(reg_idx, val, tid); // Misc. Register File
1061 }
1062}
1063
1064MiscReg
Nathan Binkert47877cf2009-05-26 09:23:13 -07001065InOrderCPU::readMiscRegNoEffect(int misc_reg, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001066{
Gabe Black32daf6f2009-07-08 23:02:20 -07001067 return isa[tid].readMiscRegNoEffect(misc_reg);
Korey Sewell973d8b82009-02-10 15:49:29 -08001068}
1069
1070MiscReg
Nathan Binkert47877cf2009-05-26 09:23:13 -07001071InOrderCPU::readMiscReg(int misc_reg, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001072{
Gabe Black32daf6f2009-07-08 23:02:20 -07001073 return isa[tid].readMiscReg(misc_reg, tcBase(tid));
Korey Sewell973d8b82009-02-10 15:49:29 -08001074}
1075
1076void
Nathan Binkert47877cf2009-05-26 09:23:13 -07001077InOrderCPU::setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001078{
Gabe Black32daf6f2009-07-08 23:02:20 -07001079 isa[tid].setMiscRegNoEffect(misc_reg, val);
Korey Sewell973d8b82009-02-10 15:49:29 -08001080}
1081
1082void
Nathan Binkert47877cf2009-05-26 09:23:13 -07001083InOrderCPU::setMiscReg(int misc_reg, const MiscReg &val, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001084{
Gabe Black32daf6f2009-07-08 23:02:20 -07001085 isa[tid].setMiscReg(misc_reg, val, tcBase(tid));
Korey Sewell973d8b82009-02-10 15:49:29 -08001086}
1087
1088
1089InOrderCPU::ListIt
1090InOrderCPU::addInst(DynInstPtr &inst)
1091{
Nathan Binkert47877cf2009-05-26 09:23:13 -07001092 ThreadID tid = inst->readTid();
Korey Sewell973d8b82009-02-10 15:49:29 -08001093
1094 instList[tid].push_back(inst);
1095
1096 return --(instList[tid].end());
1097}
1098
Korey Sewell0b29c2d2010-01-31 18:28:59 -05001099void
1100InOrderCPU::updateContextSwitchStats()
1101{
1102 // Set Average Stat Here, then reset to 0
1103 instsPerCtxtSwitch = instsPerSwitch;
1104 instsPerSwitch = 0;
1105}
1106
1107
Korey Sewell973d8b82009-02-10 15:49:29 -08001108void
Nathan Binkert47877cf2009-05-26 09:23:13 -07001109InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001110{
Korey Sewell7b3b3622010-01-31 17:18:15 -05001111 // Set the CPU's PCs - This contributes to the precise state of the CPU
Korey Sewell069b38c2010-01-31 18:27:58 -05001112 // which can be used when restoring a thread to the CPU after after any
1113 // type of context switching activity (fork, exception, etc.)
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001114 pcState(inst->pcState(), tid);
Korey Sewell973d8b82009-02-10 15:49:29 -08001115
Korey Sewell069b38c2010-01-31 18:27:58 -05001116 if (inst->isControl()) {
1117 thread[tid]->lastGradIsBranch = true;
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001118 thread[tid]->lastBranchPC = inst->pcState();
1119 TheISA::advancePC(thread[tid]->lastBranchPC, inst->staticInst);
Korey Sewell069b38c2010-01-31 18:27:58 -05001120 } else {
1121 thread[tid]->lastGradIsBranch = false;
1122 }
1123
1124
Korey Sewell973d8b82009-02-10 15:49:29 -08001125 // Finalize Trace Data For Instruction
1126 if (inst->traceData) {
Steve Reinhardt6f118792011-01-07 21:50:29 -08001127 //inst->traceData->setCycle(curTick());
Korey Sewell973d8b82009-02-10 15:49:29 -08001128 inst->traceData->setFetchSeq(inst->seqNum);
1129 //inst->traceData->setCPSeq(cpu->tcBase(tid)->numInst);
1130 inst->traceData->dump();
1131 delete inst->traceData;
1132 inst->traceData = NULL;
1133 }
1134
Korey Sewell0b29c2d2010-01-31 18:28:59 -05001135 // Increment active thread's instruction count
1136 instsPerSwitch++;
1137
Korey Sewell973d8b82009-02-10 15:49:29 -08001138 // Increment thread-state's instruction count
1139 thread[tid]->numInst++;
1140
1141 // Increment thread-state's instruction stats
1142 thread[tid]->numInsts++;
1143
1144 // Count committed insts per thread stats
1145 committedInsts[tid]++;
1146
1147 // Count total insts committed stat
1148 totalCommittedInsts++;
1149
1150 // Count SMT-committed insts per thread stat
1151 if (numActiveThreads() > 1) {
1152 smtCommittedInsts[tid]++;
1153 }
1154
Korey Sewell9f0d8f22010-06-23 18:18:20 -04001155 // Instruction-Mix Stats
1156 if (inst->isLoad()) {
1157 comLoads++;
1158 } else if (inst->isStore()) {
1159 comStores++;
1160 } else if (inst->isControl()) {
1161 comBranches++;
1162 } else if (inst->isNop()) {
1163 comNops++;
1164 } else if (inst->isNonSpeculative()) {
1165 comNonSpec++;
1166 } else if (inst->isInteger()) {
1167 comInts++;
1168 } else if (inst->isFloating()) {
1169 comFloats++;
1170 }
1171
Korey Sewell973d8b82009-02-10 15:49:29 -08001172 // Check for instruction-count-based events.
1173 comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
1174
1175 // Broadcast to other resources an instruction
1176 // has been completed
Korey Sewell7b3b3622010-01-31 17:18:15 -05001177 resPool->scheduleEvent((CPUEventType)ResourcePool::InstGraduated, inst,
Korey Sewell069b38c2010-01-31 18:27:58 -05001178 0, 0, tid);
Korey Sewell973d8b82009-02-10 15:49:29 -08001179
1180 // Finally, remove instruction from CPU
1181 removeInst(inst);
1182}
1183
Korey Sewell9357e352010-01-31 18:30:48 -05001184// currently unused function, but substitute repetitive code w/this function
1185// call
Korey Sewell973d8b82009-02-10 15:49:29 -08001186void
1187InOrderCPU::addToRemoveList(DynInstPtr &inst)
1188{
1189 removeInstsThisCycle = true;
Korey Sewellc7f6e262010-01-31 18:30:59 -05001190 if (!inst->isRemoveList()) {
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001191 DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %s "
Korey Sewellc7f6e262010-01-31 18:30:59 -05001192 "[sn:%lli] to remove list\n",
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001193 inst->threadNumber, inst->pcState(), inst->seqNum);
Korey Sewellc7f6e262010-01-31 18:30:59 -05001194 inst->setRemoveList();
1195 removeList.push(inst->getInstListIt());
1196 } else {
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001197 DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i] PC %s "
Korey Sewellc7f6e262010-01-31 18:30:59 -05001198 "[sn:%lli], already remove list\n",
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001199 inst->threadNumber, inst->pcState(), inst->seqNum);
Korey Sewellc7f6e262010-01-31 18:30:59 -05001200 }
1201
Korey Sewell973d8b82009-02-10 15:49:29 -08001202}
1203
1204void
1205InOrderCPU::removeInst(DynInstPtr &inst)
1206{
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001207 DPRINTF(InOrderCPU, "Removing graduated instruction [tid:%i] PC %s "
Korey Sewell973d8b82009-02-10 15:49:29 -08001208 "[sn:%lli]\n",
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001209 inst->threadNumber, inst->pcState(), inst->seqNum);
Korey Sewell973d8b82009-02-10 15:49:29 -08001210
1211 removeInstsThisCycle = true;
1212
1213 // Remove the instruction.
Korey Sewellc7f6e262010-01-31 18:30:59 -05001214 if (!inst->isRemoveList()) {
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001215 DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %s "
Korey Sewellc7f6e262010-01-31 18:30:59 -05001216 "[sn:%lli] to remove list\n",
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001217 inst->threadNumber, inst->pcState(), inst->seqNum);
Korey Sewellc7f6e262010-01-31 18:30:59 -05001218 inst->setRemoveList();
1219 removeList.push(inst->getInstListIt());
1220 } else {
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001221 DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i] PC %s "
Korey Sewellc7f6e262010-01-31 18:30:59 -05001222 "[sn:%lli], already on remove list\n",
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001223 inst->threadNumber, inst->pcState(), inst->seqNum);
Korey Sewellc7f6e262010-01-31 18:30:59 -05001224 }
Korey Sewell9357e352010-01-31 18:30:48 -05001225
Korey Sewell973d8b82009-02-10 15:49:29 -08001226}
1227
1228void
Nathan Binkert47877cf2009-05-26 09:23:13 -07001229InOrderCPU::removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001230{
1231 //assert(!instList[tid].empty());
1232
1233 removeInstsThisCycle = true;
1234
1235 ListIt inst_iter = instList[tid].end();
1236
1237 inst_iter--;
1238
Korey Sewell9357e352010-01-31 18:30:48 -05001239 DPRINTF(InOrderCPU, "Squashing instructions from CPU instruction "
Korey Sewell973d8b82009-02-10 15:49:29 -08001240 "list that are from [tid:%i] and above [sn:%lli] (end=%lli).\n",
1241 tid, seq_num, (*inst_iter)->seqNum);
1242
1243 while ((*inst_iter)->seqNum > seq_num) {
1244
1245 bool break_loop = (inst_iter == instList[tid].begin());
1246
1247 squashInstIt(inst_iter, tid);
1248
1249 inst_iter--;
1250
1251 if (break_loop)
1252 break;
1253 }
1254}
1255
1256
1257inline void
Nathan Binkert47877cf2009-05-26 09:23:13 -07001258InOrderCPU::squashInstIt(const ListIt &instIt, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001259{
1260 if ((*instIt)->threadNumber == tid) {
1261 DPRINTF(InOrderCPU, "Squashing instruction, "
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001262 "[tid:%i] [sn:%lli] PC %s\n",
Korey Sewell973d8b82009-02-10 15:49:29 -08001263 (*instIt)->threadNumber,
1264 (*instIt)->seqNum,
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001265 (*instIt)->pcState());
Korey Sewell973d8b82009-02-10 15:49:29 -08001266
1267 (*instIt)->setSquashed();
1268
Korey Sewellc7f6e262010-01-31 18:30:59 -05001269 if (!(*instIt)->isRemoveList()) {
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001270 DPRINTF(InOrderCPU, "Pushing instruction [tid:%i] PC %s "
Korey Sewellc7f6e262010-01-31 18:30:59 -05001271 "[sn:%lli] to remove list\n",
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001272 (*instIt)->threadNumber, (*instIt)->pcState(),
Korey Sewellc7f6e262010-01-31 18:30:59 -05001273 (*instIt)->seqNum);
1274 (*instIt)->setRemoveList();
1275 removeList.push(instIt);
1276 } else {
Korey Sewellf95430d2010-06-24 15:34:12 -04001277 DPRINTF(InOrderCPU, "Ignoring instruction removal for [tid:%i]"
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001278 " PC %s [sn:%lli], already on remove list\n",
1279 (*instIt)->threadNumber, (*instIt)->pcState(),
Korey Sewellc7f6e262010-01-31 18:30:59 -05001280 (*instIt)->seqNum);
1281 }
1282
Korey Sewell973d8b82009-02-10 15:49:29 -08001283 }
Korey Sewellc7f6e262010-01-31 18:30:59 -05001284
Korey Sewell973d8b82009-02-10 15:49:29 -08001285}
1286
1287
1288void
1289InOrderCPU::cleanUpRemovedInsts()
1290{
1291 while (!removeList.empty()) {
1292 DPRINTF(InOrderCPU, "Removing instruction, "
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001293 "[tid:%i] [sn:%lli] PC %s\n",
Korey Sewell973d8b82009-02-10 15:49:29 -08001294 (*removeList.front())->threadNumber,
1295 (*removeList.front())->seqNum,
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001296 (*removeList.front())->pcState());
Korey Sewell973d8b82009-02-10 15:49:29 -08001297
1298 DynInstPtr inst = *removeList.front();
Nathan Binkert47877cf2009-05-26 09:23:13 -07001299 ThreadID tid = inst->threadNumber;
Korey Sewell973d8b82009-02-10 15:49:29 -08001300
1301 // Make Sure Resource Schedule Is Emptied Out
1302 ThePipeline::ResSchedule *inst_sched = &inst->resSched;
1303 while (!inst_sched->empty()) {
Korey Sewell6bfd7662010-06-25 17:42:34 -04001304 ScheduleEntry* sch_entry = inst_sched->top();
Korey Sewell973d8b82009-02-10 15:49:29 -08001305 inst_sched->pop();
1306 delete sch_entry;
1307 }
1308
1309 // Remove From Register Dependency Map, If Necessary
1310 archRegDepMap[(*removeList.front())->threadNumber].
1311 remove((*removeList.front()));
1312
1313
1314 // Clear if Non-Speculative
1315 if (inst->staticInst &&
1316 inst->seqNum == nonSpecSeqNum[tid] &&
1317 nonSpecInstActive[tid] == true) {
1318 nonSpecInstActive[tid] = false;
1319 }
1320
1321 instList[tid].erase(removeList.front());
1322
1323 removeList.pop();
Korey Sewell973d8b82009-02-10 15:49:29 -08001324 }
1325
1326 removeInstsThisCycle = false;
1327}
1328
1329void
1330InOrderCPU::cleanUpRemovedReqs()
1331{
1332 while (!reqRemoveList.empty()) {
1333 ResourceRequest *res_req = reqRemoveList.front();
1334
Korey Sewell7695d4c2010-06-23 18:14:59 -04001335 DPRINTF(RefCount, "[tid:%i] [sn:%lli]: Removing Request "
Korey Sewell9357e352010-01-31 18:30:48 -05001336 "[stage_num:%i] [res:%s] [slot:%i] [completed:%i].\n",
Korey Sewell973d8b82009-02-10 15:49:29 -08001337 res_req->inst->threadNumber,
1338 res_req->inst->seqNum,
Korey Sewell973d8b82009-02-10 15:49:29 -08001339 res_req->getStageNum(),
1340 res_req->res->name(),
Korey Sewellf95430d2010-06-24 15:34:12 -04001341 (res_req->isCompleted()) ?
1342 res_req->getComplSlot() : res_req->getSlot(),
Korey Sewell9357e352010-01-31 18:30:48 -05001343 res_req->isCompleted());
Korey Sewell973d8b82009-02-10 15:49:29 -08001344
1345 reqRemoveList.pop();
1346
1347 delete res_req;
Korey Sewell973d8b82009-02-10 15:49:29 -08001348 }
1349}
1350
1351void
1352InOrderCPU::cleanUpRemovedEvents()
1353{
1354 while (!cpuEventRemoveList.empty()) {
1355 Event *cpu_event = cpuEventRemoveList.front();
1356 cpuEventRemoveList.pop();
1357 delete cpu_event;
1358 }
1359}
1360
Korey Sewell973d8b82009-02-10 15:49:29 -08001361
1362void
1363InOrderCPU::dumpInsts()
1364{
1365 int num = 0;
1366
1367 ListIt inst_list_it = instList[0].begin();
1368
1369 cprintf("Dumping Instruction List\n");
1370
1371 while (inst_list_it != instList[0].end()) {
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001372 cprintf("Instruction:%i\nPC:%s\n[tid:%i]\n[sn:%lli]\nIssued:%i\n"
Korey Sewell973d8b82009-02-10 15:49:29 -08001373 "Squashed:%i\n\n",
Gabe Black6f4bd2c2010-10-31 00:07:20 -07001374 num, (*inst_list_it)->pcState(),
1375 (*inst_list_it)->threadNumber,
Korey Sewell973d8b82009-02-10 15:49:29 -08001376 (*inst_list_it)->seqNum, (*inst_list_it)->isIssued(),
1377 (*inst_list_it)->isSquashed());
1378 inst_list_it++;
1379 ++num;
1380 }
1381}
Korey Sewell973d8b82009-02-10 15:49:29 -08001382
1383void
1384InOrderCPU::wakeCPU()
1385{
1386 if (/*activityRec.active() || */tickEvent.scheduled()) {
1387 DPRINTF(Activity, "CPU already running.\n");
1388 return;
1389 }
1390
1391 DPRINTF(Activity, "Waking up CPU\n");
1392
Steve Reinhardt6f118792011-01-07 21:50:29 -08001393 Tick extra_cycles = tickToCycles((curTick() - 1) - lastRunningCycle);
Korey Sewellffa9ecb2010-01-31 18:28:51 -05001394
1395 idleCycles += extra_cycles;
1396 for (int stage_num = 0; stage_num < NumStages; stage_num++) {
1397 pipelineStage[stage_num]->idleCycles += extra_cycles;
1398 }
1399
1400 numCycles += extra_cycles;
Korey Sewell973d8b82009-02-10 15:49:29 -08001401
Steve Reinhardt6f118792011-01-07 21:50:29 -08001402 schedule(&tickEvent, nextCycle(curTick()));
Korey Sewell973d8b82009-02-10 15:49:29 -08001403}
1404
Korey Sewellbadb2382009-09-15 01:44:48 -04001405#if FULL_SYSTEM
1406
1407void
1408InOrderCPU::wakeup()
1409{
1410 if (this->thread[0]->status() != ThreadContext::Suspended)
1411 return;
1412
1413 this->wakeCPU();
1414
1415 DPRINTF(Quiesce, "Suspended Processor woken\n");
1416 this->threadContexts[0]->activate();
1417}
1418#endif
1419
1420#if !FULL_SYSTEM
Korey Sewell973d8b82009-02-10 15:49:29 -08001421void
Nathan Binkert47877cf2009-05-26 09:23:13 -07001422InOrderCPU::syscall(int64_t callnum, ThreadID tid)
Korey Sewell973d8b82009-02-10 15:49:29 -08001423{
1424 DPRINTF(InOrderCPU, "[tid:%i] Executing syscall().\n\n", tid);
1425
1426 DPRINTF(Activity,"Activity: syscall() called.\n");
1427
1428 // Temporarily increase this by one to account for the syscall
1429 // instruction.
1430 ++(this->thread[tid]->funcExeInst);
1431
1432 // Execute the actual syscall.
1433 this->thread[tid]->syscall(callnum);
1434
1435 // Decrease funcExeInst by one as the normal commit will handle
1436 // incrementing it.
1437 --(this->thread[tid]->funcExeInst);
1438
1439 // Clear Non-Speculative Block Variable
1440 nonSpecInstActive[tid] = false;
1441}
Korey Sewellbadb2382009-09-15 01:44:48 -04001442#endif
Korey Sewell973d8b82009-02-10 15:49:29 -08001443
Korey Sewell5127ea22009-05-12 15:01:14 -04001444TheISA::TLB*
Korey Sewell1c8dfd92009-05-12 15:01:13 -04001445InOrderCPU::getITBPtr()
1446{
Korey Sewelldb2b7212009-05-12 15:01:16 -04001447 CacheUnit *itb_res =
1448 dynamic_cast<CacheUnit*>(resPool->getResource(fetchPortIdx));
Korey Sewell5127ea22009-05-12 15:01:14 -04001449 return itb_res->tlb();
Korey Sewell1c8dfd92009-05-12 15:01:13 -04001450}
1451
1452
Korey Sewell5127ea22009-05-12 15:01:14 -04001453TheISA::TLB*
Korey Sewell1c8dfd92009-05-12 15:01:13 -04001454InOrderCPU::getDTBPtr()
1455{
Korey Sewelldb2b7212009-05-12 15:01:16 -04001456 CacheUnit *dtb_res =
1457 dynamic_cast<CacheUnit*>(resPool->getResource(dataPortIdx));
Korey Sewell5127ea22009-05-12 15:01:14 -04001458 return dtb_res->tlb();
Korey Sewell1c8dfd92009-05-12 15:01:13 -04001459}
Korey Sewelldb2b7212009-05-12 15:01:16 -04001460
Korey Sewelldb2b7212009-05-12 15:01:16 -04001461Fault
Gabe Blackaa8c6e92010-08-13 06:16:02 -07001462InOrderCPU::read(DynInstPtr inst, Addr addr,
1463 uint8_t *data, unsigned size, unsigned flags)
Korey Sewelldb2b7212009-05-12 15:01:16 -04001464{
1465 //@TODO: Generalize name "CacheUnit" to "MemUnit" just in case
1466 // you want to run w/out caches?
Korey Sewell7b3b3622010-01-31 17:18:15 -05001467 CacheUnit *cache_res =
1468 dynamic_cast<CacheUnit*>(resPool->getResource(dataPortIdx));
Korey Sewelldb2b7212009-05-12 15:01:16 -04001469
Gabe Blackaa8c6e92010-08-13 06:16:02 -07001470 return cache_res->read(inst, addr, data, size, flags);
Korey Sewelldb2b7212009-05-12 15:01:16 -04001471}
1472
Korey Sewelldb2b7212009-05-12 15:01:16 -04001473Fault
Gabe Blackaa8c6e92010-08-13 06:16:02 -07001474InOrderCPU::write(DynInstPtr inst, uint8_t *data, unsigned size,
1475 Addr addr, unsigned flags, uint64_t *write_res)
Korey Sewelldb2b7212009-05-12 15:01:16 -04001476{
1477 //@TODO: Generalize name "CacheUnit" to "MemUnit" just in case
1478 // you want to run w/out caches?
1479 CacheUnit *cache_res =
1480 dynamic_cast<CacheUnit*>(resPool->getResource(dataPortIdx));
Gabe Blackaa8c6e92010-08-13 06:16:02 -07001481 return cache_res->write(inst, data, size, addr, flags, write_res);
Korey Sewelldb2b7212009-05-12 15:01:16 -04001482}