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(xc->readPC() & 0x1) << 32); + if (pc && 0x1) + return ext_inst|=(static_cast(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::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::fetch(bool &status_change) inst = TheISA::gtoh(*reinterpret_cast (&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::getInstFromCacheline() // Get the instruction from the array of the cache line. inst = htog(*reinterpret_cast(&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 §ion); @@ -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 pio_addr; @@ -121,3 +153,34 @@ CREATE_SIM_OBJECT(IsaFake) } REGISTER_SIM_OBJECT("IsaFake", IsaFake) + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadAddr) + + Param pio_addr; + Param pio_latency; + SimObjectParam platform; + SimObjectParam 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 bus_id; Param clock; Param width; + Param 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