From a7c95f702c73a332ae2d2283e7bc445876f07bc7 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 22 May 2006 21:51:59 -0400 Subject: Clean up libelf handling. SConstruct: Clean up libelf handling. Required better handling of per-build-root stuff in general (though libelf is the only thing in that category currently). src/SConscript: No libelf-specific stuff in here anymore. src/base/loader/elf_object.cc: Just need to include gelf.h... it includes libelf.h. --HG-- extra : convert_revision : 3d6bdcf8233bda0ac8d08ff777de323df8aa45ae --- src/SConscript | 5 ----- src/base/loader/elf_object.cc | 8 +------- 2 files changed, 1 insertion(+), 12 deletions(-) (limited to 'src') diff --git a/src/SConscript b/src/SConscript index a2d5de279..558c447e9 100644 --- a/src/SConscript +++ b/src/SConscript @@ -326,10 +326,6 @@ env.Command(Split('base/traceflags.hh base/traceflags.cc'), 'base/traceflags.py', 'python $SOURCE $TARGET.base') -# libelf build is described in its own SConscript file. -# SConscript-local is the per-config build, which just copies some -# header files into a place where they can be found. -SConscript('libelf/SConscript-local', exports = 'env', duplicate=0) SConscript('python/SConscript', exports = ['env'], duplicate=0) # This function adds the specified sources to the given build @@ -358,7 +354,6 @@ def make_objs(sources, env): # the corresponding build directory to pick up generated include # files. env.Append(CPPPATH='.') -env.Append(CPPPATH='./libelf') # Debug binary debugEnv = env.Copy(OBJSUFFIX='.do') diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 165501e1c..79601e9d1 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -30,16 +30,10 @@ // Because of the -Wundef flag we have to do this #define __LIBELF_INTERNAL__ 0 -// counterintuitive, but the flag below causes libelf to define -// 64-bit elf types that apparently didn't exist in some older -// versions of Linux. They seem to be there in 2.4.x, so don't -// set this now (it causes things to break on 64-bit platforms). -#define __LIBELF64_LINUX 0 #define __LIBELF_NEED_LINK_H 0 #define __LIBELF_SYMBOL_VERSIONS 0 -#include "libelf/libelf.h" -#include "libelf/gelf.h" +#include "gelf.h" #include "base/loader/elf_object.hh" #include "base/misc.hh" -- cgit v1.2.3 From 387889526430e34a7da32741d39942b7f4771bf8 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 22 May 2006 22:15:22 -0400 Subject: Fix to SPARC Nop class for multiple CPU models. src/arch/sparc/isa/formats/nop.isa: Fix nop header so we can compile with multiple CPU models. (Former code re-defined Nop object for each model.) --HG-- extra : convert_revision : 04e92622edf4dfefd9e149a17f604e17a93707c9 --- src/arch/sparc/isa/formats/nop.isa | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/arch/sparc/isa/formats/nop.isa b/src/arch/sparc/isa/formats/nop.isa index 7fd1a3b21..37ef2e8d0 100644 --- a/src/arch/sparc/isa/formats/nop.isa +++ b/src/arch/sparc/isa/formats/nop.isa @@ -32,6 +32,16 @@ // Nop instruction // +// Per-cpu-model nop execute method. +def template NopExec {{ + + Fault execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + // Nothing to see here, move along + return NoFault; + } +}}; + output header {{ /** * Nop class. @@ -46,14 +56,11 @@ output header {{ } // All Nop instructions do the same thing, so this can be - // defined here. Nops can be defined directly, so there needs - // to be a default implementation - Fault execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - //Nothing to see here, move along - return NoFault; - } + // defined here. Nops can be defined directly, so there + // needs to be a default implementation. Interpolate via + // template so i gets expanded to a set of + // cpu-model-specific functions. + %(NopExec)s std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; -- cgit v1.2.3 From 475a981f6e9bdff9436ad0ecf34f83ead5a63498 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Mon, 22 May 2006 22:18:08 -0400 Subject: Get rid of FastCPU model. It doesn't compile, and if we really want this we should start over from scratch and see if we can reuse parts from BaseSimpleCPU (e.g., derive a FastSimpleCPU). SConstruct: src/arch/SConscript: src/cpu/cpu_models.py: Get rid of FastCPU model. --HG-- extra : convert_revision : f3f0362f7292bf21e8e0d4d84c475be8a9789a0c --- src/arch/SConscript | 2 +- src/cpu/cpu_models.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/arch/SConscript b/src/arch/SConscript index 06b8e8dde..9c193207f 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -132,7 +132,7 @@ def isa_desc_emitter(target, source, env): return (isa_desc_gen_files, [isa_parser, cpu_models_file] + source) # Pieces are in place, so create the builder. -isa_desc_builder = Builder(action='python $SOURCES $TARGET.dir $CPU_MODELS', +isa_desc_builder = Builder(action='python2.4 $SOURCES $TARGET.dir $CPU_MODELS', emitter = isa_desc_emitter) env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder }) diff --git a/src/cpu/cpu_models.py b/src/cpu/cpu_models.py index 30cbabde1..8d0a15f61 100644 --- a/src/cpu/cpu_models.py +++ b/src/cpu/cpu_models.py @@ -62,9 +62,6 @@ CpuModel('AtomicSimpleCPU', 'atomic_simple_cpu_exec.cc', CpuModel('TimingSimpleCPU', 'timing_simple_cpu_exec.cc', '#include "cpu/simple/timing.hh"', { 'CPU_exec_context': 'TimingSimpleCPU' }) -CpuModel('FastCPU', 'fast_cpu_exec.cc', - '#include "cpu/fast/cpu.hh"', - { 'CPU_exec_context': 'FastCPU' }) CpuModel('FullCPU', 'full_cpu_exec.cc', '#include "encumbered/cpu/full/dyn_inst.hh"', { 'CPU_exec_context': 'DynInst' }) -- cgit v1.2.3 From cf826ae296a4277bdf2ce46e4484295efde5a3c2 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 23 May 2006 17:16:45 -0400 Subject: Minor fixes for full-system timing memory. Need to rewrite bus bridge to get any further. src/dev/io_device.cc: Set packet dest on timing responses. src/mem/bus.cc: Fix dest addr bounds check assertion. Add assertion to catch infinite loopbacks. src/mem/physical.cc: Add comment. --HG-- extra : convert_revision : 419b65a3a61e2d099884dbda117b338dffd80896 --- src/dev/io_device.cc | 2 ++ src/mem/bus.cc | 3 ++- src/mem/physical.cc | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 634b11b7e..5f7770a92 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -78,6 +78,8 @@ bool PioPort::recvTiming(Packet *pkt) { device->recvAtomic(pkt); + // turn packet around to go back to requester + pkt->dest = pkt->src; sendTiming(pkt, pkt->time - pkt->req->getTime()); return Success; } diff --git a/src/mem/bus.cc b/src/mem/bus.cc index f7c2b874a..e8dfbc2e6 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -54,7 +54,8 @@ Bus::recvTiming(Packet *pkt) if (pkt->dest == Packet::Broadcast) { port = findPort(pkt->addr, pkt->src); } else { - assert(pkt->dest > 0 && pkt->dest < interfaces.size()); + assert(pkt->dest >= 0 && pkt->dest < interfaces.size()); + assert(pkt->dest != pkt->src); // catch infinite loops port = interfaces[pkt->dest]; } return port->sendTiming(pkt); diff --git a/src/mem/physical.cc b/src/mem/physical.cc index bc2500678..75179f9e3 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -127,6 +127,7 @@ PhysicalMemory::doTimingAccess (Packet *pkt, MemoryPort* memoryPort) { doFunctionalAccess(pkt); + // turn packet around to go back to requester pkt->dest = pkt->src; MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort); response->schedule(curTick + lat); -- cgit v1.2.3 From da6a7b1263cf624790f06a5f944366fb113dffc8 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 26 May 2006 13:48:35 -0400 Subject: Add names to memory Port objects for tracing. --HG-- extra : convert_revision : ddf30084e343e8656e4812ab20356292b35507ee --- src/cpu/cpu_exec_context.cc | 12 ++++++++---- src/cpu/simple/atomic.cc | 2 +- src/cpu/simple/atomic.hh | 4 ++-- src/cpu/simple/timing.hh | 8 ++++---- src/dev/io_device.cc | 4 ++-- src/mem/bridge.hh | 2 +- src/mem/bus.cc | 10 ++++++++++ src/mem/bus.hh | 12 +++--------- src/mem/physical.cc | 9 +++++---- src/mem/physical.hh | 2 +- src/mem/port.hh | 23 +++++++++++++++++++++++ src/mem/translating_port.cc | 5 +++-- src/mem/translating_port.hh | 9 +++------ src/mem/vport.hh | 4 ++-- src/sim/process.cc | 2 +- src/sim/system.cc | 2 ++ 16 files changed, 71 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/cpu/cpu_exec_context.cc b/src/cpu/cpu_exec_context.cc index ec1e94561..b8aa9a67e 100644 --- a/src/cpu/cpu_exec_context.cc +++ b/src/cpu/cpu_exec_context.cc @@ -80,12 +80,14 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, profilePC = 3; Port *mem_port; - physPort = new FunctionalPort(); + physPort = new FunctionalPort(csprintf("%s-%d-funcport", + cpu->name(), thread_num)); mem_port = system->physmem->getPort("functional"); mem_port->setPeer(physPort); physPort->setPeer(mem_port); - virtPort = new VirtualPort(); + virtPort = new VirtualPort(csprintf("%s-%d-vport", + cpu->name(), thread_num)); mem_port = system->physmem->getPort("functional"); mem_port->setPeer(virtPort); virtPort->setPeer(mem_port); @@ -100,7 +102,9 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, { /* Use this port to for syscall emulation writes to memory. */ Port *mem_port; - port = new TranslatingPort(process->pTable, false); + port = new TranslatingPort(csprintf("%s-%d-funcport", + cpu->name(), thread_num), + process->pTable, false); mem_port = memobj->getPort("functional"); mem_port->setPeer(port); port->setPeer(mem_port); @@ -300,7 +304,7 @@ CPUExecContext::getVirtPort(ExecContext *xc) VirtualPort *vp; Port *mem_port; - vp = new VirtualPort(xc); + vp = new VirtualPort("xc-vport", xc); mem_port = system->physmem->getPort("functional"); mem_port->setPeer(vp); vp->setPeer(mem_port); diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index e9422b9c0..04a84c92a 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -117,7 +117,7 @@ AtomicSimpleCPU::CpuPort::recvRetry() AtomicSimpleCPU::AtomicSimpleCPU(Params *p) : BaseSimpleCPU(p), tickEvent(this), width(p->width), simulate_stalls(p->simulate_stalls), - icachePort(this), dcachePort(this) + icachePort(name() + "-iport", this), dcachePort(name() + "-iport", this) { _status = Idle; diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index d0ba085f0..ab3a3e8ef 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -84,8 +84,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU public: - CpuPort(AtomicSimpleCPU *_cpu) - : cpu(_cpu) + CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu) + : Port(_name), cpu(_cpu) { } protected: diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index 83be025d9..7f38e629a 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -71,8 +71,8 @@ class TimingSimpleCPU : public BaseSimpleCPU public: - CpuPort(TimingSimpleCPU *_cpu) - : cpu(_cpu) + CpuPort(const std::string &_name, TimingSimpleCPU *_cpu) + : Port(_name), cpu(_cpu) { } protected: @@ -93,7 +93,7 @@ class TimingSimpleCPU : public BaseSimpleCPU public: IcachePort(TimingSimpleCPU *_cpu) - : CpuPort(_cpu) + : CpuPort(_cpu->name() + "-iport", _cpu) { } protected: @@ -108,7 +108,7 @@ class TimingSimpleCPU : public BaseSimpleCPU public: DcachePort(TimingSimpleCPU *_cpu) - : CpuPort(_cpu) + : CpuPort(_cpu->name() + "-dport", _cpu) { } protected: diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 5f7770a92..28b50f9e8 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -31,7 +31,7 @@ PioPort::PioPort(PioDevice *dev, Platform *p) - : device(dev), platform(p) + : Port(dev->name() + "-pioport"), device(dev), platform(p) { } @@ -108,7 +108,7 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list) DmaPort::DmaPort(DmaDevice *dev, Platform *p) - : device(dev), platform(p), pendingCount(0) + : Port(dev->name() + "-dmaport"), device(dev), platform(p), pendingCount(0) { } bool diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index 5f19ded40..2672a6e8c 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -95,7 +95,7 @@ class Bridge : public MemObject /** Constructor for the BusPort.*/ BridgePort(Bridge *_bridge, Side _side) - : bridge(_bridge), side(_side) + : Port(""), bridge(_bridge), side(_side) { } int numQueued() { return outbound.size(); } diff --git a/src/mem/bus.cc b/src/mem/bus.cc index e8dfbc2e6..4139bf643 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -35,6 +35,16 @@ #include "mem/bus.hh" #include "sim/builder.hh" +Port * +Bus::getPort(const std::string &if_name) +{ + // if_name ignored? forced to be empty? + int id = interfaces.size(); + BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id); + interfaces.push_back(bp); + return bp; +} + /** Get the ranges of anyone that we are connected to. */ void Bus::init() diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 38573e514..1d3a7e528 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -100,8 +100,8 @@ class Bus : public MemObject public: /** Constructor for the BusPort.*/ - BusPort(Bus *_bus, int _id) - : bus(_bus), id(_id) + BusPort(const std::string &_name, Bus *_bus, int _id) + : Port(_name), bus(_bus), id(_id) { } protected: @@ -146,13 +146,7 @@ class Bus : public MemObject public: /** A function used to return the port associated with this bus object. */ - virtual Port *getPort(const std::string &if_name) - { - // if_name ignored? forced to be empty? - int id = interfaces.size(); - interfaces.push_back(new BusPort(this, id)); - return interfaces.back(); - } + virtual Port *getPort(const std::string &if_name); virtual void init(); diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 75179f9e3..ae27d762f 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -175,11 +175,11 @@ PhysicalMemory::getPort(const std::string &if_name) if (if_name == "") { if (port != NULL) panic("PhysicalMemory::getPort: additional port requested to memory!"); - port = new MemoryPort(this); + port = new MemoryPort(name() + "-port", this); return port; } else if (if_name == "functional") { /* special port for functional writes at startup. */ - return new MemoryPort(this); + return new MemoryPort(name() + "-funcport", this); } else { panic("PhysicalMemory::getPort: unknown port %s requested", if_name); } @@ -190,8 +190,9 @@ PhysicalMemory::recvStatusChange(Port::Status status) { } -PhysicalMemory::MemoryPort::MemoryPort(PhysicalMemory *_memory) - : memory(_memory) +PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name, + PhysicalMemory *_memory) + : Port(_name), memory(_memory) { } void diff --git a/src/mem/physical.hh b/src/mem/physical.hh index 1cf5444ab..2ced79045 100644 --- a/src/mem/physical.hh +++ b/src/mem/physical.hh @@ -51,7 +51,7 @@ class PhysicalMemory : public MemObject public: - MemoryPort(PhysicalMemory *_memory); + MemoryPort(const std::string &_name, PhysicalMemory *_memory); protected: diff --git a/src/mem/port.hh b/src/mem/port.hh index 1b1920c03..e8a20235a 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -69,9 +69,28 @@ typedef std::list >::iterator AddrRangeIter; */ class Port { + private: + + /** Descriptive name (for DPRINTF output) */ + const std::string portName; + public: + /** + * Constructor. + * + * @param _name Port name for DPRINTF output. Should include name + * of memory system object to which the port belongs. + */ + Port(const std::string &_name) + : portName(_name) + { } + + /** Return port name (for DPRINTF). */ + const std::string &name() const { return portName; } + virtual ~Port() {}; + // mey be better to use subclasses & RTTI? /** Holds the ports status. Keeps track if it is blocked, or has calculated a range change. */ @@ -224,6 +243,10 @@ class Port class FunctionalPort : public Port { public: + FunctionalPort(const std::string &_name) + : Port(_name) + {} + virtual bool recvTiming(Packet *pkt) { panic("FuncPort is UniDir"); } virtual Tick recvAtomic(Packet *pkt) { panic("FuncPort is UniDir"); } virtual void recvFunctional(Packet *pkt) { panic("FuncPort is UniDir"); } diff --git a/src/mem/translating_port.cc b/src/mem/translating_port.cc index 5dfeaff31..ee4d277b6 100644 --- a/src/mem/translating_port.cc +++ b/src/mem/translating_port.cc @@ -34,8 +34,9 @@ using namespace TheISA; -TranslatingPort::TranslatingPort(PageTable *p_table, bool alloc) - : pTable(p_table), allocating(alloc) +TranslatingPort::TranslatingPort(const std::string &_name, + PageTable *p_table, bool alloc) + : FunctionalPort(_name), pTable(p_table), allocating(alloc) { } TranslatingPort::~TranslatingPort() diff --git a/src/mem/translating_port.hh b/src/mem/translating_port.hh index 7611ac3c7..d078158a3 100644 --- a/src/mem/translating_port.hh +++ b/src/mem/translating_port.hh @@ -39,14 +39,11 @@ class TranslatingPort : public FunctionalPort PageTable *pTable; bool allocating; - TranslatingPort(const TranslatingPort &specmem); - const TranslatingPort &operator=(const TranslatingPort &specmem); - public: - TranslatingPort(PageTable *p_table, bool alloc = false); + TranslatingPort(const std::string &_name, + PageTable *p_table, bool alloc = false); virtual ~TranslatingPort(); - public: bool tryReadBlob(Addr addr, uint8_t *p, int size); bool tryWriteBlob(Addr addr, uint8_t *p, int size); bool tryMemsetBlob(Addr addr, uint8_t val, int size); @@ -56,9 +53,9 @@ class TranslatingPort : public FunctionalPort virtual void readBlob(Addr addr, uint8_t *p, int size); virtual void writeBlob(Addr addr, uint8_t *p, int size); virtual void memsetBlob(Addr addr, uint8_t val, int size); + void writeString(Addr addr, const char *str); void readString(std::string &str, Addr addr); - }; #endif diff --git a/src/mem/vport.hh b/src/mem/vport.hh index fbc230ba3..0f3b1f09e 100644 --- a/src/mem/vport.hh +++ b/src/mem/vport.hh @@ -53,8 +53,8 @@ class VirtualPort : public FunctionalPort ExecContext *xc; public: - VirtualPort(ExecContext *_xc = NULL) - : xc(_xc) + VirtualPort(const std::string &_name, ExecContext *_xc = NULL) + : FunctionalPort(_name), xc(_xc) {} /** Return true if we have an exec context. This is used to prevent someone diff --git a/src/sim/process.cc b/src/sim/process.cc index 1261b8436..1da525093 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -154,7 +154,7 @@ Process::startup() Port *mem_port; mem_port = system->physmem->getPort("functional"); - initVirtMem = new TranslatingPort(pTable, true); + initVirtMem = new TranslatingPort("process init port", pTable, true); mem_port->setPeer(initVirtMem); initVirtMem->setPeer(mem_port); } diff --git a/src/sim/system.cc b/src/sim/system.cc index ca9d68d77..89f39491e 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -25,6 +25,8 @@ System::System(Params *p) : SimObject(p->name), physmem(p->physmem), numcpus(0), #if FULL_SYSTEM init_param(p->init_param), + functionalPort(p->name + "-fport"), + virtPort(p->name + "-vport"), #else page_ptr(0), #endif -- cgit v1.2.3 From e533fad711fce66bf2e4a6669baeb8eaf02799e1 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 26 May 2006 14:17:33 -0400 Subject: Significant rework of Packet class interface: - new constructor guarantees initialization of most fields - flags track status of non-guaranteed fields (addr, size, src) - accessor functions (getAddr() etc.) check status on access - Command & Result classes are nested in Packet class scope - Command now built from vector of behavior bits - string version of Command for tracing - reinitFromRequest() and makeTimingResponse() encapsulate common manipulations of existing packets src/cpu/simple/atomic.cc: src/cpu/simple/base.cc: src/cpu/simple/timing.cc: src/dev/alpha_console.cc: src/dev/ide_ctrl.cc: src/dev/io_device.cc: src/dev/io_device.hh: src/dev/isa_fake.cc: src/dev/ns_gige.cc: src/dev/pciconfigall.cc: src/dev/sinic.cc: src/dev/tsunami_cchip.cc: src/dev/tsunami_io.cc: src/dev/tsunami_pchip.cc: src/dev/uart8250.cc: src/mem/bus.cc: src/mem/bus.hh: src/mem/physical.cc: src/mem/port.cc: src/mem/port.hh: src/mem/request.hh: Update for new Packet interface. --HG-- extra : convert_revision : 9973d09ea4fa61795f23772a7d3995fa4df5c269 --- src/cpu/simple/atomic.cc | 28 ++++------ src/cpu/simple/base.cc | 2 +- src/cpu/simple/timing.cc | 24 +++------ src/dev/alpha_console.cc | 25 ++++----- src/dev/ide_ctrl.cc | 80 +++++++++++++-------------- src/dev/io_device.cc | 59 ++++++++------------ src/dev/io_device.hh | 12 ++--- src/dev/isa_fake.cc | 14 ++--- src/dev/ns_gige.cc | 34 ++++++------ src/dev/pciconfigall.cc | 30 +++++------ src/dev/sinic.cc | 30 +++++------ src/dev/tsunami_cchip.cc | 28 +++++----- src/dev/tsunami_io.cc | 36 ++++++------- src/dev/tsunami_pchip.cc | 24 ++++----- src/dev/uart8250.cc | 20 +++---- src/mem/bus.cc | 51 ++++++++++-------- src/mem/bus.hh | 6 +-- src/mem/packet.cc | 50 ++++++++++++----- src/mem/packet.hh | 138 ++++++++++++++++++++++++++++++++++------------- src/mem/physical.cc | 20 +++---- src/mem/port.cc | 18 +++---- src/mem/port.hh | 2 +- src/mem/request.hh | 1 + 23 files changed, 395 insertions(+), 337 deletions(-) (limited to 'src') diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 04a84c92a..ec629304b 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -126,31 +126,23 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p) // @todo fix me and get the real cpu iD!!! ifetch_req->setCpuNum(0); ifetch_req->setSize(sizeof(MachInst)); - ifetch_pkt = new Packet; - ifetch_pkt->cmd = Read; + ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast); ifetch_pkt->dataStatic(&inst); - ifetch_pkt->req = ifetch_req; - ifetch_pkt->size = sizeof(MachInst); - ifetch_pkt->dest = Packet::Broadcast; data_read_req = new Request(true); // @todo fix me and get the real cpu iD!!! data_read_req->setCpuNum(0); data_read_req->setAsid(0); - data_read_pkt = new Packet; - data_read_pkt->cmd = Read; + data_read_pkt = new Packet(data_read_req, Packet::ReadReq, + Packet::Broadcast); data_read_pkt->dataStatic(&dataReg); - data_read_pkt->req = data_read_req; - data_read_pkt->dest = Packet::Broadcast; data_write_req = new Request(true); // @todo fix me and get the real cpu iD!!! data_write_req->setCpuNum(0); data_write_req->setAsid(0); - data_write_pkt = new Packet; - data_write_pkt->cmd = Write; - data_write_pkt->req = data_write_req; - data_write_pkt->dest = Packet::Broadcast; + data_write_pkt = new Packet(data_write_req, Packet::WriteReq, + Packet::Broadcast); } @@ -260,13 +252,12 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags) // Now do the access. if (fault == NoFault) { data_read_pkt->reset(); - data_read_pkt->addr = data_read_req->getPaddr(); - data_read_pkt->size = sizeof(T); + data_read_pkt->reinitFromRequest(); dcache_complete = dcachePort.sendAtomic(data_read_pkt); dcache_access = true; - assert(data_read_pkt->result == Success); + assert(data_read_pkt->result == Packet::Success); data = data_read_pkt->get(); } @@ -342,13 +333,12 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) data_write_pkt->reset(); data = htog(data); data_write_pkt->dataStatic(&data); - data_write_pkt->addr = data_write_req->getPaddr(); - data_write_pkt->size = sizeof(T); + data_write_pkt->reinitFromRequest(); dcache_complete = dcachePort.sendAtomic(data_write_pkt); dcache_access = true; - assert(data_write_pkt->result == Success); + assert(data_write_pkt->result == Packet::Success); if (res && data_write_req->getFlags() & LOCKED) { *res = data_write_req->getScResult(); diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 30c002ed5..077df8134 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -372,7 +372,7 @@ BaseSimpleCPU::setupFetchPacket(Packet *ifetch_pkt) Fault fault = cpuXC->translateInstReq(ifetch_req); if (fault == NoFault) { - ifetch_pkt->addr = ifetch_req->getPaddr(); + ifetch_pkt->reinitFromRequest(); } return fault; diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 70b88c4b1..d57935ed0 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -187,13 +187,9 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) // Now do the access. if (fault == NoFault) { - Packet *data_read_pkt = new Packet; - data_read_pkt->cmd = Read; - data_read_pkt->req = data_read_req; + Packet *data_read_pkt = + new Packet(data_read_req, Packet::ReadReq, Packet::Broadcast); data_read_pkt->dataDynamic(new T); - data_read_pkt->addr = data_read_req->getPaddr(); - data_read_pkt->size = sizeof(T); - data_read_pkt->dest = Packet::Broadcast; if (!dcachePort.sendTiming(data_read_pkt)) { _status = DcacheRetry; @@ -268,14 +264,10 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) Fault fault = cpuXC->translateDataWriteReq(data_write_req); // Now do the access. if (fault == NoFault) { - Packet *data_write_pkt = new Packet; - data_write_pkt->cmd = Write; - data_write_pkt->req = data_write_req; + Packet *data_write_pkt = + new Packet(data_write_req, Packet::WriteReq, Packet::Broadcast); data_write_pkt->allocate(); - data_write_pkt->size = sizeof(T); data_write_pkt->set(data); - data_write_pkt->addr = data_write_req->getPaddr(); - data_write_pkt->dest = Packet::Broadcast; if (!dcachePort.sendTiming(data_write_pkt)) { _status = DcacheRetry; @@ -350,12 +342,8 @@ TimingSimpleCPU::fetch() Request *ifetch_req = new Request(true); ifetch_req->setSize(sizeof(MachInst)); - ifetch_pkt = new Packet; - ifetch_pkt->cmd = Read; + ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast); ifetch_pkt->dataStatic(&inst); - ifetch_pkt->req = ifetch_req; - ifetch_pkt->size = sizeof(MachInst); - ifetch_pkt->dest = Packet::Broadcast; Fault fault = setupFetchPacket(ifetch_pkt); if (fault == NoFault) { @@ -441,7 +429,7 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt) { // received a response from the dcache: complete the load or store // instruction - assert(pkt->result == Success); + assert(pkt->result == Packet::Success); assert(_status == DcacheWaitResponse); _status = Running; diff --git a/src/dev/alpha_console.cc b/src/dev/alpha_console.cc index f24c09844..0b4bb048c 100644 --- a/src/dev/alpha_console.cc +++ b/src/dev/alpha_console.cc @@ -95,15 +95,15 @@ AlphaConsole::read(Packet *pkt) * machine dependent address swizzle is required? */ - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); pkt->time += pioDelay; - Addr daddr = pkt->addr - pioAddr; + Addr daddr = pkt->getAddr() - pioAddr; pkt->allocate(); - switch (pkt->size) + switch (pkt->getSize()) { case sizeof(uint32_t): switch (daddr) @@ -124,7 +124,7 @@ AlphaConsole::read(Packet *pkt) /* Old console code read in everyting as a 32bit int * we now break that for better error checking. */ - pkt->result = BadAddress; + pkt->result = Packet::BadAddress; } DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, pkt->get()); @@ -181,9 +181,10 @@ AlphaConsole::read(Packet *pkt) pkt->get()); break; default: - pkt->result = BadAddress; + pkt->result = Packet::BadAddress; } - if (pkt->result == Unknown) pkt->result = Success; + if (pkt->result == Packet::Unknown) + pkt->result = Packet::Success; return pioDelay; } @@ -192,12 +193,12 @@ AlphaConsole::write(Packet *pkt) { pkt->time += pioDelay; - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); - Addr daddr = pkt->addr - pioAddr; + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = pkt->getAddr() - pioAddr; uint64_t val = pkt->get(); - assert(pkt->size == sizeof(uint64_t)); + assert(pkt->getSize() == sizeof(uint64_t)); switch (daddr) { case offsetof(AlphaAccess, diskUnit): @@ -240,7 +241,7 @@ AlphaConsole::write(Packet *pkt) panic("Unknown 64bit access, %#x\n", daddr); } - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } diff --git a/src/dev/ide_ctrl.cc b/src/dev/ide_ctrl.cc index cedd5c53e..eb03d5db8 100644 --- a/src/dev/ide_ctrl.cc +++ b/src/dev/ide_ctrl.cc @@ -432,19 +432,19 @@ IdeController::read(Packet *pkt) pkt->time += pioDelay; pkt->allocate(); - if (pkt->size != 1 && pkt->size != 2 && pkt->size !=4) - panic("Bad IDE read size: %d\n", pkt->size); + if (pkt->getSize() != 1 && pkt->getSize() != 2 && pkt->getSize() !=4) + panic("Bad IDE read size: %d\n", pkt->getSize()); - parseAddr(pkt->addr, offset, channel, reg_type); + parseAddr(pkt->getAddr(), offset, channel, reg_type); if (!io_enabled) { - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } switch (reg_type) { case BMI_BLOCK: - switch (pkt->size) { + switch (pkt->getSize()) { case sizeof(uint8_t): pkt->set(bmi_regs.data[offset]); break; @@ -455,7 +455,7 @@ IdeController::read(Packet *pkt) pkt->set(*(uint32_t*)&bmi_regs.data[offset]); break; default: - panic("IDE read of BMI reg invalid size: %#x\n", pkt->size); + panic("IDE read of BMI reg invalid size: %#x\n", pkt->getSize()); } break; @@ -470,7 +470,7 @@ IdeController::read(Packet *pkt) switch (offset) { case DATA_OFFSET: - switch (pkt->size) { + switch (pkt->getSize()) { case sizeof(uint16_t): disks[disk]->read(offset, reg_type, pkt->getPtr()); break; @@ -482,30 +482,30 @@ IdeController::read(Packet *pkt) break; default: - panic("IDE read of data reg invalid size: %#x\n", pkt->size); + panic("IDE read of data reg invalid size: %#x\n", pkt->getSize()); } break; default: - if (pkt->size == sizeof(uint8_t)) { + if (pkt->getSize() == sizeof(uint8_t)) { disks[disk]->read(offset, reg_type, pkt->getPtr()); } else - panic("IDE read of command reg of invalid size: %#x\n", pkt->size); + panic("IDE read of command reg of invalid size: %#x\n", pkt->getSize()); } break; default: panic("IDE controller read of unknown register block type!\n"); } - if (pkt->size == 1) + if (pkt->getSize() == 1) DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", - offset, pkt->size, (uint32_t)pkt->get()); - else if (pkt->size == 2) + offset, pkt->getSize(), (uint32_t)pkt->get()); + else if (pkt->getSize() == 2) DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", - offset, pkt->size, pkt->get()); + offset, pkt->getSize(), pkt->get()); else DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", - offset, pkt->size, pkt->get()); + offset, pkt->getSize(), pkt->get()); - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } @@ -520,10 +520,10 @@ IdeController::write(Packet *pkt) pkt->time += pioDelay; - parseAddr(pkt->addr, offset, channel, reg_type); + parseAddr(pkt->getAddr(), offset, channel, reg_type); if (!io_enabled) { - pkt->result = Success; + pkt->result = Packet::Success; DPRINTF(IdeCtrl, "io not enabled\n"); return pioDelay; } @@ -531,7 +531,7 @@ IdeController::write(Packet *pkt) switch (reg_type) { case BMI_BLOCK: if (!bm_enabled) { - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } @@ -539,8 +539,8 @@ IdeController::write(Packet *pkt) // Bus master IDE command register case BMIC1: case BMIC0: - if (pkt->size != sizeof(uint8_t)) - panic("Invalid BMIC write size: %x\n", pkt->size); + if (pkt->getSize() != sizeof(uint8_t)) + panic("Invalid BMIC write size: %x\n", pkt->getSize()); // select the current disk based on DEV bit disk = getDisk(channel); @@ -595,8 +595,8 @@ IdeController::write(Packet *pkt) // Bus master IDE status register case BMIS0: case BMIS1: - if (pkt->size != sizeof(uint8_t)) - panic("Invalid BMIS write size: %x\n", pkt->size); + if (pkt->getSize() != sizeof(uint8_t)) + panic("Invalid BMIS write size: %x\n", pkt->getSize()); oldVal = bmi_regs.chan[channel].bmis; newVal = pkt->get(); @@ -622,22 +622,22 @@ IdeController::write(Packet *pkt) case BMIDTP0: case BMIDTP1: { - if (pkt->size != sizeof(uint32_t)) - panic("Invalid BMIDTP write size: %x\n", pkt->size); + if (pkt->getSize() != sizeof(uint32_t)) + panic("Invalid BMIDTP write size: %x\n", pkt->getSize()); bmi_regs.chan[channel].bmidtp = htole(pkt->get() & ~0x3); } break; default: - if (pkt->size != sizeof(uint8_t) && - pkt->size != sizeof(uint16_t) && - pkt->size != sizeof(uint32_t)) + if (pkt->getSize() != sizeof(uint8_t) && + pkt->getSize() != sizeof(uint16_t) && + pkt->getSize() != sizeof(uint32_t)) panic("IDE controller write of invalid write size: %x\n", - pkt->size); + pkt->getSize()); // do a default copy of data into the registers - memcpy(&bmi_regs.data[offset], pkt->getPtr(), pkt->size); + memcpy(&bmi_regs.data[offset], pkt->getPtr(), pkt->getSize()); } break; case COMMAND_BLOCK: @@ -654,7 +654,7 @@ IdeController::write(Packet *pkt) switch (offset) { case DATA_OFFSET: - switch (pkt->size) { + switch (pkt->getSize()) { case sizeof(uint16_t): disks[disk]->write(offset, reg_type, pkt->getPtr()); break; @@ -665,32 +665,32 @@ IdeController::write(Packet *pkt) sizeof(uint16_t)); break; default: - panic("IDE write of data reg invalid size: %#x\n", pkt->size); + panic("IDE write of data reg invalid size: %#x\n", pkt->getSize()); } break; default: - if (pkt->size == sizeof(uint8_t)) { + if (pkt->getSize() == sizeof(uint8_t)) { disks[disk]->write(offset, reg_type, pkt->getPtr()); } else - panic("IDE write of command reg of invalid size: %#x\n", pkt->size); + panic("IDE write of command reg of invalid size: %#x\n", pkt->getSize()); } break; default: panic("IDE controller write of unknown register block type!\n"); } - if (pkt->size == 1) + if (pkt->getSize() == 1) DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", - offset, pkt->size, (uint32_t)pkt->get()); - else if (pkt->size == 2) + offset, pkt->getSize(), (uint32_t)pkt->get()); + else if (pkt->getSize() == 2) DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", - offset, pkt->size, pkt->get()); + offset, pkt->getSize(), pkt->get()); else DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", - offset, pkt->size, pkt->get()); + offset, pkt->getSize(), pkt->get()); - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc index 28b50f9e8..87fdbb765 100644 --- a/src/dev/io_device.cc +++ b/src/dev/io_device.cc @@ -67,7 +67,7 @@ PioPort::recvRetry() void PioPort::SendEvent::process() { - if (port->Port::sendTiming(packet) == Success) + if (port->Port::sendTiming(packet)) return; port->transmitList.push_back(packet); @@ -79,9 +79,9 @@ PioPort::recvTiming(Packet *pkt) { device->recvAtomic(pkt); // turn packet around to go back to requester - pkt->dest = pkt->src; + pkt->makeTimingResponse(); sendTiming(pkt, pkt->time - pkt->req->getTime()); - return Success; + return true; } PioDevice::~PioDevice() @@ -116,7 +116,7 @@ DmaPort::recvTiming(Packet *pkt) { if (pkt->senderState) { DmaReqState *state; - state = (DmaReqState*)pkt->senderState; + state = dynamic_cast(pkt->senderState); state->completionEvent->schedule(pkt->time - pkt->req->getTime()); delete pkt->req; delete pkt; @@ -125,7 +125,7 @@ DmaPort::recvTiming(Packet *pkt) delete pkt; } - return Success; + return Packet::Success; } DmaDevice::DmaDevice(Params *p) @@ -135,7 +135,7 @@ DmaDevice::DmaDevice(Params *p) void DmaPort::SendEvent::process() { - if (port->Port::sendTiming(packet) == Success) + if (port->Port::sendTiming(packet)) return; port->transmitList.push_back(packet); @@ -148,54 +148,39 @@ DmaPort::recvRetry() transmitList.pop_front(); return pkt; } + + void -DmaPort::dmaAction(Command cmd, Addr addr, int size, Event *event, - uint8_t *data) +DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, + uint8_t *data) { - assert(event); int prevSize = 0; - Packet basePkt; - Request baseReq(false); - - basePkt.flags = 0; - basePkt.coherence = NULL; - basePkt.senderState = NULL; - basePkt.dest = Packet::Broadcast; - basePkt.cmd = cmd; - basePkt.result = Unknown; - basePkt.req = NULL; -// baseReq.nicReq = true; - baseReq.setTime(curTick); for (ChunkGenerator gen(addr, size, peerBlockSize()); !gen.done(); gen.next()) { - Packet *pkt = new Packet(basePkt); - Request *req = new Request(baseReq); - pkt->addr = gen.addr(); - pkt->size = gen.size(); - pkt->req = req; - pkt->req->setPaddr(pkt->addr); - pkt->req->setSize(pkt->size); + Request *req = new Request(false); + req->setPaddr(gen.addr()); + req->setSize(gen.size()); + req->setTime(curTick); + Packet *pkt = new Packet(req, cmd, Packet::Broadcast); + // Increment the data pointer on a write if (data) pkt->dataStatic(data + prevSize) ; - prevSize += pkt->size; + + prevSize += gen.size(); + // Set the last bit of the dma as the final packet for this dma // and set it's completion event. if (prevSize == size) { - DmaReqState *state = new DmaReqState(event, true); - - pkt->senderState = (void*)state; + pkt->senderState = new DmaReqState(event, true); } assert(pendingCount >= 0); pendingCount++; sendDma(pkt); } - // since this isn't getting used and we want a check to make sure that all - // packets had data in them at some point. - basePkt.dataStatic((uint8_t*)NULL); } @@ -208,12 +193,12 @@ DmaPort::sendDma(Packet *pkt) /* MemState state = device->platform->system->memState; if (state == Timing) { - if (sendTiming(pkt) == Failure) + if (!sendTiming(pkt)) transmitList.push_back(&packet); } else if (state == Atomic) {*/ sendAtomic(pkt); if (pkt->senderState) { - DmaReqState *state = (DmaReqState*)pkt->senderState; + DmaReqState *state = dynamic_cast(pkt->senderState); state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1); } pendingCount--; diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh index 6efa9ef63..74730ad92 100644 --- a/src/dev/io_device.hh +++ b/src/dev/io_device.hh @@ -115,7 +115,7 @@ class PioPort : public Port }; -struct DmaReqState +struct DmaReqState : public Packet::SenderState { Event *completionEvent; bool final; @@ -173,8 +173,8 @@ class DmaPort : public Port public: DmaPort(DmaDevice *dev, Platform *p); - void dmaAction(Command cmd, Addr addr, int size, Event *event, - uint8_t *data = NULL); + void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, + uint8_t *data = NULL); bool dmaPending() { return pendingCount > 0; } @@ -207,7 +207,7 @@ class PioDevice : public MemObject /** As far as the devices are concerned they only accept atomic transactions * which are converted to either a write or a read. */ Tick recvAtomic(Packet *pkt) - { return pkt->cmd == Read ? this->read(pkt) : this->write(pkt); } + { return pkt->isRead() ? this->read(pkt) : this->write(pkt); } /** Pure virtual function that the device must implement. Called when a read * command is recieved by the port. @@ -305,10 +305,10 @@ class DmaDevice : public PioDevice virtual ~DmaDevice(); void dmaWrite(Addr addr, int size, Event *event, uint8_t *data) - { dmaPort->dmaAction(Write, addr, size, event, data) ; } + { dmaPort->dmaAction(Packet::WriteReq, addr, size, event, data) ; } void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL) - { dmaPort->dmaAction(Read, addr, size, event, data); } + { dmaPort->dmaAction(Packet::ReadReq, addr, size, event, data); } bool dmaPending() { return dmaPort->dmaPending(); } diff --git a/src/dev/isa_fake.cc b/src/dev/isa_fake.cc index 9717226b7..c303ffc30 100644 --- a/src/dev/isa_fake.cc +++ b/src/dev/isa_fake.cc @@ -51,14 +51,14 @@ IsaFake::IsaFake(Params *p) Tick IsaFake::read(Packet *pkt) { - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); pkt->time += pioDelay; - DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->addr, pkt->size); + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); - switch (pkt->size) { + switch (pkt->getSize()) { pkt->set(0xFFFFFFFFFFFFFFFFULL); break; case sizeof(uint32_t): @@ -73,7 +73,7 @@ IsaFake::read(Packet *pkt) default: panic("invalid access size(?) for PCI configspace!\n"); } - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } @@ -81,8 +81,8 @@ Tick IsaFake::write(Packet *pkt) { pkt->time += pioDelay; - DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->addr, pkt->size); - pkt->result = Success; + DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize()); + pkt->result = Packet::Success; return pioDelay; } diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc index 5e27db58d..963675847 100644 --- a/src/dev/ns_gige.cc +++ b/src/dev/ns_gige.cc @@ -496,9 +496,9 @@ NSGigE::read(Packet *pkt) pkt->allocate(); //The mask is to give you only the offset into the device register file - Addr daddr = pkt->addr & 0xfff; + Addr daddr = pkt->getAddr() & 0xfff; DPRINTF(EthernetPIO, "read da=%#x pa=%#x size=%d\n", - daddr, pkt->addr, pkt->size); + daddr, pkt->getAddr(), pkt->getSize()); // there are some reserved registers, you can see ns_gige_reg.h and @@ -506,25 +506,25 @@ NSGigE::read(Packet *pkt) if (daddr > LAST && daddr <= RESERVED) { panic("Accessing reserved register"); } else if (daddr > RESERVED && daddr <= 0x3FC) { - if (pkt->size == sizeof(uint8_t)) + if (pkt->getSize() == sizeof(uint8_t)) readConfig(daddr & 0xff, pkt->getPtr()); - if (pkt->size == sizeof(uint16_t)) + if (pkt->getSize() == sizeof(uint16_t)) readConfig(daddr & 0xff, pkt->getPtr()); - if (pkt->size == sizeof(uint32_t)) + if (pkt->getSize() == sizeof(uint32_t)) readConfig(daddr & 0xff, pkt->getPtr()); - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } else if (daddr >= MIB_START && daddr <= MIB_END) { // don't implement all the MIB's. hopefully the kernel // doesn't actually DEPEND upon their values // MIB are just hardware stats keepers pkt->set(0); - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } else if (daddr > 0x3FC) panic("Something is messed up!\n"); - assert(pkt->size == sizeof(uint32_t)); + assert(pkt->getSize() == sizeof(uint32_t)); uint32_t ® = *pkt->getPtr(); uint16_t rfaddr; @@ -715,7 +715,7 @@ NSGigE::read(Packet *pkt) DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", daddr, reg, reg); - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } @@ -724,27 +724,27 @@ NSGigE::write(Packet *pkt) { assert(ioEnable); - Addr daddr = pkt->addr & 0xfff; + Addr daddr = pkt->getAddr() & 0xfff; DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n", - daddr, pkt->addr, pkt->size); + daddr, pkt->getAddr(), pkt->getSize()); pkt->time += pioDelay; if (daddr > LAST && daddr <= RESERVED) { panic("Accessing reserved register"); } else if (daddr > RESERVED && daddr <= 0x3FC) { - if (pkt->size == sizeof(uint8_t)) + if (pkt->getSize() == sizeof(uint8_t)) writeConfig(daddr & 0xff, pkt->get()); - if (pkt->size == sizeof(uint16_t)) + if (pkt->getSize() == sizeof(uint16_t)) writeConfig(daddr & 0xff, pkt->get()); - if (pkt->size == sizeof(uint32_t)) + if (pkt->getSize() == sizeof(uint32_t)) writeConfig(daddr & 0xff, pkt->get()); - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } else if (daddr > 0x3FC) panic("Something is messed up!\n"); - if (pkt->size == sizeof(uint32_t)) { + if (pkt->getSize() == sizeof(uint32_t)) { uint32_t reg = pkt->get(); uint16_t rfaddr; @@ -1131,7 +1131,7 @@ NSGigE::write(Packet *pkt) } else { panic("Invalid Request Size"); } - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } diff --git a/src/dev/pciconfigall.cc b/src/dev/pciconfigall.cc index f278a67cf..14a28e86d 100644 --- a/src/dev/pciconfigall.cc +++ b/src/dev/pciconfigall.cc @@ -91,10 +91,10 @@ PciConfigAll::startup() Tick PciConfigAll::read(Packet *pkt) { - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); - Addr daddr = pkt->addr - pioAddr; + Addr daddr = pkt->getAddr() - pioAddr; int device = (daddr >> 11) & 0x1F; int func = (daddr >> 8) & 0x7; int reg = daddr & 0xFF; @@ -102,10 +102,10 @@ PciConfigAll::read(Packet *pkt) pkt->time += pioDelay; pkt->allocate(); - DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt->addr, daddr, - pkt->size); + DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt->getAddr(), daddr, + pkt->getSize()); - switch (pkt->size) { + switch (pkt->getSize()) { case sizeof(uint32_t): if (devices[device][func] == NULL) pkt->set(0xFFFFFFFF); @@ -127,7 +127,7 @@ PciConfigAll::read(Packet *pkt) default: panic("invalid access size(?) for PCI configspace!\n"); } - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } @@ -136,11 +136,11 @@ PciConfigAll::write(Packet *pkt) { pkt->time += pioDelay; - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); - assert(pkt->size == sizeof(uint8_t) || pkt->size == sizeof(uint16_t) || - pkt->size == sizeof(uint32_t)); - Addr daddr = pkt->addr - pioAddr; + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + assert(pkt->getSize() == sizeof(uint8_t) || pkt->getSize() == sizeof(uint16_t) || + pkt->getSize() == sizeof(uint32_t)); + Addr daddr = pkt->getAddr() - pioAddr; int device = (daddr >> 11) & 0x1F; int func = (daddr >> 8) & 0x7; @@ -150,9 +150,9 @@ PciConfigAll::write(Packet *pkt) panic("Attempting to write to config space on non-existant device\n"); DPRINTF(PciConfigAll, "write - va=%#x size=%d data=%#x\n", - pkt->addr, pkt->size, pkt->get()); + pkt->getAddr(), pkt->getSize(), pkt->get()); - switch (pkt->size) { + switch (pkt->getSize()) { case sizeof(uint8_t): devices[device][func]->writeConfig(reg, pkt->get()); break; @@ -165,7 +165,7 @@ PciConfigAll::write(Packet *pkt) default: panic("invalid pci config write size\n"); } - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc index df7e4d167..31fbc49aa 100644 --- a/src/dev/sinic.cc +++ b/src/dev/sinic.cc @@ -315,10 +315,10 @@ Tick Device::read(Packet *pkt) { assert(config.command & PCI_CMD_MSE); - assert(pkt->addr >= BARAddrs[0] && pkt->size < BARSize[0]); + assert(pkt->getAddr() >= BARAddrs[0] && pkt->getSize() < BARSize[0]); int cpu = pkt->req->getCpuNum(); - Addr daddr = pkt->addr - BARAddrs[0]; + Addr daddr = pkt->getAddr() - BARAddrs[0]; Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; @@ -327,28 +327,28 @@ Device::read(Packet *pkt) if (!regValid(raddr)) panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x size=%d", - cpu, index, daddr, pkt->addr, pkt->size); + cpu, index, daddr, pkt->getAddr(), pkt->getSize()); const Regs::Info &info = regInfo(raddr); if (!info.read) panic("read %s (write only): " "cpu=%d vnic=%d da=%#x pa=%#x size=%d", - info.name, cpu, index, daddr, pkt->addr, pkt->size); + info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize()); panic("read %s (invalid size): " "cpu=%d vnic=%d da=%#x pa=%#x size=%d", - info.name, cpu, index, daddr, pkt->addr, pkt->size); + info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize()); prepareRead(cpu, index); uint64_t value = 0; - if (pkt->size == 4) { + if (pkt->getSize() == 4) { uint32_t reg = regData32(raddr); pkt->set(reg); value = reg; } - if (pkt->size == 8) { + if (pkt->getSize() == 8) { uint64_t reg = regData64(raddr); pkt->set(reg); value = reg; @@ -356,7 +356,7 @@ Device::read(Packet *pkt) DPRINTF(EthernetPIO, "read %s: cpu=%d vnic=%d da=%#x pa=%#x size=%d val=%#x\n", - info.name, cpu, index, daddr, pkt->addr, pkt->size, value); + info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize(), value); // reading the interrupt status register has the side effect of // clearing it @@ -403,10 +403,10 @@ Tick Device::write(Packet *pkt) { assert(config.command & PCI_CMD_MSE); - assert(pkt->addr >= BARAddrs[0] && pkt->size < BARSize[0]); + assert(pkt->getAddr() >= BARAddrs[0] && pkt->getSize() < BARSize[0]); int cpu = pkt->req->getCpuNum(); - Addr daddr = pkt->addr - BARAddrs[0]; + Addr daddr = pkt->getAddr() - BARAddrs[0]; Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; @@ -414,25 +414,25 @@ Device::write(Packet *pkt) if (!regValid(raddr)) panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d", - cpu, daddr, pkt->addr, pkt->size); + cpu, daddr, pkt->getAddr(), pkt->getSize()); const Regs::Info &info = regInfo(raddr); if (!info.write) panic("write %s (read only): " "cpu=%d vnic=%d da=%#x pa=%#x size=%d", - info.name, cpu, index, daddr, pkt->addr, pkt->size); + info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize()); - if (pkt->size != info.size) + if (pkt->getSize() != info.size) panic("write %s (invalid size): " "cpu=%d vnic=%d da=%#x pa=%#x size=%d", - info.name, cpu, index, daddr, pkt->addr, pkt->size); + info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize()); VirtualReg &vnic = virtualRegs[index]; DPRINTF(EthernetPIO, "write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x size=%d\n", info.name, index, cpu, info.size == 4 ? pkt->get() : - pkt->get(), daddr, pkt->addr, pkt->size); + pkt->get(), daddr, pkt->getAddr(), pkt->getSize()); prepareWrite(cpu, index); diff --git a/src/dev/tsunami_cchip.cc b/src/dev/tsunami_cchip.cc index 7206a61bb..146321b9f 100644 --- a/src/dev/tsunami_cchip.cc +++ b/src/dev/tsunami_cchip.cc @@ -71,17 +71,17 @@ TsunamiCChip::TsunamiCChip(Params *p) Tick TsunamiCChip::read(Packet *pkt) { - DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->addr, pkt->size); + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); pkt->time += pioDelay; - Addr regnum = (pkt->addr - pioAddr) >> 6; - Addr daddr = (pkt->addr - pioAddr); + Addr regnum = (pkt->getAddr() - pioAddr) >> 6; + Addr daddr = (pkt->getAddr() - pioAddr); pkt->allocate(); - switch (pkt->size) { + switch (pkt->getSize()) { case sizeof(uint64_t): if (daddr & TSDEV_CC_BDIMS) @@ -173,9 +173,9 @@ TsunamiCChip::read(Packet *pkt) panic("invalid access size(?) for tsunami register!\n"); } DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n", - regnum, pkt->size, pkt->get()); + regnum, pkt->getSize(), pkt->get()); - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } @@ -185,14 +185,14 @@ TsunamiCChip::write(Packet *pkt) pkt->time += pioDelay; - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); - Addr daddr = pkt->addr - pioAddr; - Addr regnum = (pkt->addr - pioAddr) >> 6 ; + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = pkt->getAddr() - pioAddr; + Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ; - assert(pkt->size == sizeof(uint64_t)); + assert(pkt->getSize() == sizeof(uint64_t)); - DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt->addr, pkt->get()); + DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt->getAddr(), pkt->get()); bool supportedWrite = false; @@ -362,7 +362,7 @@ TsunamiCChip::write(Packet *pkt) panic("default in cchip read reached, accessing 0x%x\n"); } // swtich(regnum) } // not BIG_TSUNAMI write - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } diff --git a/src/dev/tsunami_io.cc b/src/dev/tsunami_io.cc index dd9feae99..7c649a84a 100644 --- a/src/dev/tsunami_io.cc +++ b/src/dev/tsunami_io.cc @@ -438,18 +438,18 @@ TsunamiIO::frequency() const Tick TsunamiIO::read(Packet *pkt) { - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); pkt->time += pioDelay; - Addr daddr = pkt->addr - pioAddr; + Addr daddr = pkt->getAddr() - pioAddr; - DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->addr, - pkt->size, daddr); + DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(), + pkt->getSize(), daddr); pkt->allocate(); - if (pkt->size == sizeof(uint8_t)) { + if (pkt->getSize() == sizeof(uint8_t)) { switch(daddr) { // PIC1 mask read case TSDEV_PIC1_MASK: @@ -487,18 +487,18 @@ TsunamiIO::read(Packet *pkt) pkt->set(0x00); break; default: - panic("I/O Read - va%#x size %d\n", pkt->addr, pkt->size); + panic("I/O Read - va%#x size %d\n", pkt->getAddr(), pkt->getSize()); } - } else if (pkt->size == sizeof(uint64_t)) { + } else if (pkt->getSize() == sizeof(uint64_t)) { if (daddr == TSDEV_PIC1_ISR) pkt->set(picr); else panic("I/O Read - invalid addr - va %#x size %d\n", - pkt->addr, pkt->size); + pkt->getAddr(), pkt->getSize()); } else { - panic("I/O Read - invalid size - va %#x size %d\n", pkt->addr, pkt->size); + panic("I/O Read - invalid size - va %#x size %d\n", pkt->getAddr(), pkt->getSize()); } - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } @@ -507,14 +507,14 @@ TsunamiIO::write(Packet *pkt) { pkt->time += pioDelay; - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); - Addr daddr = pkt->addr - pioAddr; + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = pkt->getAddr() - pioAddr; DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", - pkt->addr, pkt->size, pkt->addr & 0xfff, (uint32_t)pkt->get()); + pkt->getAddr(), pkt->getSize(), pkt->getAddr() & 0xfff, (uint32_t)pkt->get()); - assert(pkt->size == sizeof(uint8_t)); + assert(pkt->getSize() == sizeof(uint8_t)); switch(daddr) { case TSDEV_PIC1_MASK: @@ -577,10 +577,10 @@ TsunamiIO::write(Packet *pkt) case TSDEV_CTRL_PORTB: break; default: - panic("I/O Write - va%#x size %d data %#x\n", pkt->addr, pkt->size, pkt->get()); + panic("I/O Write - va%#x size %d data %#x\n", pkt->getAddr(), pkt->getSize(), pkt->get()); } - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } diff --git a/src/dev/tsunami_pchip.cc b/src/dev/tsunami_pchip.cc index 999278e37..c430ca0a0 100644 --- a/src/dev/tsunami_pchip.cc +++ b/src/dev/tsunami_pchip.cc @@ -67,17 +67,17 @@ TsunamiPChip::TsunamiPChip(Params *p) Tick TsunamiPChip::read(Packet *pkt) { - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); pkt->time += pioDelay; pkt->allocate(); - Addr daddr = (pkt->addr - pioAddr) >> 6;; - assert(pkt->size == sizeof(uint64_t)); + Addr daddr = (pkt->getAddr() - pioAddr) >> 6;; + assert(pkt->getSize() == sizeof(uint64_t)); - DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->addr, pkt->size); + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize()); switch(daddr) { case TSDEV_PC_WSBA0: @@ -143,7 +143,7 @@ TsunamiPChip::read(Packet *pkt) default: panic("Default in PChip Read reached reading 0x%x\n", daddr); } - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } @@ -153,13 +153,13 @@ TsunamiPChip::write(Packet *pkt) { pkt->time += pioDelay; - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); - Addr daddr = (pkt->addr - pioAddr) >> 6; + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + Addr daddr = (pkt->getAddr() - pioAddr) >> 6; - assert(pkt->size == sizeof(uint64_t)); + assert(pkt->getSize() == sizeof(uint64_t)); - DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->addr, pkt->size); + DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize()); switch(daddr) { case TSDEV_PC_WSBA0: @@ -224,7 +224,7 @@ TsunamiPChip::write(Packet *pkt) } // uint64_t - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc index a4b30cf25..8e6843841 100644 --- a/src/dev/uart8250.cc +++ b/src/dev/uart8250.cc @@ -110,12 +110,12 @@ Uart8250::Uart8250(Params *p) Tick Uart8250::read(Packet *pkt) { - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); - assert(pkt->size == 1); + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + assert(pkt->getSize() == 1); pkt->time += pioDelay; - Addr daddr = pkt->addr - pioAddr; + Addr daddr = pkt->getAddr() - pioAddr; pkt->allocate(); DPRINTF(Uart, " read register %#x\n", daddr); @@ -186,7 +186,7 @@ Uart8250::read(Packet *pkt) /* uint32_t d32 = *data; DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32); */ - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } @@ -194,12 +194,12 @@ Tick Uart8250::write(Packet *pkt) { - assert(pkt->result == Unknown); - assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); - assert(pkt->size == 1); + assert(pkt->result == Packet::Unknown); + assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); + assert(pkt->getSize() == 1); pkt->time += pioDelay; - Addr daddr = pkt->addr - pioAddr; + Addr daddr = pkt->getAddr() - pioAddr; DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt->get()); @@ -264,7 +264,7 @@ Uart8250::write(Packet *pkt) panic("Tried to access a UART port that doesn't exist\n"); break; } - pkt->result = Success; + pkt->result = Packet::Success; return pioDelay; } diff --git a/src/mem/bus.cc b/src/mem/bus.cc index 4139bf643..a2ce00139 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -55,18 +55,22 @@ Bus::init() } -/** Function called by the port when the bus is recieving a Timing +/** Function called by the port when the bus is receiving a Timing * transaction.*/ bool Bus::recvTiming(Packet *pkt) { Port *port; - if (pkt->dest == Packet::Broadcast) { - port = findPort(pkt->addr, pkt->src); + DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n", + pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); + + short dest = pkt->getDest(); + if (dest == Packet::Broadcast) { + port = findPort(pkt->getAddr(), pkt->getSrc()); } else { - assert(pkt->dest >= 0 && pkt->dest < interfaces.size()); - assert(pkt->dest != pkt->src); // catch infinite loops - port = interfaces[pkt->dest]; + assert(dest >= 0 && dest < interfaces.size()); + assert(dest != pkt->getSrc()); // catch infinite loops + port = interfaces[dest]; } return port->sendTiming(pkt); } @@ -84,7 +88,7 @@ Bus::findPort(Addr addr, int id) if (portList[i].range == addr) { dest_id = portList[i].portId; found = true; - DPRINTF(Bus, "Found Addr: %llx on device %d\n", addr, dest_id); + DPRINTF(Bus, " found addr 0x%llx on device %d\n", addr, dest_id); } i++; } @@ -97,33 +101,37 @@ Bus::findPort(Addr addr, int id) return interfaces[dest_id]; } -/** Function called by the port when the bus is recieving a Atomic +/** Function called by the port when the bus is receiving a Atomic * transaction.*/ Tick Bus::recvAtomic(Packet *pkt) { - assert(pkt->dest == Packet::Broadcast); - return findPort(pkt->addr, pkt->src)->sendAtomic(pkt); + DPRINTF(Bus, "recvAtomic: packet src %d dest %d addr 0x%x cmd %s\n", + pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); + assert(pkt->getDest() == Packet::Broadcast); + return findPort(pkt->getAddr(), pkt->getSrc())->sendAtomic(pkt); } -/** Function called by the port when the bus is recieving a Functional +/** Function called by the port when the bus is receiving a Functional * transaction.*/ void Bus::recvFunctional(Packet *pkt) { - assert(pkt->dest == Packet::Broadcast); - findPort(pkt->addr, pkt->src)->sendFunctional(pkt); + DPRINTF(Bus, "recvFunctional: packet src %d dest %d addr 0x%x cmd %s\n", + pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); + assert(pkt->getDest() == Packet::Broadcast); + findPort(pkt->getAddr(), pkt->getSrc())->sendFunctional(pkt); } -/** Function called by the port when the bus is recieving a status change.*/ +/** Function called by the port when the bus is receiving a status change.*/ void Bus::recvStatusChange(Port::Status status, int id) { - DPRINTF(Bus, "Bus %d recieved status change from device id %d\n", - busId, id); assert(status == Port::RangeChange && "The other statuses need to be implemented."); + DPRINTF(Bus, "received RangeChange from device id %d\n", id); + assert(id < interfaces.size() && id >= 0); int x; Port *port = interfaces[id]; @@ -149,8 +157,8 @@ Bus::recvStatusChange(Port::Status status, int id) dm.portId = id; dm.range = *iter; - DPRINTF(MMU, "Adding range %llx - %llx for id %d\n", dm.range.start, - dm.range.end, id); + DPRINTF(Bus, "Adding range %llx - %llx for id %d\n", + dm.range.start, dm.range.end, id); portList.push_back(dm); } DPRINTF(MMU, "port list has %d entries\n", portList.size()); @@ -170,13 +178,12 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) resp.clear(); snoop.clear(); - DPRINTF(Bus, "Bus id %d recieved address range request returning\n", - busId); + DPRINTF(Bus, "received address range request, returning:\n"); for (portIter = portList.begin(); portIter != portList.end(); portIter++) { if (portIter->portId != id) { resp.push_back(portIter->range); - DPRINTF(Bus, "-- %#llX : %#llX\n", portIter->range.start, - portIter->range.end); + DPRINTF(Bus, " -- %#llX : %#llX\n", + portIter->range.start, portIter->range.end); } } } diff --git a/src/mem/bus.hh b/src/mem/bus.hh index 1d3a7e528..5eeb07904 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -109,17 +109,17 @@ class Bus : public MemObject /** When reciving a timing request from the peer port (at id), pass it to the bus. */ virtual bool recvTiming(Packet *pkt) - { pkt->src = id; return bus->recvTiming(pkt); } + { pkt->setSrc(id); return bus->recvTiming(pkt); } /** When reciving a Atomic requestfrom the peer port (at id), pass it to the bus. */ virtual Tick recvAtomic(Packet *pkt) - { pkt->src = id; return bus->recvAtomic(pkt); } + { pkt->setSrc(id); return bus->recvAtomic(pkt); } /** When reciving a Functional requestfrom the peer port (at id), pass it to the bus. */ virtual void recvFunctional(Packet *pkt) - { pkt->src = id; bus->recvFunctional(pkt); } + { pkt->setSrc(id); bus->recvFunctional(pkt); } /** When reciving a status changefrom the peer port (at id), pass it to the bus. */ diff --git a/src/mem/packet.cc b/src/mem/packet.cc index a9be7ac51..3b415d77f 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -34,11 +34,31 @@ #include "base/misc.hh" #include "mem/packet.hh" +static const std::string ReadReqString("ReadReq"); +static const std::string WriteReqString("WriteReq"); +static const std::string WriteReqNoAckString("WriteReqNoAck"); +static const std::string ReadRespString("ReadResp"); +static const std::string WriteRespString("WriteResp"); +static const std::string OtherCmdString(""); + +const std::string & +Packet::cmdString() const +{ + switch (cmd) { + case ReadReq: return ReadReqString; + case WriteReq: return WriteReqString; + case WriteReqNoAck: return WriteReqNoAckString; + case ReadResp: return ReadRespString; + case WriteResp: return WriteRespString; + default: return OtherCmdString; + } +} /** delete the data pointed to in the data pointer. Ok to call to matter how * data was allocted. */ void -Packet::deleteData() { +Packet::deleteData() +{ assert(staticData || dynamicData); if (staticData) return; @@ -51,22 +71,24 @@ Packet::deleteData() { /** If there isn't data in the packet, allocate some. */ void -Packet::allocate() { +Packet::allocate() +{ if (data) return; assert(!staticData); dynamicData = true; arrayData = true; - data = new uint8_t[size]; + data = new uint8_t[getSize()]; } /** Do the packet modify the same addresses. */ bool -Packet::intersect(Packet *p) { - Addr s1 = addr; - Addr e1 = addr + size; - Addr s2 = p->addr; - Addr e2 = p->addr + p->size; +Packet::intersect(Packet *p) +{ + Addr s1 = getAddr(); + Addr e1 = getAddr() + getSize(); + Addr s2 = p->getAddr(); + Addr e2 = p->getAddr() + p->getSize(); if (s1 >= s2 && s1 < e2) return true; @@ -77,7 +99,8 @@ Packet::intersect(Packet *p) { /** Minimally reset a packet so something like simple cpu can reuse it. */ void -Packet::reset() { +Packet::reset() +{ result = Unknown; if (dynamicData) { deleteData(); @@ -88,7 +111,8 @@ Packet::reset() { } - - -bool fixPacket(Packet *func, Packet *timing) -{ panic("Need to implement!"); } +bool +fixPacket(Packet *func, Packet *timing) +{ + panic("Need to implement!"); +} diff --git a/src/mem/packet.hh b/src/mem/packet.hh index e8a7b0c73..83f52ede5 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -43,24 +43,6 @@ struct Packet; typedef Packet* PacketPtr; typedef uint8_t* PacketDataPtr; -/** List of all commands associated with a packet. */ -enum Command -{ - Read, - Write -}; - -/** The result of a particular pakets request. */ -enum PacketResult -{ - Success, - BadAddress, - Unknown -}; - -class SenderState{}; -class Coherence{}; - /** * A Packet is the structure to handle requests between two levels * of the memory system. The Request is a global object that trancends @@ -74,7 +56,7 @@ class Coherence{}; * Packets are assumed to be returned in the case of a single response. If * the transaction has no response, then the consumer will delete the packet. */ -struct Packet +class Packet { private: /** A pointer to the data being transfered. It can be differnt sizes @@ -95,57 +77,132 @@ struct Packet bool arrayData; - public: /** The address of the request, could be virtual or physical (depending on cache configurations). */ Addr addr; - /** Flag structure to hold flags for this particular packet */ - uint64_t flags; + /** Indicates the size of the request. */ + int size; + + /** A index of the source of the transaction. */ + short src; + + /** A index to the destination of the transaction. */ + short dest; + + bool addrValid; + bool sizeValid; + bool srcValid; + + public: + + static const short Broadcast = -1; /** A pointer to the overall request. */ RequestPtr req; + class CoherenceState { + public: + virtual ~CoherenceState() {} + }; + /** A virtual base opaque structure used to hold coherence status messages. */ - Coherence *coherence; // virtual base opaque, + CoherenceState *coherence; // virtual base opaque, // assert(dynamic_cast) etc. - /** A virtual base opaque structure used to hold the senders state. */ - void *senderState; // virtual base opaque, - // assert(dynamic_cast) etc. - - /** Indicates the size of the request. */ - int size; + class SenderState { + public: + virtual ~SenderState() {} + }; - /** A index of the source of the transaction. */ - short src; + /** A virtual base opaque structure used to hold the senders state. */ + SenderState *senderState; // virtual base opaque, + // assert(dynamic_cast) etc. - static const short Broadcast = -1; + private: + /** List of command attributes. */ + enum CommandAttribute + { + IsRead = 1 << 0, + IsWrite = 1 << 1, + IsPrefetch = 1 << 2, + IsInvalidate = 1 << 3, + IsRequest = 1 << 4, + IsResponse = 1 << 5, + NeedsResponse = 1 << 6, + }; - /** A index to the destination of the transaction. */ - short dest; + public: + /** List of all commands associated with a packet. */ + enum Command + { + ReadReq = IsRead | IsRequest | NeedsResponse, + WriteReq = IsWrite | IsRequest | NeedsResponse, + WriteReqNoAck = IsWrite | IsRequest, + ReadResp = IsRead | IsResponse, + WriteResp = IsWrite | IsResponse + }; + + const std::string &cmdString() const; /** The command of the transaction. */ Command cmd; + bool isRead() { return (cmd & IsRead) != 0; } + bool isRequest() { return (cmd & IsRequest) != 0; } + bool isResponse() { return (cmd & IsResponse) != 0; } + bool needsResponse() { return (cmd & NeedsResponse) != 0; } + + void makeTimingResponse() { + assert(needsResponse()); + int icmd = (int)cmd; + icmd &= ~(IsRequest | NeedsResponse); + icmd |= IsResponse; + cmd = (Command)icmd; + dest = src; + srcValid = false; + } + /** The time this request was responded to. Used to calculate latencies. */ Tick time; + /** The result of a particular packets request. */ + enum Result + { + Success, + BadAddress, + Unknown + }; + /** The result of the packet transaction. */ - PacketResult result; + Result result; /** Accessor function that returns the source index of the packet. */ - short getSrc() const { return src; } + short getSrc() const { assert(srcValid); return src; } + void setSrc(short _src) { src = _src; srcValid = true; } /** Accessor function that returns the destination index of the packet. */ short getDest() const { return dest; } + void setDest(short _dest) { dest = _dest; } + + Addr getAddr() const { assert(addrValid); return addr; } + void setAddr(Addr _addr) { addr = _addr; addrValid = true; } + + int getSize() const { assert(sizeValid); return size; } + void setSize(int _size) { size = _size; sizeValid = true; } - Packet() + + Packet(Request *_req, Command _cmd, short _dest) : data(NULL), staticData(false), dynamicData(false), arrayData(false), + addr(_req->paddr), size(_req->size), dest(_dest), + addrValid(_req->validPaddr), sizeValid(_req->validSize), + srcValid(false), + req(_req), coherence(NULL), senderState(NULL), cmd(_cmd), time(curTick), result(Unknown) - {} + { + } ~Packet() { deleteData(); } @@ -154,6 +211,11 @@ struct Packet /** Minimally reset a packet so something like simple cpu can reuse it. */ void reset(); + void reinitFromRequest() { + if (req->validPaddr) setAddr(req->paddr); + if (req->validSize) setSize(req->size); + } + /** Set the data pointer to the following value that should not be freed. */ template void dataStatic(T *p); diff --git a/src/mem/physical.cc b/src/mem/physical.cc index ae27d762f..26dbef0cd 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -128,7 +128,7 @@ PhysicalMemory::doTimingAccess (Packet *pkt, MemoryPort* memoryPort) doFunctionalAccess(pkt); // turn packet around to go back to requester - pkt->dest = pkt->src; + pkt->makeTimingResponse(); MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort); response->schedule(curTick + lat); @@ -146,16 +146,18 @@ PhysicalMemory::doAtomicAccess(Packet *pkt) void PhysicalMemory::doFunctionalAccess(Packet *pkt) { - assert(pkt->addr + pkt->size < pmem_size); + assert(pkt->getAddr() + pkt->getSize() < pmem_size); switch (pkt->cmd) { - case Read: - memcpy(pkt->getPtr(), pmem_addr + pkt->addr - base_addr, - pkt->size); + case Packet::ReadReq: + memcpy(pkt->getPtr(), + pmem_addr + pkt->getAddr() - base_addr, + pkt->getSize()); break; - case Write: - memcpy(pmem_addr + pkt->addr - base_addr, pkt->getPtr(), - pkt->size); + case Packet::WriteReq: + memcpy(pmem_addr + pkt->getAddr() - base_addr, + pkt->getPtr(), + pkt->getSize()); // temporary hack: will need to add real LL/SC implementation // for cacheless systems later. if (pkt->req->getFlags() & LOCKED) { @@ -166,7 +168,7 @@ PhysicalMemory::doFunctionalAccess(Packet *pkt) panic("unimplemented"); } - pkt->result = Success; + pkt->result = Packet::Success; } Port * diff --git a/src/mem/port.cc b/src/mem/port.cc index fb3103ed1..ee224d92b 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -35,18 +35,16 @@ #include "mem/port.hh" void -Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd) +Port::blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd) { Request req(false); - Packet pkt; - pkt.req = &req; - pkt.cmd = cmd; - pkt.dest = Packet::Broadcast; + Packet pkt(&req, cmd, Packet::Broadcast); for (ChunkGenerator gen(addr, size, peerBlockSize()); !gen.done(); gen.next()) { - req.setPaddr(pkt.addr = gen.addr()); - req.setSize(pkt.size = gen.size()); + req.setPaddr(gen.addr()); + req.setSize(gen.size()); + pkt.reinitFromRequest(); pkt.dataStatic(p); sendFunctional(&pkt); p += gen.size(); @@ -56,13 +54,13 @@ Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd) void Port::writeBlob(Addr addr, uint8_t *p, int size) { - blobHelper(addr, p, size, Write); + blobHelper(addr, p, size, Packet::WriteReq); } void Port::readBlob(Addr addr, uint8_t *p, int size) { - blobHelper(addr, p, size, Read); + blobHelper(addr, p, size, Packet::ReadReq); } void @@ -72,7 +70,7 @@ Port::memsetBlob(Addr addr, uint8_t val, int size) uint8_t *buf = new uint8_t[size]; memset(buf, val, size); - blobHelper(addr, buf, size, Write); + blobHelper(addr, buf, size, Packet::WriteReq); delete [] buf; } diff --git a/src/mem/port.hh b/src/mem/port.hh index e8a20235a..85209964e 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -232,7 +232,7 @@ class Port /** Internal helper function for read/writeBlob(). */ - void blobHelper(Addr addr, uint8_t *p, int size, Command cmd); + void blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd); }; /** A simple functional port that is only meant for one way communication to diff --git a/src/mem/request.hh b/src/mem/request.hh index 2db7b7779..10550e859 100644 --- a/src/mem/request.hh +++ b/src/mem/request.hh @@ -195,6 +195,7 @@ class Request /** Accesor function for pc.*/ void setPC(Addr _pc); + friend class Packet; }; #endif // __MEM_REQUEST_HH__ -- cgit v1.2.3 From cdad113afb45a4f3b6d8f7bb3a8f510d42247d6b Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 26 May 2006 14:24:46 -0400 Subject: Add a little more tracing support for Bus/Port stuff. src/base/traceflags.py: Sort flags so you can find things. Add BusAddrRanges flag for tracking RangeChange events separately from general bus activity. src/mem/bus.cc: Add BusAddrRanges flag for tracking RangeChange events separately from general bus activity. src/mem/port.cc: src/mem/port.hh: Print Config trace message when peers are set up. --HG-- extra : convert_revision : d7c11d5f90c8de5c8d97e473501a268a567e9e44 --- src/base/traceflags.py | 152 +++++++++++++++++++++++++------------------------ src/mem/bus.cc | 8 +-- src/mem/port.cc | 8 +++ src/mem/port.hh | 4 +- 4 files changed, 91 insertions(+), 81 deletions(-) (limited to 'src') diff --git a/src/base/traceflags.py b/src/base/traceflags.py index 7dbaac60e..3b7dd0f81 100644 --- a/src/base/traceflags.py +++ b/src/base/traceflags.py @@ -45,105 +45,107 @@ ccfilename = sys.argv[1] + '.cc' # To define a new flag, simply add it to this list. # baseFlags = [ - 'TCPIP', + 'AlphaConsole', + 'BADADDR', + 'BPredRAS', 'Bus', - 'ScsiDisk', - 'ScsiCtrl', - 'ScsiNone', - 'DMA', - 'DMAReadVerbose', - 'DMAWriteVerbose', - 'TLB', - 'SimpleDisk', - 'SimpleDiskData', + 'BusAddrRanges', + 'BusBridge', + 'Cache', + 'Chains', 'Clock', - 'Regs', - 'MC146818', - 'IPI', - 'Timer', - 'Mbox', - 'PCIA', - 'PCIDEV', - 'PciConfigAll', - 'ISP', - 'BADADDR', + 'Commit', + 'CommitRate', + 'Config', 'Console', 'ConsolePoll', 'ConsoleVerbose', - 'AlphaConsole', - 'Flow', - 'Interrupt', - 'Fault', + 'Context', 'Cycle', - 'Loader', - 'MMU', + 'DMA', + 'DMAReadVerbose', + 'DMAWriteVerbose', + 'DebugPrintf', + 'Decode', + 'DiskImage', + 'DiskImageRead', + 'DiskImageWrite', + 'DynInst', 'Ethernet', - 'EthernetPIO', + 'EthernetCksum', 'EthernetDMA', 'EthernetData', 'EthernetDesc', 'EthernetIntr', + 'EthernetPIO', 'EthernetSM', - 'EthernetCksum', - 'GDBMisc', + 'Event', + 'Fault', + 'Fetch', + 'Flow', + 'FreeList', + 'FullCPU', 'GDBAcc', + 'GDBExtra', + 'GDBMisc', 'GDBRead', - 'GDBWrite', - 'GDBSend', 'GDBRecv', - 'GDBExtra', - 'VtoPhys', - 'Printf', - 'DebugPrintf', - 'Serialize', - 'Event', - 'PCEvent', - 'Syscall', - 'SyscallVerbose', - 'DiskImage', - 'DiskImageRead', - 'DiskImageWrite', - 'InstExec', - 'BPredRAS', - 'Cache', + 'GDBSend', + 'GDBWrite', + 'HWPrefetch', + 'IEW', 'IIC', 'IICMore', - 'MSHR', - 'Chains', - 'Pipeline', - 'Stats', - 'StatEvents', - 'Context', - 'Config', - 'Sampler', - 'WriteBarrier', + 'IPI', + 'IQ', + 'ISP', 'IdeCtrl', 'IdeDisk', - 'Tsunami', - 'Uart', - 'Split', - 'SQL', - 'Thread', - 'Fetch', - 'Decode', - 'Rename', - 'IEW', - 'Commit', - 'IQ', - 'ROB', - 'FreeList', - 'RenameMap', + 'InstExec', + 'Interrupt', 'LDSTQ', - 'StoreSet', + 'Loader', + 'MC146818', + 'MMU', + 'MSHR', + 'Mbox', 'MemDepUnit', - 'DynInst', - 'FullCPU', - 'CommitRate', 'OoOCPU', - 'HWPrefetch', - 'Stack', + 'PCEvent', + 'PCIA', + 'PCIDEV', + 'PciConfigAll', + 'Pipeline', + 'Printf', + 'ROB', + 'Regs', + 'Rename', + 'RenameMap', + 'SQL', + 'Sampler', + 'ScsiCtrl', + 'ScsiDisk', + 'ScsiNone', + 'Serialize', 'SimpleCPU', + 'SimpleDisk', + 'SimpleDiskData', 'Sparc', + 'Split', + 'Stack', + 'StatEvents', + 'Stats', + 'StoreSet', + 'Syscall', + 'SyscallVerbose', + 'TCPIP', + 'TLB', + 'Thread', + 'Timer', + 'Tsunami', + 'Uart', + 'VtoPhys', + 'WriteBarrier', ] # diff --git a/src/mem/bus.cc b/src/mem/bus.cc index a2ce00139..cfc99a64f 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -130,7 +130,7 @@ Bus::recvStatusChange(Port::Status status, int id) assert(status == Port::RangeChange && "The other statuses need to be implemented."); - DPRINTF(Bus, "received RangeChange from device id %d\n", id); + DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id); assert(id < interfaces.size() && id >= 0); int x; @@ -157,7 +157,7 @@ Bus::recvStatusChange(Port::Status status, int id) dm.portId = id; dm.range = *iter; - DPRINTF(Bus, "Adding range %llx - %llx for id %d\n", + DPRINTF(BusAddrRanges, "Adding range %llx - %llx for id %d\n", dm.range.start, dm.range.end, id); portList.push_back(dm); } @@ -178,11 +178,11 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id) resp.clear(); snoop.clear(); - DPRINTF(Bus, "received address range request, returning:\n"); + DPRINTF(BusAddrRanges, "received address range request, returning:\n"); for (portIter = portList.begin(); portIter != portList.end(); portIter++) { if (portIter->portId != id) { resp.push_back(portIter->range); - DPRINTF(Bus, " -- %#llX : %#llX\n", + DPRINTF(BusAddrRanges, " -- %#llX : %#llX\n", portIter->range.start, portIter->range.end); } } diff --git a/src/mem/port.cc b/src/mem/port.cc index ee224d92b..651cb739a 100644 --- a/src/mem/port.cc +++ b/src/mem/port.cc @@ -31,9 +31,17 @@ */ #include "base/chunk_generator.hh" +#include "base/trace.hh" #include "mem/packet_impl.hh" #include "mem/port.hh" +void +Port::setPeer(Port *port) +{ + DPRINTF(Config, "setting peer to %s\n", port->name()); + peer = port; +} + void Port::blobHelper(Addr addr, uint8_t *p, int size, Packet::Command cmd) { diff --git a/src/mem/port.hh b/src/mem/port.hh index 85209964e..f9103865e 100644 --- a/src/mem/port.hh +++ b/src/mem/port.hh @@ -112,9 +112,9 @@ class Port /** Function to set the pointer for the peer port. @todo should be called by the configuration stuff (python). */ - void setPeer(Port *port) { peer = port; } + void setPeer(Port *port); - /** Function to set the pointer for the peer port. + /** Function to set the pointer for the peer port. @todo should be called by the configuration stuff (python). */ Port *getPeer() { return peer; } -- cgit v1.2.3 From acb05ebcf6b6a9891ab856c466bd128f1ea62128 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 26 May 2006 14:29:29 -0400 Subject: Reorganize bridge as pair of cooperating ports. Store original source & senderState for timing packets that get a response, so we can properly route the response packet back to the original sender. --HG-- extra : convert_revision : 03dbcc8dc06d93de243bfcdc3cbaa012773c6782 --- src/mem/bridge.cc | 270 +++++++++++++++++++++++++++--------------------------- src/mem/bridge.hh | 214 +++++++++++++++++++------------------------ 2 files changed, 227 insertions(+), 257 deletions(-) (limited to 'src') diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc index c4b137869..736e8dc81 100644 --- a/src/mem/bridge.cc +++ b/src/mem/bridge.cc @@ -31,209 +31,209 @@ * @file Definition of a simple bus bridge without buffering. */ +#include #include "base/trace.hh" #include "mem/bridge.hh" #include "sim/builder.hh" +Bridge::BridgePort::BridgePort(const std::string &_name, + Bridge *_bridge, BridgePort *_otherPort, + int _delay, int _queueLimit) + : Port(_name), bridge(_bridge), otherPort(_otherPort), + delay(_delay), outstandingResponses(0), + queueLimit(_queueLimit), sendEvent(this) +{ +} + +Bridge::Bridge(const std::string &n, int qsa, int qsb, + Tick _delay, int write_ack) + : MemObject(n), + portA(n + "-portA", this, &portB, _delay, qsa), + portB(n + "-portB", this, &portA, _delay, qsa), + ackWrites(write_ack) +{ +} + +Port * +Bridge::getPort(const std::string &if_name) +{ + BridgePort *port; + + if (if_name == "side_a") + port = &portA; + else if (if_name == "side_b") + port = &portB; + else + return NULL; + + if (port->getPeer() != NULL) + panic("bridge side %s already connected to.", if_name); + return port; +} + + void Bridge::init() { // Make sure that both sides are connected to. - if (sideA == NULL || sideB == NULL) + if (portA.getPeer() == NULL || portB.getPeer() == NULL) panic("Both ports of bus bridge are not connected to a bus.\n"); } -/** Function called by the port when the bus is recieving a Timing +/** Function called by the port when the bus is receiving a Timing * transaction.*/ bool -Bridge::recvTiming(Packet *pkt, Side id) +Bridge::BridgePort::recvTiming(Packet *pkt) { - if (blockedA && id == SideA) - return false; - if (blockedB && id == SideB) - return false; - - if (delay) { - if (!sendEvent.scheduled()) - sendEvent.schedule(curTick + delay); - if (id == SideA) { - inboundA.push_back(std::make_pair(pkt, curTick)); - blockCheck(SideA); - } else { - inboundB.push_back(std::make_pair(pkt, curTick)); - blockCheck(SideB); - } - } else { - if (id == SideB) { - sideA->sendPkt(pkt); - blockCheck(SideB); - } else { - sideB->sendPkt(pkt); - blockCheck(SideA); - } + DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n", + pkt->getSrc(), pkt->getDest(), pkt->getAddr()); + + if (pkt->isResponse()) { + // This is a response for a request we forwarded earlier. The + // corresponding PacketBuffer should be stored in the packet's + // senderState field. + PacketBuffer *buf = dynamic_cast(pkt->senderState); + assert(buf != NULL); + // set up new packet dest & senderState based on values saved + // from original request + buf->fixResponse(pkt); + DPRINTF(BusBridge, " is response, new dest %d\n", pkt->getDest()); + delete buf; } - return true; + return otherPort->queueForSendTiming(pkt); } -void -Bridge::blockCheck(Side id) -{ - /* Check that we still have buffer space available. */ - if (id == SideB) { - if (sideA->numQueued() + inboundB.size() >= queueSizeA && !blockedB) { - sideB->sendStatusChange(Port::Blocked); - blockedB = true; - } else if (sideA->numQueued() + inboundB.size() < queueSizeA && blockedB) { - sideB->sendStatusChange(Port::Unblocked); - blockedB = false; - } - } else { - if (sideB->numQueued() + inboundA.size() >= queueSizeB && !blockedA) { - sideA->sendStatusChange(Port::Blocked); - blockedA = true; - } else if (sideB->numQueued() + inboundA.size() < queueSizeB && blockedA) { - sideA->sendStatusChange(Port::Unblocked); - blockedA = false; - } - } -} -void Bridge::timerEvent() +bool +Bridge::BridgePort::queueForSendTiming(Packet *pkt) { - Tick t = 0; + if (queueFull()) + return false; - assert(inboundA.size() || inboundB.size()); - if (inboundA.size()) { - while (inboundA.front().second <= curTick + delay){ - sideB->sendPkt(inboundA.front()); - inboundA.pop_front(); - } - if (inboundA.size()) - t = inboundA.front().second + delay; - } - if (inboundB.size()) { - while (inboundB.front().second <= curTick + delay){ - sideB->sendPkt(inboundA.front()); - inboundB.pop_front(); - } - if (inboundB.size()) - if (t == 0) - t = inboundB.front().second + delay; - else - t = std::min(t,inboundB.front().second + delay); - } else { - panic("timerEvent() called but nothing to do?"); + Tick readyTime = curTick + delay; + PacketBuffer *buf = new PacketBuffer(pkt, readyTime); + + // If we're about to put this packet at the head of the queue, we + // need to schedule an event to do the transmit. Otherwise there + // should already be an event scheduled for sending the head + // packet. + if (sendQueue.empty()) { + sendEvent.schedule(readyTime); } - if (t != 0) - sendEvent.schedule(t); + sendQueue.push_back(buf); + + // Did we just become blocked? If yes, let other side know. + if (queueFull()) + otherPort->sendStatusChange(Port::Blocked); + + return true; } void -Bridge::BridgePort::sendPkt(Packet *pkt) +Bridge::BridgePort::finishSend(PacketBuffer *buf) { - if (!sendTiming(pkt)) - outbound.push_back(std::make_pair(pkt, curTick)); + if (buf->expectResponse) { + // Must wait for response. We just need to count outstanding + // responses (in case we want to cap them); PacketBuffer + // pointer will be recovered on response. + ++outstandingResponses; + DPRINTF(BusBridge, " successful: awaiting response (%d)\n", + outstandingResponses); + } else { + // no response expected... deallocate packet buffer now. + DPRINTF(BusBridge, " successful: no response expected\n"); + delete buf; + } + + // If there are more packets to send, schedule event to try again. + if (!sendQueue.empty()) { + buf = sendQueue.front(); + sendEvent.schedule(std::max(buf->ready, curTick + 1)); + } } + void -Bridge::BridgePort::sendPkt(std::pair p) +Bridge::BridgePort::trySend() { - if (!sendTiming(p.first)) - outbound.push_back(p); + assert(!sendQueue.empty()); + + PacketBuffer *buf = sendQueue.front(); + + assert(buf->ready <= curTick); + + Packet *pkt = buf->pkt; + + DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n", + buf->origSrc, pkt->getDest(), pkt->getAddr()); + + if (sendTiming(pkt)) { + // send successful + sendQueue.pop_front(); + buf->pkt = NULL; // we no longer own packet, so it's not safe to look at it + finishSend(buf); + } else { + DPRINTF(BusBridge, " unsuccessful\n"); + } } Packet * Bridge::BridgePort::recvRetry() { - Packet *pkt; - assert(outbound.size() > 0); - assert(outbound.front().second >= curTick + bridge->delay); - pkt = outbound.front().first; - outbound.pop_front(); - bridge->blockCheck(side); + PacketBuffer *buf = sendQueue.front(); + Packet *pkt = buf->pkt; + finishSend(buf); return pkt; } -/** Function called by the port when the bus is recieving a Atomic +/** Function called by the port when the bus is receiving a Atomic * transaction.*/ Tick -Bridge::recvAtomic(Packet *pkt, Side id) +Bridge::BridgePort::recvAtomic(Packet *pkt) { - pkt->time += delay; - - if (id == SideA) - return sideB->sendAtomic(pkt); - else - return sideA->sendAtomic(pkt); + return otherPort->sendAtomic(pkt) + delay; } -/** Function called by the port when the bus is recieving a Functional +/** Function called by the port when the bus is receiving a Functional * transaction.*/ void -Bridge::recvFunctional(Packet *pkt, Side id) +Bridge::BridgePort::recvFunctional(Packet *pkt) { - pkt->time += delay; - std::list >::iterator i; + std::list::iterator i; bool pktContinue = true; - for(i = inboundA.begin(); i != inboundA.end(); ++i) { - if (pkt->intersect(i->first)) { - pktContinue &= fixPacket(pkt, i->first); - } - } - - for(i = inboundB.begin(); i != inboundB.end(); ++i) { - if (pkt->intersect(i->first)) { - pktContinue &= fixPacket(pkt, i->first); - } - } - - for(i = sideA->outbound.begin(); i != sideA->outbound.end(); ++i) { - if (pkt->intersect(i->first)) { - pktContinue &= fixPacket(pkt, i->first); - } - } - - for(i = sideB->outbound.begin(); i != sideB->outbound.end(); ++i) { - if (pkt->intersect(i->first)) { - pktContinue &= fixPacket(pkt, i->first); + for (i = sendQueue.begin(); i != sendQueue.end(); ++i) { + if (pkt->intersect((*i)->pkt)) { + pktContinue &= fixPacket(pkt, (*i)->pkt); } } if (pktContinue) { - if (id == SideA) - sideB->sendFunctional(pkt); - else - sideA->sendFunctional(pkt); + otherPort->sendFunctional(pkt); } } -/** Function called by the port when the bus is recieving a status change.*/ +/** Function called by the port when the bus is receiving a status change.*/ void -Bridge::recvStatusChange(Port::Status status, Side id) +Bridge::BridgePort::recvStatusChange(Port::Status status) { if (status == Port::Blocked || status == Port::Unblocked) - return ; + return; - if (id == SideA) - sideB->sendStatusChange(status); - else - sideA->sendStatusChange(status); + otherPort->sendStatusChange(status); } void -Bridge::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id) +Bridge::BridgePort::getDeviceAddressRanges(AddrRangeList &resp, + AddrRangeList &snoop) { - if (id == SideA) - sideB->getPeerAddressRanges(resp, snoop); - else - sideA->getPeerAddressRanges(resp, snoop); + otherPort->getPeerAddressRanges(resp, snoop); } BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bridge) diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh index 2672a6e8c..8a5cbf92a 100644 --- a/src/mem/bridge.hh +++ b/src/mem/bridge.hh @@ -46,132 +46,127 @@ class Bridge : public MemObject { - public: - enum Side + protected: + /** Decleration of the buses port type, one will be instantiated for each + of the interfaces connecting to the bus. */ + class BridgePort : public Port { - SideA, - SideB - }; + /** A pointer to the bridge to which this port belongs. */ + Bridge *bridge; - protected: - /** Function called by the port when the bus is recieving a Timing - transaction.*/ - bool recvTiming(Packet *pkt, Side id); + /** + * Pointer to the port on the other side of the bridge + * (connected to the other bus). + */ + BridgePort *otherPort; - /** Function called by the port when the bus is recieving a Atomic - transaction.*/ - Tick recvAtomic(Packet *pkt, Side id); + /** Minimum delay though this bridge. */ + Tick delay; - /** Function called by the port when the bus is recieving a Functional - transaction.*/ - void recvFunctional(Packet *pkt, Side id); + class PacketBuffer : public Packet::SenderState { - /** Function called by the port when the bus is recieving a status change.*/ - void recvStatusChange(Port::Status status, Side id); + public: + Tick ready; + Packet *pkt; + Packet::SenderState *origSenderState; + short origSrc; + bool expectResponse; - /** Process address range request. - * @param resp addresses that we can respond to - * @param snoop addresses that we would like to snoop - * @param id ide of the busport that made the request. - */ - void addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id); + PacketBuffer(Packet *_pkt, Tick t) + : ready(t), pkt(_pkt), + origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()), + expectResponse(_pkt->needsResponse()) + { + pkt->senderState = this; + } + void fixResponse(Packet *pkt) + { + assert(pkt->senderState == this); + pkt->setDest(origSrc); + pkt->senderState = origSenderState; + } + }; - /** Event that the SendEvent calls when it fires. This code must reschedule - * the send event as required. */ - void timerEvent(); + /** + * Outbound packet queue. Packets are held in this queue for a + * specified delay to model the processing delay of the + * bridge. + */ + std::list sendQueue; - /** Decleration of the buses port type, one will be instantiated for each - of the interfaces connecting to the bus. */ - class BridgePort : public Port - { - /** A pointer to the bus to which this port belongs. */ - Bridge *bridge; + int outstandingResponses; + + /** Max queue size for outbound packets */ + int queueLimit; + + /** + * Is this side blocked from accepting outbound packets? + */ + bool queueFull() { return (sendQueue.size() == queueLimit); } + + bool queueForSendTiming(Packet *pkt); + + void finishSend(PacketBuffer *buf); + + /** + * Handle send event, scheduled when the packet at the head of + * the outbound queue is ready to transmit (for timing + * accesses only). + */ + void trySend(); + + class SendEvent : public Event + { + BridgePort *port; + + public: + SendEvent(BridgePort *p) + : Event(&mainEventQueue), port(p) {} + + virtual void process() { port->trySend(); } - /** A id to keep track of the intercafe ID this port is connected to. */ - Bridge::Side side; + virtual const char *description() { return "bridge send event"; } + }; + + SendEvent sendEvent; public: /** Constructor for the BusPort.*/ - BridgePort(Bridge *_bridge, Side _side) - : Port(""), bridge(_bridge), side(_side) - { } - - int numQueued() { return outbound.size(); } + BridgePort(const std::string &_name, + Bridge *_bridge, BridgePort *_otherPort, + int _delay, int _queueLimit); protected: - /** Data this is waiting to be transmitted. */ - std::list > outbound; - - void sendPkt(Packet *pkt); - void sendPkt(std::pair p); - /** When reciving a timing request from the peer port, + /** When receiving a timing request from the peer port, pass it to the bridge. */ - virtual bool recvTiming(Packet *pkt) - { return bridge->recvTiming(pkt, side); } + virtual bool recvTiming(Packet *pkt); - /** When reciving a retry request from the peer port, + /** When receiving a retry request from the peer port, pass it to the bridge. */ virtual Packet* recvRetry(); - /** When reciving a Atomic requestfrom the peer port, + /** When receiving a Atomic requestfrom the peer port, pass it to the bridge. */ - virtual Tick recvAtomic(Packet *pkt) - { return bridge->recvAtomic(pkt, side); } + virtual Tick recvAtomic(Packet *pkt); - /** When reciving a Functional request from the peer port, + /** When receiving a Functional request from the peer port, pass it to the bridge. */ - virtual void recvFunctional(Packet *pkt) - { bridge->recvFunctional(pkt, side); } + virtual void recvFunctional(Packet *pkt); - /** When reciving a status changefrom the peer port, + /** When receiving a status changefrom the peer port, pass it to the bridge. */ - virtual void recvStatusChange(Status status) - { bridge->recvStatusChange(status, side); } + virtual void recvStatusChange(Status status); - /** When reciving a address range request the peer port, + /** When receiving a address range request the peer port, pass it to the bridge. */ - virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) - { bridge->addressRanges(resp, snoop, side); } - - friend class Bridge; - }; - - class SendEvent : public Event - { - Bridge *bridge; - - SendEvent(Bridge *b) - : Event(&mainEventQueue), bridge(b) {} - - virtual void process() { bridge->timerEvent(); } - - virtual const char *description() { return "bridge delay event"; } - friend class Bridge; + virtual void getDeviceAddressRanges(AddrRangeList &resp, + AddrRangeList &snoop); }; - SendEvent sendEvent; - - /** Sides of the bus bridges. */ - BridgePort* sideA; - BridgePort* sideB; - - /** inbound queues on both sides. */ - std::list > inboundA; - std::list > inboundB; - - /** The size of the queue for data coming into side a */ - int queueSizeA; - int queueSizeB; - - /* if the side is blocked or not. */ - bool blockedA; - bool blockedB; - - /** Miminum delay though this bridge. */ - Tick delay; + BridgePort portA, portB; /** If this bridge should acknowledge writes. */ bool ackWrites; @@ -179,36 +174,11 @@ class Bridge : public MemObject public: /** A function used to return the port associated with this bus object. */ - virtual Port *getPort(const std::string &if_name) - { - if (if_name == "side_a") { - if (sideA != NULL) - panic("bridge side a already connected to."); - sideA = new BridgePort(this, SideA); - return sideA; - } else if (if_name == "side_b") { - if (sideB != NULL) - panic("bridge side b already connected to."); - sideB = new BridgePort(this, SideB); - return sideB; - } else - return NULL; - } + virtual Port *getPort(const std::string &if_name); virtual void init(); - Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack) - : MemObject(n), sendEvent(this), sideA(NULL), sideB(NULL), - queueSizeA(qsa), queueSizeB(qsb), blockedA(false), blockedB(false), - delay(_delay), ackWrites(write_ack) - {} - - /** Check if the port should block/unblock after recieving/sending a packet. - * */ - void blockCheck(Side id); - - friend class Bridge::SendEvent; - + Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack); }; #endif //__MEM_BUS_HH__ -- cgit v1.2.3 From 53510f184452c46868a9e6ece9ccb7f30ab70843 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 26 May 2006 14:33:43 -0400 Subject: Fixes for TimingSimpleCPU under full system. Now boots Alpha Linux! src/cpu/simple/atomic.cc: src/cpu/simple/base.cc: Move traceData->finalize() into postExecute(). src/cpu/simple/timing.cc: Fixes for full system. Now boots Alpha Linux! - Handle ifetch faults, suspend/resume. - Delete memory request & packet objects on response. - Don't try to do split memory accesses on prefetch references (ISA description doesn't support this). src/cpu/simple/timing.hh: Minor reorganization of internal methods. --HG-- extra : convert_revision : 59e3ee5e4cb53c424ebdbe2e504d97e88c08a978 --- src/cpu/simple/atomic.cc | 4 ---- src/cpu/simple/base.cc | 4 ++++ src/cpu/simple/timing.cc | 48 ++++++++++++++++++++++++++++++------------------ src/cpu/simple/timing.hh | 4 ++-- 4 files changed, 36 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index ec629304b..3cad6e43f 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -425,10 +425,6 @@ AtomicSimpleCPU::tick() fault = curStaticInst->execute(this, traceData); postExecute(); - if (traceData) { - traceData->finalize(); - } - if (simulate_stalls) { // This calculation assumes that the icache and dcache // access latencies are always a multiple of the CPU's diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 077df8134..18f170449 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -442,6 +442,10 @@ BaseSimpleCPU::postExecute() } traceFunctions(cpuXC->readPC()); + + if (traceData) { + traceData->finalize(); + } } diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index d57935ed0..7cdcdafa1 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -158,10 +158,11 @@ TimingSimpleCPU::suspendContext(int thread_num) assert(thread_num == 0); assert(cpuXC); - panic("TimingSimpleCPU::suspendContext not implemented"); - assert(_status == Running); + // just change status to Idle... if status != Running, + // completeInst() will not initiate fetch of next instruction. + notIdleFraction--; _status = Idle; } @@ -357,20 +358,15 @@ TimingSimpleCPU::fetch() ifetch_pkt = NULL; } } else { - panic("TimingSimpleCPU fetch fault handling not implemented"); + // fetch fault: advance directly to next instruction (fault handler) + advanceInst(fault); } } void -TimingSimpleCPU::completeInst(Fault fault) +TimingSimpleCPU::advanceInst(Fault fault) { - postExecute(); - - if (traceData) { - traceData->finalize(); - } - advancePC(fault); if (_status == Running) { @@ -383,23 +379,35 @@ TimingSimpleCPU::completeInst(Fault fault) void -TimingSimpleCPU::completeIfetch() +TimingSimpleCPU::completeIfetch(Packet *pkt) { // received a response from the icache: execute the received // instruction + assert(pkt->result == Packet::Success); assert(_status == IcacheWaitResponse); _status = Running; + + delete pkt->req; + delete pkt; + preExecute(); - if (curStaticInst->isMemRef()) { + if (curStaticInst->isMemRef() && !curStaticInst->isDataPrefetch()) { // load or store: just send to dcache Fault fault = curStaticInst->initiateAcc(this, traceData); - assert(fault == NoFault); - assert(_status == DcacheWaitResponse); - // instruction will complete in dcache response callback + if (fault == NoFault) { + // successfully initiated access: instruction will + // complete in dcache response callback + assert(_status == DcacheWaitResponse); + } else { + // fault: complete now to invoke fault handler + postExecute(); + advanceInst(fault); + } } else { // non-memory instruction: execute completely now Fault fault = curStaticInst->execute(this, traceData); - completeInst(fault); + postExecute(); + advanceInst(fault); } } @@ -407,7 +415,7 @@ TimingSimpleCPU::completeIfetch() bool TimingSimpleCPU::IcachePort::recvTiming(Packet *pkt) { - cpu->completeIfetch(); + cpu->completeIfetch(pkt); return true; } @@ -435,7 +443,11 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt) Fault fault = curStaticInst->completeAcc(pkt, this, traceData); - completeInst(fault); + delete pkt->req; + delete pkt; + + postExecute(); + advanceInst(fault); } diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index 7f38e629a..b46631d5a 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -142,9 +142,9 @@ class TimingSimpleCPU : public BaseSimpleCPU Fault write(T data, Addr addr, unsigned flags, uint64_t *res); void fetch(); - void completeInst(Fault fault); - void completeIfetch(); + void completeIfetch(Packet *); void completeDataAccess(Packet *); + void advanceInst(Fault fault); }; #endif // __CPU_SIMPLE_TIMING_HH__ -- cgit v1.2.3