summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-11-02 15:20:47 -0500
committerKevin Lim <ktlim@umich.edu>2006-11-02 15:20:47 -0500
commite71ccde66369951c23eb20281c68a8cb66c4a504 (patch)
tree209293eb44ceeee7eb04bc778956f57ae812978b /src
parent683d8f0831b476a906dc2720265a2334ba0117e3 (diff)
parent45363ea658251df0c31a75d7bd5d0ac3a3809623 (diff)
downloadgem5-e71ccde66369951c23eb20281c68a8cb66c4a504.tar.xz
Merge ktlim@zizzer:/bk/newmem
into zamp.eecs.umich.edu:/z/ktlim2/clean/newmem-busfix --HG-- extra : convert_revision : a9a41e2c292bd95aa148e1cf4d9a77c0622a462b
Diffstat (limited to 'src')
-rw-r--r--src/arch/alpha/utility.hh6
-rw-r--r--src/cpu/checker/cpu_impl.hh5
-rw-r--r--src/cpu/o3/fetch_impl.hh6
-rw-r--r--src/cpu/ozone/front_end_impl.hh4
-rw-r--r--src/cpu/simple/base.cc4
-rw-r--r--src/cpu/simple_thread.cc30
-rw-r--r--src/cpu/simple_thread.hh2
-rw-r--r--src/cpu/thread_state.cc31
-rw-r--r--src/cpu/thread_state.hh9
-rw-r--r--src/dev/isa_fake.cc63
-rw-r--r--src/dev/isa_fake.hh17
-rw-r--r--src/mem/bus.cc37
-rw-r--r--src/mem/bus.hh9
-rw-r--r--src/mem/cache/base_cache.cc4
-rw-r--r--src/python/m5/objects/Bus.py10
-rw-r--r--src/python/m5/objects/Tsunami.py4
16 files changed, 188 insertions, 53 deletions
diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh
index 0304d1c3a..cb86c7e9e 100644
--- a/src/arch/alpha/utility.hh
+++ b/src/arch/alpha/utility.hh
@@ -43,11 +43,11 @@ namespace AlphaISA
{
static inline ExtMachInst
- makeExtMI(MachInst inst, ThreadContext * xc) {
+ makeExtMI(MachInst inst, Addr pc) {
#if FULL_SYSTEM
ExtMachInst ext_inst = inst;
- if (xc->readPC() && 0x1)
- return ext_inst|=(static_cast<ExtMachInst>(xc->readPC() & 0x1) << 32);
+ if (pc && 0x1)
+ return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
else
return ext_inst;
#else
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 36c7349e6..56e13dd1e 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -199,8 +199,13 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
// Checks both the machine instruction and the PC.
validateInst(inst);
+#if THE_ISA == ALPHA_ISA
+ curStaticInst = StaticInst::decode(makeExtMI(machInst,
+ thread->readPC()));
+#elif THE_ISA == SPARC_ISA
curStaticInst = StaticInst::decode(makeExtMI(machInst,
thread->getTC()));
+#endif
#if FULL_SYSTEM
thread->setInst(machInst);
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 2b152e376..31f3b96d6 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -1117,7 +1117,11 @@ DefaultFetch<Impl>::fetch(bool &status_change)
inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *>
(&cacheData[tid][offset]));
- ext_inst = TheISA::makeExtMI(inst, cpu->tcBase(tid));
+#if THE_ISA == ALPHA_ISA
+ ext_inst = TheISA::makeExtMI(inst, fetch_PC);
+#elif THE_ISA == SPARC_ISA
+ ext_inst = TheISA::makeExtMI(inst, cpu->thread[tid]->getTC());
+#endif
// Create a new DynInst from the instruction fetched.
DynInstPtr instruction = new DynInst(ext_inst, fetch_PC,
diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh
index 63cf0a952..6d02c58cb 100644
--- a/src/cpu/ozone/front_end_impl.hh
+++ b/src/cpu/ozone/front_end_impl.hh
@@ -882,7 +882,11 @@ FrontEnd<Impl>::getInstFromCacheline()
// Get the instruction from the array of the cache line.
inst = htog(*reinterpret_cast<MachInst *>(&cacheData[offset]));
+#if THE_ISA == ALPHA_ISA
+ ExtMachInst decode_inst = TheISA::makeExtMI(inst, PC);
+#elif THE_ISA == SPARC_ISA
ExtMachInst decode_inst = TheISA::makeExtMI(inst, tc);
+#endif
// Create a new DynInst from the instruction fetched.
DynInstPtr instruction = new DynInst(decode_inst, PC, PC+sizeof(MachInst),
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 47b3b938f..6a2c0bbe9 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -398,7 +398,11 @@ BaseSimpleCPU::preExecute()
inst = gtoh(inst);
//If we're not in the middle of a macro instruction
if (!curMacroStaticInst) {
+#if THE_ISA == ALPHA_ISA
+ StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->readPC()));
+#elif THE_ISA == SPARC_ISA
StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC()));
+#endif
if (instPtr->isMacroOp()) {
curMacroStaticInst = instPtr;
curStaticInst = curMacroStaticInst->
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index d4e5f8230..8bb4ec46b 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -129,6 +129,10 @@ SimpleThread::SimpleThread()
SimpleThread::~SimpleThread()
{
+#if FULL_SYSTEM
+ delete physPort;
+ delete virtPort;
+#endif
delete tc;
}
@@ -304,11 +308,9 @@ SimpleThread::getVirtPort(ThreadContext *src_tc)
if (!src_tc)
return virtPort;
- VirtualPort *vp;
- Port *mem_port;
+ VirtualPort *vp = new VirtualPort("tc-vport", src_tc);
+ Port *mem_port = getMemFuncPort();
- vp = new VirtualPort("tc-vport", src_tc);
- mem_port = system->physmem->getPort("functional");
mem_port->setPeer(vp);
vp->setPeer(mem_port);
return vp;
@@ -323,25 +325,5 @@ SimpleThread::delVirtPort(VirtualPort *vp)
}
}
-#else
-TranslatingPort *
-SimpleThread::getMemPort()
-{
- if (port != NULL)
- return port;
-
- /* Use this port to for syscall emulation writes to memory. */
- Port *dcache_port;
- port = new TranslatingPort(csprintf("%s-%d-funcport",
- cpu->name(), tid),
- process->pTable, false);
- dcache_port = cpu->getPort("dcache_port");
- assert(dcache_port != NULL);
- dcache_port = dcache_port->getPeer();
-// mem_port->setPeer(port);
- port->setPeer(dcache_port);
- return port;
-}
-
#endif
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index b654c130e..9a575f06b 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -171,8 +171,6 @@ class SimpleThread : public ThreadState
bool simPalCheck(int palFunc);
#else
- // Override this function.
- TranslatingPort *getMemPort();
Fault translateInstReq(RequestPtr &req)
{
diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc
index f81b78147..a6fff5fc3 100644
--- a/src/cpu/thread_state.cc
+++ b/src/cpu/thread_state.cc
@@ -59,6 +59,16 @@ ThreadState::ThreadState(BaseCPU *cpu, int _cpuId, int _tid, Process *_process,
numLoad = 0;
}
+ThreadState::~ThreadState()
+{
+#if !FULL_SYSTEM
+ if (port) {
+ delete port->getPeer();
+ delete port;
+ }
+#endif
+}
+
void
ThreadState::serialize(std::ostream &os)
{
@@ -124,11 +134,24 @@ ThreadState::getMemPort()
return port;
/* Use this port to for syscall emulation writes to memory. */
- Port *dcache_port, *func_mem_port;
port = new TranslatingPort(csprintf("%s-%d-funcport",
baseCpu->name(), tid),
process->pTable, false);
+ Port *func_port = getMemFuncPort();
+
+ func_port->setPeer(port);
+ port->setPeer(func_port);
+
+ return port;
+}
+#endif
+
+Port *
+ThreadState::getMemFuncPort()
+{
+ Port *dcache_port, *func_mem_port;
+
dcache_port = baseCpu->getPort("dcache_port");
assert(dcache_port != NULL);
@@ -138,9 +161,5 @@ ThreadState::getMemPort()
func_mem_port = mem_object->getPort("functional");
assert(func_mem_port != NULL);
- func_mem_port->setPeer(port);
- port->setPeer(func_mem_port);
-
- return port;
+ return func_mem_port;
}
-#endif
diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh
index 14673aabb..862d671f2 100644
--- a/src/cpu/thread_state.hh
+++ b/src/cpu/thread_state.hh
@@ -51,6 +51,7 @@ namespace Kernel {
class BaseCPU;
class Checkpoint;
+class Port;
class TranslatingPort;
/**
@@ -69,6 +70,8 @@ struct ThreadState {
short _asid);
#endif
+ ~ThreadState();
+
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
@@ -136,6 +139,12 @@ struct ThreadState {
/** Sets the status of this thread. */
void setStatus(Status new_status) { _status = new_status; }
+ protected:
+ /** Gets a functional port from the memory object that's connected
+ * to the CPU. */
+ Port *getMemFuncPort();
+
+ public:
/** Number of instructions committed. */
Counter numInst;
/** Stat for number instructions committed. */
diff --git a/src/dev/isa_fake.cc b/src/dev/isa_fake.cc
index 23761cd10..ccc9a1f7c 100644
--- a/src/dev/isa_fake.cc
+++ b/src/dev/isa_fake.cc
@@ -88,6 +88,38 @@ IsaFake::write(PacketPtr pkt)
return pioDelay;
}
+BadAddr::BadAddr(Params *p)
+ : BasicPioDevice(p)
+{
+}
+
+void
+BadAddr::init()
+{
+ // Only init this device if it's connected to anything.
+ if (pioPort)
+ PioDevice::init();
+}
+
+Tick
+BadAddr::read(PacketPtr pkt)
+{
+ assert(pkt->result == Packet::Unknown);
+ DPRINTF(Tsunami, "read to bad address va=%#x size=%d\n",
+ pkt->getAddr(), pkt->getSize());
+ pkt->result = Packet::BadAddress;
+ return pioDelay;
+}
+
+Tick
+BadAddr::write(PacketPtr pkt)
+{
+ DPRINTF(Tsunami, "write to bad address va=%#x size=%d \n",
+ pkt->getAddr(), pkt->getSize());
+ pkt->result = Packet::BadAddress;
+ return pioDelay;
+}
+
BEGIN_DECLARE_SIM_OBJECT_PARAMS(IsaFake)
Param<Addr> pio_addr;
@@ -121,3 +153,34 @@ CREATE_SIM_OBJECT(IsaFake)
}
REGISTER_SIM_OBJECT("IsaFake", IsaFake)
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadAddr)
+
+ Param<Addr> pio_addr;
+ Param<Tick> pio_latency;
+ SimObjectParam<Platform *> platform;
+ SimObjectParam<System *> system;
+
+END_DECLARE_SIM_OBJECT_PARAMS(BadAddr)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(BadAddr)
+
+ INIT_PARAM(pio_addr, "Device Address"),
+ INIT_PARAM(pio_latency, "Programmed IO latency"),
+ INIT_PARAM(platform, "platform"),
+ INIT_PARAM(system, "system object")
+
+END_INIT_SIM_OBJECT_PARAMS(BadAddr)
+
+CREATE_SIM_OBJECT(BadAddr)
+{
+ BadAddr::Params *p = new BadAddr::Params;
+ p->name = getInstanceName();
+ p->pio_addr = pio_addr;
+ p->pio_delay = pio_latency;
+ p->platform = platform;
+ p->system = system;
+ return new BadAddr(p);
+}
+
+REGISTER_SIM_OBJECT("BadAddr", BadAddr)
diff --git a/src/dev/isa_fake.hh b/src/dev/isa_fake.hh
index 366061c25..6665f1a78 100644
--- a/src/dev/isa_fake.hh
+++ b/src/dev/isa_fake.hh
@@ -79,4 +79,21 @@ class IsaFake : public BasicPioDevice
virtual Tick write(PacketPtr pkt);
};
+/**
+ * BadAddr is a device that fills the packet's result field with "BadAddress".
+ * @todo: Consider consolidating with IsaFake and similar classes.
+ */
+class BadAddr : public BasicPioDevice
+{
+ public:
+ struct Params : public BasicPioDevice::Params
+ {
+ };
+
+ BadAddr(Params *p);
+ virtual void init();
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
+};
+
#endif // __TSUNAMI_FAKE_HH__
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 41dc9acbf..28ee3476b 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -42,13 +42,14 @@
Port *
Bus::getPort(const std::string &if_name, int idx)
{
- if (if_name == "default")
+ if (if_name == "default") {
if (defaultPort == NULL) {
defaultPort = new BusPort(csprintf("%s-default",name()), this,
- defaultId);
+ defaultId);
return defaultPort;
} else
fatal("Default port already set\n");
+ }
// if_name ignored? forced to be empty?
int id = interfaces.size();
@@ -272,7 +273,16 @@ Bus::findPort(Addr addr, int id)
return defaultPort;
}
}
- panic("Unable to find destination for addr: %#llx", addr);
+
+ if (responderSet) {
+ panic("Unable to find destination for addr (user set default "
+ "responder): %#llx", addr);
+ } else {
+ DPRINTF(Bus, "Unable to find destination for addr: %#llx, will use "
+ "default port", addr);
+
+ return defaultPort;
+ }
}
@@ -395,12 +405,15 @@ Bus::recvStatusChange(Port::Status status, int id)
if (id == defaultId) {
defaultRange.clear();
- defaultPort->getPeerAddressRanges(ranges, snoops);
- assert(snoops.size() == 0);
- for(iter = ranges.begin(); iter != ranges.end(); iter++) {
- defaultRange.push_back(*iter);
- DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n",
- iter->start, iter->end);
+ // Only try to update these ranges if the user set a default responder.
+ if (responderSet) {
+ defaultPort->getPeerAddressRanges(ranges, snoops);
+ assert(snoops.size() == 0);
+ for(iter = ranges.begin(); iter != ranges.end(); iter++) {
+ defaultRange.push_back(*iter);
+ DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n",
+ iter->start, iter->end);
+ }
}
} else {
@@ -520,18 +533,20 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus)
Param<int> bus_id;
Param<int> clock;
Param<int> width;
+ Param<bool> responder_set;
END_DECLARE_SIM_OBJECT_PARAMS(Bus)
BEGIN_INIT_SIM_OBJECT_PARAMS(Bus)
INIT_PARAM(bus_id, "a globally unique bus id"),
INIT_PARAM(clock, "bus clock speed"),
- INIT_PARAM(width, "width of the bus (bits)")
+ INIT_PARAM(width, "width of the bus (bits)"),
+ INIT_PARAM(responder_set, "Is a default responder set by the user")
END_INIT_SIM_OBJECT_PARAMS(Bus)
CREATE_SIM_OBJECT(Bus)
{
- return new Bus(getInstanceName(), bus_id, clock, width);
+ return new Bus(getInstanceName(), bus_id, clock, width, responder_set);
}
REGISTER_SIM_OBJECT("Bus", Bus)
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 27624b378..1d1cfde89 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -242,6 +242,9 @@ class Bus : public MemObject
/** Port that handles requests that don't match any of the interfaces.*/
BusPort *defaultPort;
+ /** Has the user specified their own default responder? */
+ bool responderSet;
+
public:
/** A function used to return the port associated with this bus object. */
@@ -251,9 +254,11 @@ class Bus : public MemObject
unsigned int drain(Event *de);
- Bus(const std::string &n, int bus_id, int _clock, int _width)
+ Bus(const std::string &n, int bus_id, int _clock, int _width,
+ bool responder_set)
: MemObject(n), busId(bus_id), clock(_clock), width(_width),
- tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL)
+ tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL),
+ responderSet(responder_set)
{
//Both the width and clock period must be positive
if (width <= 0)
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index 47d40a490..1c519fb86 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -357,9 +357,7 @@ BaseCache::getPort(const std::string &if_name, int idx)
}
else if (if_name == "functional")
{
- if(cpuSidePort == NULL)
- cpuSidePort = new CachePort(name() + "-cpu_side_port", this, true);
- return cpuSidePort;
+ return new CachePort(name() + "-cpu_side_port", this, true);
}
else if (if_name == "cpu_side")
{
diff --git a/src/python/m5/objects/Bus.py b/src/python/m5/objects/Bus.py
index 6710111e5..e7019f3ac 100644
--- a/src/python/m5/objects/Bus.py
+++ b/src/python/m5/objects/Bus.py
@@ -1,10 +1,18 @@
+from m5 import build_env
from m5.params import *
+from m5.proxy import *
from MemObject import MemObject
+from Tsunami import BadAddr
class Bus(MemObject):
type = 'Bus'
port = VectorPort("vector port for connecting devices")
- default = Port("Default port for requests that aren't handeled by a device.")
bus_id = Param.Int(0, "blah")
clock = Param.Clock("1GHz", "bus clock speed")
width = Param.Int(64, "bus width (bytes)")
+ responder_set = Param.Bool(False, "Did the user specify a default responder.")
+ if build_env['FULL_SYSTEM']:
+ default = Port(Self.responder.pio, "Default port for requests that aren't handled by a device.")
+ responder = BadAddr(pio_addr=0x0, pio_latency="1ps")
+ else:
+ default = Port("Default port for requests that aren't handled by a device.")
diff --git a/src/python/m5/objects/Tsunami.py b/src/python/m5/objects/Tsunami.py
index 0b53153a0..42bcab089 100644
--- a/src/python/m5/objects/Tsunami.py
+++ b/src/python/m5/objects/Tsunami.py
@@ -15,6 +15,9 @@ class IsaFake(BasicPioDevice):
type = 'IsaFake'
pio_size = Param.Addr(0x8, "Size of address range")
+class BadAddr(BasicPioDevice):
+ type = 'BadAddr'
+
class TsunamiIO(BasicPioDevice):
type = 'TsunamiIO'
time = Param.UInt64(1136073600,
@@ -70,6 +73,7 @@ class Tsunami(Platform):
self.cchip.pio = bus.port
self.pchip.pio = bus.port
self.pciconfig.pio = bus.default
+ bus.responder_set = True
self.fake_sm_chip.pio = bus.port
self.fake_uart1.pio = bus.port
self.fake_uart2.pio = bus.port