Deleted Added
sdiff udiff text old ( 2665:a124942bacb8 ) new ( 2669:f2b336e89d2a )
full compact
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
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

--- 8 unchanged lines hidden (view full) ---

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: Kevin Lim
29 */
30
31#include "config/full_system.hh"
32
33#if FULL_SYSTEM
34#include "sim/system.hh"
35#else
36#include "sim/process.hh"
37#endif
38#include "sim/root.hh"
39
40#include "cpu/cpu_exec_context.hh"
41#include "cpu/exec_context.hh"
42#include "cpu/o3/alpha_dyn_inst.hh"
43#include "cpu/o3/alpha_impl.hh"
44#include "cpu/o3/cpu.hh"
45
46using namespace std;
47
48BaseFullCPU::BaseFullCPU(Params &params)
49 : BaseCPU(&params), cpu_id(0)
50{
51}
52
53template <class Impl>
54FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
55 : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c)
56{
57}
58
59template <class Impl>
60void

--- 4 unchanged lines hidden (view full) ---

65
66template <class Impl>
67const char *
68FullO3CPU<Impl>::TickEvent::description()
69{
70 return "FullO3CPU tick event";
71}
72
73//Call constructor to all the pipeline stages here
74template <class Impl>
75FullO3CPU<Impl>::FullO3CPU(Params &params)
76#if FULL_SYSTEM
77 : BaseFullCPU(params),
78#else
79 : BaseFullCPU(params),
80#endif // FULL_SYSTEM
81 tickEvent(this),
82 fetch(params),
83 decode(params),
84 rename(params),
85 iew(params),
86 commit(params),
87
88 regFile(params.numPhysIntRegs, params.numPhysFloatRegs),
89
90 freeList(TheISA::NumIntRegs, params.numPhysIntRegs,
91 TheISA::NumFloatRegs, params.numPhysFloatRegs),
92
93 renameMap(TheISA::NumIntRegs, params.numPhysIntRegs,
94 TheISA::NumFloatRegs, params.numPhysFloatRegs,
95 TheISA::NumMiscRegs,
96 TheISA::ZeroReg,
97 TheISA::ZeroReg + TheISA::NumIntRegs),
98
99 rob(params.numROBEntries, params.squashWidth),
100
101 // What to pass to these time buffers?
102 // For now just have these time buffers be pretty big.
103 timeBuffer(5, 5),
104 fetchQueue(5, 5),
105 decodeQueue(5, 5),
106 renameQueue(5, 5),
107 iewQueue(5, 5),
108
109 cpuXC(NULL),
110
111 globalSeqNum(1),
112
113#if FULL_SYSTEM
114 system(params.system),
115 memCtrl(system->memctrl),
116 physmem(system->physmem),
117 itb(params.itb),
118 dtb(params.dtb),
119 mem(params.mem),
120#else
121 // Hardcoded for a single thread!!
122 mem(params.workload[0]->getMemory()),
123#endif // FULL_SYSTEM
124
125 icacheInterface(params.icacheInterface),
126 dcacheInterface(params.dcacheInterface),
127 deferRegistration(params.defReg),
128 numInsts(0),
129 funcExeInst(0)
130{
131 _status = Idle;
132
133#if !FULL_SYSTEM
134 thread.resize(this->number_of_threads);
135#endif
136
137 for (int i = 0; i < this->number_of_threads; ++i) {
138#if FULL_SYSTEM
139 assert(i == 0);
140 thread[i] = new CPUExecContext(this, 0, system, itb, dtb, mem);
141 system->execContexts[i] = thread[i]->getProxy();
142
143 execContexts.push_back(system->execContexts[i]);
144#else
145 if (i < params.workload.size()) {
146 DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, "
147 "process is %#x",
148 i, params.workload[i]->prog_entry, thread[i]);
149 thread[i] = new CPUExecContext(this, i, params.workload[i], i);
150 }
151 assert(params.workload[i]->getMemory() != NULL);
152 assert(mem != NULL);
153 execContexts.push_back(thread[i]->getProxy());
154#endif // !FULL_SYSTEM
155 }
156
157 // Note that this is a hack so that my code which still uses xc-> will
158 // still work. I should remove this eventually
159 cpuXC = thread[0];
160
161 // The stages also need their CPU pointer setup. However this must be
162 // done at the upper level CPU because they have pointers to the upper
163 // level CPU, and not this FullO3CPU.
164
165 // Give each of the stages the time buffer they will use.
166 fetch.setTimeBuffer(&timeBuffer);
167 decode.setTimeBuffer(&timeBuffer);
168 rename.setTimeBuffer(&timeBuffer);
169 iew.setTimeBuffer(&timeBuffer);
170 commit.setTimeBuffer(&timeBuffer);
171
172 // Also setup each of the stages' queues.
173 fetch.setFetchQueue(&fetchQueue);
174 decode.setFetchQueue(&fetchQueue);
175 decode.setDecodeQueue(&decodeQueue);
176 rename.setDecodeQueue(&decodeQueue);
177 rename.setRenameQueue(&renameQueue);
178 iew.setRenameQueue(&renameQueue);
179 iew.setIEWQueue(&iewQueue);
180 commit.setIEWQueue(&iewQueue);
181 commit.setRenameQueue(&renameQueue);
182
183 // Setup the rename map for whichever stages need it.
184 rename.setRenameMap(&renameMap);
185 iew.setRenameMap(&renameMap);
186
187 // Setup the free list for whichever stages need it.
188 rename.setFreeList(&freeList);
189 renameMap.setFreeList(&freeList);
190
191 // Setup the ROB for whichever stages need it.
192 commit.setROB(&rob);
193}
194
195template <class Impl>
196FullO3CPU<Impl>::~FullO3CPU()
197{
198}
199
200template <class Impl>
201void
202FullO3CPU<Impl>::fullCPURegStats()
203{
204 // Register any of the FullCPU's stats here.
205}
206
207template <class Impl>
208void
209FullO3CPU<Impl>::tick()
210{
211 DPRINTF(FullCPU, "\n\nFullCPU: Ticking main, FullO3CPU.\n");
212
213 //Tick each of the stages if they're actually running.
214 //Will want to figure out a way to unschedule itself if they're all
215 //going to be idle for a long time.
216 fetch.tick();
217
218 decode.tick();
219
220 rename.tick();
221
222 iew.tick();
223
224 commit.tick();
225
226 // Now advance the time buffers, unless the stage is stalled.
227 timeBuffer.advance();
228
229 fetchQueue.advance();
230 decodeQueue.advance();
231 renameQueue.advance();
232 iewQueue.advance();
233
234 if (_status == Running && !tickEvent.scheduled())
235 tickEvent.schedule(curTick + 1);
236}
237
238template <class Impl>
239void
240FullO3CPU<Impl>::init()
241{
242 if(!deferRegistration)
243 {
244 this->registerExecContexts();
245
246 // Need to do a copy of the xc->regs into the CPU's regfile so
247 // that it can start properly.
248#if FULL_SYSTEM
249 ExecContext *src_xc = system->execContexts[0];
250 TheISA::initCPU(src_xc, src_xc->readCpuId());
251#else
252 ExecContext *src_xc = thread[0]->getProxy();
253#endif
254 // First loop through the integer registers.
255 for (int i = 0; i < TheISA::NumIntRegs; ++i)
256 {
257 regFile.intRegFile[i] = src_xc->readIntReg(i);
258 }
259
260 // Then loop through the floating point registers.
261 for (int i = 0; i < TheISA::NumFloatRegs; ++i)
262 {
263 regFile.floatRegFile.setRegBits(i, src_xc->readRegBits(i))
264 }
265/*
266 // Then loop through the misc registers.
267 regFile.miscRegs.fpcr = src_xc->regs.miscRegs.fpcr;
268 regFile.miscRegs.uniq = src_xc->regs.miscRegs.uniq;
269 regFile.miscRegs.lock_flag = src_xc->regs.miscRegs.lock_flag;
270 regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr;
271*/
272 // Then finally set the PC and the next PC.
273 regFile.pc = src_xc->readPC();
274 regFile.npc = src_xc->readNextPC();
275 }
276}
277
278template <class Impl>
279void
280FullO3CPU<Impl>::activateContext(int thread_num, int delay)
281{
282 // Needs to set each stage to running as well.
283
284 scheduleTickEvent(delay);
285
286 _status = Running;
287}
288
289template <class Impl>
290void
291FullO3CPU<Impl>::suspendContext(int thread_num)
292{
293 panic("suspendContext unimplemented!");
294}
295
296template <class Impl>
297void
298FullO3CPU<Impl>::deallocateContext(int thread_num)
299{
300 panic("deallocateContext unimplemented!");
301}
302
303template <class Impl>
304void
305FullO3CPU<Impl>::haltContext(int thread_num)
306{
307 panic("haltContext unimplemented!");
308}
309
310template <class Impl>
311void
312FullO3CPU::switchOut()
313{
314 panic("FullO3CPU does not have a switch out function.\n");
315}
316
317template <class Impl>
318void
319FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
320{
321 BaseCPU::takeOverFrom(oldCPU);
322
323 assert(!tickEvent.scheduled());
324
325 // Set all status's to active, schedule the
326 // CPU's tick event.
327 for (int i = 0; i < execContexts.size(); ++i) {
328 ExecContext *xc = execContexts[i];
329 if (xc->status() == ExecContext::Active && _status != Running) {
330 _status = Running;
331 tickEvent.schedule(curTick);
332 }
333 }
334}
335
336template <class Impl>
337InstSeqNum
338FullO3CPU<Impl>::getAndIncrementInstSeq()
339{
340 // Hopefully this works right.
341 return globalSeqNum++;
342}
343
344template <class Impl>
345uint64_t
346FullO3CPU<Impl>::readIntReg(int reg_idx)
347{
348 return regFile.readIntReg(reg_idx);
349}
350
351template <class Impl>
352FloatReg

--- 55 unchanged lines hidden (view full) ---

408void
409FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
410{
411 regFile.setFloatRegBits(reg_idx, val);
412}
413
414template <class Impl>
415uint64_t
416FullO3CPU<Impl>::readPC()
417{
418 return regFile.readPC();
419}
420
421template <class Impl>
422void
423FullO3CPU<Impl>::setNextPC(uint64_t val)
424{
425 regFile.setNextPC(val);
426}
427
428template <class Impl>
429void
430FullO3CPU<Impl>::setPC(Addr new_PC)
431{
432 regFile.setPC(new_PC);
433}
434
435template <class Impl>
436void
437FullO3CPU<Impl>::addInst(DynInstPtr &inst)
438{
439 instList.push_back(inst);
440}
441
442template <class Impl>
443void
444FullO3CPU<Impl>::instDone()
445{
446 // Keep an instruction count.
447 numInsts++;
448
449 // Check for instruction-count-based events.
450 comInstEventQueue[0]->serviceEvents(numInsts);
451}
452
453template <class Impl>
454void
455FullO3CPU<Impl>::removeBackInst(DynInstPtr &inst)
456{
457 DynInstPtr inst_to_delete;
458
459 // Walk through the instruction list, removing any instructions
460 // that were inserted after the given instruction, inst.
461 while (instList.back() != inst)
462 {
463 assert(!instList.empty());
464
465 // Obtain the pointer to the instruction.
466 inst_to_delete = instList.back();
467
468 DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
469 inst_to_delete->seqNum, inst_to_delete->readPC());
470
471 // Remove the instruction from the list.
472 instList.pop_back();
473
474 // Mark it as squashed.
475 inst_to_delete->setSquashed();
476 }
477}
478
479template <class Impl>
480void
481FullO3CPU<Impl>::removeFrontInst(DynInstPtr &inst)
482{
483 DynInstPtr inst_to_remove;
484
485 // The front instruction should be the same one being asked to be removed.
486 assert(instList.front() == inst);
487
488 // Remove the front instruction.
489 inst_to_remove = inst;
490 instList.pop_front();
491
492 DPRINTF(FullCPU, "FullCPU: Removing committed instruction %#x, PC %#x\n",
493 inst_to_remove, inst_to_remove->readPC());
494}
495
496template <class Impl>
497void
498FullO3CPU::removeInstsNotInROB()
499{
500 DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
501 "list.\n");
502
503 DynInstPtr rob_tail = rob.readTailInst();
504
505 removeBackInst(rob_tail);
506}
507
508template <class Impl>
509void
510FullO3CPU<Impl>::removeInstsUntil(const InstSeqNum &seq_num)
511{
512 DPRINTF(FullCPU, "FullCPU: Deleting instructions from instruction "
513 "list.\n");
514
515 DynInstPtr inst_to_delete;
516
517 while (instList.back()->seqNum > seq_num) {
518 assert(!instList.empty());
519
520 // Obtain the pointer to the instruction.
521 inst_to_delete = instList.back();
522
523 DPRINTF(FullCPU, "FullCPU: Removing instruction %i, PC %#x\n",
524 inst_to_delete->seqNum, inst_to_delete->readPC());
525
526 // Remove the instruction from the list.
527 instList.back() = NULL;
528 instList.pop_back();
529
530 // Mark it as squashed.
531 inst_to_delete->setSquashed();
532 }
533
534}
535
536template <class Impl>
537void
538FullO3CPU<Impl>::removeAllInsts()
539{
540 instList.clear();
541}
542
543template <class Impl>
544void
545FullO3CPU<Impl>::dumpInsts()
546{
547 int num = 0;
548 typename list<DynInstPtr>::iterator inst_list_it = instList.begin();
549
550 while (inst_list_it != instList.end())
551 {
552 cprintf("Instruction:%i\nPC:%#x\nSN:%lli\nIssued:%i\nSquashed:%i\n\n",
553 num, (*inst_list_it)->readPC(), (*inst_list_it)->seqNum,
554 (*inst_list_it)->isIssued(), (*inst_list_it)->isSquashed());
555 inst_list_it++;
556 ++num;
557 }
558}
559
560template <class Impl>
561void
562FullO3CPU<Impl>::wakeDependents(DynInstPtr &inst)
563{
564 iew.wakeDependents(inst);
565}
566
567// Forward declaration of FullO3CPU.
568template class FullO3CPU<AlphaSimpleImpl>;