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 *
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"
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;
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
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>
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
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);
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);
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
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();
526 else if (if_name == "icache_port")
586 return &icachePort;
527 return fetch.getIcachePort();
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
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());
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
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)
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);
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();
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);
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}
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());
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();
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();
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>;