cpu.cc (8737:770ccf3af571) cpu.cc (8766:b0773af78423)
1/*
1/*
2 * Copyright (c) 2011 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2004-2006 The Regents of The University of Michigan
15 * Copyright (c) 2011 Regents of the University of California
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;

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

63#if FULL_SYSTEM
64#include "cpu/quiesce_event.hh"
65#else
66#include "sim/process.hh"
67#endif
68
69#if USE_CHECKER
70#include "cpu/checker/cpu.hh"
2 * Copyright (c) 2004-2006 The Regents of The University of Michigan
3 * Copyright (c) 2011 Regents of the University of California
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;

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

51#if FULL_SYSTEM
52#include "cpu/quiesce_event.hh"
53#else
54#include "sim/process.hh"
55#endif
56
57#if USE_CHECKER
58#include "cpu/checker/cpu.hh"
71#include "cpu/checker/thread_context.hh"
72#endif
73
74#if THE_ISA == ALPHA_ISA
75#include "arch/alpha/osfpal.hh"
76#include "debug/Activity.hh"
77#endif
78
59#endif
60
61#if THE_ISA == ALPHA_ISA
62#include "arch/alpha/osfpal.hh"
63#include "debug/Activity.hh"
64#endif
65
79struct BaseCPUParams;
66class BaseCPUParams;
80
81using namespace TheISA;
82using namespace std;
83
84BaseO3CPU::BaseO3CPU(BaseCPUParams *params)
85 : BaseCPU(params)
86{
87}
88
89void
90BaseO3CPU::regStats()
91{
92 BaseCPU::regStats();
93}
94
67
68using namespace TheISA;
69using namespace std;
70
71BaseO3CPU::BaseO3CPU(BaseCPUParams *params)
72 : BaseCPU(params)
73{
74}
75
76void
77BaseO3CPU::regStats()
78{
79 BaseCPU::regStats();
80}
81
95template<class Impl>
96bool
97FullO3CPU<Impl>::IcachePort::recvTiming(PacketPtr pkt)
98{
99 DPRINTF(O3CPU, "Fetch unit received timing\n");
100 if (pkt->isResponse()) {
101 // We shouldn't ever get a block in ownership state
102 assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
103
104 fetch->processCacheCompletion(pkt);
105 }
106 //else Snooped a coherence request, just return
107 return true;
108}
109
110template<class Impl>
111void
112FullO3CPU<Impl>::IcachePort::recvRetry()
113{
114 fetch->recvRetry();
115}
116
117template <class Impl>
82template <class Impl>
118bool
119FullO3CPU<Impl>::DcachePort::recvTiming(PacketPtr pkt)
120{
121 return lsq->recvTiming(pkt);
122}
123
124template <class Impl>
125void
126FullO3CPU<Impl>::DcachePort::recvRetry()
127{
128 lsq->recvRetry();
129}
130
131template <class Impl>
132FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
133 : Event(CPU_Tick_Pri), cpu(c)
134{
135}
136
137template <class Impl>
138void
139FullO3CPU<Impl>::TickEvent::process()

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

238 params->numThreads),
239
240 scoreboard(params->numThreads,
241 TheISA::NumIntRegs, params->numPhysIntRegs,
242 TheISA::NumFloatRegs, params->numPhysFloatRegs,
243 TheISA::NumMiscRegs * numThreads,
244 TheISA::ZeroReg),
245
83FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
84 : Event(CPU_Tick_Pri), cpu(c)
85{
86}
87
88template <class Impl>
89void
90FullO3CPU<Impl>::TickEvent::process()

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

189 params->numThreads),
190
191 scoreboard(params->numThreads,
192 TheISA::NumIntRegs, params->numPhysIntRegs,
193 TheISA::NumFloatRegs, params->numPhysFloatRegs,
194 TheISA::NumMiscRegs * numThreads,
195 TheISA::ZeroReg),
196
246 icachePort(&fetch, this),
247 dcachePort(&iew.ldstQueue, this),
248
249 timeBuffer(params->backComSize, params->forwardComSize),
250 fetchQueue(params->backComSize, params->forwardComSize),
251 decodeQueue(params->backComSize, params->forwardComSize),
252 renameQueue(params->backComSize, params->forwardComSize),
253 iewQueue(params->backComSize, params->forwardComSize),
254 activityRec(name(), NumStages,
255 params->backComSize + params->forwardComSize,
256 params->activity),

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

264 _status = Running;
265 } else {
266 _status = Idle;
267 }
268
269#if USE_CHECKER
270 if (params->checker) {
271 BaseCPU *temp_checker = params->checker;
197 timeBuffer(params->backComSize, params->forwardComSize),
198 fetchQueue(params->backComSize, params->forwardComSize),
199 decodeQueue(params->backComSize, params->forwardComSize),
200 renameQueue(params->backComSize, params->forwardComSize),
201 iewQueue(params->backComSize, params->forwardComSize),
202 activityRec(name(), NumStages,
203 params->backComSize + params->forwardComSize,
204 params->activity),

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

212 _status = Running;
213 } else {
214 _status = Idle;
215 }
216
217#if USE_CHECKER
218 if (params->checker) {
219 BaseCPU *temp_checker = params->checker;
272 checker = dynamic_cast<Checker<Impl> *>(temp_checker);
273 checker->setIcachePort(&icachePort);
220 checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
274#if FULL_SYSTEM
275 checker->setSystem(params->system);
276#endif
277 } else {
278 checker = NULL;
279 }
280#endif // USE_CHECKER
281

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

405
406 // Setup any thread state.
407 this->thread.resize(this->numThreads);
408
409 for (ThreadID tid = 0; tid < this->numThreads; ++tid) {
410#if FULL_SYSTEM
411 // SMT is not supported in FS mode yet.
412 assert(this->numThreads == 1);
221#if FULL_SYSTEM
222 checker->setSystem(params->system);
223#endif
224 } else {
225 checker = NULL;
226 }
227#endif // USE_CHECKER
228

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

352
353 // Setup any thread state.
354 this->thread.resize(this->numThreads);
355
356 for (ThreadID tid = 0; tid < this->numThreads; ++tid) {
357#if FULL_SYSTEM
358 // SMT is not supported in FS mode yet.
359 assert(this->numThreads == 1);
413 this->thread[tid] = new Thread(this, 0);
360 this->thread[tid] = new Thread(this, 0, NULL);
414#else
415 if (tid < params->workload.size()) {
416 DPRINTF(O3CPU, "Workload[%i] process is %#x",
417 tid, this->thread[tid]);
418 this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
419 (typename Impl::O3CPU *)(this),
420 tid, params->workload[tid]);
421

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

490 .prereq(timesIdled);
491
492 idleCycles
493 .name(name() + ".idleCycles")
494 .desc("Total number of cycles that the CPU has spent unscheduled due "
495 "to idling")
496 .prereq(idleCycles);
497
361#else
362 if (tid < params->workload.size()) {
363 DPRINTF(O3CPU, "Workload[%i] process is %#x",
364 tid, this->thread[tid]);
365 this->thread[tid] = new typename FullO3CPU<Impl>::Thread(
366 (typename Impl::O3CPU *)(this),
367 tid, params->workload[tid]);
368

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

437 .prereq(timesIdled);
438
439 idleCycles
440 .name(name() + ".idleCycles")
441 .desc("Total number of cycles that the CPU has spent unscheduled due "
442 "to idling")
443 .prereq(idleCycles);
444
498 quiesceCycles
499 .name(name() + ".quiesceCycles")
500 .desc("Total number of cycles that CPU has spent quiesced or waiting "
501 "for an interrupt")
502 .prereq(quiesceCycles);
503
504 // Number of Instructions simulated
505 // --------------------------------
506 // Should probably be in Base CPU but need templated
507 // MaxThreads so put in here instead
508 committedInsts
509 .init(numThreads)
510 .name(name() + ".committedInsts")
511 .desc("Number of Instructions Simulated");

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

576 .prereq(miscRegfileWrites);
577}
578
579template <class Impl>
580Port *
581FullO3CPU<Impl>::getPort(const std::string &if_name, int idx)
582{
583 if (if_name == "dcache_port")
445 // Number of Instructions simulated
446 // --------------------------------
447 // Should probably be in Base CPU but need templated
448 // MaxThreads so put in here instead
449 committedInsts
450 .init(numThreads)
451 .name(name() + ".committedInsts")
452 .desc("Number of Instructions Simulated");

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

517 .prereq(miscRegfileWrites);
518}
519
520template <class Impl>
521Port *
522FullO3CPU<Impl>::getPort(const std::string &if_name, int idx)
523{
524 if (if_name == "dcache_port")
584 return &dcachePort;
525 return iew.getDcachePort();
585 else if (if_name == "icache_port")
526 else if (if_name == "icache_port")
586 return &icachePort;
527 return fetch.getIcachePort();
587 else
588 panic("No Such Port\n");
589}
590
591template <class Impl>
592void
593FullO3CPU<Impl>::tick()
594{

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

654{
655 BaseCPU::init();
656
657 // Set inSyscall so that the CPU doesn't squash when initially
658 // setting up registers.
659 for (ThreadID tid = 0; tid < numThreads; ++tid)
660 thread[tid]->inSyscall = true;
661
528 else
529 panic("No Such Port\n");
530}
531
532template <class Impl>
533void
534FullO3CPU<Impl>::tick()
535{

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

595{
596 BaseCPU::init();
597
598 // Set inSyscall so that the CPU doesn't squash when initially
599 // setting up registers.
600 for (ThreadID tid = 0; tid < numThreads; ++tid)
601 thread[tid]->inSyscall = true;
602
662 // this CPU could still be unconnected if we are restoring from a
663 // checkpoint and this CPU is to be switched in, thus we can only
664 // do this here if the instruction port is actually connected, if
665 // not we have to do it as part of takeOverFrom
666 if (icachePort.isConnected())
667 fetch.setIcache();
668
669#if FULL_SYSTEM
670 for (ThreadID tid = 0; tid < numThreads; tid++) {
671 ThreadContext *src_tc = threadContexts[tid];
672 TheISA::initCPU(src_tc, src_tc->contextId());
603#if FULL_SYSTEM
604 for (ThreadID tid = 0; tid < numThreads; tid++) {
605 ThreadContext *src_tc = threadContexts[tid];
606 TheISA::initCPU(src_tc, src_tc->contextId());
673 // Initialise the ThreadContext's memory proxies
674 thread[tid]->initMemProxies(thread[tid]->getTC());
675 }
676#endif
677
678 // Clear inSyscall.
679 for (int tid = 0; tid < numThreads; ++tid)
680 thread[tid]->inSyscall = false;
681
682 // Initialize stages.

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

751 if (lastActivatedCycle < curTick()) {
752 scheduleTickEvent(delay);
753
754 // Be sure to signal that there's some activity so the CPU doesn't
755 // deschedule itself.
756 activityRec.activity();
757 fetch.wakeFromQuiesce();
758
607 }
608#endif
609
610 // Clear inSyscall.
611 for (int tid = 0; tid < numThreads; ++tid)
612 thread[tid]->inSyscall = false;
613
614 // Initialize stages.

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

683 if (lastActivatedCycle < curTick()) {
684 scheduleTickEvent(delay);
685
686 // Be sure to signal that there's some activity so the CPU doesn't
687 // deschedule itself.
688 activityRec.activity();
689 fetch.wakeFromQuiesce();
690
759 quiesceCycles += tickToCycles((curTick() - 1) - lastRunningCycle);
760
761 lastActivatedCycle = curTick();
762
763 _status = Running;
764 }
765}
766
767template <class Impl>
768bool
691 lastActivatedCycle = curTick();
692
693 _status = Running;
694 }
695}
696
697template <class Impl>
698bool
769FullO3CPU<Impl>::scheduleDeallocateContext(ThreadID tid, bool remove,
770 int delay)
699FullO3CPU<Impl>::deallocateContext(ThreadID tid, bool remove, int delay)
771{
772 // Schedule removal of thread data from CPU
773 if (delay){
774 DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to deallocate "
775 "on cycle %d\n", tid, curTick() + ticks(delay));
776 scheduleDeallocateContextEvent(tid, remove, delay);
777 return false;
778 } else {

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

783 }
784}
785
786template <class Impl>
787void
788FullO3CPU<Impl>::suspendContext(ThreadID tid)
789{
790 DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
700{
701 // Schedule removal of thread data from CPU
702 if (delay){
703 DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to deallocate "
704 "on cycle %d\n", tid, curTick() + ticks(delay));
705 scheduleDeallocateContextEvent(tid, remove, delay);
706 return false;
707 } else {

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

712 }
713}
714
715template <class Impl>
716void
717FullO3CPU<Impl>::suspendContext(ThreadID tid)
718{
719 DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
791 bool deallocated = scheduleDeallocateContext(tid, false, 1);
720 bool deallocated = deallocateContext(tid, false, 1);
792 // If this was the last thread then unschedule the tick event.
793 if ((activeThreads.size() == 1 && !deallocated) ||
794 activeThreads.size() == 0)
795 unscheduleTickEvent();
721 // If this was the last thread then unschedule the tick event.
722 if ((activeThreads.size() == 1 && !deallocated) ||
723 activeThreads.size() == 0)
724 unscheduleTickEvent();
796
797 DPRINTF(Quiesce, "Suspending Context\n");
798 lastRunningCycle = curTick();
799 _status = Idle;
800}
801
802template <class Impl>
803void
804FullO3CPU<Impl>::haltContext(ThreadID tid)
805{
806 //For now, this is the same as deallocate
807 DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid);
725 _status = Idle;
726}
727
728template <class Impl>
729void
730FullO3CPU<Impl>::haltContext(ThreadID tid)
731{
732 //For now, this is the same as deallocate
733 DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid);
808 scheduleDeallocateContext(tid, true, 1);
734 deallocateContext(tid, true, 1);
809}
810
811template <class Impl>
812void
813FullO3CPU<Impl>::insertThread(ThreadID tid)
814{
815 DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU");
816 // Will change now that the PC and thread state is internal to the CPU

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

1032
1033 assert(interrupt != NoFault);
1034 this->interrupts->updateIntrInfo(this->threadContexts[0]);
1035
1036 DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
1037 this->trap(interrupt, 0, NULL);
1038}
1039
735}
736
737template <class Impl>
738void
739FullO3CPU<Impl>::insertThread(ThreadID tid)
740{
741 DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU");
742 // Will change now that the PC and thread state is internal to the CPU

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

958
959 assert(interrupt != NoFault);
960 this->interrupts->updateIntrInfo(this->threadContexts[0]);
961
962 DPRINTF(O3CPU, "Interrupt %s being handled\n", interrupt->name());
963 this->trap(interrupt, 0, NULL);
964}
965
966template <class Impl>
967void
968FullO3CPU<Impl>::updateMemPorts()
969{
970 // Update all ThreadContext's memory ports (Functional/Virtual
971 // Ports)
972 ThreadID size = thread.size();
973 for (ThreadID i = 0; i < size; ++i)
974 thread[i]->connectMemPorts(thread[i]->getTC());
975}
1040#endif
1041
1042template <class Impl>
1043void
1044FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst)
1045{
1046 // Pass the thread's TC into the invoke method.
1047 fault->invoke(this->threadContexts[tid], inst);

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

1226 fetchQueue.advance();
1227 decodeQueue.advance();
1228 renameQueue.advance();
1229 iewQueue.advance();
1230 }
1231
1232 activityRec.reset();
1233
976#endif
977
978template <class Impl>
979void
980FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst)
981{
982 // Pass the thread's TC into the invoke method.
983 fault->invoke(this->threadContexts[tid], inst);

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

1162 fetchQueue.advance();
1163 decodeQueue.advance();
1164 renameQueue.advance();
1165 iewQueue.advance();
1166 }
1167
1168 activityRec.reset();
1169
1234 BaseCPU::takeOverFrom(oldCPU);
1170 BaseCPU::takeOverFrom(oldCPU, fetch.getIcachePort(), iew.getDcachePort());
1235
1236 fetch.takeOverFrom();
1237 decode.takeOverFrom();
1238 rename.takeOverFrom();
1239 iew.takeOverFrom();
1240 commit.takeOverFrom();
1241
1242 assert(!tickEvent.scheduled() || tickEvent.squashed());

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

1264 ThreadContext *tc = threadContexts[i];
1265 if (tc->status() == ThreadContext::Active && _status != Running) {
1266 _status = Running;
1267 reschedule(tickEvent, nextCycle(), true);
1268 }
1269 }
1270 if (!tickEvent.scheduled())
1271 schedule(tickEvent, nextCycle());
1171
1172 fetch.takeOverFrom();
1173 decode.takeOverFrom();
1174 rename.takeOverFrom();
1175 iew.takeOverFrom();
1176 commit.takeOverFrom();
1177
1178 assert(!tickEvent.scheduled() || tickEvent.squashed());

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

1200 ThreadContext *tc = threadContexts[i];
1201 if (tc->status() == ThreadContext::Active && _status != Running) {
1202 _status = Running;
1203 reschedule(tickEvent, nextCycle(), true);
1204 }
1205 }
1206 if (!tickEvent.scheduled())
1207 schedule(tickEvent, nextCycle());
1272
1273 lastRunningCycle = curTick();
1274}
1275
1276template <class Impl>
1277TheISA::MiscReg
1278FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, ThreadID tid)
1279{
1280 return this->isa[tid].readMiscRegNoEffect(misc_reg);
1281}

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

1714template <class Impl>
1715void
1716FullO3CPU<Impl>::updateThreadPriority()
1717{
1718 if (activeThreads.size() > 1) {
1719 //DEFAULT TO ROUND ROBIN SCHEME
1720 //e.g. Move highest priority to end of thread list
1721 list<ThreadID>::iterator list_begin = activeThreads.begin();
1208}
1209
1210template <class Impl>
1211TheISA::MiscReg
1212FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, ThreadID tid)
1213{
1214 return this->isa[tid].readMiscRegNoEffect(misc_reg);
1215}

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

1648template <class Impl>
1649void
1650FullO3CPU<Impl>::updateThreadPriority()
1651{
1652 if (activeThreads.size() > 1) {
1653 //DEFAULT TO ROUND ROBIN SCHEME
1654 //e.g. Move highest priority to end of thread list
1655 list<ThreadID>::iterator list_begin = activeThreads.begin();
1656 list<ThreadID>::iterator list_end = activeThreads.end();
1722
1723 unsigned high_thread = *list_begin;
1724
1725 activeThreads.erase(list_begin);
1726
1727 activeThreads.push_back(high_thread);
1728 }
1729}
1730
1731// Forward declaration of FullO3CPU.
1732template class FullO3CPU<O3CPUImpl>;
1657
1658 unsigned high_thread = *list_begin;
1659
1660 activeThreads.erase(list_begin);
1661
1662 activeThreads.push_back(high_thread);
1663 }
1664}
1665
1666// Forward declaration of FullO3CPU.
1667template class FullO3CPU<O3CPUImpl>;