summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct54
-rw-r--r--src/SConscript5
-rw-r--r--src/arch/SConscript2
-rw-r--r--src/arch/sparc/isa/formats/nop.isa23
-rw-r--r--src/base/loader/elf_object.cc8
-rw-r--r--src/base/traceflags.py152
-rw-r--r--src/cpu/cpu_exec_context.cc12
-rw-r--r--src/cpu/cpu_models.py3
-rw-r--r--src/cpu/simple/atomic.cc34
-rw-r--r--src/cpu/simple/atomic.hh4
-rw-r--r--src/cpu/simple/base.cc6
-rw-r--r--src/cpu/simple/timing.cc72
-rw-r--r--src/cpu/simple/timing.hh12
-rw-r--r--src/dev/alpha_console.cc25
-rw-r--r--src/dev/ide_ctrl.cc80
-rw-r--r--src/dev/io_device.cc63
-rw-r--r--src/dev/io_device.hh12
-rw-r--r--src/dev/isa_fake.cc14
-rw-r--r--src/dev/ns_gige.cc34
-rw-r--r--src/dev/pciconfigall.cc30
-rw-r--r--src/dev/sinic.cc30
-rw-r--r--src/dev/tsunami_cchip.cc28
-rw-r--r--src/dev/tsunami_io.cc36
-rw-r--r--src/dev/tsunami_pchip.cc24
-rw-r--r--src/dev/uart8250.cc20
-rw-r--r--src/mem/bridge.cc270
-rw-r--r--src/mem/bridge.hh214
-rw-r--r--src/mem/bus.cc60
-rw-r--r--src/mem/bus.hh18
-rw-r--r--src/mem/packet.cc50
-rw-r--r--src/mem/packet.hh138
-rw-r--r--src/mem/physical.cc30
-rw-r--r--src/mem/physical.hh2
-rw-r--r--src/mem/port.cc26
-rw-r--r--src/mem/port.hh29
-rw-r--r--src/mem/request.hh1
-rw-r--r--src/mem/translating_port.cc5
-rw-r--r--src/mem/translating_port.hh9
-rw-r--r--src/mem/vport.hh4
-rw-r--r--src/sim/process.cc2
-rw-r--r--src/sim/system.cc2
41 files changed, 868 insertions, 775 deletions
diff --git a/SConstruct b/SConstruct
index f29d10cef..3fac9eb2e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -105,9 +105,10 @@ def rfind(l, elt, offs = -1):
# recognize that ALPHA_SE specifies the configuration because it
# follow 'build' in the bulid path.
-# Generate a list of the unique configs that the collected targets
-# reference.
+# Generate a list of the unique build roots and configs that the
+# collected targets reference.
build_paths = []
+build_root = None
for t in abs_targets:
path_dirs = t.split('/')
try:
@@ -115,9 +116,17 @@ for t in abs_targets:
except:
print "Error: no non-leaf 'build' dir found on target path", t
Exit(1)
- config_dir = os.path.join('/',*path_dirs[:build_top+2])
- if config_dir not in build_paths:
- build_paths.append(config_dir)
+ this_build_root = os.path.join('/',*path_dirs[:build_top+1])
+ if not build_root:
+ build_root = this_build_root
+ else:
+ if this_build_root != build_root:
+ print "Error: build targets not under same build root\n"\
+ " %s\n %s" % (build_root, this_build_root)
+ Exit(1)
+ build_path = os.path.join('/',*path_dirs[:build_top+2])
+ if build_path not in build_paths:
+ build_paths.append(build_path)
###################################################
#
@@ -153,8 +162,11 @@ env.Append(CPPPATH=[Dir('ext/dnet')])
# Default libraries
env.Append(LIBS=['z'])
-# Platform-specific configuration
-conf = Configure(env)
+# Platform-specific configuration. Note again that we assume that all
+# builds under a given build root run on the same host platform.
+conf = Configure(env,
+ conf_dir = os.path.join(build_root, '.scons_config'),
+ log_file = os.path.join(build_root, 'scons_config.log'))
# Check for <fenv.h> (C99 FP environment control)
have_fenv = conf.CheckHeader('fenv.h', '<>')
@@ -195,7 +207,7 @@ env['ALL_ISA_LIST'] = ['alpha', 'sparc', 'mips']
# Define the universe of supported CPU models
env['ALL_CPU_LIST'] = ['AtomicSimpleCPU', 'TimingSimpleCPU',
- 'FastCPU', 'FullCPU', 'AlphaFullCPU']
+ 'FullCPU', 'AlphaFullCPU']
# Sticky options get saved in the options file so they persist from
# one invocation to the next (unless overridden, in which case the new
@@ -208,7 +220,8 @@ sticky_opts.AddOptions(
# values (more than one value) not to be able to be restored from
# a saved option file. If this causes trouble then upgrade to
# scons 0.96.90 or later.
- ListOption('CPU_MODELS', 'CPU models', 'all', env['ALL_CPU_LIST']),
+ ListOption('CPU_MODELS', 'CPU models', 'AtomicSimpleCPU,TimingSimpleCPU',
+ env['ALL_CPU_LIST']),
BoolOption('ALPHA_TLASER',
'Model Alpha TurboLaser platform (vs. Tsunami)', False),
BoolOption('NO_FAST_ALLOC', 'Disable fast object allocator', False),
@@ -246,11 +259,6 @@ def no_action(target, source, env):
env.NoAction = Action(no_action, None)
-# libelf build is described in its own SConscript file.
-# SConscript-global is the build in build/libelf shared among all
-# configs.
-env.SConscript('src/libelf/SConscript-global', exports = 'env')
-
###################################################
#
# Define a SCons builder for configuration flag headers.
@@ -292,6 +300,17 @@ config_builder = Builder(emitter = config_emitter, action = config_action)
env.Append(BUILDERS = { 'ConfigFile' : config_builder })
+# base help text
+help_text = '''
+Usage: scons [scons options] [build options] [target(s)]
+
+'''
+
+# libelf build is shared across all configs in the build root.
+env.SConscript('ext/libelf/SConscript',
+ build_dir = os.path.join(build_root, 'libelf'),
+ exports = 'env')
+
###################################################
#
# Define build environments for selected configurations.
@@ -301,17 +320,12 @@ env.Append(BUILDERS = { 'ConfigFile' : config_builder })
# rename base env
base_env = env
-help_text = '''
-Usage: scons [scons options] [build options] [target(s)]
-
-'''
-
for build_path in build_paths:
print "Building in", build_path
# build_dir is the tail component of build path, and is used to
# determine the build parameters (e.g., 'ALPHA_SE')
(build_root, build_dir) = os.path.split(build_path)
- # Make a copy of the default environment to use for this config.
+ # Make a copy of the build-root environment to use for this config.
env = base_env.Copy()
# Set env options according to the build directory config.
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/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/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;
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"
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/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/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' })
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index e9422b9c0..3cad6e43f 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;
@@ -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<T>();
}
@@ -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();
@@ -435,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/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/base.cc b/src/cpu/simple/base.cc
index 30c002ed5..18f170449 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;
@@ -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 70b88c4b1..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;
}
@@ -187,13 +188,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<T>(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 +265,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 +343,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) {
@@ -369,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) {
@@ -395,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);
}
}
@@ -419,7 +415,7 @@ TimingSimpleCPU::completeIfetch()
bool
TimingSimpleCPU::IcachePort::recvTiming(Packet *pkt)
{
- cpu->completeIfetch();
+ cpu->completeIfetch(pkt);
return true;
}
@@ -441,13 +437,17 @@ 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;
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 83be025d9..b46631d5a 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:
@@ -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__
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<uint32_t>());
@@ -181,9 +181,10 @@ AlphaConsole::read(Packet *pkt)
pkt->get<uint64_t>());
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<uint64_t>();
- 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<uint8_t>());
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<uint8_t>());
} 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<uint8_t>());
- else if (pkt->size == 2)
+ offset, pkt->getSize(), (uint32_t)pkt->get<uint8_t>());
+ else if (pkt->getSize() == 2)
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
- offset, pkt->size, pkt->get<uint16_t>());
+ offset, pkt->getSize(), pkt->get<uint16_t>());
else
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
- offset, pkt->size, pkt->get<uint32_t>());
+ offset, pkt->getSize(), pkt->get<uint32_t>());
- 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<uint8_t>();
@@ -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<uint32_t>() & ~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<uint8_t>(), pkt->size);
+ memcpy(&bmi_regs.data[offset], pkt->getPtr<uint8_t>(), 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<uint8_t>());
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<uint8_t>());
} 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<uint8_t>());
- else if (pkt->size == 2)
+ offset, pkt->getSize(), (uint32_t)pkt->get<uint8_t>());
+ else if (pkt->getSize() == 2)
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
- offset, pkt->size, pkt->get<uint16_t>());
+ offset, pkt->getSize(), pkt->get<uint16_t>());
else
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
- offset, pkt->size, pkt->get<uint32_t>());
+ offset, pkt->getSize(), pkt->get<uint32_t>());
- pkt->result = Success;
+ pkt->result = Packet::Success;
return pioDelay;
}
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc
index 634b11b7e..87fdbb765 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)
{ }
@@ -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);
@@ -78,8 +78,10 @@ bool
PioPort::recvTiming(Packet *pkt)
{
device->recvAtomic(pkt);
+ // turn packet around to go back to requester
+ pkt->makeTimingResponse();
sendTiming(pkt, pkt->time - pkt->req->getTime());
- return Success;
+ return true;
}
PioDevice::~PioDevice()
@@ -106,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
@@ -114,7 +116,7 @@ DmaPort::recvTiming(Packet *pkt)
{
if (pkt->senderState) {
DmaReqState *state;
- state = (DmaReqState*)pkt->senderState;
+ state = dynamic_cast<DmaReqState*>(pkt->senderState);
state->completionEvent->schedule(pkt->time - pkt->req->getTime());
delete pkt->req;
delete pkt;
@@ -123,7 +125,7 @@ DmaPort::recvTiming(Packet *pkt)
delete pkt;
}
- return Success;
+ return Packet::Success;
}
DmaDevice::DmaDevice(Params *p)
@@ -133,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);
@@ -146,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);
}
@@ -206,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<DmaReqState*>(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<uint8_t>());
- if (pkt->size == sizeof(uint16_t))
+ if (pkt->getSize() == sizeof(uint16_t))
readConfig(daddr & 0xff, pkt->getPtr<uint16_t>());
- if (pkt->size == sizeof(uint32_t))
+ if (pkt->getSize() == sizeof(uint32_t))
readConfig(daddr & 0xff, pkt->getPtr<uint32_t>());
- 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<uint32_t>(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 &reg = *pkt->getPtr<uint32_t>();
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<uint8_t>());
- if (pkt->size == sizeof(uint16_t))
+ if (pkt->getSize() == sizeof(uint16_t))
writeConfig(daddr & 0xff, pkt->get<uint16_t>());
- if (pkt->size == sizeof(uint32_t))
+ if (pkt->getSize() == sizeof(uint32_t))
writeConfig(daddr & 0xff, pkt->get<uint32_t>());
- 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<uint32_t>();
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<uint32_t>(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<uint32_t>());
+ pkt->getAddr(), pkt->getSize(), pkt->get<uint32_t>());
- switch (pkt->size) {
+ switch (pkt->getSize()) {
case sizeof(uint8_t):
devices[device][func]->writeConfig(reg, pkt->get<uint8_t>());
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<uint32_t>() :
- pkt->get<uint64_t>(), daddr, pkt->addr, pkt->size);
+ pkt->get<uint64_t>(), 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<uint64_t>());
+ regnum, pkt->getSize(), pkt->get<uint64_t>());
- 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<uint64_t>());
+ DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt->getAddr(), pkt->get<uint64_t>());
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<uint64_t>(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<uint8_t>());
+ pkt->getAddr(), pkt->getSize(), pkt->getAddr() & 0xfff, (uint32_t)pkt->get<uint8_t>());
- 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<uint8_t>());
+ panic("I/O Write - va%#x size %d data %#x\n", pkt->getAddr(), pkt->getSize(), pkt->get<uint8_t>());
}
- 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<uint8_t>());
@@ -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/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 <algorithm>
#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<Packet*, Tick>(pkt, curTick));
- blockCheck(SideA);
- } else {
- inboundB.push_back(std::make_pair<Packet*, Tick>(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<PacketBuffer*>(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<Packet*,Tick>(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<Packet*, Tick> 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<std::pair<Packet*, Tick> >::iterator i;
+ std::list<PacketBuffer*>::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 5f19ded40..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<PacketBuffer*> 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)
- : 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<std::pair<Packet*, Tick> > outbound;
-
- void sendPkt(Packet *pkt);
- void sendPkt(std::pair<Packet*, Tick> 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<std::pair<Packet*, Tick> > inboundA;
- std::list<std::pair<Packet*, Tick> > 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__
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index f7c2b874a..cfc99a64f 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()
@@ -45,17 +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());
- port = interfaces[pkt->dest];
+ assert(dest >= 0 && dest < interfaces.size());
+ assert(dest != pkt->getSrc()); // catch infinite loops
+ port = interfaces[dest];
}
return port->sendTiming(pkt);
}
@@ -73,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++;
}
@@ -86,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(BusAddrRanges, "received RangeChange from device id %d\n", id);
+
assert(id < interfaces.size() && id >= 0);
int x;
Port *port = interfaces[id];
@@ -138,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(BusAddrRanges, "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());
@@ -159,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(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", portIter->range.start,
- portIter->range.end);
+ DPRINTF(BusAddrRanges, " -- %#llX : %#llX\n",
+ portIter->range.start, portIter->range.end);
}
}
}
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 38573e514..5eeb07904 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:
@@ -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. */
@@ -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/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("<other>");
+
+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<Foo>) etc.
- /** A virtual base opaque structure used to hold the senders state. */
- void *senderState; // virtual base opaque,
- // assert(dynamic_cast<Foo>) 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<Foo>) 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 <typename T>
void dataStatic(T *p);
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index bc2500678..26dbef0cd 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -127,7 +127,8 @@ PhysicalMemory::doTimingAccess (Packet *pkt, MemoryPort* memoryPort)
{
doFunctionalAccess(pkt);
- pkt->dest = pkt->src;
+ // turn packet around to go back to requester
+ pkt->makeTimingResponse();
MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort);
response->schedule(curTick + lat);
@@ -145,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<uint8_t>(), pmem_addr + pkt->addr - base_addr,
- pkt->size);
+ case Packet::ReadReq:
+ memcpy(pkt->getPtr<uint8_t>(),
+ pmem_addr + pkt->getAddr() - base_addr,
+ pkt->getSize());
break;
- case Write:
- memcpy(pmem_addr + pkt->addr - base_addr, pkt->getPtr<uint8_t>(),
- pkt->size);
+ case Packet::WriteReq:
+ memcpy(pmem_addr + pkt->getAddr() - base_addr,
+ pkt->getPtr<uint8_t>(),
+ pkt->getSize());
// temporary hack: will need to add real LL/SC implementation
// for cacheless systems later.
if (pkt->req->getFlags() & LOCKED) {
@@ -165,7 +168,7 @@ PhysicalMemory::doFunctionalAccess(Packet *pkt)
panic("unimplemented");
}
- pkt->result = Success;
+ pkt->result = Packet::Success;
}
Port *
@@ -174,11 +177,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);
}
@@ -189,8 +192,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.cc b/src/mem/port.cc
index fb3103ed1..651cb739a 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -31,22 +31,28 @@
*/
#include "base/chunk_generator.hh"
+#include "base/trace.hh"
#include "mem/packet_impl.hh"
#include "mem/port.hh"
void
-Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd)
+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)
{
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 +62,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 +78,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 1b1920c03..f9103865e 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -69,9 +69,28 @@ typedef std::list<Range<Addr> >::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. */
@@ -93,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; }
@@ -213,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
@@ -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/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__
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