Merge zizzer.eecs.umich.edu:/bk/newmem
into zower.eecs.umich.edu:/home/gblack/m5/newmem-statetrace --HG-- extra : convert_revision : 82a956ffc1bedb2c0d05c4ea3469f843f559a475
This commit is contained in:
commit
df1ea2cf05
32 changed files with 302 additions and 95 deletions
|
@ -123,6 +123,9 @@ namespace AlphaISA
|
||||||
|
|
||||||
// Alpha IPR register accessors
|
// Alpha IPR register accessors
|
||||||
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
inline bool PcPAL(Addr addr) { return addr & 0x3; }
|
||||||
|
inline void startupCPU(ThreadContext *tc, int cpuId) {
|
||||||
|
tc->activate(0);
|
||||||
|
}
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||||
|
* Copyright (c) 2007 MIPS Technologies, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
*
|
*
|
||||||
* Authors: Nathan Binkert
|
* Authors: Nathan Binkert
|
||||||
* Steve Reinhardt
|
* Steve Reinhardt
|
||||||
|
* Korey Sewell
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ARCH_MIPS_UTILITY_HH__
|
#ifndef __ARCH_MIPS_UTILITY_HH__
|
||||||
|
@ -98,6 +100,11 @@ namespace MipsISA {
|
||||||
return ExtMachInst(inst);
|
return ExtMachInst(inst);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void startupCPU(ThreadContext *tc, int cpuId)
|
||||||
|
{
|
||||||
|
tc->activate(0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -247,7 +247,8 @@ namespace SparcISA
|
||||||
bool AsiIsCmt(ASI asi)
|
bool AsiIsCmt(ASI asi)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
(asi == ASI_CMT_PER_STRAND);
|
(asi == ASI_CMT_PER_STRAND) ||
|
||||||
|
(asi == ASI_CMT_SHARED);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsiIsQueue(ASI asi)
|
bool AsiIsQueue(ASI asi)
|
||||||
|
@ -295,7 +296,8 @@ namespace SparcISA
|
||||||
bool AsiIsReg(ASI asi)
|
bool AsiIsReg(ASI asi)
|
||||||
{
|
{
|
||||||
return AsiIsMmu(asi) || AsiIsScratchPad(asi) ||
|
return AsiIsMmu(asi) || AsiIsScratchPad(asi) ||
|
||||||
AsiIsSparcError(asi) || AsiIsInterrupt(asi);
|
AsiIsSparcError(asi) || AsiIsInterrupt(asi)
|
||||||
|
|| AsiIsCmt(asi);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsiIsSparcError(ASI asi)
|
bool AsiIsSparcError(ASI asi)
|
||||||
|
|
|
@ -115,6 +115,7 @@ namespace SparcISA
|
||||||
ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1 = 0x3E,
|
ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1 = 0x3E,
|
||||||
ASI_IMMU_CTXT_NONZERO_CONFIG = 0x3F,
|
ASI_IMMU_CTXT_NONZERO_CONFIG = 0x3F,
|
||||||
ASI_STREAM_MA = 0x40,
|
ASI_STREAM_MA = 0x40,
|
||||||
|
ASI_CMT_SHARED = 0x41,
|
||||||
//0x41 implementation dependent
|
//0x41 implementation dependent
|
||||||
ASI_SPARC_BIST_CONTROL = 0x42,
|
ASI_SPARC_BIST_CONTROL = 0x42,
|
||||||
ASI_INST_MASK_REG = 0x42,
|
ASI_INST_MASK_REG = 0x42,
|
||||||
|
|
|
@ -620,10 +620,6 @@ decode OP default Unknown::unknown()
|
||||||
}});
|
}});
|
||||||
0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
|
0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}});
|
||||||
0x1A: Priv::wrstrand_sts_reg({{
|
0x1A: Priv::wrstrand_sts_reg({{
|
||||||
if(Pstate<2:> && !Hpstate<2:>)
|
|
||||||
StrandStsReg = StrandStsReg<63:1> |
|
|
||||||
(Rs1 ^ Rs2_or_imm13)<0:>;
|
|
||||||
else
|
|
||||||
StrandStsReg = Rs1 ^ Rs2_or_imm13;
|
StrandStsReg = Rs1 ^ Rs2_or_imm13;
|
||||||
}});
|
}});
|
||||||
//0x1A is supposed to be reserved, but it writes the strand
|
//0x1A is supposed to be reserved, but it writes the strand
|
||||||
|
|
|
@ -163,6 +163,23 @@ namespace SparcISA
|
||||||
const static int ie = 0x2;
|
const static int ie = 0x2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct STS {
|
||||||
|
const static int st_idle = 0x00;
|
||||||
|
const static int st_wait = 0x01;
|
||||||
|
const static int st_halt = 0x02;
|
||||||
|
const static int st_run = 0x05;
|
||||||
|
const static int st_spec_run = 0x07;
|
||||||
|
const static int st_spec_rdy = 0x13;
|
||||||
|
const static int st_ready = 0x19;
|
||||||
|
const static int active = 0x01;
|
||||||
|
const static int speculative = 0x04;
|
||||||
|
const static int shft_id = 8;
|
||||||
|
const static int shft_fsm0 = 31;
|
||||||
|
const static int shft_fsm1 = 26;
|
||||||
|
const static int shft_fsm2 = 21;
|
||||||
|
const static int shft_fsm3 = 16;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
|
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
|
||||||
const int NumMiscRegs = MISCREG_NUMMISCREGS;
|
const int NumMiscRegs = MISCREG_NUMMISCREGS;
|
||||||
|
|
|
@ -693,6 +693,9 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
||||||
if (AsiIsPartialStore(asi))
|
if (AsiIsPartialStore(asi))
|
||||||
panic("Partial Store ASIs not supported\n");
|
panic("Partial Store ASIs not supported\n");
|
||||||
|
|
||||||
|
if (AsiIsCmt(asi))
|
||||||
|
panic("Cmt ASI registers not implmented\n");
|
||||||
|
|
||||||
if (AsiIsInterrupt(asi))
|
if (AsiIsInterrupt(asi))
|
||||||
goto handleIntRegAccess;
|
goto handleIntRegAccess;
|
||||||
if (AsiIsMmu(asi))
|
if (AsiIsMmu(asi))
|
||||||
|
|
|
@ -26,11 +26,13 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "arch/sparc/kernel_stats.hh"
|
||||||
#include "arch/sparc/miscregfile.hh"
|
#include "arch/sparc/miscregfile.hh"
|
||||||
#include "base/bitfield.hh"
|
#include "base/bitfield.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace SparcISA;
|
using namespace SparcISA;
|
||||||
|
|
||||||
|
@ -185,10 +187,21 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case MISCREG_HTSTATE:
|
case MISCREG_HTSTATE:
|
||||||
case MISCREG_STRAND_STS_REG:
|
|
||||||
setRegNoEffect(miscReg, val);
|
setRegNoEffect(miscReg, val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MISCREG_STRAND_STS_REG:
|
||||||
|
if (bits(val,2,2))
|
||||||
|
panic("No support for setting spec_en bit\n");
|
||||||
|
setRegNoEffect(miscReg, bits(val,0,0));
|
||||||
|
if (!bits(val,0,0)) {
|
||||||
|
// Time to go to sleep
|
||||||
|
tc->suspend();
|
||||||
|
if (tc->getKernelStats())
|
||||||
|
tc->getKernelStats()->quiesce();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
|
panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg));
|
||||||
}
|
}
|
||||||
|
@ -197,6 +210,8 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
|
||||||
MiscReg
|
MiscReg
|
||||||
MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
|
MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
|
||||||
{
|
{
|
||||||
|
uint64_t temp;
|
||||||
|
|
||||||
switch (miscReg) {
|
switch (miscReg) {
|
||||||
/* Privileged registers. */
|
/* Privileged registers. */
|
||||||
case MISCREG_QUEUE_CPU_MONDO_HEAD:
|
case MISCREG_QUEUE_CPU_MONDO_HEAD:
|
||||||
|
@ -214,7 +229,6 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
|
||||||
case MISCREG_HPSTATE:
|
case MISCREG_HPSTATE:
|
||||||
case MISCREG_HINTP:
|
case MISCREG_HINTP:
|
||||||
case MISCREG_HTSTATE:
|
case MISCREG_HTSTATE:
|
||||||
case MISCREG_STRAND_STS_REG:
|
|
||||||
case MISCREG_HSTICK_CMPR:
|
case MISCREG_HSTICK_CMPR:
|
||||||
return readRegNoEffect(miscReg) ;
|
return readRegNoEffect(miscReg) ;
|
||||||
|
|
||||||
|
@ -223,6 +237,38 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc)
|
||||||
case MISCREG_HVER:
|
case MISCREG_HVER:
|
||||||
return NWindows | MaxTL << 8 | MaxGL << 16;
|
return NWindows | MaxTL << 8 | MaxGL << 16;
|
||||||
|
|
||||||
|
case MISCREG_STRAND_STS_REG:
|
||||||
|
System *sys;
|
||||||
|
int x;
|
||||||
|
sys = tc->getSystemPtr();
|
||||||
|
|
||||||
|
temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative);
|
||||||
|
// Check that the CPU array is fully populated (by calling getNumCPus())
|
||||||
|
assert(sys->getNumCPUs() > tc->readCpuId());
|
||||||
|
|
||||||
|
temp |= tc->readCpuId() << STS::shft_id;
|
||||||
|
|
||||||
|
for (x = tc->readCpuId() & ~3; x < sys->threadContexts.size(); x++) {
|
||||||
|
switch (sys->threadContexts[x]->status()) {
|
||||||
|
case ThreadContext::Active:
|
||||||
|
temp |= STS::st_run << (STS::shft_fsm0 -
|
||||||
|
((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
|
||||||
|
break;
|
||||||
|
case ThreadContext::Suspended:
|
||||||
|
// should this be idle?
|
||||||
|
temp |= STS::st_idle << (STS::shft_fsm0 -
|
||||||
|
((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
|
||||||
|
break;
|
||||||
|
case ThreadContext::Halted:
|
||||||
|
temp |= STS::st_halt << (STS::shft_fsm0 -
|
||||||
|
((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("What state are we in?!\n");
|
||||||
|
} // switch
|
||||||
|
} // for
|
||||||
|
|
||||||
|
return temp;
|
||||||
default:
|
default:
|
||||||
panic("Invalid read to FS misc register\n");
|
panic("Invalid read to FS misc register\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,20 @@ namespace SparcISA
|
||||||
inline void initCPU(ThreadContext *tc, int cpuId)
|
inline void initCPU(ThreadContext *tc, int cpuId)
|
||||||
{
|
{
|
||||||
static Fault por = new PowerOnReset();
|
static Fault por = new PowerOnReset();
|
||||||
|
if (cpuId == 0)
|
||||||
por->invoke(tc);
|
por->invoke(tc);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void startupCPU(ThreadContext *tc, int cpuId)
|
||||||
|
{
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
// Other CPUs will get activated by IPIs
|
||||||
|
if (cpuId == 0)
|
||||||
|
tc->activate(0);
|
||||||
|
#else
|
||||||
|
tc->activate(0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace SparcISA
|
} // namespace SparcISA
|
||||||
|
|
|
@ -126,6 +126,11 @@ namespace X86ISA
|
||||||
{
|
{
|
||||||
panic("initCPU not implemented!\n");
|
panic("initCPU not implemented!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void startupCPU(ThreadContext *tc, int cpuId)
|
||||||
|
{
|
||||||
|
tc->activate(0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ARCH_X86_UTILITY_HH__
|
#endif // __ARCH_X86_UTILITY_HH__
|
||||||
|
|
|
@ -319,7 +319,7 @@ BaseCPU::switchOut()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BaseCPU::takeOverFrom(BaseCPU *oldCPU)
|
BaseCPU::takeOverFrom(BaseCPU *oldCPU, Port *ic, Port *dc)
|
||||||
{
|
{
|
||||||
assert(threadContexts.size() == oldCPU->threadContexts.size());
|
assert(threadContexts.size() == oldCPU->threadContexts.size());
|
||||||
|
|
||||||
|
@ -352,6 +352,26 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
|
||||||
// if (profileEvent)
|
// if (profileEvent)
|
||||||
// profileEvent->schedule(curTick);
|
// profileEvent->schedule(curTick);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Connect new CPU to old CPU's memory only if new CPU isn't
|
||||||
|
// connected to anything. Also connect old CPU's memory to new
|
||||||
|
// CPU.
|
||||||
|
Port *peer;
|
||||||
|
if (ic->getPeer() == NULL) {
|
||||||
|
peer = oldCPU->getPort("icache_port")->getPeer();
|
||||||
|
ic->setPeer(peer);
|
||||||
|
} else {
|
||||||
|
peer = ic->getPeer();
|
||||||
|
}
|
||||||
|
peer->setPeer(ic);
|
||||||
|
|
||||||
|
if (dc->getPeer() == NULL) {
|
||||||
|
peer = oldCPU->getPort("dcache_port")->getPeer();
|
||||||
|
dc->setPeer(peer);
|
||||||
|
} else {
|
||||||
|
peer = dc->getPeer();
|
||||||
|
}
|
||||||
|
peer->setPeer(dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ class BaseCPU : public MemObject
|
||||||
|
|
||||||
/// Take over execution from the given CPU. Used for warm-up and
|
/// Take over execution from the given CPU. Used for warm-up and
|
||||||
/// sampling.
|
/// sampling.
|
||||||
virtual void takeOverFrom(BaseCPU *);
|
virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of threads we're actually simulating (<= SMT_MAX_THREADS).
|
* Number of threads we're actually simulating (<= SMT_MAX_THREADS).
|
||||||
|
|
|
@ -557,12 +557,6 @@ template <class Impl>
|
||||||
void
|
void
|
||||||
FullO3CPU<Impl>::activateContext(int tid, int delay)
|
FullO3CPU<Impl>::activateContext(int tid, int delay)
|
||||||
{
|
{
|
||||||
#if FULL_SYSTEM
|
|
||||||
// Connect the ThreadContext's memory ports (Functional/Virtual
|
|
||||||
// Ports)
|
|
||||||
threadContexts[tid]->connectMemPorts();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Needs to set each stage to running as well.
|
// Needs to set each stage to running as well.
|
||||||
if (delay){
|
if (delay){
|
||||||
DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
|
DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
|
||||||
|
@ -781,6 +775,18 @@ FullO3CPU<Impl>::activateWhenReady(int tid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
template <class Impl>
|
||||||
|
void
|
||||||
|
FullO3CPU<Impl>::updateMemPorts()
|
||||||
|
{
|
||||||
|
// Update all ThreadContext's memory ports (Functional/Virtual
|
||||||
|
// Ports)
|
||||||
|
for (int i = 0; i < thread.size(); ++i)
|
||||||
|
thread[i]->connectMemPorts();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
FullO3CPU<Impl>::serialize(std::ostream &os)
|
FullO3CPU<Impl>::serialize(std::ostream &os)
|
||||||
|
@ -941,7 +947,7 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
|
||||||
|
|
||||||
activityRec.reset();
|
activityRec.reset();
|
||||||
|
|
||||||
BaseCPU::takeOverFrom(oldCPU);
|
BaseCPU::takeOverFrom(oldCPU, fetch.getIcachePort(), iew.getDcachePort());
|
||||||
|
|
||||||
fetch.takeOverFrom();
|
fetch.takeOverFrom();
|
||||||
decode.takeOverFrom();
|
decode.takeOverFrom();
|
||||||
|
@ -978,25 +984,6 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
|
||||||
}
|
}
|
||||||
if (!tickEvent.scheduled())
|
if (!tickEvent.scheduled())
|
||||||
tickEvent.schedule(curTick);
|
tickEvent.schedule(curTick);
|
||||||
|
|
||||||
Port *peer;
|
|
||||||
Port *icachePort = fetch.getIcachePort();
|
|
||||||
if (icachePort->getPeer() == NULL) {
|
|
||||||
peer = oldCPU->getPort("icache_port")->getPeer();
|
|
||||||
icachePort->setPeer(peer);
|
|
||||||
} else {
|
|
||||||
peer = icachePort->getPeer();
|
|
||||||
}
|
|
||||||
peer->setPeer(icachePort);
|
|
||||||
|
|
||||||
Port *dcachePort = iew.getDcachePort();
|
|
||||||
if (dcachePort->getPeer() == NULL) {
|
|
||||||
peer = oldCPU->getPort("dcache_port")->getPeer();
|
|
||||||
dcachePort->setPeer(peer);
|
|
||||||
} else {
|
|
||||||
peer = dcachePort->getPeer();
|
|
||||||
}
|
|
||||||
peer->setPeer(dcachePort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
|
|
@ -357,6 +357,10 @@ class FullO3CPU : public BaseO3CPU
|
||||||
{ return globalSeqNum++; }
|
{ return globalSeqNum++; }
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
|
/** Update the Virt and Phys ports of all ThreadContexts to
|
||||||
|
* reflect change in memory connections. */
|
||||||
|
void updateMemPorts();
|
||||||
|
|
||||||
/** Check if this address is a valid instruction address. */
|
/** Check if this address is a valid instruction address. */
|
||||||
bool validInstAddr(Addr addr) { return true; }
|
bool validInstAddr(Addr addr) { return true; }
|
||||||
|
|
||||||
|
|
|
@ -300,6 +300,8 @@ class LSQ {
|
||||||
|
|
||||||
bool snoopRangeSent;
|
bool snoopRangeSent;
|
||||||
|
|
||||||
|
virtual void setPeer(Port *port);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Atomic version of receive. Panics. */
|
/** Atomic version of receive. Panics. */
|
||||||
virtual Tick recvAtomic(PacketPtr pkt);
|
virtual Tick recvAtomic(PacketPtr pkt);
|
||||||
|
@ -327,6 +329,11 @@ class LSQ {
|
||||||
/** D-cache port. */
|
/** D-cache port. */
|
||||||
DcachePort dcachePort;
|
DcachePort dcachePort;
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
/** Tell the CPU to update the Phys and Virt ports. */
|
||||||
|
void updateMemPorts() { cpu->updateMemPorts(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** The LSQ policy for SMT mode. */
|
/** The LSQ policy for SMT mode. */
|
||||||
LSQPolicy lsqPolicy;
|
LSQPolicy lsqPolicy;
|
||||||
|
|
|
@ -34,6 +34,19 @@
|
||||||
|
|
||||||
#include "cpu/o3/lsq.hh"
|
#include "cpu/o3/lsq.hh"
|
||||||
|
|
||||||
|
template<class Impl>
|
||||||
|
void
|
||||||
|
LSQ<Impl>::DcachePort::setPeer(Port *port)
|
||||||
|
{
|
||||||
|
Port::setPeer(port);
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
// Update the ThreadContext's memory ports (Functional/Virtual
|
||||||
|
// Ports)
|
||||||
|
lsq->updateMemPorts();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
Tick
|
Tick
|
||||||
LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
|
LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
|
||||||
|
|
|
@ -126,6 +126,17 @@ AtomicSimpleCPU::CpuPort::recvRetry()
|
||||||
panic("AtomicSimpleCPU doesn't expect recvRetry callback!");
|
panic("AtomicSimpleCPU doesn't expect recvRetry callback!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AtomicSimpleCPU::DcachePort::setPeer(Port *port)
|
||||||
|
{
|
||||||
|
Port::setPeer(port);
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
// Update the ThreadContext's memory ports (Functional/Virtual
|
||||||
|
// Ports)
|
||||||
|
cpu->tcBase()->connectMemPorts();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
|
AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
|
||||||
: BaseSimpleCPU(p), tickEvent(this),
|
: BaseSimpleCPU(p), tickEvent(this),
|
||||||
|
@ -211,7 +222,7 @@ AtomicSimpleCPU::switchOut()
|
||||||
void
|
void
|
||||||
AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
|
AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
|
||||||
{
|
{
|
||||||
BaseCPU::takeOverFrom(oldCPU);
|
BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
|
||||||
|
|
||||||
assert(!tickEvent.scheduled());
|
assert(!tickEvent.scheduled());
|
||||||
|
|
||||||
|
@ -242,12 +253,6 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay)
|
||||||
|
|
||||||
notIdleFraction++;
|
notIdleFraction++;
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
// Connect the ThreadContext's memory ports (Functional/Virtual
|
|
||||||
// Ports)
|
|
||||||
tc->connectMemPorts();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Make sure ticks are still on multiples of cycles
|
//Make sure ticks are still on multiples of cycles
|
||||||
tickEvent.schedule(nextCycle(curTick + cycles(delay)));
|
tickEvent.schedule(nextCycle(curTick + cycles(delay)));
|
||||||
_status = Running;
|
_status = Running;
|
||||||
|
|
|
@ -81,9 +81,6 @@ class AtomicSimpleCPU : public BaseSimpleCPU
|
||||||
|
|
||||||
class CpuPort : public Port
|
class CpuPort : public Port
|
||||||
{
|
{
|
||||||
|
|
||||||
AtomicSimpleCPU *cpu;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu)
|
CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu)
|
||||||
|
@ -94,6 +91,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
AtomicSimpleCPU *cpu;
|
||||||
|
|
||||||
virtual bool recvTiming(PacketPtr pkt);
|
virtual bool recvTiming(PacketPtr pkt);
|
||||||
|
|
||||||
virtual Tick recvAtomic(PacketPtr pkt);
|
virtual Tick recvAtomic(PacketPtr pkt);
|
||||||
|
@ -110,7 +109,17 @@ class AtomicSimpleCPU : public BaseSimpleCPU
|
||||||
|
|
||||||
};
|
};
|
||||||
CpuPort icachePort;
|
CpuPort icachePort;
|
||||||
CpuPort dcachePort;
|
|
||||||
|
class DcachePort : public CpuPort
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DcachePort(const std::string &_name, AtomicSimpleCPU *_cpu)
|
||||||
|
: CpuPort(_name, _cpu)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void setPeer(Port *port);
|
||||||
|
};
|
||||||
|
DcachePort dcachePort;
|
||||||
|
|
||||||
Request *ifetch_req;
|
Request *ifetch_req;
|
||||||
PacketPtr ifetch_pkt;
|
PacketPtr ifetch_pkt;
|
||||||
|
|
|
@ -194,7 +194,7 @@ TimingSimpleCPU::switchOut()
|
||||||
void
|
void
|
||||||
TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
|
TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
|
||||||
{
|
{
|
||||||
BaseCPU::takeOverFrom(oldCPU);
|
BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
|
||||||
|
|
||||||
// if any of this CPU's ThreadContexts are active, mark the CPU as
|
// if any of this CPU's ThreadContexts are active, mark the CPU as
|
||||||
// running and schedule its tick event.
|
// running and schedule its tick event.
|
||||||
|
@ -209,23 +209,6 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
|
||||||
if (_status != Running) {
|
if (_status != Running) {
|
||||||
_status = Idle;
|
_status = Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
Port *peer;
|
|
||||||
if (icachePort.getPeer() == NULL) {
|
|
||||||
peer = oldCPU->getPort("icache_port")->getPeer();
|
|
||||||
icachePort.setPeer(peer);
|
|
||||||
} else {
|
|
||||||
peer = icachePort.getPeer();
|
|
||||||
}
|
|
||||||
peer->setPeer(&icachePort);
|
|
||||||
|
|
||||||
if (dcachePort.getPeer() == NULL) {
|
|
||||||
peer = oldCPU->getPort("dcache_port")->getPeer();
|
|
||||||
dcachePort.setPeer(peer);
|
|
||||||
} else {
|
|
||||||
peer = dcachePort.getPeer();
|
|
||||||
}
|
|
||||||
peer->setPeer(&dcachePort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,12 +223,6 @@ TimingSimpleCPU::activateContext(int thread_num, int delay)
|
||||||
notIdleFraction++;
|
notIdleFraction++;
|
||||||
_status = Running;
|
_status = Running;
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
// Connect the ThreadContext's memory ports (Functional/Virtual
|
|
||||||
// Ports)
|
|
||||||
tc->connectMemPorts();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// kick things off by initiating the fetch of the next instruction
|
// kick things off by initiating the fetch of the next instruction
|
||||||
fetchEvent =
|
fetchEvent =
|
||||||
new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false);
|
new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false);
|
||||||
|
@ -649,6 +626,18 @@ TimingSimpleCPU::completeDrain()
|
||||||
drainEvent->process();
|
drainEvent->process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimingSimpleCPU::DcachePort::setPeer(Port *port)
|
||||||
|
{
|
||||||
|
Port::setPeer(port);
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
// Update the ThreadContext's memory ports (Functional/Virtual
|
||||||
|
// Ports)
|
||||||
|
cpu->tcBase()->connectMemPorts();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
|
TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -144,6 +144,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
||||||
: CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu)
|
: CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
virtual void setPeer(Port *port);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual bool recvTiming(PacketPtr pkt);
|
virtual bool recvTiming(PacketPtr pkt);
|
||||||
|
|
|
@ -125,6 +125,9 @@ ThreadState::connectPhysPort()
|
||||||
// @todo: For now this disregards any older port that may have
|
// @todo: For now this disregards any older port that may have
|
||||||
// already existed. Fix this memory leak once the bus port IDs
|
// already existed. Fix this memory leak once the bus port IDs
|
||||||
// for functional ports is resolved.
|
// for functional ports is resolved.
|
||||||
|
if (physPort)
|
||||||
|
physPort->removeConn();
|
||||||
|
else
|
||||||
physPort = new FunctionalPort(csprintf("%s-%d-funcport",
|
physPort = new FunctionalPort(csprintf("%s-%d-funcport",
|
||||||
baseCpu->name(), tid));
|
baseCpu->name(), tid));
|
||||||
connectToMemFunc(physPort);
|
connectToMemFunc(physPort);
|
||||||
|
@ -136,6 +139,9 @@ ThreadState::connectVirtPort()
|
||||||
// @todo: For now this disregards any older port that may have
|
// @todo: For now this disregards any older port that may have
|
||||||
// already existed. Fix this memory leak once the bus port IDs
|
// already existed. Fix this memory leak once the bus port IDs
|
||||||
// for functional ports is resolved.
|
// for functional ports is resolved.
|
||||||
|
if (virtPort)
|
||||||
|
virtPort->removeConn();
|
||||||
|
else
|
||||||
virtPort = new VirtualPort(csprintf("%s-%d-vport",
|
virtPort = new VirtualPort(csprintf("%s-%d-vport",
|
||||||
baseCpu->name(), tid));
|
baseCpu->name(), tid));
|
||||||
connectToMemFunc(virtPort);
|
connectToMemFunc(virtPort);
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "arch/sparc/isa_traits.hh"
|
#include "arch/sparc/isa_traits.hh"
|
||||||
|
#include "arch/sparc/faults.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/intr_control.hh"
|
#include "cpu/intr_control.hh"
|
||||||
#include "dev/sparc/iob.hh"
|
#include "dev/sparc/iob.hh"
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
#include "mem/port.hh"
|
#include "mem/port.hh"
|
||||||
#include "mem/packet_access.hh"
|
#include "mem/packet_access.hh"
|
||||||
#include "sim/builder.hh"
|
#include "sim/builder.hh"
|
||||||
|
#include "sim/faults.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
Iob::Iob(Params *p)
|
Iob::Iob(Params *p)
|
||||||
|
@ -261,13 +263,30 @@ Iob::receiveDeviceInterrupt(DeviceId devid)
|
||||||
void
|
void
|
||||||
Iob::generateIpi(Type type, int cpu_id, int vector)
|
Iob::generateIpi(Type type, int cpu_id, int vector)
|
||||||
{
|
{
|
||||||
// Only handle interrupts for the moment... Cpu Idle/reset/resume will be
|
SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
|
||||||
// later
|
if (cpu_id >= sys->getNumCPUs())
|
||||||
if (type != 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
assert(type == 0);
|
switch (type) {
|
||||||
|
case 0: // interrupt
|
||||||
ic->post(cpu_id, SparcISA::IT_INT_VEC, vector);
|
ic->post(cpu_id, SparcISA::IT_INT_VEC, vector);
|
||||||
|
break;
|
||||||
|
case 1: // reset
|
||||||
|
warn("Sending reset to CPU: %d\n", cpu_id);
|
||||||
|
if (vector != por->trapType())
|
||||||
|
panic("Don't know how to set non-POR reset to cpu\n");
|
||||||
|
por->invoke(sys->threadContexts[cpu_id]);
|
||||||
|
sys->threadContexts[cpu_id]->activate();
|
||||||
|
break;
|
||||||
|
case 2: // idle -- this means stop executing and don't wake on interrupts
|
||||||
|
sys->threadContexts[cpu_id]->halt();
|
||||||
|
break;
|
||||||
|
case 3: // resume
|
||||||
|
sys->threadContexts[cpu_id]->activate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("Invalid type to generate ipi\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "mem/bus.hh"
|
#include "mem/bus.hh"
|
||||||
|
@ -52,20 +54,30 @@ Bus::getPort(const std::string &if_name, int idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if_name ignored? forced to be empty?
|
// if_name ignored? forced to be empty?
|
||||||
int id = interfaces.size();
|
int id = maxId++;
|
||||||
|
assert(maxId < std::numeric_limits<typeof(maxId)>::max());
|
||||||
BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id);
|
BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id);
|
||||||
interfaces.push_back(bp);
|
interfaces[id] = bp;
|
||||||
return bp;
|
return bp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Bus::deletePortRefs(Port *p)
|
||||||
|
{
|
||||||
|
BusPort *bp = dynamic_cast<BusPort*>(p);
|
||||||
|
if (bp == NULL)
|
||||||
|
panic("Couldn't convert Port* to BusPort*\n");
|
||||||
|
interfaces.erase(bp->getId());
|
||||||
|
}
|
||||||
|
|
||||||
/** Get the ranges of anyone other buses that we are connected to. */
|
/** Get the ranges of anyone other buses that we are connected to. */
|
||||||
void
|
void
|
||||||
Bus::init()
|
Bus::init()
|
||||||
{
|
{
|
||||||
std::vector<BusPort*>::iterator intIter;
|
m5::hash_map<short,BusPort*>::iterator intIter;
|
||||||
|
|
||||||
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
|
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
|
||||||
(*intIter)->sendStatusChange(Port::RangeChange);
|
intIter->second->sendStatusChange(Port::RangeChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bus::BusFreeEvent::BusFreeEvent(Bus *_bus) : Event(&mainEventQueue), bus(_bus)
|
Bus::BusFreeEvent::BusFreeEvent(Bus *_bus) : Event(&mainEventQueue), bus(_bus)
|
||||||
|
@ -186,7 +198,7 @@ Bus::recvTiming(PacketPtr pkt)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(dest >= 0 && dest < interfaces.size());
|
assert(dest >= 0 && dest < maxId);
|
||||||
assert(dest != pkt->getSrc()); // catch infinite loops
|
assert(dest != pkt->getSrc()); // catch infinite loops
|
||||||
port = interfaces[dest];
|
port = interfaces[dest];
|
||||||
}
|
}
|
||||||
|
@ -435,7 +447,6 @@ Bus::recvStatusChange(Port::Status status, int id)
|
||||||
{
|
{
|
||||||
AddrRangeList ranges;
|
AddrRangeList ranges;
|
||||||
AddrRangeList snoops;
|
AddrRangeList snoops;
|
||||||
int x;
|
|
||||||
AddrRangeIter iter;
|
AddrRangeIter iter;
|
||||||
|
|
||||||
assert(status == Port::RangeChange &&
|
assert(status == Port::RangeChange &&
|
||||||
|
@ -457,7 +468,7 @@ Bus::recvStatusChange(Port::Status status, int id)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
assert((id < interfaces.size() && id >= 0) || id == defaultId);
|
assert((id < maxId && id >= 0) || id == defaultId);
|
||||||
Port *port = interfaces[id];
|
Port *port = interfaces[id];
|
||||||
range_map<Addr,int>::iterator portIter;
|
range_map<Addr,int>::iterator portIter;
|
||||||
std::vector<DevMap>::iterator snoopIter;
|
std::vector<DevMap>::iterator snoopIter;
|
||||||
|
@ -502,9 +513,11 @@ Bus::recvStatusChange(Port::Status status, int id)
|
||||||
|
|
||||||
// tell all our peers that our address range has changed.
|
// tell all our peers that our address range has changed.
|
||||||
// Don't tell the device that caused this change, it already knows
|
// Don't tell the device that caused this change, it already knows
|
||||||
for (x = 0; x < interfaces.size(); x++)
|
m5::hash_map<short,BusPort*>::iterator intIter;
|
||||||
if (x != id)
|
|
||||||
interfaces[x]->sendStatusChange(Port::RangeChange);
|
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
|
||||||
|
if (intIter->first != id)
|
||||||
|
intIter->second->sendStatusChange(Port::RangeChange);
|
||||||
|
|
||||||
if (id != defaultId && defaultPort)
|
if (id != defaultId && defaultPort)
|
||||||
defaultPort->sendStatusChange(Port::RangeChange);
|
defaultPort->sendStatusChange(Port::RangeChange);
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "base/range.hh"
|
#include "base/range.hh"
|
||||||
|
#include "base/hashmap.hh"
|
||||||
#include "base/range_map.hh"
|
#include "base/range_map.hh"
|
||||||
#include "mem/mem_object.hh"
|
#include "mem/mem_object.hh"
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
|
@ -212,9 +213,12 @@ class Bus : public MemObject
|
||||||
|
|
||||||
bool inRetry;
|
bool inRetry;
|
||||||
|
|
||||||
|
/** max number of bus ids we've handed out so far */
|
||||||
|
short maxId;
|
||||||
|
|
||||||
/** An array of pointers to the peer port interfaces
|
/** An array of pointers to the peer port interfaces
|
||||||
connected to this bus.*/
|
connected to this bus.*/
|
||||||
std::vector<BusPort*> interfaces;
|
m5::hash_map<short,BusPort*> interfaces;
|
||||||
|
|
||||||
/** An array of pointers to ports that retry should be called on because the
|
/** An array of pointers to ports that retry should be called on because the
|
||||||
* original send failed for whatever reason.*/
|
* original send failed for whatever reason.*/
|
||||||
|
@ -252,6 +256,7 @@ class Bus : public MemObject
|
||||||
|
|
||||||
/** A function used to return the port associated with this bus object. */
|
/** A function used to return the port associated with this bus object. */
|
||||||
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
||||||
|
virtual void deletePortRefs(Port *p);
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
|
||||||
|
@ -261,7 +266,7 @@ class Bus : public MemObject
|
||||||
bool responder_set)
|
bool responder_set)
|
||||||
: MemObject(n), busId(bus_id), clock(_clock), width(_width),
|
: MemObject(n), busId(bus_id), clock(_clock), width(_width),
|
||||||
tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false),
|
tickNextIdle(0), drainEvent(NULL), busIdle(this), inRetry(false),
|
||||||
defaultPort(NULL), responderSet(responder_set)
|
maxId(0), defaultPort(NULL), responderSet(responder_set)
|
||||||
{
|
{
|
||||||
//Both the width and clock period must be positive
|
//Both the width and clock period must be positive
|
||||||
if (width <= 0)
|
if (width <= 0)
|
||||||
|
|
1
src/mem/cache/cache.hh
vendored
1
src/mem/cache/cache.hh
vendored
|
@ -331,6 +331,7 @@ class Cache : public BaseCache
|
||||||
Cache(const std::string &_name, Params ¶ms);
|
Cache(const std::string &_name, Params ¶ms);
|
||||||
|
|
||||||
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
||||||
|
virtual void deletePortRefs(Port *p);
|
||||||
|
|
||||||
virtual void recvStatusChange(Port::Status status, bool isCpuSide);
|
virtual void recvStatusChange(Port::Status status, bool isCpuSide);
|
||||||
|
|
||||||
|
|
11
src/mem/cache/cache_impl.hh
vendored
11
src/mem/cache/cache_impl.hh
vendored
|
@ -1100,7 +1100,7 @@ Cache<TagStore,Coherence>::getPort(const std::string &if_name, int idx)
|
||||||
}
|
}
|
||||||
else if (if_name == "functional")
|
else if (if_name == "functional")
|
||||||
{
|
{
|
||||||
return new CpuSidePort(name() + "-cpu_side_port", this);
|
return new CpuSidePort(name() + "-cpu_side_funcport", this);
|
||||||
}
|
}
|
||||||
else if (if_name == "cpu_side")
|
else if (if_name == "cpu_side")
|
||||||
{
|
{
|
||||||
|
@ -1121,6 +1121,15 @@ Cache<TagStore,Coherence>::getPort(const std::string &if_name, int idx)
|
||||||
else panic("Port name %s unrecognized\n", if_name);
|
else panic("Port name %s unrecognized\n", if_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
void
|
||||||
|
Cache<TagStore,Coherence>::deletePortRefs(Port *p)
|
||||||
|
{
|
||||||
|
if (cpuSidePort == p || memSidePort == p)
|
||||||
|
panic("Can only delete functional ports\n");
|
||||||
|
// nothing else to do
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class TagStore, class Coherence>
|
template<class TagStore, class Coherence>
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -35,5 +35,10 @@ MemObject::MemObject(const std::string &name)
|
||||||
: SimObject(name)
|
: SimObject(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
void
|
||||||
|
MemObject::deletePortRefs(Port *p)
|
||||||
|
{
|
||||||
|
panic("This object does not support port deletion\n");
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_SIM_OBJECT_CLASS_NAME("MemObject", MemObject)
|
DEFINE_SIM_OBJECT_CLASS_NAME("MemObject", MemObject)
|
||||||
|
|
|
@ -51,6 +51,10 @@ class MemObject : public SimObject
|
||||||
public:
|
public:
|
||||||
/** Additional function to return the Port of a memory object. */
|
/** Additional function to return the Port of a memory object. */
|
||||||
virtual Port *getPort(const std::string &if_name, int idx = -1) = 0;
|
virtual Port *getPort(const std::string &if_name, int idx = -1) = 0;
|
||||||
|
|
||||||
|
/** Tell object that this port is about to disappear, so it should remove it
|
||||||
|
* from any structures that it's keeping it in. */
|
||||||
|
virtual void deletePortRefs(Port *p) ;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__MEM_MEM_OBJECT_HH__
|
#endif //__MEM_MEM_OBJECT_HH__
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include "base/chunk_generator.hh"
|
#include "base/chunk_generator.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
|
#include "mem/mem_object.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port.hh"
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -45,6 +46,15 @@ Port::setPeer(Port *port)
|
||||||
peer = port;
|
peer = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Port::removeConn()
|
||||||
|
{
|
||||||
|
if (peer->getOwner())
|
||||||
|
peer->getOwner()->deletePortRefs(peer);
|
||||||
|
delete peer;
|
||||||
|
peer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd)
|
Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,7 +120,7 @@ class Port
|
||||||
{ portName = name; }
|
{ portName = name; }
|
||||||
|
|
||||||
/** Function to set the pointer for the peer port. */
|
/** Function to set the pointer for the peer port. */
|
||||||
void setPeer(Port *port);
|
virtual void setPeer(Port *port);
|
||||||
|
|
||||||
/** Function to get the pointer to the peer port. */
|
/** Function to get the pointer to the peer port. */
|
||||||
Port *getPeer() { return peer; }
|
Port *getPeer() { return peer; }
|
||||||
|
@ -131,6 +131,11 @@ class Port
|
||||||
/** Function to return the owner of this port. */
|
/** Function to return the owner of this port. */
|
||||||
MemObject *getOwner() { return owner; }
|
MemObject *getOwner() { return owner; }
|
||||||
|
|
||||||
|
/** Inform the peer port to delete itself and notify it's owner about it's
|
||||||
|
* demise. */
|
||||||
|
void removeConn();
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** These functions are protected because they should only be
|
/** These functions are protected because they should only be
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "arch/isa_traits.hh"
|
#include "arch/isa_traits.hh"
|
||||||
#include "arch/remote_gdb.hh"
|
#include "arch/remote_gdb.hh"
|
||||||
|
#include "arch/utility.hh"
|
||||||
#include "base/loader/object_file.hh"
|
#include "base/loader/object_file.hh"
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
|
@ -203,7 +204,7 @@ System::startup()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < threadContexts.size(); i++)
|
for (i = 0; i < threadContexts.size(); i++)
|
||||||
threadContexts[i]->activate(0);
|
TheISA::startupCPU(threadContexts[i], i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -88,7 +88,7 @@ try:
|
||||||
else:
|
else:
|
||||||
# Ugly! Since we don't have any quick SPARC_FS tests remove the SPARC_FS target
|
# Ugly! Since we don't have any quick SPARC_FS tests remove the SPARC_FS target
|
||||||
# If we ever get a quick SPARC_FS test, this code should be removed
|
# If we ever get a quick SPARC_FS test, this code should be removed
|
||||||
if 'quick' in tests:
|
if 'quick' in tests and 'SPARC_FS' in builds:
|
||||||
builds.remove('SPARC_FS')
|
builds.remove('SPARC_FS')
|
||||||
targets = ['build/%s/tests/%s/%s' % (build, variant, test)
|
targets = ['build/%s/tests/%s/%s' % (build, variant, test)
|
||||||
for build in builds
|
for build in builds
|
||||||
|
|
Loading…
Reference in a new issue