summaryrefslogtreecommitdiff
path: root/src/cpu/o3
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/o3')
-rw-r--r--src/cpu/o3/alpha_cpu.hh141
-rw-r--r--src/cpu/o3/alpha_cpu_impl.hh39
-rw-r--r--src/cpu/o3/alpha_dyn_inst.hh8
-rw-r--r--src/cpu/o3/commit_impl.hh2
-rw-r--r--src/cpu/o3/cpu.cc1
-rw-r--r--src/cpu/o3/cpu.hh2
-rw-r--r--src/cpu/o3/dep_graph.hh29
-rw-r--r--src/cpu/o3/fetch.hh13
-rw-r--r--src/cpu/o3/fetch_impl.hh73
-rw-r--r--src/cpu/o3/fu_pool.cc4
-rw-r--r--src/cpu/o3/fu_pool.hh4
-rw-r--r--src/cpu/o3/lsq.cc2
-rw-r--r--src/cpu/o3/lsq.hh2
-rw-r--r--src/cpu/o3/lsq_impl.hh2
-rw-r--r--src/cpu/o3/lsq_unit.cc5
-rw-r--r--src/cpu/o3/lsq_unit.hh14
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh146
-rw-r--r--src/cpu/o3/regfile.hh40
-rw-r--r--src/cpu/o3/scoreboard.cc5
-rw-r--r--src/cpu/o3/scoreboard.hh5
-rw-r--r--src/cpu/o3/thread_state.hh4
21 files changed, 309 insertions, 232 deletions
diff --git a/src/cpu/o3/alpha_cpu.hh b/src/cpu/o3/alpha_cpu.hh
index 3449454bd..f81837f3c 100644
--- a/src/cpu/o3/alpha_cpu.hh
+++ b/src/cpu/o3/alpha_cpu.hh
@@ -77,6 +77,11 @@ class AlphaFullCPU : public FullO3CPU<Impl>
* external objects try to update state through this interface,
* the CPU will create an event to squash all in-flight
* instructions in order to ensure state is maintained correctly.
+ * It must be defined specifically for the AlphaFullCPU because
+ * not all architectural state is located within the O3ThreadState
+ * (such as the commit PC, and registers), and specific actions
+ * must be taken when using this interface (such as squashing all
+ * in-flight instructions when doing a write to this interface).
*/
class AlphaTC : public ThreadContext
{
@@ -96,8 +101,6 @@ class AlphaFullCPU : public FullO3CPU<Impl>
/** Reads this CPU's ID. */
virtual int readCpuId() { return cpu->cpu_id; }
- virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
-
#if FULL_SYSTEM
/** Returns a pointer to the system. */
virtual System *getSystemPtr() { return cpu->system; }
@@ -114,7 +117,15 @@ class AlphaFullCPU : public FullO3CPU<Impl>
/** Returns a pointer to this thread's kernel statistics. */
virtual Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; }
+
+ virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+
+ virtual VirtualPort *getVirtPort(ThreadContext *src_tc = NULL);
+
+ void delVirtPort(VirtualPort *vp);
#else
+ virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
+
/** Returns a pointer to this thread's process. */
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
#endif
@@ -301,43 +312,40 @@ class AlphaFullCPU : public FullO3CPU<Impl>
#if FULL_SYSTEM
/** Translates instruction requestion. */
- Fault translateInstReq(RequestPtr &req)
+ Fault translateInstReq(RequestPtr &req, Thread *thread)
{
- return itb->translate(req);
+ return itb->translate(req, thread->getTC());
}
/** Translates data read request. */
- Fault translateDataReadReq(RequestPtr &req)
+ Fault translateDataReadReq(RequestPtr &req, Thread *thread)
{
- return dtb->translate(req, false);
+ return dtb->translate(req, thread->getTC(), false);
}
/** Translates data write request. */
- Fault translateDataWriteReq(RequestPtr &req)
+ Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
{
- return dtb->translate(req, true);
+ return dtb->translate(req, thread->getTC(), true);
}
#else
/** Translates instruction requestion in syscall emulation mode. */
- Fault translateInstReq(RequestPtr &req)
+ Fault translateInstReq(RequestPtr &req, Thread *thread)
{
- int tid = req->getThreadNum();
- return this->thread[tid]->getProcessPtr()->pTable->translate(req);
+ return thread->getProcessPtr()->pTable->translate(req);
}
/** Translates data read request in syscall emulation mode. */
- Fault translateDataReadReq(RequestPtr &req)
+ Fault translateDataReadReq(RequestPtr &req, Thread *thread)
{
- int tid = req->getThreadNum();
- return this->thread[tid]->getProcessPtr()->pTable->translate(req);
+ return thread->getProcessPtr()->pTable->translate(req);
}
/** Translates data write request in syscall emulation mode. */
- Fault translateDataWriteReq(RequestPtr &req)
+ Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
{
- int tid = req->getThreadNum();
- return this->thread[tid]->getProcessPtr()->pTable->translate(req);
+ return thread->getProcessPtr()->pTable->translate(req);
}
#endif
@@ -403,33 +411,6 @@ class AlphaFullCPU : public FullO3CPU<Impl>
void setSyscallReturn(SyscallReturn return_value, int tid);
#endif
- /** Read from memory function. */
- template <class T>
- Fault read(RequestPtr &req, T &data)
- {
-#if 0
-#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
- if (req->flags & LOCKED) {
- req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
- req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
- }
-#endif
-#endif
- Fault error;
-
-#if FULL_SYSTEM
- // @todo: Fix this LL/SC hack.
- if (req->flags & LOCKED) {
- lockAddr = req->paddr;
- lockFlag = true;
- }
-#endif
-
- error = this->mem->read(req, data);
- data = gtoh(data);
- return error;
- }
-
/** CPU read function, forwards read to LSQ. */
template <class T>
Fault read(RequestPtr &req, T &data, int load_idx)
@@ -437,78 +418,6 @@ class AlphaFullCPU : public FullO3CPU<Impl>
return this->iew.ldstQueue.read(req, data, load_idx);
}
- /** Write to memory function. */
- template <class T>
- Fault write(RequestPtr &req, T &data)
- {
-#if 0
-#if FULL_SYSTEM && THE_ISA == ALPHA_ISA
- ExecContext *xc;
-
- // If this is a store conditional, act appropriately
- if (req->flags & LOCKED) {
- xc = req->xc;
-
- if (req->flags & UNCACHEABLE) {
- // Don't update result register (see stq_c in isa_desc)
- req->result = 2;
- xc->setStCondFailures(0);//Needed? [RGD]
- } else {
- bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag);
- Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag);
- req->result = lock_flag;
- if (!lock_flag ||
- ((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
- xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
- xc->setStCondFailures(xc->readStCondFailures() + 1);
- if (((xc->readStCondFailures()) % 100000) == 0) {
- std::cerr << "Warning: "
- << xc->readStCondFailures()
- << " consecutive store conditional failures "
- << "on cpu " << req->xc->readCpuId()
- << std::endl;
- }
- return NoFault;
- }
- else xc->setStCondFailures(0);
- }
- }
-
- // Need to clear any locked flags on other proccessors for
- // this address. Only do this for succsful Store Conditionals
- // and all other stores (WH64?). Unsuccessful Store
- // Conditionals would have returned above, and wouldn't fall
- // through.
- for (int i = 0; i < this->system->execContexts.size(); i++){
- xc = this->system->execContexts[i];
- if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
- (req->paddr & ~0xf)) {
- xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
- }
- }
-
-#endif
-#endif
-
-#if FULL_SYSTEM
- // @todo: Fix this LL/SC hack.
- if (req->getFlags() & LOCKED) {
- if (req->getFlags() & UNCACHEABLE) {
- req->setScResult(2);
- } else {
- if (this->lockFlag) {
- req->setScResult(1);
- } else {
- req->setScResult(0);
- return NoFault;
- }
- }
- }
-#endif
-
- return this->mem->write(req, (T)htog(data));
- }
-
/** CPU write function, forwards write to LSQ. */
template <class T>
Fault write(RequestPtr &req, T &data, int store_idx)
diff --git a/src/cpu/o3/alpha_cpu_impl.hh b/src/cpu/o3/alpha_cpu_impl.hh
index 2debe074b..fb2fea8e6 100644
--- a/src/cpu/o3/alpha_cpu_impl.hh
+++ b/src/cpu/o3/alpha_cpu_impl.hh
@@ -46,6 +46,7 @@
#include "arch/isa_traits.hh"
#include "cpu/quiesce_event.hh"
#include "kern/kernel_stats.hh"
+#include "sim/system.hh"
#endif
using namespace TheISA;
@@ -67,7 +68,7 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
#if FULL_SYSTEM
// SMT is not supported in FS mode yet.
assert(this->numThreads == 1);
- this->thread[i] = new Thread(this, 0, params->mem);
+ this->thread[i] = new Thread(this, 0);
this->thread[i]->setStatus(ThreadContext::Suspended);
#else
if (i < params->workload.size()) {
@@ -128,14 +129,14 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
FunctionalPort *phys_port;
VirtualPort *virt_port;
phys_port = new FunctionalPort(csprintf("%s-%d-funcport",
- cpu->name(), tid));
- mem_port = system->physmem->getPort("functional");
+ name(), i));
+ mem_port = this->system->physmem->getPort("functional");
mem_port->setPeer(phys_port);
phys_port->setPeer(mem_port);
virt_port = new VirtualPort(csprintf("%s-%d-vport",
- cpu->name(), tid));
- mem_port = system->physmem->getPort("functional");
+ name(), i));
+ mem_port = this->system->physmem->getPort("functional");
mem_port->setPeer(virt_port);
virt_port->setPeer(mem_port);
@@ -183,6 +184,23 @@ AlphaFullCPU<Impl>::regStats()
#if FULL_SYSTEM
template <class Impl>
+VirtualPort *
+AlphaFullCPU<Impl>::AlphaTC::getVirtPort(ThreadContext *src_tc)
+{
+ if (!src_tc)
+ return thread->getVirtPort();
+
+ VirtualPort *vp;
+ Port *mem_port;
+
+ vp = new VirtualPort("tc-vport", src_tc);
+ mem_port = cpu->system->physmem->getPort("functional");
+ mem_port->setPeer(vp);
+ vp->setPeer(mem_port);
+ return vp;
+}
+
+template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::dumpFuncProfile()
{
@@ -195,7 +213,6 @@ void
AlphaFullCPU<Impl>::AlphaTC::takeOverFrom(ThreadContext *old_context)
{
// some things should already be set up
- assert(getMemPort() == old_context->getMemPort());
#if FULL_SYSTEM
assert(getSystemPtr() == old_context->getSystemPtr());
#else
@@ -232,6 +249,16 @@ AlphaFullCPU<Impl>::AlphaTC::takeOverFrom(ThreadContext *old_context)
thread->trapPending = false;
}
+#if FULL_SYSTEM
+template <class Impl>
+void
+AlphaFullCPU<Impl>::AlphaTC::delVirtPort(VirtualPort *vp)
+{
+ delete vp->getPeer();
+ delete vp;
+}
+#endif
+
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::activate(int delay)
diff --git a/src/cpu/o3/alpha_dyn_inst.hh b/src/cpu/o3/alpha_dyn_inst.hh
index 143ffe7e4..36a08c4a7 100644
--- a/src/cpu/o3/alpha_dyn_inst.hh
+++ b/src/cpu/o3/alpha_dyn_inst.hh
@@ -207,26 +207,26 @@ class AlphaDynInst : public BaseDynInst<Impl>
void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width)
{
this->cpu->setFloatReg(_destRegIdx[idx], val, width);
- BaseDynInst<Impl>::setFloatRegSingle(si, idx, val);
+ BaseDynInst<Impl>::setFloatReg(si, idx, val, width);
}
void setFloatReg(const StaticInst *si, int idx, FloatReg val)
{
this->cpu->setFloatReg(_destRegIdx[idx], val);
- BaseDynInst<Impl>::setFloatRegDouble(si, idx, val);
+ BaseDynInst<Impl>::setFloatReg(si, idx, val);
}
void setFloatRegBits(const StaticInst *si, int idx,
FloatRegBits val, int width)
{
this->cpu->setFloatRegBits(_destRegIdx[idx], val, width);
- this->instResult.integer = val;
+ BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
}
void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val)
{
this->cpu->setFloatRegBits(_destRegIdx[idx], val);
- BaseDynInst<Impl>::setFloatRegInt(si, idx, val);
+ BaseDynInst<Impl>::setFloatRegBits(si, idx, val);
}
/** Returns the physical register index of the i'th destination
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh
index 8ee47e907..ceb2918e0 100644
--- a/src/cpu/o3/commit_impl.hh
+++ b/src/cpu/o3/commit_impl.hh
@@ -907,7 +907,7 @@ DefaultCommit<Impl>::commitInsts()
!thread[tid]->trapPending);
oldpc = PC[tid];
cpu->system->pcEventQueue.service(
- thread[tid]->getXCProxy());
+ thread[tid]->getTC());
count++;
} while (oldpc != PC[tid]);
if (count > 1) {
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index c5f78d63d..788c6b164 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -122,7 +122,6 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
#if FULL_SYSTEM
system(params->system),
- memCtrl(system->memctrl),
physmem(system->physmem),
#endif // FULL_SYSTEM
mem(params->mem),
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 8e482f1e5..7c8729749 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -474,8 +474,6 @@ class FullO3CPU : public BaseFullCPU
/** Pointer to the system. */
System *system;
- /** Pointer to the memory controller. */
- MemoryController *memCtrl;
/** Pointer to physical memory. */
PhysicalMemory *physmem;
#endif
diff --git a/src/cpu/o3/dep_graph.hh b/src/cpu/o3/dep_graph.hh
index b6c5f1ab1..3659b1a37 100644
--- a/src/cpu/o3/dep_graph.hh
+++ b/src/cpu/o3/dep_graph.hh
@@ -1,3 +1,32 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Kevin Lim
+ */
#ifndef __CPU_O3_DEP_GRAPH_HH__
#define __CPU_O3_DEP_GRAPH_HH__
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 9e8aeb8fb..960d42178 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -115,7 +115,7 @@ class DefaultFetch
QuiescePending,
SwitchOut,
IcacheWaitResponse,
- IcacheRetry,
+ IcacheWaitRetry,
IcacheAccessComplete
};
@@ -268,6 +268,8 @@ class DefaultFetch
}
private:
+ void recvRetry();
+
/** Returns the appropriate thread to fetch, given the fetch policy. */
int getFetchingThread(FetchPriority &fetch_priority);
@@ -360,6 +362,15 @@ class DefaultFetch
/** The width of fetch in instructions. */
unsigned fetchWidth;
+ /** Is the cache blocked? If so no threads can access it. */
+ bool cacheBlocked;
+
+ /** The packet that is waiting to be retried. */
+ PacketPtr retryPkt;
+
+ /** The thread that is waiting on the cache to tell fetch to retry. */
+ int retryTid;
+
/** Cache block size. */
int cacheBlkSize;
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index f3793db6d..e75bc264b 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -43,8 +43,6 @@
#include "arch/tlb.hh"
#include "arch/vtophys.hh"
#include "base/remote_gdb.hh"
-#include "mem/functional/memory_control.hh"
-#include "mem/functional/physical.hh"
#include "sim/system.hh"
#endif // FULL_SYSTEM
@@ -90,18 +88,7 @@ template<class Impl>
void
DefaultFetch<Impl>::IcachePort::recvRetry()
{
- panic("DefaultFetch doesn't support retry yet.");
- // we shouldn't get a retry unless we have a packet that we're
- // waiting to transmit
-/*
- assert(cpu->dcache_pkt != NULL);
- assert(cpu->_status == DcacheRetry);
- Packet *tmp = cpu->dcache_pkt;
- if (sendTiming(tmp)) {
- cpu->_status = DcacheWaitResponse;
- cpu->dcache_pkt = NULL;
- }
-*/
+ fetch->recvRetry();
}
template<class Impl>
@@ -113,6 +100,9 @@ DefaultFetch<Impl>::DefaultFetch(Params *params)
iewToFetchDelay(params->iewToFetchDelay),
commitToFetchDelay(params->commitToFetchDelay),
fetchWidth(params->fetchWidth),
+ cacheBlocked(false),
+ retryPkt(NULL),
+ retryTid(-1),
numThreads(params->numberOfThreads),
numFetchingThreads(params->smtNumFetchingThreads),
interruptPending(false),
@@ -512,9 +502,11 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
unsigned flags = 0;
#endif // FULL_SYSTEM
- if (interruptPending && flags == 0 || switchedOut) {
- // Hold off fetch from getting new instructions while an interrupt
- // is pending.
+ if (cacheBlocked || (interruptPending && flags == 0) || switchedOut) {
+ // Hold off fetch from getting new instructions when:
+ // Cache is blocked, or
+ // while an interrupt is pending and we're not in PAL mode, or
+ // fetch is switched out.
return false;
}
@@ -530,11 +522,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
memReq[tid] = mem_req;
// Translate the instruction request.
-//#if FULL_SYSTEM
- fault = cpu->translateInstReq(mem_req);
-//#else
-// fault = pTable->translate(memReq[tid]);
-//#endif
+ fault = cpu->translateInstReq(mem_req, cpu->thread[tid]);
// In the case of faults, the fetch stage may need to stall and wait
// for the ITB miss to be handled.
@@ -542,7 +530,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
// If translation was successful, attempt to read the first
// instruction.
if (fault == NoFault) {
-#if FULL_SYSTEM
+#if 0
if (cpu->system->memctrl->badaddr(memReq[tid]->paddr) ||
memReq[tid]->flags & UNCACHEABLE) {
DPRINTF(Fetch, "Fetch: Bad address %#x (hopefully on a "
@@ -565,8 +553,13 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
// Now do the timing access to see whether or not the instruction
// exists within the cache.
if (!icachePort->sendTiming(data_pkt)) {
+ assert(retryPkt == NULL);
+ assert(retryTid == -1);
DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
- ret_fault = NoFault;
+ fetchStatus[tid] = IcacheWaitRetry;
+ retryPkt = data_pkt;
+ retryTid = tid;
+ cacheBlocked = true;
return false;
}
@@ -606,6 +599,16 @@ DefaultFetch<Impl>::doSquash(const Addr &new_PC, unsigned tid)
memReq[tid] = NULL;
}
+ // Get rid of the retrying packet if it was from this thread.
+ if (retryTid == tid) {
+ assert(cacheBlocked);
+ cacheBlocked = false;
+ retryTid = -1;
+ retryPkt = NULL;
+ delete retryPkt->req;
+ delete retryPkt;
+ }
+
fetchStatus[tid] = Squashing;
++fetchSquashCycles;
@@ -1105,6 +1108,28 @@ DefaultFetch<Impl>::fetch(bool &status_change)
}
}
+template<class Impl>
+void
+DefaultFetch<Impl>::recvRetry()
+{
+ assert(cacheBlocked);
+ if (retryPkt != NULL) {
+ assert(retryTid != -1);
+ assert(fetchStatus[retryTid] == IcacheWaitRetry);
+
+ if (icachePort->sendTiming(retryPkt)) {
+ fetchStatus[retryTid] = IcacheWaitResponse;
+ retryPkt = NULL;
+ retryTid = -1;
+ cacheBlocked = false;
+ }
+ } else {
+ assert(retryTid == -1);
+ // Access has been squashed since it was sent out. Just clear
+ // the cache being blocked.
+ cacheBlocked = false;
+ }
+}
///////////////////////////////////////
// //
diff --git a/src/cpu/o3/fu_pool.cc b/src/cpu/o3/fu_pool.cc
index b28b5d37f..545deea9b 100644
--- a/src/cpu/o3/fu_pool.cc
+++ b/src/cpu/o3/fu_pool.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,6 +24,8 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Kevin Lim
*/
#include <sstream>
diff --git a/src/cpu/o3/fu_pool.hh b/src/cpu/o3/fu_pool.hh
index 1d4c76690..52d83f056 100644
--- a/src/cpu/o3/fu_pool.hh
+++ b/src/cpu/o3/fu_pool.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,6 +24,8 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Kevin Lim
*/
#ifndef __CPU_O3_FU_POOL_HH__
diff --git a/src/cpu/o3/lsq.cc b/src/cpu/o3/lsq.cc
index 8991ab8f8..de0325920 100644
--- a/src/cpu/o3/lsq.cc
+++ b/src/cpu/o3/lsq.cc
@@ -24,6 +24,8 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
*/
#include "cpu/o3/alpha_dyn_inst.hh"
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index d65510c30..99e0bf9d5 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -24,6 +24,8 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
*/
#ifndef __CPU_O3_LSQ_HH__
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index a6ad27522..d87007bb5 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -24,6 +24,8 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
*/
#include <algorithm>
diff --git a/src/cpu/o3/lsq_unit.cc b/src/cpu/o3/lsq_unit.cc
index dd29007bc..e935ffa5c 100644
--- a/src/cpu/o3/lsq_unit.cc
+++ b/src/cpu/o3/lsq_unit.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Kevin Lim
+ * Korey Sewell
*/
#include "cpu/o3/alpha_dyn_inst.hh"
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index 414309679..3123e246d 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Kevin Lim
+ * Korey Sewell
*/
#ifndef __CPU_O3_LSQ_UNIT_HH__
@@ -210,9 +213,14 @@ class LSQUnit {
private:
void writeback(DynInstPtr &inst, PacketPtr pkt);
+ void storePostSend(Packet *pkt);
+
/** Completes the store at the specified index. */
void completeStore(int store_idx);
+ /** Handles doing the retry. */
+ void recvRetry();
+
/** Increments the given store index (circular queue). */
inline void incrStIdx(int &store_idx);
/** Decrements the given store index (circular queue). */
@@ -396,6 +404,8 @@ class LSQUnit {
/** The index of the above store. */
int stallingLoadIdx;
+ PacketPtr sendingPkt;
+
bool isStoreBlocked;
/** Whether or not a load is blocked due to the memory system. */
@@ -501,7 +511,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
"storeHead: %i addr: %#x\n",
load_idx, store_idx, storeHead, req->getPaddr());
-#if 0
+#if FULL_SYSTEM
if (req->getFlags() & LOCKED) {
cpu->lockAddr = req->getPaddr();
cpu->lockFlag = true;
@@ -556,7 +566,7 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
DPRINTF(LSQUnit, "Forwarding from store idx %i to load to "
"addr %#x, data %#x\n",
- store_idx, req->getVaddr(), *(load_inst->memData));
+ store_idx, req->getVaddr(), data);
PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
data_pkt->dataStatic(load_inst->memData);
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index 2679eb52b..a768b021c 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Kevin Lim
+ * Korey Sewell
*/
#include "cpu/checker/cpu.hh"
@@ -122,18 +125,7 @@ template <class Impl>
void
LSQUnit<Impl>::DcachePort::recvRetry()
{
- panic("Retry unsupported for now!");
- // we shouldn't get a retry unless we have a packet that we're
- // waiting to transmit
-/*
- assert(cpu->dcache_pkt != NULL);
- assert(cpu->_status == DcacheRetry);
- PacketPtr tmp = cpu->dcache_pkt;
- if (sendTiming(tmp)) {
- cpu->_status = DcacheWaitResponse;
- cpu->dcache_pkt = NULL;
- }
-*/
+ lsq->recvRetry();
}
template <class Impl>
@@ -612,47 +604,34 @@ LSQUnit<Impl>::writebackStores()
req->getPaddr(), *(inst->memData),
storeQueue[storeWBIdx].inst->seqNum);
+ // @todo: Remove this SC hack once the memory system handles it.
+ if (req->getFlags() & LOCKED) {
+ if (req->getFlags() & UNCACHEABLE) {
+ req->setScResult(2);
+ } else {
+ if (cpu->lockFlag) {
+ req->setScResult(1);
+ } else {
+ req->setScResult(0);
+ // Hack: Instantly complete this store.
+ completeDataAccess(data_pkt);
+ incrStIdx(storeWBIdx);
+ continue;
+ }
+ }
+ } else {
+ // Non-store conditionals do not need a writeback.
+ state->noWB = true;
+ }
+
if (!dcachePort->sendTiming(data_pkt)) {
// Need to handle becoming blocked on a store.
isStoreBlocked = true;
- } else {
- if (isStalled() &&
- storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) {
- DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] "
- "load idx:%i\n",
- stallingStoreIsn, stallingLoadIdx);
- stalled = false;
- stallingStoreIsn = 0;
- iewStage->replayMemInst(loadQueue[stallingLoadIdx]);
- }
-
- if (!(req->getFlags() & LOCKED)) {
- assert(!storeQueue[storeWBIdx].inst->isStoreConditional());
- // Non-store conditionals do not need a writeback.
- state->noWB = true;
- }
-
- if (data_pkt->result != Packet::Success) {
- DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n",
- storeWBIdx);
-
- DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n",
- storeQueue[storeWBIdx].inst->seqNum);
-
- //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum);
- //DPRINTF(LSQUnit, "Added MSHR. count = %i\n",mshrSeqNums.size());
-
- // @todo: Increment stat here.
- } else {
- DPRINTF(LSQUnit,"D-Cache: Write Hit on idx:%i !\n",
- storeWBIdx);
-
- DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n",
- storeQueue[storeWBIdx].inst->seqNum);
- }
-
- incrStIdx(storeWBIdx);
+ assert(sendingPkt == NULL);
+ sendingPkt = data_pkt;
+ } else {
+ storePostSend(data_pkt);
}
}
@@ -758,6 +737,53 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
template <class Impl>
void
+LSQUnit<Impl>::storePostSend(Packet *pkt)
+{
+ if (isStalled() &&
+ storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) {
+ DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] "
+ "load idx:%i\n",
+ stallingStoreIsn, stallingLoadIdx);
+ stalled = false;
+ stallingStoreIsn = 0;
+ iewStage->replayMemInst(loadQueue[stallingLoadIdx]);
+ }
+
+ if (!storeQueue[storeWBIdx].inst->isStoreConditional()) {
+ // The store is basically completed at this time. This
+ // only works so long as the checker doesn't try to
+ // verify the value in memory for stores.
+ storeQueue[storeWBIdx].inst->setCompleted();
+ if (cpu->checker) {
+ cpu->checker->tick(storeQueue[storeWBIdx].inst);
+ }
+ }
+
+ if (pkt->result != Packet::Success) {
+ DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n",
+ storeWBIdx);
+
+ DPRINTF(Activity, "Active st accessing mem miss [sn:%lli]\n",
+ storeQueue[storeWBIdx].inst->seqNum);
+
+ //mshrSeqNums.push_back(storeQueue[storeWBIdx].inst->seqNum);
+
+ //DPRINTF(LSQUnit, "Added MSHR. count = %i\n",mshrSeqNums.size());
+
+ // @todo: Increment stat here.
+ } else {
+ DPRINTF(LSQUnit,"D-Cache: Write Hit on idx:%i !\n",
+ storeWBIdx);
+
+ DPRINTF(Activity, "Active st accessing mem hit [sn:%lli]\n",
+ storeQueue[storeWBIdx].inst->seqNum);
+ }
+
+ incrStIdx(storeWBIdx);
+}
+
+template <class Impl>
+void
LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
{
iewStage->wakeCPU();
@@ -829,6 +855,28 @@ LSQUnit<Impl>::completeStore(int store_idx)
}
template <class Impl>
+void
+LSQUnit<Impl>::recvRetry()
+{
+ assert(sendingPkt != NULL);
+
+ if (isStoreBlocked) {
+ if (dcachePort->sendTiming(sendingPkt)) {
+ storePostSend(sendingPkt);
+ sendingPkt = NULL;
+ isStoreBlocked = false;
+ } else {
+ // Still blocked!
+ }
+ } else if (isLoadBlocked) {
+ DPRINTF(LSQUnit, "Loads squash themselves and all younger insts, "
+ "no need to resend packet.\n");
+ } else {
+ DPRINTF(LSQUnit, "Retry received but LSQ is no longer blocked.\n");
+ }
+}
+
+template <class Impl>
inline void
LSQUnit<Impl>::incrStIdx(int &store_idx)
{
diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh
index a142b7102..ade5e4e56 100644
--- a/src/cpu/o3/regfile.hh
+++ b/src/cpu/o3/regfile.hh
@@ -96,7 +96,7 @@ class PhysRegFile
assert(reg_idx < numPhysicalIntRegs);
DPRINTF(IEW, "RegFile: Access to int register %i, has data "
- "%i\n", int(reg_idx), intRegFile[reg_idx]);
+ "%#x\n", int(reg_idx), intRegFile[reg_idx]);
return intRegFile[reg_idx];
}
@@ -110,7 +110,7 @@ class PhysRegFile
FloatReg floatReg = floatRegFile[reg_idx].d;
DPRINTF(IEW, "RegFile: Access to %d byte float register %i, has "
- "data %8.8d\n", int(reg_idx), (double)floatReg);
+ "data %#x\n", int(reg_idx), floatRegFile[reg_idx].q);
return floatReg;
}
@@ -126,7 +126,7 @@ class PhysRegFile
FloatReg floatReg = floatRegFile[reg_idx].d;
DPRINTF(IEW, "RegFile: Access to float register %i, has "
- "data %8.8d\n", int(reg_idx), (double)floatReg);
+ "data %#x\n", int(reg_idx), floatRegFile[reg_idx].q);
return floatReg;
}
@@ -141,8 +141,8 @@ class PhysRegFile
FloatRegBits floatRegBits = floatRegFile[reg_idx].q;
- DPRINTF(IEW, "RegFile: Access to %d byte float register %i as int, "
- "has data %lli\n", int(reg_idx), (uint64_t)floatRegBits);
+ DPRINTF(IEW, "RegFile: Access to float register %i as int, "
+ "has data %#x\n", int(reg_idx), (uint64_t)floatRegBits);
return floatRegBits;
}
@@ -157,7 +157,7 @@ class PhysRegFile
FloatRegBits floatRegBits = floatRegFile[reg_idx].q;
DPRINTF(IEW, "RegFile: Access to float register %i as int, "
- "has data %lli\n", int(reg_idx), (uint64_t)floatRegBits);
+ "has data %#x\n", int(reg_idx), (uint64_t)floatRegBits);
return floatRegBits;
}
@@ -167,7 +167,7 @@ class PhysRegFile
{
assert(reg_idx < numPhysicalIntRegs);
- DPRINTF(IEW, "RegFile: Setting int register %i to %lli\n",
+ DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n",
int(reg_idx), val);
if (reg_idx != TheISA::ZeroReg)
@@ -182,11 +182,11 @@ class PhysRegFile
assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
- DPRINTF(IEW, "RegFile: Setting float register %i to %8.8d\n",
- int(reg_idx), (double)val);
+ DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
+ int(reg_idx), (uint64_t)val);
if (reg_idx != TheISA::ZeroReg)
- floatRegFile[reg_idx].d = width;
+ floatRegFile[reg_idx].d = val;
}
/** Sets a double precision floating point register to the given value. */
@@ -197,8 +197,8 @@ class PhysRegFile
assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
- DPRINTF(IEW, "RegFile: Setting float register %i to %8.8d\n",
- int(reg_idx), (double)val);
+ DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
+ int(reg_idx), (uint64_t)val);
if (reg_idx != TheISA::ZeroReg)
floatRegFile[reg_idx].d = val;
@@ -212,7 +212,7 @@ class PhysRegFile
assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
- DPRINTF(IEW, "RegFile: Setting float register %i to %lli\n",
+ DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
int(reg_idx), (uint64_t)val);
floatRegFile[reg_idx].q = val;
@@ -225,7 +225,7 @@ class PhysRegFile
assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
- DPRINTF(IEW, "RegFile: Setting float register %i to %lli\n",
+ DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
int(reg_idx), (uint64_t)val);
floatRegFile[reg_idx].q = val;
@@ -263,10 +263,10 @@ class PhysRegFile
public:
/** (signed) integer register file. */
- std::vector<IntReg> intRegFile;
+ IntReg *intRegFile;
/** Floating point register file. */
- std::vector<PhysFloatReg> floatRegFile;
+ PhysFloatReg *floatRegFile;
/** Miscellaneous register file. */
MiscRegFile miscRegs[Impl::MaxThreads];
@@ -296,15 +296,15 @@ PhysRegFile<Impl>::PhysRegFile(unsigned _numPhysicalIntRegs,
: numPhysicalIntRegs(_numPhysicalIntRegs),
numPhysicalFloatRegs(_numPhysicalFloatRegs)
{
- intRegFile.resize(numPhysicalIntRegs);
- floatRegFile.resize(numPhysicalFloatRegs);
+ intRegFile = new IntReg[numPhysicalIntRegs];
+ floatRegFile = new PhysFloatReg[numPhysicalFloatRegs];
for (int i = 0; i < Impl::MaxThreads; ++i) {
miscRegs[i].clear();
}
- //memset(intRegFile, 0, sizeof(*intRegFile));
- //memset(floatRegFile, 0, sizeof(*floatRegFile));
+ memset(intRegFile, 0, sizeof(IntReg) * numPhysicalIntRegs);
+ memset(floatRegFile, 0, sizeof(PhysFloatReg) * numPhysicalFloatRegs);
}
#endif
diff --git a/src/cpu/o3/scoreboard.cc b/src/cpu/o3/scoreboard.cc
index b0e433620..1859b35a4 100644
--- a/src/cpu/o3/scoreboard.cc
+++ b/src/cpu/o3/scoreboard.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2005-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
+ * Kevin Lim
*/
#include "cpu/o3/scoreboard.hh"
diff --git a/src/cpu/o3/scoreboard.hh b/src/cpu/o3/scoreboard.hh
index 77f2cf157..f8e4df3b7 100644
--- a/src/cpu/o3/scoreboard.hh
+++ b/src/cpu/o3/scoreboard.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2005-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
+ * Kevin Lim
*/
#ifndef __CPU_O3_SCOREBOARD_HH__
diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh
index 38d37ec96..b6535baa1 100644
--- a/src/cpu/o3/thread_state.hh
+++ b/src/cpu/o3/thread_state.hh
@@ -24,6 +24,8 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Kevin Lim
*/
#ifndef __CPU_O3_THREAD_STATE_HH__
@@ -73,7 +75,7 @@ struct O3ThreadState : public ThreadState {
bool trapPending;
#if FULL_SYSTEM
- O3ThreadState(FullCPU *_cpu, int _thread_num, )
+ O3ThreadState(FullCPU *_cpu, int _thread_num)
: ThreadState(-1, _thread_num),
inSyscall(0), trapPending(0)
{ }