Merge zeep.pool:/z/saidi/work/m5.newmem

into  zeep.pool:/z/saidi/work/m5.newmem.head

--HG--
extra : convert_revision : 1344e6a30073a1091a904593e6d4733baf19d7e2
This commit is contained in:
Ali Saidi 2006-05-26 17:03:47 -04:00
commit f456360bbc
41 changed files with 884 additions and 791 deletions

View file

@ -105,9 +105,10 @@ def rfind(l, elt, offs = -1):
# recognize that ALPHA_SE specifies the configuration because it # recognize that ALPHA_SE specifies the configuration because it
# follow 'build' in the bulid path. # follow 'build' in the bulid path.
# Generate a list of the unique configs that the collected targets # Generate a list of the unique build roots and configs that the
# reference. # collected targets reference.
build_paths = [] build_paths = []
build_root = None
for t in abs_targets: for t in abs_targets:
path_dirs = t.split('/') path_dirs = t.split('/')
try: try:
@ -115,9 +116,17 @@ for t in abs_targets:
except: except:
print "Error: no non-leaf 'build' dir found on target path", t print "Error: no non-leaf 'build' dir found on target path", t
Exit(1) Exit(1)
config_dir = os.path.join('/',*path_dirs[:build_top+2]) this_build_root = os.path.join('/',*path_dirs[:build_top+1])
if config_dir not in build_paths: if not build_root:
build_paths.append(config_dir) 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 # Default libraries
env.Append(LIBS=['z']) env.Append(LIBS=['z'])
# Platform-specific configuration # Platform-specific configuration. Note again that we assume that all
conf = Configure(env) # 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) # Check for <fenv.h> (C99 FP environment control)
have_fenv = conf.CheckHeader('fenv.h', '<>') have_fenv = conf.CheckHeader('fenv.h', '<>')
@ -195,7 +207,7 @@ env['ALL_ISA_LIST'] = ['alpha', 'sparc', 'mips']
# Define the universe of supported CPU models # Define the universe of supported CPU models
env['ALL_CPU_LIST'] = ['AtomicSimpleCPU', 'TimingSimpleCPU', env['ALL_CPU_LIST'] = ['AtomicSimpleCPU', 'TimingSimpleCPU',
'FastCPU', 'FullCPU', 'AlphaFullCPU'] 'FullCPU', 'AlphaFullCPU']
# Sticky options get saved in the options file so they persist from # Sticky options get saved in the options file so they persist from
# one invocation to the next (unless overridden, in which case the new # 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 # values (more than one value) not to be able to be restored from
# a saved option file. If this causes trouble then upgrade to # a saved option file. If this causes trouble then upgrade to
# scons 0.96.90 or later. # 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', BoolOption('ALPHA_TLASER',
'Model Alpha TurboLaser platform (vs. Tsunami)', False), 'Model Alpha TurboLaser platform (vs. Tsunami)', False),
BoolOption('NO_FAST_ALLOC', 'Disable fast object allocator', 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) 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. # 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 }) 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. # Define build environments for selected configurations.
@ -301,17 +320,12 @@ env.Append(BUILDERS = { 'ConfigFile' : config_builder })
# rename base env # rename base env
base_env = env base_env = env
help_text = '''
Usage: scons [scons options] [build options] [target(s)]
'''
for build_path in build_paths: for build_path in build_paths:
print "Building in", build_path print "Building in", build_path
# build_dir is the tail component of build path, and is used to # build_dir is the tail component of build path, and is used to
# determine the build parameters (e.g., 'ALPHA_SE') # determine the build parameters (e.g., 'ALPHA_SE')
(build_root, build_dir) = os.path.split(build_path) (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() env = base_env.Copy()
# Set env options according to the build directory config. # Set env options according to the build directory config.

View file

@ -326,10 +326,6 @@ env.Command(Split('base/traceflags.hh base/traceflags.cc'),
'base/traceflags.py', 'base/traceflags.py',
'python $SOURCE $TARGET.base') '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) SConscript('python/SConscript', exports = ['env'], duplicate=0)
# This function adds the specified sources to the given build # 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 # the corresponding build directory to pick up generated include
# files. # files.
env.Append(CPPPATH='.') env.Append(CPPPATH='.')
env.Append(CPPPATH='./libelf')
# Debug binary # Debug binary
debugEnv = env.Copy(OBJSUFFIX='.do') debugEnv = env.Copy(OBJSUFFIX='.do')

View file

@ -132,7 +132,7 @@ def isa_desc_emitter(target, source, env):
return (isa_desc_gen_files, [isa_parser, cpu_models_file] + source) return (isa_desc_gen_files, [isa_parser, cpu_models_file] + source)
# Pieces are in place, so create the builder. # 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) emitter = isa_desc_emitter)
env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder }) env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })

View file

@ -32,6 +32,16 @@
// Nop instruction // 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 {{ output header {{
/** /**
* Nop class. * Nop class.
@ -46,14 +56,11 @@ output header {{
} }
// All Nop instructions do the same thing, so this can be // All Nop instructions do the same thing, so this can be
// defined here. Nops can be defined directly, so there needs // defined here. Nops can be defined directly, so there
// to be a default implementation // needs to be a default implementation. Interpolate via
Fault execute(%(CPU_exec_context)s *xc, // template so i gets expanded to a set of
Trace::InstRecord *traceData) const // cpu-model-specific functions.
{ %(NopExec)s
//Nothing to see here, move along
return NoFault;
}
std::string generateDisassembly(Addr pc, std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const; const SymbolTable *symtab) const;

View file

@ -30,16 +30,10 @@
// Because of the -Wundef flag we have to do this // Because of the -Wundef flag we have to do this
#define __LIBELF_INTERNAL__ 0 #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_NEED_LINK_H 0
#define __LIBELF_SYMBOL_VERSIONS 0 #define __LIBELF_SYMBOL_VERSIONS 0
#include "libelf/libelf.h" #include "gelf.h"
#include "libelf/gelf.h"
#include "base/loader/elf_object.hh" #include "base/loader/elf_object.hh"
#include "base/misc.hh" #include "base/misc.hh"

View file

@ -45,105 +45,107 @@ ccfilename = sys.argv[1] + '.cc'
# To define a new flag, simply add it to this list. # To define a new flag, simply add it to this list.
# #
baseFlags = [ baseFlags = [
'TCPIP', 'AlphaConsole',
'Bus',
'ScsiDisk',
'ScsiCtrl',
'ScsiNone',
'DMA',
'DMAReadVerbose',
'DMAWriteVerbose',
'TLB',
'SimpleDisk',
'SimpleDiskData',
'Clock',
'Regs',
'MC146818',
'IPI',
'Timer',
'Mbox',
'PCIA',
'PCIDEV',
'PciConfigAll',
'ISP',
'BADADDR', 'BADADDR',
'BPredRAS',
'Bus',
'BusAddrRanges',
'BusBridge',
'Cache',
'Chains',
'Clock',
'Commit',
'CommitRate',
'Config',
'Console', 'Console',
'ConsolePoll', 'ConsolePoll',
'ConsoleVerbose', 'ConsoleVerbose',
'AlphaConsole', 'Context',
'Flow',
'Interrupt',
'Fault',
'Cycle', 'Cycle',
'Loader', 'DMA',
'MMU', 'DMAReadVerbose',
'DMAWriteVerbose',
'DebugPrintf',
'Decode',
'DiskImage',
'DiskImageRead',
'DiskImageWrite',
'DynInst',
'Ethernet', 'Ethernet',
'EthernetPIO', 'EthernetCksum',
'EthernetDMA', 'EthernetDMA',
'EthernetData', 'EthernetData',
'EthernetDesc', 'EthernetDesc',
'EthernetIntr', 'EthernetIntr',
'EthernetPIO',
'EthernetSM', 'EthernetSM',
'EthernetCksum',
'GDBMisc',
'GDBAcc',
'GDBRead',
'GDBWrite',
'GDBSend',
'GDBRecv',
'GDBExtra',
'VtoPhys',
'Printf',
'DebugPrintf',
'Serialize',
'Event', 'Event',
'PCEvent', 'Fault',
'Syscall', 'Fetch',
'SyscallVerbose', 'Flow',
'DiskImage', 'FreeList',
'DiskImageRead', 'FullCPU',
'DiskImageWrite', 'GDBAcc',
'InstExec', 'GDBExtra',
'BPredRAS', 'GDBMisc',
'Cache', 'GDBRead',
'GDBRecv',
'GDBSend',
'GDBWrite',
'HWPrefetch',
'IEW',
'IIC', 'IIC',
'IICMore', 'IICMore',
'MSHR', 'IPI',
'Chains', 'IQ',
'Pipeline', 'ISP',
'Stats',
'StatEvents',
'Context',
'Config',
'Sampler',
'WriteBarrier',
'IdeCtrl', 'IdeCtrl',
'IdeDisk', 'IdeDisk',
'InstExec',
'Interrupt',
'LDSTQ',
'Loader',
'MC146818',
'MMU',
'MSHR',
'Mbox',
'MemDepUnit',
'OoOCPU',
'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', 'Tsunami',
'Uart', 'Uart',
'Split', 'VtoPhys',
'SQL', 'WriteBarrier',
'Thread',
'Fetch',
'Decode',
'Rename',
'IEW',
'Commit',
'IQ',
'ROB',
'FreeList',
'RenameMap',
'LDSTQ',
'StoreSet',
'MemDepUnit',
'DynInst',
'FullCPU',
'CommitRate',
'OoOCPU',
'HWPrefetch',
'Stack',
'SimpleCPU',
'Sparc',
] ]
# #

View file

@ -80,12 +80,14 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
profilePC = 3; profilePC = 3;
Port *mem_port; 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 = system->physmem->getPort("functional");
mem_port->setPeer(physPort); mem_port->setPeer(physPort);
physPort->setPeer(mem_port); 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 = system->physmem->getPort("functional");
mem_port->setPeer(virtPort); mem_port->setPeer(virtPort);
virtPort->setPeer(mem_port); 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. */ /* Use this port to for syscall emulation writes to memory. */
Port *mem_port; 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 = memobj->getPort("functional");
mem_port->setPeer(port); mem_port->setPeer(port);
port->setPeer(mem_port); port->setPeer(mem_port);
@ -300,7 +304,7 @@ CPUExecContext::getVirtPort(ExecContext *xc)
VirtualPort *vp; VirtualPort *vp;
Port *mem_port; Port *mem_port;
vp = new VirtualPort(xc); vp = new VirtualPort("xc-vport", xc);
mem_port = system->physmem->getPort("functional"); mem_port = system->physmem->getPort("functional");
mem_port->setPeer(vp); mem_port->setPeer(vp);
vp->setPeer(mem_port); vp->setPeer(mem_port);

View file

@ -62,9 +62,6 @@ CpuModel('AtomicSimpleCPU', 'atomic_simple_cpu_exec.cc',
CpuModel('TimingSimpleCPU', 'timing_simple_cpu_exec.cc', CpuModel('TimingSimpleCPU', 'timing_simple_cpu_exec.cc',
'#include "cpu/simple/timing.hh"', '#include "cpu/simple/timing.hh"',
{ 'CPU_exec_context': 'TimingSimpleCPU' }) { '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', CpuModel('FullCPU', 'full_cpu_exec.cc',
'#include "encumbered/cpu/full/dyn_inst.hh"', '#include "encumbered/cpu/full/dyn_inst.hh"',
{ 'CPU_exec_context': 'DynInst' }) { 'CPU_exec_context': 'DynInst' })

View file

@ -117,7 +117,7 @@ AtomicSimpleCPU::CpuPort::recvRetry()
AtomicSimpleCPU::AtomicSimpleCPU(Params *p) AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
: BaseSimpleCPU(p), tickEvent(this), : BaseSimpleCPU(p), tickEvent(this),
width(p->width), simulate_stalls(p->simulate_stalls), width(p->width), simulate_stalls(p->simulate_stalls),
icachePort(this), dcachePort(this) icachePort(name() + "-iport", this), dcachePort(name() + "-iport", this)
{ {
_status = Idle; _status = Idle;
@ -126,31 +126,23 @@ AtomicSimpleCPU::AtomicSimpleCPU(Params *p)
// @todo fix me and get the real cpu iD!!! // @todo fix me and get the real cpu iD!!!
ifetch_req->setCpuNum(0); ifetch_req->setCpuNum(0);
ifetch_req->setSize(sizeof(MachInst)); ifetch_req->setSize(sizeof(MachInst));
ifetch_pkt = new Packet; ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
ifetch_pkt->cmd = Read;
ifetch_pkt->dataStatic(&inst); 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); data_read_req = new Request(true);
// @todo fix me and get the real cpu iD!!! // @todo fix me and get the real cpu iD!!!
data_read_req->setCpuNum(0); data_read_req->setCpuNum(0);
data_read_req->setAsid(0); data_read_req->setAsid(0);
data_read_pkt = new Packet; data_read_pkt = new Packet(data_read_req, Packet::ReadReq,
data_read_pkt->cmd = Read; Packet::Broadcast);
data_read_pkt->dataStatic(&dataReg); data_read_pkt->dataStatic(&dataReg);
data_read_pkt->req = data_read_req;
data_read_pkt->dest = Packet::Broadcast;
data_write_req = new Request(true); data_write_req = new Request(true);
// @todo fix me and get the real cpu iD!!! // @todo fix me and get the real cpu iD!!!
data_write_req->setCpuNum(0); data_write_req->setCpuNum(0);
data_write_req->setAsid(0); data_write_req->setAsid(0);
data_write_pkt = new Packet; data_write_pkt = new Packet(data_write_req, Packet::WriteReq,
data_write_pkt->cmd = Write; Packet::Broadcast);
data_write_pkt->req = data_write_req;
data_write_pkt->dest = Packet::Broadcast;
} }
@ -260,13 +252,12 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
// Now do the access. // Now do the access.
if (fault == NoFault) { if (fault == NoFault) {
data_read_pkt->reset(); data_read_pkt->reset();
data_read_pkt->addr = data_read_req->getPaddr(); data_read_pkt->reinitFromRequest();
data_read_pkt->size = sizeof(T);
dcache_complete = dcachePort.sendAtomic(data_read_pkt); dcache_complete = dcachePort.sendAtomic(data_read_pkt);
dcache_access = true; dcache_access = true;
assert(data_read_pkt->result == Success); assert(data_read_pkt->result == Packet::Success);
data = data_read_pkt->get<T>(); 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_write_pkt->reset();
data = htog(data); data = htog(data);
data_write_pkt->dataStatic(&data); data_write_pkt->dataStatic(&data);
data_write_pkt->addr = data_write_req->getPaddr(); data_write_pkt->reinitFromRequest();
data_write_pkt->size = sizeof(T);
dcache_complete = dcachePort.sendAtomic(data_write_pkt); dcache_complete = dcachePort.sendAtomic(data_write_pkt);
dcache_access = true; dcache_access = true;
assert(data_write_pkt->result == Success); assert(data_write_pkt->result == Packet::Success);
if (res && data_write_req->getFlags() & LOCKED) { if (res && data_write_req->getFlags() & LOCKED) {
*res = data_write_req->getScResult(); *res = data_write_req->getScResult();
@ -435,10 +425,6 @@ AtomicSimpleCPU::tick()
fault = curStaticInst->execute(this, traceData); fault = curStaticInst->execute(this, traceData);
postExecute(); postExecute();
if (traceData) {
traceData->finalize();
}
if (simulate_stalls) { if (simulate_stalls) {
// This calculation assumes that the icache and dcache // This calculation assumes that the icache and dcache
// access latencies are always a multiple of the CPU's // access latencies are always a multiple of the CPU's

View file

@ -84,8 +84,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
public: public:
CpuPort(AtomicSimpleCPU *_cpu) CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu)
: cpu(_cpu) : Port(_name), cpu(_cpu)
{ } { }
protected: protected:

View file

@ -372,7 +372,7 @@ BaseSimpleCPU::setupFetchPacket(Packet *ifetch_pkt)
Fault fault = cpuXC->translateInstReq(ifetch_req); Fault fault = cpuXC->translateInstReq(ifetch_req);
if (fault == NoFault) { if (fault == NoFault) {
ifetch_pkt->addr = ifetch_req->getPaddr(); ifetch_pkt->reinitFromRequest();
} }
return fault; return fault;
@ -442,6 +442,10 @@ BaseSimpleCPU::postExecute()
} }
traceFunctions(cpuXC->readPC()); traceFunctions(cpuXC->readPC());
if (traceData) {
traceData->finalize();
}
} }

View file

@ -158,10 +158,11 @@ TimingSimpleCPU::suspendContext(int thread_num)
assert(thread_num == 0); assert(thread_num == 0);
assert(cpuXC); assert(cpuXC);
panic("TimingSimpleCPU::suspendContext not implemented");
assert(_status == Running); assert(_status == Running);
// just change status to Idle... if status != Running,
// completeInst() will not initiate fetch of next instruction.
notIdleFraction--; notIdleFraction--;
_status = Idle; _status = Idle;
} }
@ -187,13 +188,9 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// Now do the access. // Now do the access.
if (fault == NoFault) { if (fault == NoFault) {
Packet *data_read_pkt = new Packet; Packet *data_read_pkt =
data_read_pkt->cmd = Read; new Packet(data_read_req, Packet::ReadReq, Packet::Broadcast);
data_read_pkt->req = data_read_req;
data_read_pkt->dataDynamic<T>(new T); 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)) { if (!dcachePort.sendTiming(data_read_pkt)) {
_status = DcacheRetry; _status = DcacheRetry;
@ -268,14 +265,10 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
Fault fault = cpuXC->translateDataWriteReq(data_write_req); Fault fault = cpuXC->translateDataWriteReq(data_write_req);
// Now do the access. // Now do the access.
if (fault == NoFault) { if (fault == NoFault) {
Packet *data_write_pkt = new Packet; Packet *data_write_pkt =
data_write_pkt->cmd = Write; new Packet(data_write_req, Packet::WriteReq, Packet::Broadcast);
data_write_pkt->req = data_write_req;
data_write_pkt->allocate(); data_write_pkt->allocate();
data_write_pkt->size = sizeof(T);
data_write_pkt->set(data); 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)) { if (!dcachePort.sendTiming(data_write_pkt)) {
_status = DcacheRetry; _status = DcacheRetry;
@ -350,12 +343,8 @@ TimingSimpleCPU::fetch()
Request *ifetch_req = new Request(true); Request *ifetch_req = new Request(true);
ifetch_req->setSize(sizeof(MachInst)); ifetch_req->setSize(sizeof(MachInst));
ifetch_pkt = new Packet; ifetch_pkt = new Packet(ifetch_req, Packet::ReadReq, Packet::Broadcast);
ifetch_pkt->cmd = Read;
ifetch_pkt->dataStatic(&inst); ifetch_pkt->dataStatic(&inst);
ifetch_pkt->req = ifetch_req;
ifetch_pkt->size = sizeof(MachInst);
ifetch_pkt->dest = Packet::Broadcast;
Fault fault = setupFetchPacket(ifetch_pkt); Fault fault = setupFetchPacket(ifetch_pkt);
if (fault == NoFault) { if (fault == NoFault) {
@ -369,20 +358,15 @@ TimingSimpleCPU::fetch()
ifetch_pkt = NULL; ifetch_pkt = NULL;
} }
} else { } else {
panic("TimingSimpleCPU fetch fault handling not implemented"); // fetch fault: advance directly to next instruction (fault handler)
advanceInst(fault);
} }
} }
void void
TimingSimpleCPU::completeInst(Fault fault) TimingSimpleCPU::advanceInst(Fault fault)
{ {
postExecute();
if (traceData) {
traceData->finalize();
}
advancePC(fault); advancePC(fault);
if (_status == Running) { if (_status == Running) {
@ -395,23 +379,35 @@ TimingSimpleCPU::completeInst(Fault fault)
void void
TimingSimpleCPU::completeIfetch() TimingSimpleCPU::completeIfetch(Packet *pkt)
{ {
// received a response from the icache: execute the received // received a response from the icache: execute the received
// instruction // instruction
assert(pkt->result == Packet::Success);
assert(_status == IcacheWaitResponse); assert(_status == IcacheWaitResponse);
_status = Running; _status = Running;
delete pkt->req;
delete pkt;
preExecute(); preExecute();
if (curStaticInst->isMemRef()) { if (curStaticInst->isMemRef() && !curStaticInst->isDataPrefetch()) {
// load or store: just send to dcache // load or store: just send to dcache
Fault fault = curStaticInst->initiateAcc(this, traceData); Fault fault = curStaticInst->initiateAcc(this, traceData);
assert(fault == NoFault); if (fault == NoFault) {
// successfully initiated access: instruction will
// complete in dcache response callback
assert(_status == DcacheWaitResponse); assert(_status == DcacheWaitResponse);
// instruction will complete in dcache response callback } else {
// fault: complete now to invoke fault handler
postExecute();
advanceInst(fault);
}
} else { } else {
// non-memory instruction: execute completely now // non-memory instruction: execute completely now
Fault fault = curStaticInst->execute(this, traceData); Fault fault = curStaticInst->execute(this, traceData);
completeInst(fault); postExecute();
advanceInst(fault);
} }
} }
@ -419,7 +415,7 @@ TimingSimpleCPU::completeIfetch()
bool bool
TimingSimpleCPU::IcachePort::recvTiming(Packet *pkt) TimingSimpleCPU::IcachePort::recvTiming(Packet *pkt)
{ {
cpu->completeIfetch(); cpu->completeIfetch(pkt);
return true; return true;
} }
@ -441,13 +437,17 @@ TimingSimpleCPU::completeDataAccess(Packet *pkt)
{ {
// received a response from the dcache: complete the load or store // received a response from the dcache: complete the load or store
// instruction // instruction
assert(pkt->result == Success); assert(pkt->result == Packet::Success);
assert(_status == DcacheWaitResponse); assert(_status == DcacheWaitResponse);
_status = Running; _status = Running;
Fault fault = curStaticInst->completeAcc(pkt, this, traceData); Fault fault = curStaticInst->completeAcc(pkt, this, traceData);
completeInst(fault); delete pkt->req;
delete pkt;
postExecute();
advanceInst(fault);
} }

View file

@ -71,8 +71,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
public: public:
CpuPort(TimingSimpleCPU *_cpu) CpuPort(const std::string &_name, TimingSimpleCPU *_cpu)
: cpu(_cpu) : Port(_name), cpu(_cpu)
{ } { }
protected: protected:
@ -93,7 +93,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
public: public:
IcachePort(TimingSimpleCPU *_cpu) IcachePort(TimingSimpleCPU *_cpu)
: CpuPort(_cpu) : CpuPort(_cpu->name() + "-iport", _cpu)
{ } { }
protected: protected:
@ -108,7 +108,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
public: public:
DcachePort(TimingSimpleCPU *_cpu) DcachePort(TimingSimpleCPU *_cpu)
: CpuPort(_cpu) : CpuPort(_cpu->name() + "-dport", _cpu)
{ } { }
protected: protected:
@ -142,9 +142,9 @@ class TimingSimpleCPU : public BaseSimpleCPU
Fault write(T data, Addr addr, unsigned flags, uint64_t *res); Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
void fetch(); void fetch();
void completeInst(Fault fault); void completeIfetch(Packet *);
void completeIfetch();
void completeDataAccess(Packet *); void completeDataAccess(Packet *);
void advanceInst(Fault fault);
}; };
#endif // __CPU_SIMPLE_TIMING_HH__ #endif // __CPU_SIMPLE_TIMING_HH__

View file

@ -95,15 +95,15 @@ AlphaConsole::read(Packet *pkt)
* machine dependent address swizzle is required? * machine dependent address swizzle is required?
*/ */
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
pkt->time += pioDelay; pkt->time += pioDelay;
Addr daddr = pkt->addr - pioAddr; Addr daddr = pkt->getAddr() - pioAddr;
pkt->allocate(); pkt->allocate();
switch (pkt->size) switch (pkt->getSize())
{ {
case sizeof(uint32_t): case sizeof(uint32_t):
switch (daddr) switch (daddr)
@ -124,7 +124,7 @@ AlphaConsole::read(Packet *pkt)
/* Old console code read in everyting as a 32bit int /* Old console code read in everyting as a 32bit int
* we now break that for better error checking. * we now break that for better error checking.
*/ */
pkt->result = BadAddress; pkt->result = Packet::BadAddress;
} }
DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr,
pkt->get<uint32_t>()); pkt->get<uint32_t>());
@ -181,9 +181,10 @@ AlphaConsole::read(Packet *pkt)
pkt->get<uint64_t>()); pkt->get<uint64_t>());
break; break;
default: 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; return pioDelay;
} }
@ -192,12 +193,12 @@ AlphaConsole::write(Packet *pkt)
{ {
pkt->time += pioDelay; pkt->time += pioDelay;
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
Addr daddr = pkt->addr - pioAddr; Addr daddr = pkt->getAddr() - pioAddr;
uint64_t val = pkt->get<uint64_t>(); uint64_t val = pkt->get<uint64_t>();
assert(pkt->size == sizeof(uint64_t)); assert(pkt->getSize() == sizeof(uint64_t));
switch (daddr) { switch (daddr) {
case offsetof(AlphaAccess, diskUnit): case offsetof(AlphaAccess, diskUnit):
@ -240,7 +241,7 @@ AlphaConsole::write(Packet *pkt)
panic("Unknown 64bit access, %#x\n", daddr); panic("Unknown 64bit access, %#x\n", daddr);
} }
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }

View file

@ -432,19 +432,19 @@ IdeController::read(Packet *pkt)
pkt->time += pioDelay; pkt->time += pioDelay;
pkt->allocate(); pkt->allocate();
if (pkt->size != 1 && pkt->size != 2 && pkt->size !=4) if (pkt->getSize() != 1 && pkt->getSize() != 2 && pkt->getSize() !=4)
panic("Bad IDE read size: %d\n", pkt->size); 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) { if (!io_enabled) {
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }
switch (reg_type) { switch (reg_type) {
case BMI_BLOCK: case BMI_BLOCK:
switch (pkt->size) { switch (pkt->getSize()) {
case sizeof(uint8_t): case sizeof(uint8_t):
pkt->set(bmi_regs.data[offset]); pkt->set(bmi_regs.data[offset]);
break; break;
@ -455,7 +455,7 @@ IdeController::read(Packet *pkt)
pkt->set(*(uint32_t*)&bmi_regs.data[offset]); pkt->set(*(uint32_t*)&bmi_regs.data[offset]);
break; break;
default: 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; break;
@ -470,7 +470,7 @@ IdeController::read(Packet *pkt)
switch (offset) { switch (offset) {
case DATA_OFFSET: case DATA_OFFSET:
switch (pkt->size) { switch (pkt->getSize()) {
case sizeof(uint16_t): case sizeof(uint16_t):
disks[disk]->read(offset, reg_type, pkt->getPtr<uint8_t>()); disks[disk]->read(offset, reg_type, pkt->getPtr<uint8_t>());
break; break;
@ -482,30 +482,30 @@ IdeController::read(Packet *pkt)
break; break;
default: 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; break;
default: default:
if (pkt->size == sizeof(uint8_t)) { if (pkt->getSize() == sizeof(uint8_t)) {
disks[disk]->read(offset, reg_type, pkt->getPtr<uint8_t>()); disks[disk]->read(offset, reg_type, pkt->getPtr<uint8_t>());
} else } 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; break;
default: default:
panic("IDE controller read of unknown register block type!\n"); 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", DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
offset, pkt->size, (uint32_t)pkt->get<uint8_t>()); offset, pkt->getSize(), (uint32_t)pkt->get<uint8_t>());
else if (pkt->size == 2) else if (pkt->getSize() == 2)
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", 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 else
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", 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; return pioDelay;
} }
@ -520,10 +520,10 @@ IdeController::write(Packet *pkt)
pkt->time += pioDelay; pkt->time += pioDelay;
parseAddr(pkt->addr, offset, channel, reg_type); parseAddr(pkt->getAddr(), offset, channel, reg_type);
if (!io_enabled) { if (!io_enabled) {
pkt->result = Success; pkt->result = Packet::Success;
DPRINTF(IdeCtrl, "io not enabled\n"); DPRINTF(IdeCtrl, "io not enabled\n");
return pioDelay; return pioDelay;
} }
@ -531,7 +531,7 @@ IdeController::write(Packet *pkt)
switch (reg_type) { switch (reg_type) {
case BMI_BLOCK: case BMI_BLOCK:
if (!bm_enabled) { if (!bm_enabled) {
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }
@ -539,8 +539,8 @@ IdeController::write(Packet *pkt)
// Bus master IDE command register // Bus master IDE command register
case BMIC1: case BMIC1:
case BMIC0: case BMIC0:
if (pkt->size != sizeof(uint8_t)) if (pkt->getSize() != sizeof(uint8_t))
panic("Invalid BMIC write size: %x\n", pkt->size); panic("Invalid BMIC write size: %x\n", pkt->getSize());
// select the current disk based on DEV bit // select the current disk based on DEV bit
disk = getDisk(channel); disk = getDisk(channel);
@ -595,8 +595,8 @@ IdeController::write(Packet *pkt)
// Bus master IDE status register // Bus master IDE status register
case BMIS0: case BMIS0:
case BMIS1: case BMIS1:
if (pkt->size != sizeof(uint8_t)) if (pkt->getSize() != sizeof(uint8_t))
panic("Invalid BMIS write size: %x\n", pkt->size); panic("Invalid BMIS write size: %x\n", pkt->getSize());
oldVal = bmi_regs.chan[channel].bmis; oldVal = bmi_regs.chan[channel].bmis;
newVal = pkt->get<uint8_t>(); newVal = pkt->get<uint8_t>();
@ -622,22 +622,22 @@ IdeController::write(Packet *pkt)
case BMIDTP0: case BMIDTP0:
case BMIDTP1: case BMIDTP1:
{ {
if (pkt->size != sizeof(uint32_t)) if (pkt->getSize() != sizeof(uint32_t))
panic("Invalid BMIDTP write size: %x\n", pkt->size); panic("Invalid BMIDTP write size: %x\n", pkt->getSize());
bmi_regs.chan[channel].bmidtp = htole(pkt->get<uint32_t>() & ~0x3); bmi_regs.chan[channel].bmidtp = htole(pkt->get<uint32_t>() & ~0x3);
} }
break; break;
default: default:
if (pkt->size != sizeof(uint8_t) && if (pkt->getSize() != sizeof(uint8_t) &&
pkt->size != sizeof(uint16_t) && pkt->getSize() != sizeof(uint16_t) &&
pkt->size != sizeof(uint32_t)) pkt->getSize() != sizeof(uint32_t))
panic("IDE controller write of invalid write size: %x\n", panic("IDE controller write of invalid write size: %x\n",
pkt->size); pkt->getSize());
// do a default copy of data into the registers // 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; break;
case COMMAND_BLOCK: case COMMAND_BLOCK:
@ -654,7 +654,7 @@ IdeController::write(Packet *pkt)
switch (offset) { switch (offset) {
case DATA_OFFSET: case DATA_OFFSET:
switch (pkt->size) { switch (pkt->getSize()) {
case sizeof(uint16_t): case sizeof(uint16_t):
disks[disk]->write(offset, reg_type, pkt->getPtr<uint8_t>()); disks[disk]->write(offset, reg_type, pkt->getPtr<uint8_t>());
break; break;
@ -665,32 +665,32 @@ IdeController::write(Packet *pkt)
sizeof(uint16_t)); sizeof(uint16_t));
break; break;
default: 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; break;
default: default:
if (pkt->size == sizeof(uint8_t)) { if (pkt->getSize() == sizeof(uint8_t)) {
disks[disk]->write(offset, reg_type, pkt->getPtr<uint8_t>()); disks[disk]->write(offset, reg_type, pkt->getPtr<uint8_t>());
} else } 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; break;
default: default:
panic("IDE controller write of unknown register block type!\n"); 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", DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
offset, pkt->size, (uint32_t)pkt->get<uint8_t>()); offset, pkt->getSize(), (uint32_t)pkt->get<uint8_t>());
else if (pkt->size == 2) else if (pkt->getSize() == 2)
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", 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 else
DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", 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; return pioDelay;
} }

View file

@ -31,7 +31,7 @@
PioPort::PioPort(PioDevice *dev, Platform *p) 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 void
PioPort::SendEvent::process() PioPort::SendEvent::process()
{ {
if (port->Port::sendTiming(packet) == Success) if (port->Port::sendTiming(packet))
return; return;
port->transmitList.push_back(packet); port->transmitList.push_back(packet);
@ -78,8 +78,10 @@ bool
PioPort::recvTiming(Packet *pkt) PioPort::recvTiming(Packet *pkt)
{ {
device->recvAtomic(pkt); device->recvAtomic(pkt);
// turn packet around to go back to requester
pkt->makeTimingResponse();
sendTiming(pkt, pkt->time - pkt->req->getTime()); sendTiming(pkt, pkt->time - pkt->req->getTime());
return Success; return true;
} }
PioDevice::~PioDevice() PioDevice::~PioDevice()
@ -106,7 +108,7 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list)
DmaPort::DmaPort(DmaDevice *dev, Platform *p) DmaPort::DmaPort(DmaDevice *dev, Platform *p)
: device(dev), platform(p), pendingCount(0) : Port(dev->name() + "-dmaport"), device(dev), platform(p), pendingCount(0)
{ } { }
bool bool
@ -114,7 +116,7 @@ DmaPort::recvTiming(Packet *pkt)
{ {
if (pkt->senderState) { if (pkt->senderState) {
DmaReqState *state; DmaReqState *state;
state = (DmaReqState*)pkt->senderState; state = dynamic_cast<DmaReqState*>(pkt->senderState);
state->completionEvent->schedule(pkt->time - pkt->req->getTime()); state->completionEvent->schedule(pkt->time - pkt->req->getTime());
delete pkt->req; delete pkt->req;
delete pkt; delete pkt;
@ -123,7 +125,7 @@ DmaPort::recvTiming(Packet *pkt)
delete pkt; delete pkt;
} }
return Success; return Packet::Success;
} }
DmaDevice::DmaDevice(Params *p) DmaDevice::DmaDevice(Params *p)
@ -133,7 +135,7 @@ DmaDevice::DmaDevice(Params *p)
void void
DmaPort::SendEvent::process() DmaPort::SendEvent::process()
{ {
if (port->Port::sendTiming(packet) == Success) if (port->Port::sendTiming(packet))
return; return;
port->transmitList.push_back(packet); port->transmitList.push_back(packet);
@ -146,54 +148,39 @@ DmaPort::recvRetry()
transmitList.pop_front(); transmitList.pop_front();
return pkt; return pkt;
} }
void void
DmaPort::dmaAction(Command cmd, Addr addr, int size, Event *event, DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
uint8_t *data) uint8_t *data)
{ {
assert(event); assert(event);
int prevSize = 0; 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()); for (ChunkGenerator gen(addr, size, peerBlockSize());
!gen.done(); gen.next()) { !gen.done(); gen.next()) {
Packet *pkt = new Packet(basePkt); Request *req = new Request(false);
Request *req = new Request(baseReq); req->setPaddr(gen.addr());
pkt->addr = gen.addr(); req->setSize(gen.size());
pkt->size = gen.size(); req->setTime(curTick);
pkt->req = req; Packet *pkt = new Packet(req, cmd, Packet::Broadcast);
pkt->req->setPaddr(pkt->addr);
pkt->req->setSize(pkt->size);
// Increment the data pointer on a write // Increment the data pointer on a write
if (data) if (data)
pkt->dataStatic(data + prevSize) ; pkt->dataStatic(data + prevSize) ;
prevSize += pkt->size;
prevSize += gen.size();
// Set the last bit of the dma as the final packet for this dma // Set the last bit of the dma as the final packet for this dma
// and set it's completion event. // and set it's completion event.
if (prevSize == size) { if (prevSize == size) {
DmaReqState *state = new DmaReqState(event, true); pkt->senderState = new DmaReqState(event, true);
pkt->senderState = (void*)state;
} }
assert(pendingCount >= 0); assert(pendingCount >= 0);
pendingCount++; pendingCount++;
sendDma(pkt); 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; /* MemState state = device->platform->system->memState;
if (state == Timing) { if (state == Timing) {
if (sendTiming(pkt) == Failure) if (!sendTiming(pkt))
transmitList.push_back(&packet); transmitList.push_back(&packet);
} else if (state == Atomic) {*/ } else if (state == Atomic) {*/
sendAtomic(pkt); sendAtomic(pkt);
if (pkt->senderState) { 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); state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1);
} }
pendingCount--; pendingCount--;

View file

@ -115,7 +115,7 @@ class PioPort : public Port
}; };
struct DmaReqState struct DmaReqState : public Packet::SenderState
{ {
Event *completionEvent; Event *completionEvent;
bool final; bool final;
@ -173,7 +173,7 @@ class DmaPort : public Port
public: public:
DmaPort(DmaDevice *dev, Platform *p); DmaPort(DmaDevice *dev, Platform *p);
void dmaAction(Command cmd, Addr addr, int size, Event *event, void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
uint8_t *data = NULL); uint8_t *data = NULL);
bool dmaPending() { return pendingCount > 0; } 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 /** As far as the devices are concerned they only accept atomic transactions
* which are converted to either a write or a read. */ * which are converted to either a write or a read. */
Tick recvAtomic(Packet *pkt) 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 /** Pure virtual function that the device must implement. Called when a read
* command is recieved by the port. * command is recieved by the port.
@ -305,10 +305,10 @@ class DmaDevice : public PioDevice
virtual ~DmaDevice(); virtual ~DmaDevice();
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data) 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) 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(); } bool dmaPending() { return dmaPort->dmaPending(); }

View file

@ -51,14 +51,14 @@ IsaFake::IsaFake(Params *p)
Tick Tick
IsaFake::read(Packet *pkt) IsaFake::read(Packet *pkt)
{ {
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
pkt->time += pioDelay; 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); pkt->set(0xFFFFFFFFFFFFFFFFULL);
break; break;
case sizeof(uint32_t): case sizeof(uint32_t):
@ -73,7 +73,7 @@ IsaFake::read(Packet *pkt)
default: default:
panic("invalid access size(?) for PCI configspace!\n"); panic("invalid access size(?) for PCI configspace!\n");
} }
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }
@ -81,8 +81,8 @@ Tick
IsaFake::write(Packet *pkt) IsaFake::write(Packet *pkt)
{ {
pkt->time += pioDelay; pkt->time += pioDelay;
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->addr, pkt->size); DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize());
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }

View file

@ -496,9 +496,9 @@ NSGigE::read(Packet *pkt)
pkt->allocate(); pkt->allocate();
//The mask is to give you only the offset into the device register file //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", 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 // 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) { if (daddr > LAST && daddr <= RESERVED) {
panic("Accessing reserved register"); panic("Accessing reserved register");
} else if (daddr > RESERVED && daddr <= 0x3FC) { } 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>()); 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>()); 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>()); readConfig(daddr & 0xff, pkt->getPtr<uint32_t>());
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} else if (daddr >= MIB_START && daddr <= MIB_END) { } else if (daddr >= MIB_START && daddr <= MIB_END) {
// don't implement all the MIB's. hopefully the kernel // don't implement all the MIB's. hopefully the kernel
// doesn't actually DEPEND upon their values // doesn't actually DEPEND upon their values
// MIB are just hardware stats keepers // MIB are just hardware stats keepers
pkt->set<uint32_t>(0); pkt->set<uint32_t>(0);
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} else if (daddr > 0x3FC) } else if (daddr > 0x3FC)
panic("Something is messed up!\n"); 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>(); uint32_t &reg = *pkt->getPtr<uint32_t>();
uint16_t rfaddr; uint16_t rfaddr;
@ -715,7 +715,7 @@ NSGigE::read(Packet *pkt)
DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n",
daddr, reg, reg); daddr, reg, reg);
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }
@ -724,27 +724,27 @@ NSGigE::write(Packet *pkt)
{ {
assert(ioEnable); assert(ioEnable);
Addr daddr = pkt->addr & 0xfff; Addr daddr = pkt->getAddr() & 0xfff;
DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n", DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n",
daddr, pkt->addr, pkt->size); daddr, pkt->getAddr(), pkt->getSize());
pkt->time += pioDelay; pkt->time += pioDelay;
if (daddr > LAST && daddr <= RESERVED) { if (daddr > LAST && daddr <= RESERVED) {
panic("Accessing reserved register"); panic("Accessing reserved register");
} else if (daddr > RESERVED && daddr <= 0x3FC) { } 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>()); 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>()); 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>()); writeConfig(daddr & 0xff, pkt->get<uint32_t>());
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} else if (daddr > 0x3FC) } else if (daddr > 0x3FC)
panic("Something is messed up!\n"); 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>(); uint32_t reg = pkt->get<uint32_t>();
uint16_t rfaddr; uint16_t rfaddr;
@ -1131,7 +1131,7 @@ NSGigE::write(Packet *pkt)
} else { } else {
panic("Invalid Request Size"); panic("Invalid Request Size");
} }
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }

View file

@ -91,10 +91,10 @@ PciConfigAll::startup()
Tick Tick
PciConfigAll::read(Packet *pkt) PciConfigAll::read(Packet *pkt)
{ {
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
Addr daddr = pkt->addr - pioAddr; Addr daddr = pkt->getAddr() - pioAddr;
int device = (daddr >> 11) & 0x1F; int device = (daddr >> 11) & 0x1F;
int func = (daddr >> 8) & 0x7; int func = (daddr >> 8) & 0x7;
int reg = daddr & 0xFF; int reg = daddr & 0xFF;
@ -102,10 +102,10 @@ PciConfigAll::read(Packet *pkt)
pkt->time += pioDelay; pkt->time += pioDelay;
pkt->allocate(); pkt->allocate();
DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt->addr, daddr, DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt->getAddr(), daddr,
pkt->size); pkt->getSize());
switch (pkt->size) { switch (pkt->getSize()) {
case sizeof(uint32_t): case sizeof(uint32_t):
if (devices[device][func] == NULL) if (devices[device][func] == NULL)
pkt->set<uint32_t>(0xFFFFFFFF); pkt->set<uint32_t>(0xFFFFFFFF);
@ -127,7 +127,7 @@ PciConfigAll::read(Packet *pkt)
default: default:
panic("invalid access size(?) for PCI configspace!\n"); panic("invalid access size(?) for PCI configspace!\n");
} }
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }
@ -136,11 +136,11 @@ PciConfigAll::write(Packet *pkt)
{ {
pkt->time += pioDelay; pkt->time += pioDelay;
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
assert(pkt->size == sizeof(uint8_t) || pkt->size == sizeof(uint16_t) || assert(pkt->getSize() == sizeof(uint8_t) || pkt->getSize() == sizeof(uint16_t) ||
pkt->size == sizeof(uint32_t)); pkt->getSize() == sizeof(uint32_t));
Addr daddr = pkt->addr - pioAddr; Addr daddr = pkt->getAddr() - pioAddr;
int device = (daddr >> 11) & 0x1F; int device = (daddr >> 11) & 0x1F;
int func = (daddr >> 8) & 0x7; 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"); panic("Attempting to write to config space on non-existant device\n");
DPRINTF(PciConfigAll, "write - va=%#x size=%d data=%#x\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): case sizeof(uint8_t):
devices[device][func]->writeConfig(reg, pkt->get<uint8_t>()); devices[device][func]->writeConfig(reg, pkt->get<uint8_t>());
break; break;
@ -165,7 +165,7 @@ PciConfigAll::write(Packet *pkt)
default: default:
panic("invalid pci config write size\n"); panic("invalid pci config write size\n");
} }
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }

View file

@ -315,10 +315,10 @@ Tick
Device::read(Packet *pkt) Device::read(Packet *pkt)
{ {
assert(config.command & PCI_CMD_MSE); 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(); int cpu = pkt->req->getCpuNum();
Addr daddr = pkt->addr - BARAddrs[0]; Addr daddr = pkt->getAddr() - BARAddrs[0];
Addr index = daddr >> Regs::VirtualShift; Addr index = daddr >> Regs::VirtualShift;
Addr raddr = daddr & Regs::VirtualMask; Addr raddr = daddr & Regs::VirtualMask;
@ -327,28 +327,28 @@ Device::read(Packet *pkt)
if (!regValid(raddr)) if (!regValid(raddr))
panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x size=%d", 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); const Regs::Info &info = regInfo(raddr);
if (!info.read) if (!info.read)
panic("read %s (write only): " panic("read %s (write only): "
"cpu=%d vnic=%d da=%#x pa=%#x size=%d", "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): " panic("read %s (invalid size): "
"cpu=%d vnic=%d da=%#x pa=%#x size=%d", "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); prepareRead(cpu, index);
uint64_t value = 0; uint64_t value = 0;
if (pkt->size == 4) { if (pkt->getSize() == 4) {
uint32_t reg = regData32(raddr); uint32_t reg = regData32(raddr);
pkt->set(reg); pkt->set(reg);
value = reg; value = reg;
} }
if (pkt->size == 8) { if (pkt->getSize() == 8) {
uint64_t reg = regData64(raddr); uint64_t reg = regData64(raddr);
pkt->set(reg); pkt->set(reg);
value = reg; value = reg;
@ -356,7 +356,7 @@ Device::read(Packet *pkt)
DPRINTF(EthernetPIO, DPRINTF(EthernetPIO,
"read %s: cpu=%d vnic=%d da=%#x pa=%#x size=%d val=%#x\n", "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 // reading the interrupt status register has the side effect of
// clearing it // clearing it
@ -403,10 +403,10 @@ Tick
Device::write(Packet *pkt) Device::write(Packet *pkt)
{ {
assert(config.command & PCI_CMD_MSE); 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(); int cpu = pkt->req->getCpuNum();
Addr daddr = pkt->addr - BARAddrs[0]; Addr daddr = pkt->getAddr() - BARAddrs[0];
Addr index = daddr >> Regs::VirtualShift; Addr index = daddr >> Regs::VirtualShift;
Addr raddr = daddr & Regs::VirtualMask; Addr raddr = daddr & Regs::VirtualMask;
@ -414,25 +414,25 @@ Device::write(Packet *pkt)
if (!regValid(raddr)) if (!regValid(raddr))
panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d", 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); const Regs::Info &info = regInfo(raddr);
if (!info.write) if (!info.write)
panic("write %s (read only): " panic("write %s (read only): "
"cpu=%d vnic=%d da=%#x pa=%#x size=%d", "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): " panic("write %s (invalid size): "
"cpu=%d vnic=%d da=%#x pa=%#x size=%d", "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]; VirtualReg &vnic = virtualRegs[index];
DPRINTF(EthernetPIO, DPRINTF(EthernetPIO,
"write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x size=%d\n", "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>() : 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); prepareWrite(cpu, index);

View file

@ -71,17 +71,17 @@ TsunamiCChip::TsunamiCChip(Params *p)
Tick Tick
TsunamiCChip::read(Packet *pkt) 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->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
pkt->time += pioDelay; pkt->time += pioDelay;
Addr regnum = (pkt->addr - pioAddr) >> 6; Addr regnum = (pkt->getAddr() - pioAddr) >> 6;
Addr daddr = (pkt->addr - pioAddr); Addr daddr = (pkt->getAddr() - pioAddr);
pkt->allocate(); pkt->allocate();
switch (pkt->size) { switch (pkt->getSize()) {
case sizeof(uint64_t): case sizeof(uint64_t):
if (daddr & TSDEV_CC_BDIMS) if (daddr & TSDEV_CC_BDIMS)
@ -173,9 +173,9 @@ TsunamiCChip::read(Packet *pkt)
panic("invalid access size(?) for tsunami register!\n"); panic("invalid access size(?) for tsunami register!\n");
} }
DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\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; return pioDelay;
} }
@ -185,14 +185,14 @@ TsunamiCChip::write(Packet *pkt)
pkt->time += pioDelay; pkt->time += pioDelay;
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
Addr daddr = pkt->addr - pioAddr; Addr daddr = pkt->getAddr() - pioAddr;
Addr regnum = (pkt->addr - pioAddr) >> 6 ; 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; bool supportedWrite = false;
@ -362,7 +362,7 @@ TsunamiCChip::write(Packet *pkt)
panic("default in cchip read reached, accessing 0x%x\n"); panic("default in cchip read reached, accessing 0x%x\n");
} // swtich(regnum) } // swtich(regnum)
} // not BIG_TSUNAMI write } // not BIG_TSUNAMI write
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }

View file

@ -438,18 +438,18 @@ TsunamiIO::frequency() const
Tick Tick
TsunamiIO::read(Packet *pkt) TsunamiIO::read(Packet *pkt)
{ {
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
pkt->time += pioDelay; 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, DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt->getAddr(),
pkt->size, daddr); pkt->getSize(), daddr);
pkt->allocate(); pkt->allocate();
if (pkt->size == sizeof(uint8_t)) { if (pkt->getSize() == sizeof(uint8_t)) {
switch(daddr) { switch(daddr) {
// PIC1 mask read // PIC1 mask read
case TSDEV_PIC1_MASK: case TSDEV_PIC1_MASK:
@ -487,18 +487,18 @@ TsunamiIO::read(Packet *pkt)
pkt->set(0x00); pkt->set(0x00);
break; break;
default: 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) if (daddr == TSDEV_PIC1_ISR)
pkt->set<uint64_t>(picr); pkt->set<uint64_t>(picr);
else else
panic("I/O Read - invalid addr - va %#x size %d\n", panic("I/O Read - invalid addr - va %#x size %d\n",
pkt->addr, pkt->size); pkt->getAddr(), pkt->getSize());
} else { } 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; return pioDelay;
} }
@ -507,14 +507,14 @@ TsunamiIO::write(Packet *pkt)
{ {
pkt->time += pioDelay; pkt->time += pioDelay;
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
Addr daddr = pkt->addr - pioAddr; Addr daddr = pkt->getAddr() - pioAddr;
DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", 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) { switch(daddr) {
case TSDEV_PIC1_MASK: case TSDEV_PIC1_MASK:
@ -577,10 +577,10 @@ TsunamiIO::write(Packet *pkt)
case TSDEV_CTRL_PORTB: case TSDEV_CTRL_PORTB:
break; break;
default: 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; return pioDelay;
} }

View file

@ -67,17 +67,17 @@ TsunamiPChip::TsunamiPChip(Params *p)
Tick Tick
TsunamiPChip::read(Packet *pkt) TsunamiPChip::read(Packet *pkt)
{ {
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
pkt->time += pioDelay; pkt->time += pioDelay;
pkt->allocate(); pkt->allocate();
Addr daddr = (pkt->addr - pioAddr) >> 6;; Addr daddr = (pkt->getAddr() - pioAddr) >> 6;;
assert(pkt->size == sizeof(uint64_t)); 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) { switch(daddr) {
case TSDEV_PC_WSBA0: case TSDEV_PC_WSBA0:
@ -143,7 +143,7 @@ TsunamiPChip::read(Packet *pkt)
default: default:
panic("Default in PChip Read reached reading 0x%x\n", daddr); panic("Default in PChip Read reached reading 0x%x\n", daddr);
} }
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }
@ -153,13 +153,13 @@ TsunamiPChip::write(Packet *pkt)
{ {
pkt->time += pioDelay; pkt->time += pioDelay;
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
Addr daddr = (pkt->addr - pioAddr) >> 6; 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) { switch(daddr) {
case TSDEV_PC_WSBA0: case TSDEV_PC_WSBA0:
@ -224,7 +224,7 @@ TsunamiPChip::write(Packet *pkt)
} // uint64_t } // uint64_t
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }

View file

@ -110,12 +110,12 @@ Uart8250::Uart8250(Params *p)
Tick Tick
Uart8250::read(Packet *pkt) Uart8250::read(Packet *pkt)
{ {
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
assert(pkt->size == 1); assert(pkt->getSize() == 1);
pkt->time += pioDelay; pkt->time += pioDelay;
Addr daddr = pkt->addr - pioAddr; Addr daddr = pkt->getAddr() - pioAddr;
pkt->allocate(); pkt->allocate();
DPRINTF(Uart, " read register %#x\n", daddr); DPRINTF(Uart, " read register %#x\n", daddr);
@ -186,7 +186,7 @@ Uart8250::read(Packet *pkt)
/* uint32_t d32 = *data; /* uint32_t d32 = *data;
DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32); DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32);
*/ */
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }
@ -194,12 +194,12 @@ Tick
Uart8250::write(Packet *pkt) Uart8250::write(Packet *pkt)
{ {
assert(pkt->result == Unknown); assert(pkt->result == Packet::Unknown);
assert(pkt->addr >= pioAddr && pkt->addr < pioAddr + pioSize); assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
assert(pkt->size == 1); assert(pkt->getSize() == 1);
pkt->time += pioDelay; 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>()); 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"); panic("Tried to access a UART port that doesn't exist\n");
break; break;
} }
pkt->result = Success; pkt->result = Packet::Success;
return pioDelay; return pioDelay;
} }

View file

@ -31,209 +31,209 @@
* @file Definition of a simple bus bridge without buffering. * @file Definition of a simple bus bridge without buffering.
*/ */
#include <algorithm>
#include "base/trace.hh" #include "base/trace.hh"
#include "mem/bridge.hh" #include "mem/bridge.hh"
#include "sim/builder.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 void
Bridge::init() Bridge::init()
{ {
// Make sure that both sides are connected to. // 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"); 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.*/ * transaction.*/
bool bool
Bridge::recvTiming(Packet *pkt, Side id) Bridge::BridgePort::recvTiming(Packet *pkt)
{ {
if (blockedA && id == SideA) DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n",
return false; pkt->getSrc(), pkt->getDest(), pkt->getAddr());
if (blockedB && id == SideB)
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 otherPort->queueForSendTiming(pkt);
}
bool
Bridge::BridgePort::queueForSendTiming(Packet *pkt)
{
if (queueFull())
return false; return false;
if (delay) { Tick readyTime = curTick + delay;
if (!sendEvent.scheduled()) PacketBuffer *buf = new PacketBuffer(pkt, readyTime);
sendEvent.schedule(curTick + delay);
if (id == SideA) { // If we're about to put this packet at the head of the queue, we
inboundA.push_back(std::make_pair<Packet*, Tick>(pkt, curTick)); // need to schedule an event to do the transmit. Otherwise there
blockCheck(SideA); // should already be an event scheduled for sending the head
} else { // packet.
inboundB.push_back(std::make_pair<Packet*, Tick>(pkt, curTick)); if (sendQueue.empty()) {
blockCheck(SideB); sendEvent.schedule(readyTime);
}
} else {
if (id == SideB) {
sideA->sendPkt(pkt);
blockCheck(SideB);
} else {
sideB->sendPkt(pkt);
blockCheck(SideA);
}
} }
sendQueue.push_back(buf);
// Did we just become blocked? If yes, let other side know.
if (queueFull())
otherPort->sendStatusChange(Port::Blocked);
return true; return true;
} }
void void
Bridge::blockCheck(Side id) Bridge::BridgePort::finishSend(PacketBuffer *buf)
{ {
/* Check that we still have buffer space available. */ if (buf->expectResponse) {
if (id == SideB) { // Must wait for response. We just need to count outstanding
if (sideA->numQueued() + inboundB.size() >= queueSizeA && !blockedB) { // responses (in case we want to cap them); PacketBuffer
sideB->sendStatusChange(Port::Blocked); // pointer will be recovered on response.
blockedB = true; ++outstandingResponses;
} else if (sideA->numQueued() + inboundB.size() < queueSizeA && blockedB) { DPRINTF(BusBridge, " successful: awaiting response (%d)\n",
sideB->sendStatusChange(Port::Unblocked); outstandingResponses);
blockedB = false;
}
} else { } else {
if (sideB->numQueued() + inboundA.size() >= queueSizeB && !blockedA) { // no response expected... deallocate packet buffer now.
sideA->sendStatusChange(Port::Blocked); DPRINTF(BusBridge, " successful: no response expected\n");
blockedA = true; delete buf;
} else if (sideB->numQueued() + inboundA.size() < queueSizeB && blockedA) {
sideA->sendStatusChange(Port::Unblocked);
blockedA = false;
} }
// 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::timerEvent()
void
Bridge::BridgePort::trySend()
{ {
Tick t = 0; assert(!sendQueue.empty());
assert(inboundA.size() || inboundB.size()); PacketBuffer *buf = sendQueue.front();
if (inboundA.size()) {
while (inboundA.front().second <= curTick + delay){ assert(buf->ready <= curTick);
sideB->sendPkt(inboundA.front());
inboundA.pop_front(); Packet *pkt = buf->pkt;
}
if (inboundA.size()) DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
t = inboundA.front().second + delay; buf->origSrc, pkt->getDest(), pkt->getAddr());
}
if (inboundB.size()) { if (sendTiming(pkt)) {
while (inboundB.front().second <= curTick + delay){ // send successful
sideB->sendPkt(inboundA.front()); sendQueue.pop_front();
inboundB.pop_front(); buf->pkt = NULL; // we no longer own packet, so it's not safe to look at it
} finishSend(buf);
if (inboundB.size())
if (t == 0)
t = inboundB.front().second + delay;
else
t = std::min(t,inboundB.front().second + delay);
} else { } else {
panic("timerEvent() called but nothing to do?"); DPRINTF(BusBridge, " unsuccessful\n");
} }
if (t != 0)
sendEvent.schedule(t);
}
void
Bridge::BridgePort::sendPkt(Packet *pkt)
{
if (!sendTiming(pkt))
outbound.push_back(std::make_pair<Packet*,Tick>(pkt, curTick));
}
void
Bridge::BridgePort::sendPkt(std::pair<Packet*, Tick> p)
{
if (!sendTiming(p.first))
outbound.push_back(p);
} }
Packet * Packet *
Bridge::BridgePort::recvRetry() Bridge::BridgePort::recvRetry()
{ {
Packet *pkt; PacketBuffer *buf = sendQueue.front();
assert(outbound.size() > 0); Packet *pkt = buf->pkt;
assert(outbound.front().second >= curTick + bridge->delay); finishSend(buf);
pkt = outbound.front().first;
outbound.pop_front();
bridge->blockCheck(side);
return pkt; 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.*/ * transaction.*/
Tick Tick
Bridge::recvAtomic(Packet *pkt, Side id) Bridge::BridgePort::recvAtomic(Packet *pkt)
{ {
pkt->time += delay; return otherPort->sendAtomic(pkt) + delay;
if (id == SideA)
return sideB->sendAtomic(pkt);
else
return sideA->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.*/ * transaction.*/
void void
Bridge::recvFunctional(Packet *pkt, Side id) Bridge::BridgePort::recvFunctional(Packet *pkt)
{ {
pkt->time += delay; std::list<PacketBuffer*>::iterator i;
std::list<std::pair<Packet*, Tick> >::iterator i;
bool pktContinue = true; bool pktContinue = true;
for(i = inboundA.begin(); i != inboundA.end(); ++i) { for (i = sendQueue.begin(); i != sendQueue.end(); ++i) {
if (pkt->intersect(i->first)) { if (pkt->intersect((*i)->pkt)) {
pktContinue &= fixPacket(pkt, i->first); pktContinue &= fixPacket(pkt, (*i)->pkt);
}
}
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);
} }
} }
if (pktContinue) { if (pktContinue) {
if (id == SideA) otherPort->sendFunctional(pkt);
sideB->sendFunctional(pkt);
else
sideA->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 void
Bridge::recvStatusChange(Port::Status status, Side id) Bridge::BridgePort::recvStatusChange(Port::Status status)
{ {
if (status == Port::Blocked || status == Port::Unblocked) if (status == Port::Blocked || status == Port::Unblocked)
return; return;
if (id == SideA) otherPort->sendStatusChange(status);
sideB->sendStatusChange(status);
else
sideA->sendStatusChange(status);
} }
void void
Bridge::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, Side id) Bridge::BridgePort::getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
{ {
if (id == SideA) otherPort->getPeerAddressRanges(resp, snoop);
sideB->getPeerAddressRanges(resp, snoop);
else
sideA->getPeerAddressRanges(resp, snoop);
} }
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bridge) BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bridge)

View file

@ -46,132 +46,127 @@
class Bridge : public MemObject class Bridge : public MemObject
{ {
public:
enum Side
{
SideA,
SideB
};
protected: protected:
/** Function called by the port when the bus is recieving a Timing
transaction.*/
bool recvTiming(Packet *pkt, Side id);
/** Function called by the port when the bus is recieving a Atomic
transaction.*/
Tick recvAtomic(Packet *pkt, Side id);
/** Function called by the port when the bus is recieving a Functional
transaction.*/
void recvFunctional(Packet *pkt, Side id);
/** Function called by the port when the bus is recieving a status change.*/
void recvStatusChange(Port::Status status, Side id);
/** 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);
/** Event that the SendEvent calls when it fires. This code must reschedule
* the send event as required. */
void timerEvent();
/** Decleration of the buses port type, one will be instantiated for each /** Decleration of the buses port type, one will be instantiated for each
of the interfaces connecting to the bus. */ of the interfaces connecting to the bus. */
class BridgePort : public Port class BridgePort : public Port
{ {
/** A pointer to the bus to which this port belongs. */ /** A pointer to the bridge to which this port belongs. */
Bridge *bridge; Bridge *bridge;
/** A id to keep track of the intercafe ID this port is connected to. */ /**
Bridge::Side side; * Pointer to the port on the other side of the bridge
* (connected to the other bus).
*/
BridgePort *otherPort;
/** Minimum delay though this bridge. */
Tick delay;
class PacketBuffer : public Packet::SenderState {
public: public:
Tick ready;
Packet *pkt;
Packet::SenderState *origSenderState;
short origSrc;
bool expectResponse;
/** Constructor for the BusPort.*/ PacketBuffer(Packet *_pkt, Tick t)
BridgePort(Bridge *_bridge, Side _side) : ready(t), pkt(_pkt),
: bridge(_bridge), side(_side) origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
{ } expectResponse(_pkt->needsResponse())
{
pkt->senderState = this;
}
int numQueued() { return outbound.size(); } void fixResponse(Packet *pkt)
{
protected: assert(pkt->senderState == this);
/** Data this is waiting to be transmitted. */ pkt->setDest(origSrc);
std::list<std::pair<Packet*, Tick> > outbound; pkt->senderState = origSenderState;
}
void sendPkt(Packet *pkt);
void sendPkt(std::pair<Packet*, Tick> p);
/** When reciving a timing request from the peer port,
pass it to the bridge. */
virtual bool recvTiming(Packet *pkt)
{ return bridge->recvTiming(pkt, side); }
/** When reciving a retry request from the peer port,
pass it to the bridge. */
virtual Packet* recvRetry();
/** When reciving a Atomic requestfrom the peer port,
pass it to the bridge. */
virtual Tick recvAtomic(Packet *pkt)
{ return bridge->recvAtomic(pkt, side); }
/** When reciving a Functional request from the peer port,
pass it to the bridge. */
virtual void recvFunctional(Packet *pkt)
{ bridge->recvFunctional(pkt, side); }
/** When reciving a status changefrom the peer port,
pass it to the bridge. */
virtual void recvStatusChange(Status status)
{ bridge->recvStatusChange(status, side); }
/** When reciving 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;
}; };
/**
* 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;
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 class SendEvent : public Event
{ {
Bridge *bridge; BridgePort *port;
SendEvent(Bridge *b) public:
: Event(&mainEventQueue), bridge(b) {} SendEvent(BridgePort *p)
: Event(&mainEventQueue), port(p) {}
virtual void process() { bridge->timerEvent(); } virtual void process() { port->trySend(); }
virtual const char *description() { return "bridge delay event"; } virtual const char *description() { return "bridge send event"; }
friend class Bridge;
}; };
SendEvent sendEvent; SendEvent sendEvent;
/** Sides of the bus bridges. */ public:
BridgePort* sideA;
BridgePort* sideB;
/** inbound queues on both sides. */ /** Constructor for the BusPort.*/
std::list<std::pair<Packet*, Tick> > inboundA; BridgePort(const std::string &_name,
std::list<std::pair<Packet*, Tick> > inboundB; Bridge *_bridge, BridgePort *_otherPort,
int _delay, int _queueLimit);
/** The size of the queue for data coming into side a */ protected:
int queueSizeA;
int queueSizeB;
/* if the side is blocked or not. */ /** When receiving a timing request from the peer port,
bool blockedA; pass it to the bridge. */
bool blockedB; virtual bool recvTiming(Packet *pkt);
/** Miminum delay though this bridge. */ /** When receiving a retry request from the peer port,
Tick delay; pass it to the bridge. */
virtual Packet* recvRetry();
/** When receiving a Atomic requestfrom the peer port,
pass it to the bridge. */
virtual Tick recvAtomic(Packet *pkt);
/** When receiving a Functional request from the peer port,
pass it to the bridge. */
virtual void recvFunctional(Packet *pkt);
/** When receiving a status changefrom the peer port,
pass it to the bridge. */
virtual void recvStatusChange(Status status);
/** When receiving a address range request the peer port,
pass it to the bridge. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop);
};
BridgePort portA, portB;
/** If this bridge should acknowledge writes. */ /** If this bridge should acknowledge writes. */
bool ackWrites; bool ackWrites;
@ -179,36 +174,11 @@ class Bridge : public MemObject
public: public:
/** A function used to return the port associated with this bus object. */ /** A function used to return the port associated with this bus object. */
virtual Port *getPort(const std::string &if_name) 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 void init(); virtual void init();
Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack) 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;
}; };
#endif //__MEM_BUS_HH__ #endif //__MEM_BUS_HH__

View file

@ -35,6 +35,16 @@
#include "mem/bus.hh" #include "mem/bus.hh"
#include "sim/builder.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. */ /** Get the ranges of anyone that we are connected to. */
void void
Bus::init() 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.*/ * transaction.*/
bool bool
Bus::recvTiming(Packet *pkt) Bus::recvTiming(Packet *pkt)
{ {
Port *port; Port *port;
if (pkt->dest == Packet::Broadcast) { DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
port = findPort(pkt->addr, pkt->src); pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
short dest = pkt->getDest();
if (dest == Packet::Broadcast) {
port = findPort(pkt->getAddr(), pkt->getSrc());
} else { } else {
assert(pkt->dest > 0 && pkt->dest < interfaces.size()); assert(dest >= 0 && dest < interfaces.size());
port = interfaces[pkt->dest]; assert(dest != pkt->getSrc()); // catch infinite loops
port = interfaces[dest];
} }
return port->sendTiming(pkt); return port->sendTiming(pkt);
} }
@ -73,7 +88,7 @@ Bus::findPort(Addr addr, int id)
if (portList[i].range == addr) { if (portList[i].range == addr) {
dest_id = portList[i].portId; dest_id = portList[i].portId;
found = true; 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++; i++;
} }
@ -86,33 +101,37 @@ Bus::findPort(Addr addr, int id)
return interfaces[dest_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.*/ * transaction.*/
Tick Tick
Bus::recvAtomic(Packet *pkt) Bus::recvAtomic(Packet *pkt)
{ {
assert(pkt->dest == Packet::Broadcast); DPRINTF(Bus, "recvAtomic: packet src %d dest %d addr 0x%x cmd %s\n",
return findPort(pkt->addr, pkt->src)->sendAtomic(pkt); 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.*/ * transaction.*/
void void
Bus::recvFunctional(Packet *pkt) Bus::recvFunctional(Packet *pkt)
{ {
assert(pkt->dest == Packet::Broadcast); DPRINTF(Bus, "recvFunctional: packet src %d dest %d addr 0x%x cmd %s\n",
findPort(pkt->addr, pkt->src)->sendFunctional(pkt); 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 void
Bus::recvStatusChange(Port::Status status, int id) 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 && assert(status == Port::RangeChange &&
"The other statuses need to be implemented."); "The other statuses need to be implemented.");
DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id);
assert(id < interfaces.size() && id >= 0); assert(id < interfaces.size() && id >= 0);
int x; int x;
Port *port = interfaces[id]; Port *port = interfaces[id];
@ -138,8 +157,8 @@ Bus::recvStatusChange(Port::Status status, int id)
dm.portId = id; dm.portId = id;
dm.range = *iter; dm.range = *iter;
DPRINTF(MMU, "Adding range %llx - %llx for id %d\n", dm.range.start, DPRINTF(BusAddrRanges, "Adding range %llx - %llx for id %d\n",
dm.range.end, id); dm.range.start, dm.range.end, id);
portList.push_back(dm); portList.push_back(dm);
} }
DPRINTF(MMU, "port list has %d entries\n", portList.size()); DPRINTF(MMU, "port list has %d entries\n", portList.size());
@ -159,13 +178,12 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id)
resp.clear(); resp.clear();
snoop.clear(); snoop.clear();
DPRINTF(Bus, "Bus id %d recieved address range request returning\n", DPRINTF(BusAddrRanges, "received address range request, returning:\n");
busId);
for (portIter = portList.begin(); portIter != portList.end(); portIter++) { for (portIter = portList.begin(); portIter != portList.end(); portIter++) {
if (portIter->portId != id) { if (portIter->portId != id) {
resp.push_back(portIter->range); resp.push_back(portIter->range);
DPRINTF(Bus, "-- %#llX : %#llX\n", portIter->range.start, DPRINTF(BusAddrRanges, " -- %#llX : %#llX\n",
portIter->range.end); portIter->range.start, portIter->range.end);
} }
} }
} }

View file

@ -100,8 +100,8 @@ class Bus : public MemObject
public: public:
/** Constructor for the BusPort.*/ /** Constructor for the BusPort.*/
BusPort(Bus *_bus, int _id) BusPort(const std::string &_name, Bus *_bus, int _id)
: bus(_bus), id(_id) : Port(_name), bus(_bus), id(_id)
{ } { }
protected: protected:
@ -109,17 +109,17 @@ class Bus : public MemObject
/** When reciving a timing request from the peer port (at id), /** When reciving a timing request from the peer port (at id),
pass it to the bus. */ pass it to the bus. */
virtual bool recvTiming(Packet *pkt) 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), /** When reciving a Atomic requestfrom the peer port (at id),
pass it to the bus. */ pass it to the bus. */
virtual Tick recvAtomic(Packet *pkt) 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), /** When reciving a Functional requestfrom the peer port (at id),
pass it to the bus. */ pass it to the bus. */
virtual void recvFunctional(Packet *pkt) 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), /** When reciving a status changefrom the peer port (at id),
pass it to the bus. */ pass it to the bus. */
@ -146,13 +146,7 @@ class Bus : public MemObject
public: public:
/** A function used to return the port associated with this bus object. */ /** A function used to return the port associated with this bus object. */
virtual Port *getPort(const std::string &if_name) 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 void init(); virtual void init();

View file

@ -34,11 +34,31 @@
#include "base/misc.hh" #include "base/misc.hh"
#include "mem/packet.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 /** delete the data pointed to in the data pointer. Ok to call to matter how
* data was allocted. */ * data was allocted. */
void void
Packet::deleteData() { Packet::deleteData()
{
assert(staticData || dynamicData); assert(staticData || dynamicData);
if (staticData) if (staticData)
return; return;
@ -51,22 +71,24 @@ Packet::deleteData() {
/** If there isn't data in the packet, allocate some. */ /** If there isn't data in the packet, allocate some. */
void void
Packet::allocate() { Packet::allocate()
{
if (data) if (data)
return; return;
assert(!staticData); assert(!staticData);
dynamicData = true; dynamicData = true;
arrayData = true; arrayData = true;
data = new uint8_t[size]; data = new uint8_t[getSize()];
} }
/** Do the packet modify the same addresses. */ /** Do the packet modify the same addresses. */
bool bool
Packet::intersect(Packet *p) { Packet::intersect(Packet *p)
Addr s1 = addr; {
Addr e1 = addr + size; Addr s1 = getAddr();
Addr s2 = p->addr; Addr e1 = getAddr() + getSize();
Addr e2 = p->addr + p->size; Addr s2 = p->getAddr();
Addr e2 = p->getAddr() + p->getSize();
if (s1 >= s2 && s1 < e2) if (s1 >= s2 && s1 < e2)
return true; return true;
@ -77,7 +99,8 @@ Packet::intersect(Packet *p) {
/** Minimally reset a packet so something like simple cpu can reuse it. */ /** Minimally reset a packet so something like simple cpu can reuse it. */
void void
Packet::reset() { Packet::reset()
{
result = Unknown; result = Unknown;
if (dynamicData) { if (dynamicData) {
deleteData(); deleteData();
@ -88,7 +111,8 @@ Packet::reset() {
} }
bool
fixPacket(Packet *func, Packet *timing)
bool fixPacket(Packet *func, Packet *timing) {
{ panic("Need to implement!"); } panic("Need to implement!");
}

View file

@ -43,24 +43,6 @@ struct Packet;
typedef Packet* PacketPtr; typedef Packet* PacketPtr;
typedef uint8_t* PacketDataPtr; 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 * A Packet is the structure to handle requests between two levels
* of the memory system. The Request is a global object that trancends * 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 * 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. * the transaction has no response, then the consumer will delete the packet.
*/ */
struct Packet class Packet
{ {
private: private:
/** A pointer to the data being transfered. It can be differnt sizes /** A pointer to the data being transfered. It can be differnt sizes
@ -95,57 +77,132 @@ struct Packet
bool arrayData; bool arrayData;
public:
/** The address of the request, could be virtual or physical (depending on /** The address of the request, could be virtual or physical (depending on
cache configurations). */ cache configurations). */
Addr addr; Addr addr;
/** Flag structure to hold flags for this particular packet */
uint64_t flags;
/** A pointer to the overall request. */
RequestPtr req;
/** A virtual base opaque structure used to hold
coherence status messages. */
Coherence *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. */ /** Indicates the size of the request. */
int size; int size;
/** A index of the source of the transaction. */ /** A index of the source of the transaction. */
short src; short src;
static const short Broadcast = -1;
/** A index to the destination of the transaction. */ /** A index to the destination of the transaction. */
short dest; 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. */
CoherenceState *coherence; // virtual base opaque,
// assert(dynamic_cast<Foo>) etc.
class SenderState {
public:
virtual ~SenderState() {}
};
/** A virtual base opaque structure used to hold the senders state. */
SenderState *senderState; // virtual base opaque,
// assert(dynamic_cast<Foo>) etc.
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,
};
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. */ /** The command of the transaction. */
Command cmd; 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. */ /** The time this request was responded to. Used to calculate latencies. */
Tick time; Tick time;
/** The result of a particular packets request. */
enum Result
{
Success,
BadAddress,
Unknown
};
/** The result of the packet transaction. */ /** The result of the packet transaction. */
PacketResult result; Result result;
/** Accessor function that returns the source index of the packet. */ /** 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 /** Accessor function that returns the destination index of
the packet. */ the packet. */
short getDest() const { return dest; } short getDest() const { return dest; }
void setDest(short _dest) { dest = _dest; }
Packet() 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(Request *_req, Command _cmd, short _dest)
: data(NULL), staticData(false), dynamicData(false), arrayData(false), : 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) time(curTick), result(Unknown)
{} {
}
~Packet() ~Packet()
{ deleteData(); } { deleteData(); }
@ -154,6 +211,11 @@ struct Packet
/** Minimally reset a packet so something like simple cpu can reuse it. */ /** Minimally reset a packet so something like simple cpu can reuse it. */
void reset(); 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. */ /** Set the data pointer to the following value that should not be freed. */
template <typename T> template <typename T>
void dataStatic(T *p); void dataStatic(T *p);

View file

@ -127,7 +127,8 @@ PhysicalMemory::doTimingAccess (Packet *pkt, MemoryPort* memoryPort)
{ {
doFunctionalAccess(pkt); doFunctionalAccess(pkt);
pkt->dest = pkt->src; // turn packet around to go back to requester
pkt->makeTimingResponse();
MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort); MemResponseEvent* response = new MemResponseEvent(pkt, memoryPort);
response->schedule(curTick + lat); response->schedule(curTick + lat);
@ -145,16 +146,18 @@ PhysicalMemory::doAtomicAccess(Packet *pkt)
void void
PhysicalMemory::doFunctionalAccess(Packet *pkt) PhysicalMemory::doFunctionalAccess(Packet *pkt)
{ {
assert(pkt->addr + pkt->size < pmem_size); assert(pkt->getAddr() + pkt->getSize() < pmem_size);
switch (pkt->cmd) { switch (pkt->cmd) {
case Read: case Packet::ReadReq:
memcpy(pkt->getPtr<uint8_t>(), pmem_addr + pkt->addr - base_addr, memcpy(pkt->getPtr<uint8_t>(),
pkt->size); pmem_addr + pkt->getAddr() - base_addr,
pkt->getSize());
break; break;
case Write: case Packet::WriteReq:
memcpy(pmem_addr + pkt->addr - base_addr, pkt->getPtr<uint8_t>(), memcpy(pmem_addr + pkt->getAddr() - base_addr,
pkt->size); pkt->getPtr<uint8_t>(),
pkt->getSize());
// temporary hack: will need to add real LL/SC implementation // temporary hack: will need to add real LL/SC implementation
// for cacheless systems later. // for cacheless systems later.
if (pkt->req->getFlags() & LOCKED) { if (pkt->req->getFlags() & LOCKED) {
@ -165,7 +168,7 @@ PhysicalMemory::doFunctionalAccess(Packet *pkt)
panic("unimplemented"); panic("unimplemented");
} }
pkt->result = Success; pkt->result = Packet::Success;
} }
Port * Port *
@ -174,11 +177,11 @@ PhysicalMemory::getPort(const std::string &if_name)
if (if_name == "") { if (if_name == "") {
if (port != NULL) if (port != NULL)
panic("PhysicalMemory::getPort: additional port requested to memory!"); panic("PhysicalMemory::getPort: additional port requested to memory!");
port = new MemoryPort(this); port = new MemoryPort(name() + "-port", this);
return port; return port;
} else if (if_name == "functional") { } else if (if_name == "functional") {
/* special port for functional writes at startup. */ /* special port for functional writes at startup. */
return new MemoryPort(this); return new MemoryPort(name() + "-funcport", this);
} else { } else {
panic("PhysicalMemory::getPort: unknown port %s requested", if_name); panic("PhysicalMemory::getPort: unknown port %s requested", if_name);
} }
@ -189,8 +192,9 @@ PhysicalMemory::recvStatusChange(Port::Status status)
{ {
} }
PhysicalMemory::MemoryPort::MemoryPort(PhysicalMemory *_memory) PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name,
: memory(_memory) PhysicalMemory *_memory)
: Port(_name), memory(_memory)
{ } { }
void void

View file

@ -51,7 +51,7 @@ class PhysicalMemory : public MemObject
public: public:
MemoryPort(PhysicalMemory *_memory); MemoryPort(const std::string &_name, PhysicalMemory *_memory);
protected: protected:

View file

@ -31,22 +31,28 @@
*/ */
#include "base/chunk_generator.hh" #include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "mem/packet_impl.hh" #include "mem/packet_impl.hh"
#include "mem/port.hh" #include "mem/port.hh"
void 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); Request req(false);
Packet pkt; Packet pkt(&req, cmd, Packet::Broadcast);
pkt.req = &req;
pkt.cmd = cmd;
pkt.dest = Packet::Broadcast;
for (ChunkGenerator gen(addr, size, peerBlockSize()); for (ChunkGenerator gen(addr, size, peerBlockSize());
!gen.done(); gen.next()) { !gen.done(); gen.next()) {
req.setPaddr(pkt.addr = gen.addr()); req.setPaddr(gen.addr());
req.setSize(pkt.size = gen.size()); req.setSize(gen.size());
pkt.reinitFromRequest();
pkt.dataStatic(p); pkt.dataStatic(p);
sendFunctional(&pkt); sendFunctional(&pkt);
p += gen.size(); p += gen.size();
@ -56,13 +62,13 @@ Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd)
void void
Port::writeBlob(Addr addr, uint8_t *p, int size) Port::writeBlob(Addr addr, uint8_t *p, int size)
{ {
blobHelper(addr, p, size, Write); blobHelper(addr, p, size, Packet::WriteReq);
} }
void void
Port::readBlob(Addr addr, uint8_t *p, int size) Port::readBlob(Addr addr, uint8_t *p, int size)
{ {
blobHelper(addr, p, size, Read); blobHelper(addr, p, size, Packet::ReadReq);
} }
void void
@ -72,7 +78,7 @@ Port::memsetBlob(Addr addr, uint8_t val, int size)
uint8_t *buf = new uint8_t[size]; uint8_t *buf = new uint8_t[size];
memset(buf, val, size); memset(buf, val, size);
blobHelper(addr, buf, size, Write); blobHelper(addr, buf, size, Packet::WriteReq);
delete [] buf; delete [] buf;
} }

View file

@ -69,9 +69,28 @@ typedef std::list<Range<Addr> >::iterator AddrRangeIter;
*/ */
class Port class Port
{ {
private:
/** Descriptive name (for DPRINTF output) */
const std::string portName;
public: 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() {}; virtual ~Port() {};
// mey be better to use subclasses & RTTI? // mey be better to use subclasses & RTTI?
/** Holds the ports status. Keeps track if it is blocked, or has /** Holds the ports status. Keeps track if it is blocked, or has
calculated a range change. */ calculated a range change. */
@ -93,7 +112,7 @@ class 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). @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). @todo should be called by the configuration stuff (python).
@ -213,7 +232,7 @@ class Port
/** Internal helper function for read/writeBlob(). /** 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 /** A simple functional port that is only meant for one way communication to
@ -224,6 +243,10 @@ class Port
class FunctionalPort : public Port class FunctionalPort : public Port
{ {
public: public:
FunctionalPort(const std::string &_name)
: Port(_name)
{}
virtual bool recvTiming(Packet *pkt) { panic("FuncPort is UniDir"); } virtual bool recvTiming(Packet *pkt) { panic("FuncPort is UniDir"); }
virtual Tick recvAtomic(Packet *pkt) { panic("FuncPort is UniDir"); } virtual Tick recvAtomic(Packet *pkt) { panic("FuncPort is UniDir"); }
virtual void recvFunctional(Packet *pkt) { panic("FuncPort is UniDir"); } virtual void recvFunctional(Packet *pkt) { panic("FuncPort is UniDir"); }

View file

@ -195,6 +195,7 @@ class Request
/** Accesor function for pc.*/ /** Accesor function for pc.*/
void setPC(Addr _pc); void setPC(Addr _pc);
friend class Packet;
}; };
#endif // __MEM_REQUEST_HH__ #endif // __MEM_REQUEST_HH__

View file

@ -34,8 +34,9 @@
using namespace TheISA; using namespace TheISA;
TranslatingPort::TranslatingPort(PageTable *p_table, bool alloc) TranslatingPort::TranslatingPort(const std::string &_name,
: pTable(p_table), allocating(alloc) PageTable *p_table, bool alloc)
: FunctionalPort(_name), pTable(p_table), allocating(alloc)
{ } { }
TranslatingPort::~TranslatingPort() TranslatingPort::~TranslatingPort()

View file

@ -39,14 +39,11 @@ class TranslatingPort : public FunctionalPort
PageTable *pTable; PageTable *pTable;
bool allocating; bool allocating;
TranslatingPort(const TranslatingPort &specmem);
const TranslatingPort &operator=(const TranslatingPort &specmem);
public: public:
TranslatingPort(PageTable *p_table, bool alloc = false); TranslatingPort(const std::string &_name,
PageTable *p_table, bool alloc = false);
virtual ~TranslatingPort(); virtual ~TranslatingPort();
public:
bool tryReadBlob(Addr addr, uint8_t *p, int size); bool tryReadBlob(Addr addr, uint8_t *p, int size);
bool tryWriteBlob(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); 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 readBlob(Addr addr, uint8_t *p, int size);
virtual void writeBlob(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); virtual void memsetBlob(Addr addr, uint8_t val, int size);
void writeString(Addr addr, const char *str); void writeString(Addr addr, const char *str);
void readString(std::string &str, Addr addr); void readString(std::string &str, Addr addr);
}; };
#endif #endif

View file

@ -53,8 +53,8 @@ class VirtualPort : public FunctionalPort
ExecContext *xc; ExecContext *xc;
public: public:
VirtualPort(ExecContext *_xc = NULL) VirtualPort(const std::string &_name, ExecContext *_xc = NULL)
: xc(_xc) : FunctionalPort(_name), xc(_xc)
{} {}
/** Return true if we have an exec context. This is used to prevent someone /** Return true if we have an exec context. This is used to prevent someone

View file

@ -154,7 +154,7 @@ Process::startup()
Port *mem_port; Port *mem_port;
mem_port = system->physmem->getPort("functional"); mem_port = system->physmem->getPort("functional");
initVirtMem = new TranslatingPort(pTable, true); initVirtMem = new TranslatingPort("process init port", pTable, true);
mem_port->setPeer(initVirtMem); mem_port->setPeer(initVirtMem);
initVirtMem->setPeer(mem_port); initVirtMem->setPeer(mem_port);
} }

View file

@ -25,6 +25,8 @@ System::System(Params *p)
: SimObject(p->name), physmem(p->physmem), numcpus(0), : SimObject(p->name), physmem(p->physmem), numcpus(0),
#if FULL_SYSTEM #if FULL_SYSTEM
init_param(p->init_param), init_param(p->init_param),
functionalPort(p->name + "-fport"),
virtPort(p->name + "-vport"),
#else #else
page_ptr(0), page_ptr(0),
#endif #endif