Deleted Added
sdiff udiff text old ( 9436:4a0223da4924 ) new ( 9444:ab47fe7f03f0 )
full compact
1/*
2 * Copyright (c) 2011-2012 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

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

252 renameQueue(params->backComSize, params->forwardComSize),
253 iewQueue(params->backComSize, params->forwardComSize),
254 activityRec(name(), NumStages,
255 params->backComSize + params->forwardComSize,
256 params->activity),
257
258 globalSeqNum(1),
259 system(params->system),
260 drainCount(0),
261 lastRunningCycle(curCycle())
262{
263 if (!params->switched_out) {
264 _status = Running;
265 } else {
266 _status = SwitchedOut;
267 }
268

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

579 .prereq(miscRegfileWrites);
580}
581
582template <class Impl>
583void
584FullO3CPU<Impl>::tick()
585{
586 DPRINTF(O3CPU, "\n\nFullO3CPU: Ticking main, FullO3CPU.\n");
587
588 ++numCycles;
589
590// activity = false;
591
592 //Tick each of the stages
593 fetch.tick();
594

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

613
614 activityRec.advance();
615
616 if (removeInstsThisCycle) {
617 cleanUpRemovedInsts();
618 }
619
620 if (!tickEvent.scheduled()) {
621 if (_status == SwitchedOut ||
622 getDrainState() == Drainable::Drained) {
623 DPRINTF(O3CPU, "Switched out!\n");
624 // increment stat
625 lastRunningCycle = curCycle();
626 } else if (!activityRec.active() || _status == Idle) {
627 DPRINTF(O3CPU, "Idle!\n");
628 lastRunningCycle = curCycle();
629 timesIdled++;
630 } else {
631 schedule(tickEvent, clockEdge(Cycles(1)));
632 DPRINTF(O3CPU, "Scheduling next tick!\n");
633 }
634 }
635
636 if (!FullSystem)
637 updateThreadPriority();
638}
639
640template <class Impl>
641void
642FullO3CPU<Impl>::init()
643{
644 BaseCPU::init();
645

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

652 for (ThreadID tid = 0; tid < numThreads; ++tid) {
653 // Set noSquashFromTC so that the CPU doesn't squash when initially
654 // setting up registers.
655 thread[tid]->noSquashFromTC = true;
656 // Initialise the ThreadContext's memory proxies
657 thread[tid]->initMemProxies(thread[tid]->getTC());
658 }
659
660 // this CPU could still be unconnected if we are restoring from a
661 // checkpoint and this CPU is to be switched in, thus we can only
662 // do this here if the instruction port is actually connected, if
663 // not we have to do it as part of takeOverFrom
664 if (icachePort.isConnected())
665 fetch.setIcache();
666
667 if (FullSystem && !params()->switched_out) {
668 for (ThreadID tid = 0; tid < numThreads; tid++) {
669 ThreadContext *src_tc = threadContexts[tid];
670 TheISA::initCPU(src_tc, src_tc->contextId());
671 }
672 }
673
674 // Clear noSquashFromTC.
675 for (int tid = 0; tid < numThreads; ++tid)
676 thread[tid]->noSquashFromTC = false;
677
678 commit.setThreads(thread);
679}
680
681template <class Impl>
682void
683FullO3CPU<Impl>::startup()
684{
685 fetch.startupStage();
686 iew.startupStage();
687 rename.startupStage();
688 commit.startupStage();
689}
690
691template <class Impl>
692void
693FullO3CPU<Impl>::activateThread(ThreadID tid)
694{
695 list<ThreadID>::iterator isActive =
696 std::find(activeThreads.begin(), activeThreads.end(), tid);
697
698 DPRINTF(O3CPU, "[tid:%i]: Calling activate thread.\n", tid);
699
700 if (isActive == activeThreads.end()) {
701 DPRINTF(O3CPU, "[tid:%i]: Adding to active threads list\n",
702 tid);
703
704 activeThreads.push_back(tid);
705 }
706}
707
708template <class Impl>
709void
710FullO3CPU<Impl>::deactivateThread(ThreadID tid)
711{
712 //Remove From Active List, if Active
713 list<ThreadID>::iterator thread_it =
714 std::find(activeThreads.begin(), activeThreads.end(), tid);
715
716 DPRINTF(O3CPU, "[tid:%i]: Calling deactivate thread.\n", tid);
717
718 if (thread_it != activeThreads.end()) {
719 DPRINTF(O3CPU,"[tid:%i]: Removing from active threads list\n",
720 tid);
721 activeThreads.erase(thread_it);
722 }
723}
724

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

747
748 return total;
749}
750
751template <class Impl>
752void
753FullO3CPU<Impl>::activateContext(ThreadID tid, Cycles delay)
754{
755 // Needs to set each stage to running as well.
756 if (delay){
757 DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
758 "on cycle %d\n", tid, clockEdge(delay));
759 scheduleActivateThreadEvent(tid, delay);
760 } else {
761 activateThread(tid);
762 }
763
764 // If we are time 0 or if the last activation time is in the past,
765 // schedule the next tick and wake up the fetch unit
766 if (lastActivatedCycle == 0 || lastActivatedCycle < curTick()) {
767 scheduleTickEvent(delay);
768
769 // Be sure to signal that there's some activity so the CPU doesn't
770 // deschedule itself.
771 activityRec.activity();

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

802 }
803}
804
805template <class Impl>
806void
807FullO3CPU<Impl>::suspendContext(ThreadID tid)
808{
809 DPRINTF(O3CPU,"[tid: %i]: Suspending Thread Context.\n", tid);
810 bool deallocated = scheduleDeallocateContext(tid, false, Cycles(1));
811 // If this was the last thread then unschedule the tick event.
812 if ((activeThreads.size() == 1 && !deallocated) ||
813 activeThreads.size() == 0)
814 unscheduleTickEvent();
815
816 DPRINTF(Quiesce, "Suspending Context\n");
817 lastRunningCycle = curCycle();
818 _status = Idle;
819}
820
821template <class Impl>
822void
823FullO3CPU<Impl>::haltContext(ThreadID tid)
824{
825 //For now, this is the same as deallocate
826 DPRINTF(O3CPU,"[tid:%i]: Halt Context called. Deallocating", tid);
827 scheduleDeallocateContext(tid, true, Cycles(1));
828}
829
830template <class Impl>
831void
832FullO3CPU<Impl>::insertThread(ThreadID tid)
833{
834 DPRINTF(O3CPU,"[tid:%i] Initializing thread into CPU");

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

1115 activateThread(i);
1116 }
1117}
1118
1119template <class Impl>
1120unsigned int
1121FullO3CPU<Impl>::drain(DrainManager *drain_manager)
1122{
1123 DPRINTF(O3CPU, "Switching out\n");
1124
1125 // If the CPU isn't doing anything, then return immediately.
1126 if (_status == SwitchedOut)
1127 return 0;
1128
1129 drainCount = 0;
1130 fetch.drain();
1131 decode.drain();
1132 rename.drain();
1133 iew.drain();
1134 commit.drain();
1135
1136 // Wake the CPU and record activity so everything can drain out if
1137 // the CPU was not able to immediately drain.
1138 if (getDrainState() != Drainable::Drained) {
1139 // A bit of a hack...set the drainManager after all the drain()
1140 // calls have been made, that way if all of the stages drain
1141 // immediately, the signalDrained() function knows not to call
1142 // process on the drain event.
1143 drainManager = drain_manager;
1144
1145 wakeCPU();
1146 activityRec.activity();
1147
1148 DPRINTF(Drain, "CPU not drained\n");
1149
1150 return 1;
1151 } else {
1152 return 0;
1153 }
1154}
1155
1156template <class Impl>
1157void
1158FullO3CPU<Impl>::drainResume()
1159{
1160 fetch.resume();
1161 decode.resume();
1162 rename.resume();
1163 iew.resume();
1164 commit.resume();
1165
1166 setDrainState(Drainable::Running);
1167
1168 if (_status == SwitchedOut)
1169 return;
1170
1171 if (system->getMemoryMode() != Enums::timing) {
1172 fatal("The O3 CPU requires the memory system to be in "
1173 "'timing' mode.\n");
1174 }
1175
1176 if (!tickEvent.scheduled())
1177 schedule(tickEvent, nextCycle());
1178 _status = Running;
1179}
1180
1181template <class Impl>
1182void
1183FullO3CPU<Impl>::signalDrained()
1184{
1185 if (++drainCount == NumStages) {
1186 if (tickEvent.scheduled())
1187 tickEvent.squash();
1188
1189 setDrainState(Drainable::Drained);
1190
1191 if (drainManager) {
1192 DPRINTF(Drain, "CPU done draining, processing drain event\n");
1193 drainManager->signalDrainDone();
1194 drainManager = NULL;
1195 }
1196 }
1197 assert(drainCount <= 5);
1198}
1199
1200template <class Impl>
1201void
1202FullO3CPU<Impl>::switchOut()
1203{
1204 BaseCPU::switchOut();
1205
1206 fetch.switchOut();
1207 rename.switchOut();
1208 iew.switchOut();
1209 commit.switchOut();
1210 instList.clear();
1211 while (!removeList.empty()) {
1212 removeList.pop();
1213 }
1214
1215 _status = SwitchedOut;
1216
1217 if (checker)
1218 checker->switchOut();
1219
1220 if (tickEvent.scheduled())
1221 tickEvent.squash();
1222}
1223
1224template <class Impl>
1225void
1226FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
1227{
1228 // Flush out any old data from the time buffers.
1229 for (int i = 0; i < timeBuffer.getSize(); ++i) {
1230 timeBuffer.advance();
1231 fetchQueue.advance();
1232 decodeQueue.advance();
1233 renameQueue.advance();
1234 iewQueue.advance();
1235 }
1236
1237 activityRec.reset();
1238
1239 BaseCPU::takeOverFrom(oldCPU);
1240
1241 fetch.takeOverFrom();
1242 decode.takeOverFrom();
1243 rename.takeOverFrom();
1244 iew.takeOverFrom();
1245 commit.takeOverFrom();
1246
1247 assert(!tickEvent.scheduled() || tickEvent.squashed());
1248
1249 FullO3CPU<Impl> *oldO3CPU = dynamic_cast<FullO3CPU<Impl>*>(oldCPU);
1250 if (oldO3CPU)
1251 globalSeqNum = oldO3CPU->globalSeqNum;
1252
1253 // @todo: Figure out how to properly select the tid to put onto
1254 // the active threads list.
1255 ThreadID tid = 0;
1256
1257 list<ThreadID>::iterator isActive =
1258 std::find(activeThreads.begin(), activeThreads.end(), tid);
1259
1260 if (isActive == activeThreads.end()) {
1261 //May Need to Re-code this if the delay variable is the delay
1262 //needed for thread to activate
1263 DPRINTF(O3CPU, "Adding Thread %i to active threads list\n",
1264 tid);
1265
1266 activeThreads.push_back(tid);
1267 }
1268
1269 // Set all statuses to active, schedule the CPU's tick event.
1270 // @todo: Fix up statuses so this is handled properly
1271 ThreadID size = threadContexts.size();
1272 for (ThreadID i = 0; i < size; ++i) {
1273 ThreadContext *tc = threadContexts[i];
1274 if (tc->status() == ThreadContext::Active && _status != Running) {
1275 _status = Running;
1276 reschedule(tickEvent, nextCycle(), true);
1277 }
1278 }
1279 if (!tickEvent.scheduled())
1280 schedule(tickEvent, nextCycle());
1281
1282 lastRunningCycle = curCycle();
1283}
1284
1285template <class Impl>
1286TheISA::MiscReg
1287FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, ThreadID tid)
1288{
1289 return this->isa[tid]->readMiscRegNoEffect(misc_reg);
1290}

--- 459 unchanged lines hidden ---