summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2012-01-28 07:24:01 -0800
committerGabe Black <gblack@eecs.umich.edu>2012-01-28 07:24:01 -0800
commitc3d41a2def15cdaf2ac3984315f452dacc6a0884 (patch)
tree5324ebec3add54b934a841eee901983ac3463a7f /src
parentda2a4acc26ba264c3c4a12495776fd6a1c4fb133 (diff)
parent4acca8a0536d4445ed25b67edf571ae460446ab9 (diff)
downloadgem5-c3d41a2def15cdaf2ac3984315f452dacc6a0884.tar.xz
Merge with the main repo.
--HG-- rename : src/mem/vport.hh => src/mem/fs_translating_port_proxy.hh rename : src/mem/translating_port.cc => src/mem/se_translating_port_proxy.cc rename : src/mem/translating_port.hh => src/mem/se_translating_port_proxy.hh
Diffstat (limited to 'src')
-rw-r--r--src/arch/alpha/freebsd/system.cc8
-rw-r--r--src/arch/alpha/linux/process.cc6
-rw-r--r--src/arch/alpha/linux/system.cc26
-rw-r--r--src/arch/alpha/linux/system.hh7
-rw-r--r--src/arch/alpha/linux/threadinfo.hh2
-rw-r--r--src/arch/alpha/remote_gdb.cc10
-rw-r--r--src/arch/alpha/remote_gdb.hh2
-rw-r--r--src/arch/alpha/stacktrace.cc12
-rw-r--r--src/arch/alpha/system.cc50
-rw-r--r--src/arch/alpha/system.hh6
-rw-r--r--src/arch/alpha/tru64/process.cc18
-rw-r--r--src/arch/alpha/tru64/system.cc6
-rw-r--r--src/arch/alpha/utility.cc4
-rw-r--r--src/arch/alpha/vtophys.cc6
-rw-r--r--src/arch/alpha/vtophys.hh4
-rw-r--r--src/arch/arm/linux/process.cc12
-rw-r--r--src/arch/arm/linux/system.cc40
-rw-r--r--src/arch/arm/process.cc1
-rw-r--r--src/arch/arm/stacktrace.cc6
-rw-r--r--src/arch/arm/system.cc34
-rw-r--r--src/arch/arm/system.hh5
-rw-r--r--src/arch/arm/utility.cc4
-rw-r--r--src/arch/arm/vtophys.cc4
-rw-r--r--src/arch/mips/linux/process.cc6
-rw-r--r--src/arch/mips/linux/system.cc81
-rw-r--r--src/arch/mips/linux/threadinfo.hh2
-rw-r--r--src/arch/mips/stacktrace.cc10
-rwxr-xr-xsrc/arch/mips/system.cc62
-rw-r--r--src/arch/mips/utility.cc7
-rwxr-xr-xsrc/arch/mips/vtophys.cc1
-rw-r--r--src/arch/power/linux/process.cc2
-rw-r--r--src/arch/power/process.cc1
-rw-r--r--src/arch/sparc/linux/syscalls.cc8
-rw-r--r--src/arch/sparc/process.cc5
-rw-r--r--src/arch/sparc/solaris/process.cc2
-rw-r--r--src/arch/sparc/system.cc39
-rw-r--r--src/arch/sparc/system.hh14
-rw-r--r--src/arch/sparc/utility.cc4
-rw-r--r--src/arch/sparc/vtophys.cc4
-rw-r--r--src/arch/x86/bios/intelmp.cc156
-rw-r--r--src/arch/x86/bios/intelmp.hh24
-rw-r--r--src/arch/x86/bios/smbios.cc78
-rw-r--r--src/arch/x86/bios/smbios.hh10
-rw-r--r--src/arch/x86/interrupts.cc22
-rw-r--r--src/arch/x86/interrupts.hh4
-rw-r--r--src/arch/x86/linux/syscalls.cc12
-rw-r--r--src/arch/x86/linux/system.cc12
-rw-r--r--src/arch/x86/pagetable_walker.cc11
-rw-r--r--src/arch/x86/pagetable_walker.hh14
-rw-r--r--src/arch/x86/process.cc1
-rw-r--r--src/arch/x86/stacktrace.cc14
-rw-r--r--src/arch/x86/system.cc43
-rw-r--r--src/base/debug.cc2
-rw-r--r--src/base/loader/elf_object.cc6
-rw-r--r--src/base/loader/elf_object.hh2
-rwxr-xr-xsrc/base/loader/hex_file.cc6
-rwxr-xr-xsrc/base/loader/hex_file.hh4
-rw-r--r--src/base/loader/object_file.cc16
-rw-r--r--src/base/loader/object_file.hh6
-rw-r--r--src/base/remote_gdb.cc12
-rw-r--r--src/base/remote_gdb.hh2
-rw-r--r--src/cpu/BaseCPU.py7
-rw-r--r--src/cpu/base.cc45
-rw-r--r--src/cpu/base.hh48
-rw-r--r--src/cpu/checker/thread_context.hh8
-rw-r--r--src/cpu/inorder/InOrderCPU.py3
-rw-r--r--src/cpu/inorder/cpu.cc14
-rw-r--r--src/cpu/inorder/cpu.hh4
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc23
-rw-r--r--src/cpu/inorder/resources/cache_unit.hh15
-rw-r--r--src/cpu/inorder/thread_context.cc6
-rw-r--r--src/cpu/inorder/thread_context.hh15
-rw-r--r--src/cpu/o3/O3CPU.py3
-rw-r--r--src/cpu/o3/cpu.cc78
-rw-r--r--src/cpu/o3/cpu.hh89
-rw-r--r--src/cpu/o3/fetch.hh56
-rw-r--r--src/cpu/o3/fetch_impl.hh87
-rw-r--r--src/cpu/o3/iew.hh3
-rw-r--r--src/cpu/o3/lsq.hh81
-rw-r--r--src/cpu/o3/lsq_impl.hh140
-rwxr-xr-xsrc/cpu/o3/thread_context.hh13
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh6
-rw-r--r--src/cpu/ozone/cpu.hh8
-rw-r--r--src/cpu/ozone/cpu_impl.hh20
-rw-r--r--src/cpu/ozone/front_end.hh9
-rw-r--r--src/cpu/ozone/front_end_impl.hh6
-rw-r--r--src/cpu/ozone/lw_lsq.hh10
-rw-r--r--src/cpu/ozone/lw_lsq_impl.hh6
-rw-r--r--src/cpu/simple/AtomicSimpleCPU.py4
-rw-r--r--src/cpu/simple/TimingSimpleCPU.py3
-rw-r--r--src/cpu/simple/atomic.cc65
-rw-r--r--src/cpu/simple/atomic.hh46
-rw-r--r--src/cpu/simple/timing.cc53
-rw-r--r--src/cpu/simple/timing.hh45
-rw-r--r--src/cpu/simple_thread.cc7
-rw-r--r--src/cpu/simple_thread.hh5
-rw-r--r--src/cpu/testers/memtest/memtest.cc14
-rw-r--r--src/cpu/testers/memtest/memtest.hh10
-rw-r--r--src/cpu/testers/networktest/networktest.cc13
-rw-r--r--src/cpu/testers/networktest/networktest.hh10
-rw-r--r--src/cpu/thread_context.hh32
-rw-r--r--src/cpu/thread_state.cc97
-rw-r--r--src/cpu/thread_state.hh47
-rw-r--r--src/dev/Device.py2
-rw-r--r--src/dev/Pci.py2
-rw-r--r--src/dev/arm/RealView.py42
-rw-r--r--src/dev/arm/gic.cc11
-rw-r--r--src/dev/arm/gic.hh2
-rw-r--r--src/dev/arm/pl111.cc9
-rw-r--r--src/dev/arm/pl111.hh8
-rw-r--r--src/dev/copy_engine.hh1
-rw-r--r--src/dev/io_device.cc34
-rw-r--r--src/dev/io_device.hh45
-rw-r--r--src/dev/ns_gige.cc20
-rw-r--r--src/dev/pciconfigall.cc9
-rw-r--r--src/dev/pciconfigall.hh2
-rw-r--r--src/dev/pcidev.cc29
-rw-r--r--src/dev/pcidev.hh11
-rw-r--r--src/dev/simple_disk.cc4
-rw-r--r--src/dev/sinic.cc2
-rw-r--r--src/dev/sparc/iob.cc11
-rw-r--r--src/dev/sparc/iob.hh2
-rw-r--r--src/dev/uart8250.cc12
-rw-r--r--src/dev/uart8250.hh2
-rw-r--r--src/dev/x86/SouthBridge.py2
-rw-r--r--src/dev/x86/i8042.cc11
-rw-r--r--src/dev/x86/i8042.hh2
-rw-r--r--src/dev/x86/i82094aa.hh20
-rw-r--r--src/dev/x86/intdev.cc2
-rw-r--r--src/dev/x86/intdev.hh9
-rw-r--r--src/kern/tru64/tru64.hh63
-rw-r--r--src/kern/tru64/tru64_events.cc6
-rw-r--r--src/mem/Bridge.py16
-rw-r--r--src/mem/SConscript4
-rw-r--r--src/mem/bridge.cc399
-rw-r--r--src/mem/bridge.hh332
-rw-r--r--src/mem/bus.cc194
-rw-r--r--src/mem/bus.hh126
-rw-r--r--src/mem/cache/base.cc10
-rw-r--r--src/mem/cache/base.hh2
-rw-r--r--src/mem/cache/cache.hh24
-rw-r--r--src/mem/cache/cache_impl.hh61
-rw-r--r--src/mem/fs_translating_port_proxy.cc (renamed from src/mem/vport.cc)91
-rw-r--r--src/mem/fs_translating_port_proxy.hh (renamed from src/mem/vport.hh)72
-rw-r--r--src/mem/mem_object.cc6
-rw-r--r--src/mem/mem_object.hh4
-rw-r--r--src/mem/packet.cc3
-rw-r--r--src/mem/packet.hh1
-rw-r--r--src/mem/physical.cc105
-rw-r--r--src/mem/physical.hh37
-rw-r--r--src/mem/port.cc64
-rw-r--r--src/mem/port.hh129
-rw-r--r--src/mem/port_proxy.hh174
-rw-r--r--src/mem/protocol/MESI_CMP_directory-L1cache.sm27
-rw-r--r--src/mem/protocol/MI_example-cache.sm16
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-L1cache.sm24
-rw-r--r--src/mem/protocol/MOESI_CMP_token-L1cache.sm35
-rw-r--r--src/mem/protocol/MOESI_hammer-cache.sm26
-rw-r--r--src/mem/protocol/MOESI_hammer-dir.sm2
-rw-r--r--src/mem/protocol/RubySlicc_Types.sm1
-rw-r--r--src/mem/ruby/system/RubyPort.cc32
-rw-r--r--src/mem/ruby/system/RubyPort.hh4
-rw-r--r--src/mem/ruby/system/RubyPortProxy.cc (renamed from src/mem/port_impl.hh)53
-rw-r--r--src/mem/ruby/system/RubyPortProxy.hh114
-rw-r--r--src/mem/ruby/system/SConscript1
-rw-r--r--src/mem/ruby/system/Sequencer.cc6
-rw-r--r--src/mem/ruby/system/Sequencer.hh2
-rw-r--r--src/mem/ruby/system/Sequencer.py3
-rw-r--r--src/mem/se_translating_port_proxy.cc (renamed from src/mem/translating_port.cc)56
-rw-r--r--src/mem/se_translating_port_proxy.hh (renamed from src/mem/translating_port.hh)47
-rw-r--r--src/mem/tport.cc19
-rw-r--r--src/mem/tport.hh34
-rw-r--r--src/python/m5/SimObject.py2
-rw-r--r--src/python/m5/params.py5
-rw-r--r--src/sim/System.py3
-rw-r--r--src/sim/arguments.hh2
-rw-r--r--src/sim/process.cc10
-rw-r--r--src/sim/process.hh4
-rw-r--r--src/sim/process_impl.hh10
-rw-r--r--src/sim/stat_control.cc14
-rw-r--r--src/sim/syscall_emul.cc30
-rw-r--r--src/sim/syscall_emul.hh62
-rw-r--r--src/sim/system.cc138
-rw-r--r--src/sim/system.hh79
-rw-r--r--src/sim/vptr.hh6
185 files changed, 2907 insertions, 2421 deletions
diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc
index 6c7da711f..81aea8696 100644
--- a/src/arch/alpha/freebsd/system.cc
+++ b/src/arch/alpha/freebsd/system.cc
@@ -41,9 +41,7 @@
#include "arch/vtophys.hh"
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh"
-#include "mem/physical.hh"
-#include "mem/port.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "sim/byteswap.hh"
#define TIMER_FREQUENCY 1193180
@@ -78,8 +76,8 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
ppc_vaddr = (Addr)tc->readIntReg(17);
timer_vaddr = (Addr)tc->readIntReg(18);
- virtPort->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
- virtPort->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
+ virtProxy->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
+ virtProxy->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
}
void
diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc
index 97df1feca..f4457b389 100644
--- a/src/arch/alpha/linux/process.cc
+++ b/src/arch/alpha/linux/process.cc
@@ -56,7 +56,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "alpha");
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
@@ -78,7 +78,7 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
TypedBufferArg<uint64_t> fpcr(bufPtr);
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
- fpcr.copyOut(tc->getMemPort());
+ fpcr.copyOut(tc->getMemProxy());
return 0;
}
@@ -106,7 +106,7 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
case 14: { // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(bufPtr);
// I don't think this exactly matches the HW FPCR
- fpcr.copyIn(tc->getMemPort());
+ fpcr.copyIn(tc->getMemProxy());
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
return 0;
diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc
index e662ef9ce..6f3cf6b32 100644
--- a/src/arch/alpha/linux/system.cc
+++ b/src/arch/alpha/linux/system.cc
@@ -63,6 +63,17 @@ using namespace Linux;
LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
: AlphaSystem(p)
{
+}
+
+void
+LinuxAlphaSystem::initState()
+{
+ // Moved from the constructor to here since it relies on the
+ // address map being resolved in the interconnect
+
+ // Call the initialisation of the super class
+ AlphaSystem::initState();
+
Addr addr = 0;
/**
@@ -77,8 +88,9 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
* Since we aren't using a bootloader, we have to copy the
* kernel arguments directly into the kernel's memory.
*/
- virtPort->writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
- params()->boot_osflags.length()+1);
+ virtProxy->writeBlob(CommandLine(),
+ (uint8_t*)params()->boot_osflags.c_str(),
+ params()->boot_osflags.length()+1);
/**
* find the address of the est_cycle_freq variable and insert it
@@ -86,8 +98,8 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
* calculated it by using the PIT, RTC, etc.
*/
if (kernelSymtab->findAddress("est_cycle_freq", addr))
- virtPort->write(addr, (uint64_t)(SimClock::Frequency /
- p->boot_cpu_frequency));
+ virtProxy->write(addr, (uint64_t)(SimClock::Frequency /
+ params()->boot_cpu_frequency));
/**
@@ -97,7 +109,7 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
* 255 ASNs.
*/
if (kernelSymtab->findAddress("dp264_mv", addr))
- virtPort->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
+ virtProxy->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
else
panic("could not find dp264_mv\n");
@@ -164,9 +176,9 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
Tick cpuFreq = tc->getCpuPtr()->frequency();
assert(intrFreq);
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
}
}
diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh
index 3e4de7b2a..5436a27b2 100644
--- a/src/arch/alpha/linux/system.hh
+++ b/src/arch/alpha/linux/system.hh
@@ -128,7 +128,14 @@ class LinuxAlphaSystem : public AlphaSystem
LinuxAlphaSystem(Params *p);
~LinuxAlphaSystem();
+ /**
+ * Initialise the system
+ */
+ virtual void initState();
+
void setDelayLoop(ThreadContext *tc);
+
+ const Params *params() const { return (const Params *)_params; }
};
#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__
diff --git a/src/arch/alpha/linux/threadinfo.hh b/src/arch/alpha/linux/threadinfo.hh
index 6144cb773..262da9007 100644
--- a/src/arch/alpha/linux/threadinfo.hh
+++ b/src/arch/alpha/linux/threadinfo.hh
@@ -78,7 +78,7 @@ class ThreadInfo
if (!addr)
addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
- FunctionalPort *p = tc->getPhysPort();
+ PortProxy* p = tc->getPhysProxy();
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
return sp & ~ULL(0x3fff);
diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc
index 4b285e7ec..aaf9ecb3c 100644
--- a/src/arch/alpha/remote_gdb.cc
+++ b/src/arch/alpha/remote_gdb.cc
@@ -188,7 +188,7 @@ RemoteGDB::acc(Addr va, size_t len)
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
PageTableEntry pte =
- kernel_pte_lookup(context->getPhysPort(), ptbr, va);
+ kernel_pte_lookup(context->getPhysProxy(), ptbr, va);
if (!pte.valid()) {
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
return false;
@@ -312,3 +312,11 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data)
}
}
+
+bool
+RemoteGDB::insertHardBreak(Addr addr, size_t len)
+{
+ warn_once("Breakpoints do not work in Alpha PAL mode.\n"
+ " See PCEventQueue::doService() in cpu/pc_event.cc.\n");
+ return BaseRemoteGDB::insertHardBreak(addr, len);
+}
diff --git a/src/arch/alpha/remote_gdb.hh b/src/arch/alpha/remote_gdb.hh
index b7aef5f64..7223fea55 100644
--- a/src/arch/alpha/remote_gdb.hh
+++ b/src/arch/alpha/remote_gdb.hh
@@ -63,6 +63,8 @@ class RemoteGDB : public BaseRemoteGDB
bool acc(Addr addr, size_t len);
bool write(Addr addr, size_t size, const char *data);
+ virtual bool insertHardBreak(Addr addr, size_t len);
+
public:
RemoteGDB(System *system, ThreadContext *context);
};
diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc
index 9744d56d1..e83827630 100644
--- a/src/arch/alpha/stacktrace.cc
+++ b/src/arch/alpha/stacktrace.cc
@@ -37,7 +37,7 @@
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "sim/system.hh"
using namespace std;
@@ -48,7 +48,7 @@ ProcessInfo::ProcessInfo(ThreadContext *_tc)
: tc(_tc)
{
Addr addr = 0;
- VirtualPort *vp = tc->getVirtPort();
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
if (!symtab->findAddress("thread_info_size", addr))
@@ -81,9 +81,9 @@ ProcessInfo::task(Addr ksp) const
Addr tsk;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
tsk = vp->readGtoH<Addr>(base + task_off);
return tsk;
@@ -98,9 +98,9 @@ ProcessInfo::pid(Addr ksp) const
uint16_t pd;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
pd = vp->readGtoH<uint16_t>(task + pid_off);
return pd;
diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc
index f1afda76e..656ab4d6f 100644
--- a/src/arch/alpha/system.cc
+++ b/src/arch/alpha/system.cc
@@ -38,8 +38,7 @@
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "debug/Loader.hh"
-#include "mem/physical.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "params/AlphaSystem.hh"
#include "sim/byteswap.hh"
@@ -64,11 +63,30 @@ AlphaSystem::AlphaSystem(Params *p)
pal = createObjectFile(params()->pal);
if (pal == NULL)
fatal("Could not load PALcode file %s", params()->pal);
+}
+
+AlphaSystem::~AlphaSystem()
+{
+ delete consoleSymtab;
+ delete console;
+ delete pal;
+#ifdef DEBUG
+ delete consolePanicEvent;
+#endif
+}
+
+void
+AlphaSystem::initState()
+{
+ // Moved from the constructor to here since it relies on the
+ // address map being resolved in the interconnect
+ // Call the initialisation of the super class
+ System::initState();
// Load program sections into memory
- pal->loadSections(functionalPort, loadAddrMask);
- console->loadSections(functionalPort, loadAddrMask);
+ pal->loadSections(physProxy, loadAddrMask);
+ console->loadSections(physProxy, loadAddrMask);
// load symbols
if (!console->loadGlobalSymbols(consoleSymtab))
@@ -101,8 +119,8 @@ AlphaSystem::AlphaSystem(Params *p)
* others do.)
*/
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
- virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
- strlen(params()->boot_osflags.c_str()));
+ virtProxy->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
+ strlen(params()->boot_osflags.c_str()));
}
/**
@@ -112,23 +130,13 @@ AlphaSystem::AlphaSystem(Params *p)
if (consoleSymtab->findAddress("m5_rpb", addr)) {
uint64_t data;
data = htog(params()->system_type);
- virtPort->write(addr+0x50, data);
+ virtProxy->write(addr+0x50, data);
data = htog(params()->system_rev);
- virtPort->write(addr+0x58, data);
+ virtProxy->write(addr+0x58, data);
} else
panic("could not find hwrpb\n");
}
-AlphaSystem::~AlphaSystem()
-{
- delete consoleSymtab;
- delete console;
- delete pal;
-#ifdef DEBUG
- delete consolePanicEvent;
-#endif
-}
-
/**
* This function fixes up addresses that are used to match PCs for
* hooking simulator events on to target function executions.
@@ -170,8 +178,8 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
// lda gp,Y(gp): opcode 8, Ra = 29, rb = 29
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
- uint32_t i1 = virtPort->read<uint32_t>(addr);
- uint32_t i2 = virtPort->read<uint32_t>(addr + sizeof(MachInst));
+ uint32_t i1 = virtProxy->read<uint32_t>(addr);
+ uint32_t i2 = virtProxy->read<uint32_t>(addr + sizeof(MachInst));
if ((i1 & inst_mask) == gp_ldah_pattern &&
(i2 & inst_mask) == gp_lda_pattern) {
@@ -188,7 +196,7 @@ AlphaSystem::setAlphaAccess(Addr access)
{
Addr addr = 0;
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
- virtPort->write(addr, htog(Phys2K0Seg(access)));
+ virtProxy->write(addr, htog(Phys2K0Seg(access)));
} else {
panic("could not find m5AlphaAccess\n");
}
diff --git a/src/arch/alpha/system.hh b/src/arch/alpha/system.hh
index a74aa206f..0e809cb94 100644
--- a/src/arch/alpha/system.hh
+++ b/src/arch/alpha/system.hh
@@ -50,6 +50,12 @@ class AlphaSystem : public System
~AlphaSystem();
public:
+
+ /**
+ * Initialise the state of the system.
+ */
+ virtual void initState();
+
/**
* Serialization stuff
*/
diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc
index 96fe2725f..071428d5e 100644
--- a/src/arch/alpha/tru64/process.cc
+++ b/src/arch/alpha/tru64/process.cc
@@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->version, "732");
strcpy(name->machine, "alpha");
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
@@ -74,21 +74,21 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
case AlphaTru64::GSI_MAX_CPU: {
TypedBufferArg<uint32_t> max_cpu(bufPtr);
*max_cpu = htog((uint32_t)process->numCpus());
- max_cpu.copyOut(tc->getMemPort());
+ max_cpu.copyOut(tc->getMemProxy());
return 1;
}
case AlphaTru64::GSI_CPUS_IN_BOX: {
TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
*cpus_in_box = htog((uint32_t)process->numCpus());
- cpus_in_box.copyOut(tc->getMemPort());
+ cpus_in_box.copyOut(tc->getMemProxy());
return 1;
}
case AlphaTru64::GSI_PHYSMEM: {
TypedBufferArg<uint64_t> physmem(bufPtr);
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
- physmem.copyOut(tc->getMemPort());
+ physmem.copyOut(tc->getMemProxy());
return 1;
}
@@ -105,14 +105,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
infop->cpu_ex_binding = htog(0);
infop->mhz = htog(667);
- infop.copyOut(tc->getMemPort());
+ infop.copyOut(tc->getMemProxy());
return 1;
}
case AlphaTru64::GSI_PROC_TYPE: {
TypedBufferArg<uint64_t> proc_type(bufPtr);
*proc_type = htog((uint64_t)11);
- proc_type.copyOut(tc->getMemPort());
+ proc_type.copyOut(tc->getMemProxy());
return 1;
}
@@ -121,14 +121,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strncpy((char *)bufArg.bufferPtr(),
"COMPAQ Professional Workstation XP1000",
nbytes);
- bufArg.copyOut(tc->getMemPort());
+ bufArg.copyOut(tc->getMemProxy());
return 1;
}
case AlphaTru64::GSI_CLK_TCK: {
TypedBufferArg<uint64_t> clk_hz(bufPtr);
*clk_hz = htog((uint64_t)1024);
- clk_hz.copyOut(tc->getMemPort());
+ clk_hz.copyOut(tc->getMemProxy());
return 1;
}
@@ -193,7 +193,7 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
elp->si_phz = htog(clk_hz);
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
elp->si_max_procs = htog(process->numCpus());
- elp.copyOut(tc->getMemPort());
+ elp.copyOut(tc->getMemProxy());
return 0;
}
diff --git a/src/arch/alpha/tru64/system.cc b/src/arch/alpha/tru64/system.cc
index 5a47addbd..13cc93247 100644
--- a/src/arch/alpha/tru64/system.cc
+++ b/src/arch/alpha/tru64/system.cc
@@ -38,9 +38,7 @@
#include "cpu/thread_context.hh"
#include "kern/tru64/tru64_events.hh"
#include "kern/system_events.hh"
-#include "mem/physical.hh"
-#include "mem/port.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
using namespace std;
@@ -49,7 +47,7 @@ Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p)
{
Addr addr = 0;
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
- virtPort->write(addr, (uint32_t)0);
+ virtProxy->write(addr, (uint32_t)0);
}
#ifdef DEBUG
diff --git a/src/arch/alpha/utility.cc b/src/arch/alpha/utility.cc
index 0048e43e9..efafec4bc 100644
--- a/src/arch/alpha/utility.cc
+++ b/src/arch/alpha/utility.cc
@@ -31,7 +31,7 @@
#include "arch/alpha/utility.hh"
#include "arch/alpha/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "sim/full_system.hh"
namespace AlphaISA {
@@ -48,7 +48,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
return tc->readIntReg(16 + number);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
- VirtualPort *vp = tc->getVirtPort();
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
uint64_t arg = vp->read<uint64_t>(sp +
(number-NumArgumentRegs) * sizeof(uint64_t));
return arg;
diff --git a/src/arch/alpha/vtophys.cc b/src/arch/alpha/vtophys.cc
index c51cddd11..453c48444 100644
--- a/src/arch/alpha/vtophys.cc
+++ b/src/arch/alpha/vtophys.cc
@@ -38,14 +38,14 @@
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/VtoPhys.hh"
-#include "mem/vport.hh"
+#include "mem/port_proxy.hh"
using namespace std;
namespace AlphaISA {
PageTableEntry
-kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr)
+kernel_pte_lookup(PortProxy* mem, Addr ptbr, VAddr vaddr)
{
Addr level1_pte = ptbr + vaddr.level1();
PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
@@ -103,7 +103,7 @@ vtophys(ThreadContext *tc, Addr addr)
paddr = vaddr;
} else {
PageTableEntry pte =
- kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
+ kernel_pte_lookup(tc->getPhysProxy(), ptbr, vaddr);
if (pte.valid())
paddr = pte.paddr() | vaddr.offset();
}
diff --git a/src/arch/alpha/vtophys.hh b/src/arch/alpha/vtophys.hh
index b13afd090..1695676cb 100644
--- a/src/arch/alpha/vtophys.hh
+++ b/src/arch/alpha/vtophys.hh
@@ -37,11 +37,11 @@
#include "arch/alpha/utility.hh"
class ThreadContext;
-class FunctionalPort;
+class PortProxy;
namespace AlphaISA {
-PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr,
+PageTableEntry kernel_pte_lookup(PortProxy* mem, Addr ptbr,
VAddr vaddr);
Addr vtophys(Addr vaddr);
diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc
index c65962d00..1074b0362 100644
--- a/src/arch/arm/linux/process.cc
+++ b/src/arch/arm/linux/process.cc
@@ -70,7 +70,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "armv7l");
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
@@ -452,7 +452,7 @@ setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
int index = 0;
uint32_t tlsPtr = process->getSyscallArg(tc, index);
- tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
+ tc->getMemProxy()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
tc->setMiscReg(MISCREG_TPIDRURO,tlsPtr);
return 0;
@@ -512,7 +512,7 @@ ArmLinuxProcess::initState()
// Fill this page with swi -1 so we'll no if we land in it somewhere.
for (Addr addr = 0; addr < PageBytes; addr += sizeof(swiNeg1)) {
- tc->getMemPort()->writeBlob(commPage + addr,
+ tc->getMemProxy()->writeBlob(commPage + addr,
swiNeg1, sizeof(swiNeg1));
}
@@ -521,7 +521,7 @@ ArmLinuxProcess::initState()
0x5f, 0xf0, 0x7f, 0xf5, // dmb
0x0e, 0xf0, 0xa0, 0xe1 // return
};
- tc->getMemPort()->writeBlob(commPage + 0x0fa0, memory_barrier,
+ tc->getMemProxy()->writeBlob(commPage + 0x0fa0, memory_barrier,
sizeof(memory_barrier));
uint8_t cmpxchg[] =
@@ -535,7 +535,7 @@ ArmLinuxProcess::initState()
0x5f, 0xf0, 0x7f, 0xf5, // dmb
0x0e, 0xf0, 0xa0, 0xe1 // return
};
- tc->getMemPort()->writeBlob(commPage + 0x0fc0, cmpxchg, sizeof(cmpxchg));
+ tc->getMemProxy()->writeBlob(commPage + 0x0fc0, cmpxchg, sizeof(cmpxchg));
uint8_t get_tls[] =
{
@@ -543,7 +543,7 @@ ArmLinuxProcess::initState()
0x70, 0x0f, 0x1d, 0xee, // mrc p15, 0, r0, c13, c0, 3
0x0e, 0xf0, 0xa0, 0xe1 // return
};
- tc->getMemPort()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls));
+ tc->getMemProxy()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls));
}
ArmISA::IntReg
diff --git a/src/arch/arm/linux/system.cc b/src/arch/arm/linux/system.cc
index 66f4f26af..a764edaca 100644
--- a/src/arch/arm/linux/system.cc
+++ b/src/arch/arm/linux/system.cc
@@ -49,6 +49,7 @@
#include "cpu/thread_context.hh"
#include "debug/Loader.hh"
#include "kern/linux/events.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "mem/physical.hh"
using namespace ArmISA;
@@ -57,6 +58,27 @@ using namespace Linux;
LinuxArmSystem::LinuxArmSystem(Params *p)
: ArmSystem(p)
{
+}
+
+bool
+LinuxArmSystem::adderBootUncacheable(Addr a)
+{
+ Addr block = a & ~ULL(0x7F);
+ if (block == secDataPtrAddr || block == secDataAddr ||
+ block == penReleaseAddr)
+ return true;
+ return false;
+}
+
+void
+LinuxArmSystem::initState()
+{
+ // Moved from the constructor to here since it relies on the
+ // address map being resolved in the interconnect
+
+ // Call the initialisation of the super class
+ ArmSystem::initState();
+
// Load symbols at physical address, we might not want
// to do this perminately, for but early bootup work
// it is helpfulp.
@@ -92,7 +114,7 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
DDUMP(Loader, boot_data, size << 2);
- functionalPort->writeBlob(ParamsList, boot_data, size << 2);
+ physProxy->writeBlob(ParamsList, boot_data, size << 2);
#ifndef NDEBUG
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
@@ -128,22 +150,6 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
secDataPtrAddr &= ~ULL(0x7F);
secDataAddr &= ~ULL(0x7F);
penReleaseAddr &= ~ULL(0x7F);
-}
-
-bool
-LinuxArmSystem::adderBootUncacheable(Addr a)
-{
- Addr block = a & ~ULL(0x7F);
- if (block == secDataPtrAddr || block == secDataAddr ||
- block == penReleaseAddr)
- return true;
- return false;
-}
-
-void
-LinuxArmSystem::initState()
-{
- ArmSystem::initState();
for (int i = 0; i < threadContexts.size(); i++) {
threadContexts[i]->setIntReg(0, 0);
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
index aa5d7dfce..c149f5409 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -50,7 +50,6 @@
#include "cpu/thread_context.hh"
#include "debug/Stack.hh"
#include "mem/page_table.hh"
-#include "mem/translating_port.hh"
#include "sim/byteswap.hh"
#include "sim/process_impl.hh"
#include "sim/system.hh"
diff --git a/src/arch/arm/stacktrace.cc b/src/arch/arm/stacktrace.cc
index 31376cdae..69d0f354c 100644
--- a/src/arch/arm/stacktrace.cc
+++ b/src/arch/arm/stacktrace.cc
@@ -37,7 +37,7 @@
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "sim/system.hh"
using namespace std;
@@ -48,9 +48,9 @@ namespace ArmISA
{
Addr addr = 0;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
panic("thread info not compiled into kernel\n");
diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc
index 4d4dff4d9..ca5bfc471 100644
--- a/src/arch/arm/system.cc
+++ b/src/arch/arm/system.cc
@@ -47,6 +47,7 @@
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh"
#include "mem/physical.hh"
+#include "mem/fs_translating_port_proxy.hh"
using namespace std;
using namespace Linux;
@@ -55,6 +56,18 @@ ArmSystem::ArmSystem(Params *p)
: System(p), bootldr(NULL)
{
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
+}
+
+void
+ArmSystem::initState()
+{
+ // Moved from the constructor to here since it relies on the
+ // address map being resolved in the interconnect
+
+ // Call the initialisation of the super class
+ System::initState();
+
+ const Params* p = params();
if ((p->boot_loader == "") != (p->boot_loader_mem == NULL))
fatal("If boot_loader is specifed, memory to load it must be also.\n");
@@ -65,29 +78,18 @@ ArmSystem::ArmSystem(Params *p)
if (!bootldr)
fatal("Could not read bootloader: %s\n", p->boot_loader);
- Port *mem_port;
- FunctionalPort fp(name() + "-fport");
- mem_port = p->boot_loader_mem->getPort("functional");
- fp.setPeer(mem_port);
- mem_port->setPeer(&fp);
-
- bootldr->loadSections(&fp);
+ bootldr->loadSections(physProxy);
bootldr->loadGlobalSymbols(debugSymbolTable);
uint8_t jump_to_bl[] =
{
0x07, 0xf0, 0xa0, 0xe1 // branch to r7
};
- functionalPort->writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl));
+ physProxy->writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl));
inform("Using bootloader at address %#x\n", bootldr->entryPoint());
}
-}
-void
-ArmSystem::initState()
-{
- System::initState();
if (bootldr) {
// Put the address of the boot loader into r7 so we know
// where to branch to after the reset fault
@@ -98,16 +100,16 @@ ArmSystem::initState()
threadContexts[i]->setIntReg(5, params()->flags_addr);
threadContexts[i]->setIntReg(7, bootldr->entryPoint());
}
- if (!params()->gic_cpu_addr || !params()->flags_addr)
+ if (!p->gic_cpu_addr || !p->flags_addr)
fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
} else {
// Set the initial PC to be at start of the kernel code
threadContexts[0]->pcState(kernelEntry & loadAddrMask);
}
for (int i = 0; i < threadContexts.size(); i++) {
- if (params()->midr_regval) {
+ if (p->midr_regval) {
threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
- params()->midr_regval);
+ p->midr_regval);
}
}
diff --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh
index 32b48a85b..7cf36fd6c 100644
--- a/src/arch/arm/system.hh
+++ b/src/arch/arm/system.hh
@@ -76,7 +76,10 @@ class ArmSystem : public System
ArmSystem(Params *p);
~ArmSystem();
- void initState();
+ /**
+ * Initialise the system
+ */
+ virtual void initState();
/** Check if an address should be uncacheable until all caches are enabled.
* This exits because coherence on some addresses at boot is maintained via
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index 6c2997a27..42b5be181 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -44,7 +44,7 @@
#include "arch/arm/utility.hh"
#include "arch/arm/vtophys.hh"
#include "cpu/thread_context.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "sim/full_system.hh"
namespace ArmISA {
@@ -86,7 +86,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
}
} else {
Addr sp = tc->readIntReg(StackPointerReg);
- VirtualPort *vp = tc->getVirtPort();
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
uint64_t arg;
if (size == sizeof(uint64_t)) {
// If the argument is even it must be aligned
diff --git a/src/arch/arm/vtophys.cc b/src/arch/arm/vtophys.cc
index 1691a387c..45e6f1849 100644
--- a/src/arch/arm/vtophys.cc
+++ b/src/arch/arm/vtophys.cc
@@ -51,7 +51,7 @@
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
using namespace std;
using namespace ArmISA;
@@ -101,7 +101,7 @@ ArmISA::vtophys(ThreadContext *tc, Addr addr)
N = 0;
}
- FunctionalPort *port = tc->getPhysPort();
+ PortProxy* port = tc->getPhysProxy();
Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(addr,31-N,20) << 2);
TableWalker::L1Descriptor l1desc;
diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc
index 0982e05cb..fda32b97b 100644
--- a/src/arch/mips/linux/process.cc
+++ b/src/arch/mips/linux/process.cc
@@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "mips");
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
@@ -82,7 +82,7 @@ sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
TypedBufferArg<uint64_t> fpcr(bufPtr);
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
- fpcr.copyOut(tc->getMemPort());
+ fpcr.copyOut(tc->getMemProxy());
return 0;
}
default:
@@ -111,7 +111,7 @@ sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
// SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(bufPtr);
// I don't think this exactly matches the HW FPCR
- fpcr.copyIn(tc->getMemPort());
+ fpcr.copyIn(tc->getMemProxy());
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
return 0;
diff --git a/src/arch/mips/linux/system.cc b/src/arch/mips/linux/system.cc
index 30e0f95e9..f97426f85 100644
--- a/src/arch/mips/linux/system.cc
+++ b/src/arch/mips/linux/system.cc
@@ -63,91 +63,10 @@ using namespace Linux;
LinuxMipsSystem::LinuxMipsSystem(Params *p)
: MipsSystem(p)
{
- Addr addr = 0;
-
- /**
- * The symbol swapper_pg_dir marks the beginning of the kernel and
- * the location of bootloader passed arguments
- */
- if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) {
- panic("Could not determine start location of kernel");
- }
-
- /**
- * Since we aren't using a bootloader, we have to copy the
- * kernel arguments directly into the kernel's memory.
- */
- virtPort->writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
- params()->boot_osflags.length()+1);
-
- /**
- * find the address of the est_cycle_freq variable and insert it
- * so we don't through the lengthly process of trying to
- * calculated it by using the PIT, RTC, etc.
- */
- if (kernelSymtab->findAddress("est_cycle_freq", addr))
- virtPort->write(addr, (uint64_t)(SimClock::Frequency /
- p->boot_cpu_frequency));
-
- /**
- * EV5 only supports 127 ASNs so we are going to tell the kernel that the
- * paritiuclar EV6 we have only supports 127 asns.
- * @todo At some point we should change ev5.hh and the palcode to support
- * 255 ASNs.
- */
- if (kernelSymtab->findAddress("dp264_mv", addr))
- virtPort->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
- else
- panic("could not find dp264_mv\n");
-
-#ifndef NDEBUG
- kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
- if (!kernelPanicEvent)
- panic("could not find kernel symbol \'panic\'");
-
-#endif
-
- /**
- * Any time ide_delay_50ms, calibarte_delay or
- * determine_cpu_caches is called just skip the
- * function. Currently determine_cpu_caches only is used put
- * information in proc, however if that changes in the future we
- * will have to fill in the cache size variables appropriately.
- */
-
- skipIdeDelay50msEvent =
- addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms");
- skipDelayLoopEvent =
- addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay");
- skipCacheProbeEvent =
- addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches");
- debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
- idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle");
-
- // Disable for now as it runs into panic() calls in VPTr methods
- // (see sim/vptr.hh). Once those bugs are fixed, we can
- // re-enable, but we should find a better way to turn it on than
- // using DTRACE(Thread), since looking at a trace flag at tick 0
- // leads to non-intuitive behavior with --trace-start.
- if (false && kernelSymtab->findAddress("mips_switch_to", addr)) {
- printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo",
- addr + sizeof(MachInst) * 6);
- } else {
- printThreadEvent = NULL;
- }
}
LinuxMipsSystem::~LinuxMipsSystem()
{
-#ifndef NDEBUG
- delete kernelPanicEvent;
-#endif
- delete skipIdeDelay50msEvent;
- delete skipDelayLoopEvent;
- delete skipCacheProbeEvent;
- delete debugPrintkEvent;
- delete idleStartEvent;
- delete printThreadEvent;
}
diff --git a/src/arch/mips/linux/threadinfo.hh b/src/arch/mips/linux/threadinfo.hh
index 20a4033dd..40dd435d6 100644
--- a/src/arch/mips/linux/threadinfo.hh
+++ b/src/arch/mips/linux/threadinfo.hh
@@ -79,7 +79,7 @@ class ThreadInfo
if (!addr)
addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/);
- FunctionalPort *p = tc->getPhysPort();
+ PortProxy* p = tc->getPhysProxy();
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
return sp & ~ULL(0x3fff);
diff --git a/src/arch/mips/stacktrace.cc b/src/arch/mips/stacktrace.cc
index 50f6e1fb0..d4548b4bb 100644
--- a/src/arch/mips/stacktrace.cc
+++ b/src/arch/mips/stacktrace.cc
@@ -37,7 +37,7 @@
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "sim/system.hh"
using namespace std;
@@ -55,9 +55,9 @@ ProcessInfo::task(Addr ksp) const
Addr tsk;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
tsk = vp->readGtoH<Addr>(base + task_off);
return tsk;
@@ -72,9 +72,9 @@ ProcessInfo::pid(Addr ksp) const
uint16_t pd;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
pd = vp->readGtoH<uint16_t>(task + pid_off);
return pd;
diff --git a/src/arch/mips/system.cc b/src/arch/mips/system.cc
index d367acd64..f0d4c250e 100755
--- a/src/arch/mips/system.cc
+++ b/src/arch/mips/system.cc
@@ -38,7 +38,6 @@
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "mem/physical.hh"
-#include "mem/vport.hh"
#include "params/MipsSystem.hh"
#include "sim/byteswap.hh"
@@ -46,67 +45,6 @@ using namespace LittleEndianGuest;
MipsSystem::MipsSystem(Params *p) : System(p)
{
- if (p->bare_iron == true) {
- hexFile = new HexFile(params()->hex_file_name);
- if (!hexFile->loadSections(functionalPort))
- panic("Could not load hex file\n");
- }
-
- Addr addr = 0;
-
- consoleSymtab = new SymbolTable;
-
-
- /**
- * Load the console code into memory
- */
- // Load Console Code
- console = createObjectFile(params()->console);
-
- warn("console code is located at: %s\n", params()->console);
-
- if (console == NULL)
- fatal("Could not load console file %s", params()->console);
- //Load program sections into memory
- console->loadSections(functionalPort, loadAddrMask);
-
- //load symbols
- if (!console->loadGlobalSymbols(consoleSymtab))
- panic("could not load console symbols\n");
-
- if (!console->loadGlobalSymbols(debugSymbolTable))
- panic("could not load console symbols\n");
-
-
-#ifndef NDEBUG
- consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
-#endif
-
- /**
- * Copy the osflags (kernel arguments) into the consoles
- * memory. (Presently Linux does not use the console service
- * routine to get these command line arguments, but Tru64 and
- * others do.)
- */
- if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
- warn("writing addr starting from %#x", addr);
- virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
- strlen(params()->boot_osflags.c_str()));
- }
-
- /**
- * Set the hardware reset parameter block system type and revision
- * information to Tsunami.
- */
- if (consoleSymtab->findAddress("m5_rpb", addr)) {
- uint64_t data;
- data = htog(params()->system_type);
- virtPort->write(addr + 0x50, data);
- data = htog(params()->system_rev);
- virtPort->write(addr + 0x58, data);
- } else {
- panic("could not find hwrpb\n");
- }
}
MipsSystem::~MipsSystem()
diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc
index 1f3b19c7b..65432b4ea 100644
--- a/src/arch/mips/utility.cc
+++ b/src/arch/mips/utility.cc
@@ -31,17 +31,16 @@
#include <cmath>
#include "arch/mips/isa_traits.hh"
+#include "arch/mips/registers.hh"
#include "arch/mips/utility.hh"
+#include "arch/mips/vtophys.hh"
#include "base/bitfield.hh"
#include "base/misc.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "sim/serialize.hh"
-#include "arch/mips/registers.hh"
-#include "arch/mips/vtophys.hh"
-#include "mem/vport.hh"
-
using namespace MipsISA;
using namespace std;
diff --git a/src/arch/mips/vtophys.cc b/src/arch/mips/vtophys.cc
index c6a317df8..60d9bc1ba 100755
--- a/src/arch/mips/vtophys.cc
+++ b/src/arch/mips/vtophys.cc
@@ -38,7 +38,6 @@
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/VtoPhys.hh"
-#include "mem/vport.hh"
using namespace std;
using namespace MipsISA;
diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc
index 1c1b2827f..f83df41d1 100644
--- a/src/arch/power/linux/process.cc
+++ b/src/arch/power/linux/process.cc
@@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "power");
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
index 788c7cc0c..4a5c06673 100644
--- a/src/arch/power/process.cc
+++ b/src/arch/power/process.cc
@@ -39,7 +39,6 @@
#include "cpu/thread_context.hh"
#include "debug/Stack.hh"
#include "mem/page_table.hh"
-#include "mem/translating_port.hh"
#include "sim/process_impl.hh"
#include "sim/system.hh"
diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc
index 034c38bef..9433cb508 100644
--- a/src/arch/sparc/linux/syscalls.cc
+++ b/src/arch/sparc/linux/syscalls.cc
@@ -50,7 +50,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "sparc");
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
@@ -69,19 +69,19 @@ getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
if (ruid) {
BufferArg ruidBuff(ruid, sizeof(IntReg));
memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
- ruidBuff.copyOut(tc->getMemPort());
+ ruidBuff.copyOut(tc->getMemProxy());
}
// Set the euid
if (euid) {
BufferArg euidBuff(euid, sizeof(IntReg));
memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
- euidBuff.copyOut(tc->getMemPort());
+ euidBuff.copyOut(tc->getMemProxy());
}
// Set the suid
if (suid) {
BufferArg suidBuff(suid, sizeof(IntReg));
memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
- suidBuff.copyOut(tc->getMemPort());
+ suidBuff.copyOut(tc->getMemProxy());
}
return 0;
}
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 5c594dcbc..cc39ecf31 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -41,7 +41,6 @@
#include "cpu/thread_context.hh"
#include "debug/Stack.hh"
#include "mem/page_table.hh"
-#include "mem/translating_port.hh"
#include "sim/process_impl.hh"
#include "sim/system.hh"
@@ -448,7 +447,7 @@ void Sparc32LiveProcess::flushWindows(ThreadContext *tc)
for (int index = 16; index < 32; index++) {
uint32_t regVal = tc->readIntReg(index);
regVal = htog(regVal);
- if (!tc->getMemPort()->tryWriteBlob(
+ if (!tc->getMemProxy()->tryWriteBlob(
sp + (index - 16) * 4, (uint8_t *)&regVal, 4)) {
warn("Failed to save register to the stack when "
"flushing windows.\n");
@@ -483,7 +482,7 @@ Sparc64LiveProcess::flushWindows(ThreadContext *tc)
for (int index = 16; index < 32; index++) {
IntReg regVal = tc->readIntReg(index);
regVal = htog(regVal);
- if (!tc->getMemPort()->tryWriteBlob(
+ if (!tc->getMemProxy()->tryWriteBlob(
sp + 2047 + (index - 16) * 8, (uint8_t *)&regVal, 8)) {
warn("Failed to save register to the stack when "
"flushing windows.\n");
diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc
index e47377d42..f929877f3 100644
--- a/src/arch/sparc/solaris/process.cc
+++ b/src/arch/sparc/solaris/process.cc
@@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->version, "Generic_118558-21");
strcpy(name->machine, "sun4u");
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc
index 9988702d2..ab5f7432e 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -40,10 +40,7 @@
using namespace BigEndianGuest;
SparcSystem::SparcSystem(Params *p)
- : System(p), sysTick(0),funcRomPort(p->name + "-fromport"),
- funcNvramPort(p->name + "-fnvramport"),
- funcHypDescPort(p->name + "-fhypdescport"),
- funcPartDescPort(p->name + "-fpartdescport")
+ : System(p), sysTick(0)
{
resetSymtab = new SymbolTable;
hypervisorSymtab = new SymbolTable;
@@ -51,23 +48,13 @@ SparcSystem::SparcSystem(Params *p)
nvramSymtab = new SymbolTable;
hypervisorDescSymtab = new SymbolTable;
partitionDescSymtab = new SymbolTable;
+}
- Port *rom_port;
- rom_port = params()->rom->getPort("functional");
- funcRomPort.setPeer(rom_port);
- rom_port->setPeer(&funcRomPort);
-
- rom_port = params()->nvram->getPort("functional");
- funcNvramPort.setPeer(rom_port);
- rom_port->setPeer(&funcNvramPort);
-
- rom_port = params()->hypervisor_desc->getPort("functional");
- funcHypDescPort.setPeer(rom_port);
- rom_port->setPeer(&funcHypDescPort);
-
- rom_port = params()->partition_desc->getPort("functional");
- funcPartDescPort.setPeer(rom_port);
- rom_port->setPeer(&funcPartDescPort);
+void
+SparcSystem::initState()
+{
+ // Call the initialisation of the super class
+ System::initState();
/**
* Load the boot code, and hypervisor into memory.
@@ -107,22 +94,22 @@ SparcSystem::SparcSystem(Params *p)
// Load reset binary into memory
reset->setTextBase(params()->reset_addr);
- reset->loadSections(&funcRomPort);
+ reset->loadSections(physProxy);
// Load the openboot binary
openboot->setTextBase(params()->openboot_addr);
- openboot->loadSections(&funcRomPort);
+ openboot->loadSections(physProxy);
// Load the hypervisor binary
hypervisor->setTextBase(params()->hypervisor_addr);
- hypervisor->loadSections(&funcRomPort);
+ hypervisor->loadSections(physProxy);
// Load the nvram image
nvram->setTextBase(params()->nvram_addr);
- nvram->loadSections(&funcNvramPort);
+ nvram->loadSections(physProxy);
// Load the hypervisor description image
hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
- hypervisor_desc->loadSections(&funcHypDescPort);
+ hypervisor_desc->loadSections(physProxy);
// Load the partition description image
partition_desc->setTextBase(params()->partition_desc_addr);
- partition_desc->loadSections(&funcPartDescPort);
+ partition_desc->loadSections(physProxy);
// load symbols
if (!reset->loadGlobalSymbols(resetSymtab))
diff --git a/src/arch/sparc/system.hh b/src/arch/sparc/system.hh
index 292f56b60..4b3da6287 100644
--- a/src/arch/sparc/system.hh
+++ b/src/arch/sparc/system.hh
@@ -48,6 +48,8 @@ class SparcSystem : public System
SparcSystem(Params *p);
~SparcSystem();
+ virtual void initState();
+
/**
* Serialization stuff
*/
@@ -94,18 +96,6 @@ class SparcSystem : public System
/** System Tick for syncronized tick across all cpus. */
Tick sysTick;
- /** functional port to ROM */
- FunctionalPort funcRomPort;
-
- /** functional port to nvram */
- FunctionalPort funcNvramPort;
-
- /** functional port to hypervisor description */
- FunctionalPort funcHypDescPort;
-
- /** functional port to partition description */
- FunctionalPort funcPartDescPort;
-
protected:
const Params *params() const { return (const Params *)_params; }
diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc
index 63b8e7960..74b1b2794 100644
--- a/src/arch/sparc/utility.cc
+++ b/src/arch/sparc/utility.cc
@@ -32,7 +32,7 @@
#include "arch/sparc/faults.hh"
#include "arch/sparc/utility.hh"
#include "arch/sparc/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
namespace SparcISA {
@@ -52,7 +52,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
return tc->readIntReg(8 + number);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
- VirtualPort *vp = tc->getVirtPort();
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
uint64_t arg = vp->read<uint64_t>(sp + 92 +
(number-NumArgumentRegs) * sizeof(uint64_t));
return arg;
diff --git a/src/arch/sparc/vtophys.cc b/src/arch/sparc/vtophys.cc
index edcf88828..7e3c5fe01 100644
--- a/src/arch/sparc/vtophys.cc
+++ b/src/arch/sparc/vtophys.cc
@@ -37,7 +37,7 @@
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/VtoPhys.hh"
-#include "mem/vport.hh"
+#include "mem/port_proxy.hh"
using namespace std;
@@ -81,7 +81,7 @@ vtophys(ThreadContext *tc, Addr addr)
int pri_context = bits(tlbdata,47,32);
// int sec_context = bits(tlbdata,63,48);
- FunctionalPort *mem = tc->getPhysPort();
+ PortProxy* mem = tc->getPhysProxy();
TLB* itb = tc->getITBPtr();
TLB* dtb = tc->getDTBPtr();
TlbEntry* tbe;
diff --git a/src/arch/x86/bios/intelmp.cc b/src/arch/x86/bios/intelmp.cc
index af32709aa..974af28a5 100644
--- a/src/arch/x86/bios/intelmp.cc
+++ b/src/arch/x86/bios/intelmp.cc
@@ -41,7 +41,7 @@
#include "arch/x86/isa_traits.hh"
#include "base/misc.hh"
#include "base/types.hh"
-#include "mem/port.hh"
+#include "mem/port_proxy.hh"
#include "sim/byteswap.hh"
// Config entry types
@@ -70,10 +70,10 @@ const char X86ISA::IntelMP::FloatingPointer::signature[] = "_MP_";
template<class T>
uint8_t
-writeOutField(FunctionalPort * port, Addr addr, T val)
+writeOutField(PortProxy* proxy, Addr addr, T val)
{
T guestVal = X86ISA::htog(val);
- port->writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T));
+ proxy->writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T));
uint8_t checkSum = 0;
while(guestVal) {
@@ -84,7 +84,7 @@ writeOutField(FunctionalPort * port, Addr addr, T val)
}
uint8_t
-writeOutString(FunctionalPort * port, Addr addr, string str, int length)
+writeOutString(PortProxy* proxy, Addr addr, string str, int length)
{
char cleanedString[length + 1];
cleanedString[length] = 0;
@@ -97,7 +97,7 @@ writeOutString(FunctionalPort * port, Addr addr, string str, int length)
memcpy(cleanedString, str.c_str(), str.length());
memset(cleanedString + str.length(), 0, length - str.length());
}
- port->writeBlob(addr, (uint8_t *)(&cleanedString), length);
+ proxy->writeBlob(addr, (uint8_t *)(&cleanedString), length);
uint8_t checkSum = 0;
for (int i = 0; i < length; i++)
@@ -107,7 +107,7 @@ writeOutString(FunctionalPort * port, Addr addr, string str, int length)
}
Addr
-X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr)
+X86ISA::IntelMP::FloatingPointer::writeOut(PortProxy* proxy, Addr addr)
{
// Make sure that either a config table is present or a default
// configuration was found but not both.
@@ -120,28 +120,28 @@ X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr)
uint8_t checkSum = 0;
- port->writeBlob(addr, (uint8_t *)signature, 4);
+ proxy->writeBlob(addr, (uint8_t *)signature, 4);
for (int i = 0; i < 4; i++)
checkSum += signature[i];
- checkSum += writeOutField(port, addr + 4, tableAddr);
+ checkSum += writeOutField(proxy, addr + 4, tableAddr);
// The length of the structure in paragraphs, aka 16 byte chunks.
uint8_t length = 1;
- port->writeBlob(addr + 8, &length, 1);
+ proxy->writeBlob(addr + 8, &length, 1);
checkSum += length;
- port->writeBlob(addr + 9, &specRev, 1);
+ proxy->writeBlob(addr + 9, &specRev, 1);
checkSum += specRev;
- port->writeBlob(addr + 11, &defaultConfig, 1);
+ proxy->writeBlob(addr + 11, &defaultConfig, 1);
checkSum += defaultConfig;
uint32_t features2_5 = imcrPresent ? (1 << 7) : 0;
- checkSum += writeOutField(port, addr + 12, features2_5);
+ checkSum += writeOutField(proxy, addr + 12, features2_5);
checkSum = -checkSum;
- port->writeBlob(addr + 10, &checkSum, 1);
+ proxy->writeBlob(addr + 10, &checkSum, 1);
return 16;
}
@@ -158,10 +158,10 @@ X86IntelMPFloatingPointerParams::create()
}
Addr
-X86ISA::IntelMP::BaseConfigEntry::writeOut(FunctionalPort * port,
+X86ISA::IntelMP::BaseConfigEntry::writeOut(PortProxy* proxy,
Addr addr, uint8_t &checkSum)
{
- port->writeBlob(addr, &type, 1);
+ proxy->writeBlob(addr, &type, 1);
checkSum += type;
return 1;
}
@@ -171,12 +171,12 @@ X86ISA::IntelMP::BaseConfigEntry::BaseConfigEntry(Params * p, uint8_t _type) :
{}
Addr
-X86ISA::IntelMP::ExtConfigEntry::writeOut(FunctionalPort * port,
+X86ISA::IntelMP::ExtConfigEntry::writeOut(PortProxy* proxy,
Addr addr, uint8_t &checkSum)
{
- port->writeBlob(addr, &type, 1);
+ proxy->writeBlob(addr, &type, 1);
checkSum += type;
- port->writeBlob(addr + 1, &length, 1);
+ proxy->writeBlob(addr + 1, &length, 1);
checkSum += length;
return 1;
}
@@ -189,59 +189,59 @@ X86ISA::IntelMP::ExtConfigEntry::ExtConfigEntry(Params * p,
const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP";
Addr
-X86ISA::IntelMP::ConfigTable::writeOut(FunctionalPort * port, Addr addr)
+X86ISA::IntelMP::ConfigTable::writeOut(PortProxy* proxy, Addr addr)
{
uint8_t checkSum = 0;
- port->writeBlob(addr, (uint8_t *)signature, 4);
+ proxy->writeBlob(addr, (uint8_t *)signature, 4);
for (int i = 0; i < 4; i++)
checkSum += signature[i];
// Base table length goes here but will be calculated later.
- port->writeBlob(addr + 6, (uint8_t *)(&specRev), 1);
+ proxy->writeBlob(addr + 6, (uint8_t *)(&specRev), 1);
checkSum += specRev;
// The checksum goes here but is still being calculated.
- checkSum += writeOutString(port, addr + 8, oemID, 8);
- checkSum += writeOutString(port, addr + 16, productID, 12);
+ checkSum += writeOutString(proxy, addr + 8, oemID, 8);
+ checkSum += writeOutString(proxy, addr + 16, productID, 12);
- checkSum += writeOutField(port, addr + 28, oemTableAddr);
- checkSum += writeOutField(port, addr + 32, oemTableSize);
- checkSum += writeOutField(port, addr + 34, (uint16_t)baseEntries.size());
- checkSum += writeOutField(port, addr + 36, localApic);
+ checkSum += writeOutField(proxy, addr + 28, oemTableAddr);
+ checkSum += writeOutField(proxy, addr + 32, oemTableSize);
+ checkSum += writeOutField(proxy, addr + 34, (uint16_t)baseEntries.size());
+ checkSum += writeOutField(proxy, addr + 36, localApic);
uint8_t reserved = 0;
- port->writeBlob(addr + 43, &reserved, 1);
+ proxy->writeBlob(addr + 43, &reserved, 1);
checkSum += reserved;
vector<BaseConfigEntry *>::iterator baseEnt;
uint16_t offset = 44;
for (baseEnt = baseEntries.begin();
baseEnt != baseEntries.end(); baseEnt++) {
- offset += (*baseEnt)->writeOut(port, addr + offset, checkSum);
+ offset += (*baseEnt)->writeOut(proxy, addr + offset, checkSum);
}
// We've found the end of the base table this point.
- checkSum += writeOutField(port, addr + 4, offset);
+ checkSum += writeOutField(proxy, addr + 4, offset);
vector<ExtConfigEntry *>::iterator extEnt;
uint16_t extOffset = 0;
uint8_t extCheckSum = 0;
for (extEnt = extEntries.begin();
extEnt != extEntries.end(); extEnt++) {
- extOffset += (*extEnt)->writeOut(port,
+ extOffset += (*extEnt)->writeOut(proxy,
addr + offset + extOffset, extCheckSum);
}
- checkSum += writeOutField(port, addr + 40, extOffset);
+ checkSum += writeOutField(proxy, addr + 40, extOffset);
extCheckSum = -extCheckSum;
- checkSum += writeOutField(port, addr + 42, extCheckSum);
+ checkSum += writeOutField(proxy, addr + 42, extCheckSum);
// And now, we finally have the whole check sum completed.
checkSum = -checkSum;
- writeOutField(port, addr + 7, checkSum);
+ writeOutField(proxy, addr + 7, checkSum);
return offset + extOffset;
};
@@ -261,18 +261,18 @@ X86IntelMPConfigTableParams::create()
Addr
X86ISA::IntelMP::Processor::writeOut(
- FunctionalPort * port, Addr addr, uint8_t &checkSum)
+ PortProxy* proxy, Addr addr, uint8_t &checkSum)
{
- BaseConfigEntry::writeOut(port, addr, checkSum);
- checkSum += writeOutField(port, addr + 1, localApicID);
- checkSum += writeOutField(port, addr + 2, localApicVersion);
- checkSum += writeOutField(port, addr + 3, cpuFlags);
- checkSum += writeOutField(port, addr + 4, cpuSignature);
- checkSum += writeOutField(port, addr + 8, featureFlags);
+ BaseConfigEntry::writeOut(proxy, addr, checkSum);
+ checkSum += writeOutField(proxy, addr + 1, localApicID);
+ checkSum += writeOutField(proxy, addr + 2, localApicVersion);
+ checkSum += writeOutField(proxy, addr + 3, cpuFlags);
+ checkSum += writeOutField(proxy, addr + 4, cpuSignature);
+ checkSum += writeOutField(proxy, addr + 8, featureFlags);
uint32_t reserved = 0;
- port->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
- port->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
+ proxy->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
+ proxy->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
return 20;
}
@@ -298,11 +298,11 @@ X86IntelMPProcessorParams::create()
Addr
X86ISA::IntelMP::Bus::writeOut(
- FunctionalPort * port, Addr addr, uint8_t &checkSum)
+ PortProxy* proxy, Addr addr, uint8_t &checkSum)
{
- BaseConfigEntry::writeOut(port, addr, checkSum);
- checkSum += writeOutField(port, addr + 1, busID);
- checkSum += writeOutString(port, addr + 2, busType, 6);
+ BaseConfigEntry::writeOut(proxy, addr, checkSum);
+ checkSum += writeOutField(proxy, addr + 1, busID);
+ checkSum += writeOutString(proxy, addr + 2, busType, 6);
return 8;
}
@@ -318,13 +318,13 @@ X86IntelMPBusParams::create()
Addr
X86ISA::IntelMP::IOAPIC::writeOut(
- FunctionalPort * port, Addr addr, uint8_t &checkSum)
+ PortProxy* proxy, Addr addr, uint8_t &checkSum)
{
- BaseConfigEntry::writeOut(port, addr, checkSum);
- checkSum += writeOutField(port, addr + 1, id);
- checkSum += writeOutField(port, addr + 2, version);
- checkSum += writeOutField(port, addr + 3, flags);
- checkSum += writeOutField(port, addr + 4, address);
+ BaseConfigEntry::writeOut(proxy, addr, checkSum);
+ checkSum += writeOutField(proxy, addr + 1, id);
+ checkSum += writeOutField(proxy, addr + 2, version);
+ checkSum += writeOutField(proxy, addr + 3, flags);
+ checkSum += writeOutField(proxy, addr + 4, address);
return 8;
}
@@ -343,15 +343,15 @@ X86IntelMPIOAPICParams::create()
Addr
X86ISA::IntelMP::IntAssignment::writeOut(
- FunctionalPort * port, Addr addr, uint8_t &checkSum)
+ PortProxy* proxy, Addr addr, uint8_t &checkSum)
{
- BaseConfigEntry::writeOut(port, addr, checkSum);
- checkSum += writeOutField(port, addr + 1, interruptType);
- checkSum += writeOutField(port, addr + 2, flags);
- checkSum += writeOutField(port, addr + 4, sourceBusID);
- checkSum += writeOutField(port, addr + 5, sourceBusIRQ);
- checkSum += writeOutField(port, addr + 6, destApicID);
- checkSum += writeOutField(port, addr + 7, destApicIntIn);
+ BaseConfigEntry::writeOut(proxy, addr, checkSum);
+ checkSum += writeOutField(proxy, addr + 1, interruptType);
+ checkSum += writeOutField(proxy, addr + 2, flags);
+ checkSum += writeOutField(proxy, addr + 4, sourceBusID);
+ checkSum += writeOutField(proxy, addr + 5, sourceBusIRQ);
+ checkSum += writeOutField(proxy, addr + 6, destApicID);
+ checkSum += writeOutField(proxy, addr + 7, destApicIntIn);
return 8;
}
@@ -381,13 +381,13 @@ X86IntelMPLocalIntAssignmentParams::create()
Addr
X86ISA::IntelMP::AddrSpaceMapping::writeOut(
- FunctionalPort * port, Addr addr, uint8_t &checkSum)
+ PortProxy* proxy, Addr addr, uint8_t &checkSum)
{
- ExtConfigEntry::writeOut(port, addr, checkSum);
- checkSum += writeOutField(port, addr + 2, busID);
- checkSum += writeOutField(port, addr + 3, addrType);
- checkSum += writeOutField(port, addr + 4, addr);
- checkSum += writeOutField(port, addr + 12, addrLength);
+ ExtConfigEntry::writeOut(proxy, addr, checkSum);
+ checkSum += writeOutField(proxy, addr + 2, busID);
+ checkSum += writeOutField(proxy, addr + 3, addrType);
+ checkSum += writeOutField(proxy, addr + 4, addr);
+ checkSum += writeOutField(proxy, addr + 12, addrLength);
return length;
}
@@ -405,15 +405,15 @@ X86IntelMPAddrSpaceMappingParams::create()
Addr
X86ISA::IntelMP::BusHierarchy::writeOut(
- FunctionalPort * port, Addr addr, uint8_t &checkSum)
+ PortProxy* proxy, Addr addr, uint8_t &checkSum)
{
- ExtConfigEntry::writeOut(port, addr, checkSum);
- checkSum += writeOutField(port, addr + 2, busID);
- checkSum += writeOutField(port, addr + 3, info);
- checkSum += writeOutField(port, addr + 4, parentBus);
+ ExtConfigEntry::writeOut(proxy, addr, checkSum);
+ checkSum += writeOutField(proxy, addr + 2, busID);
+ checkSum += writeOutField(proxy, addr + 3, info);
+ checkSum += writeOutField(proxy, addr + 4, parentBus);
uint32_t reserved = 0;
- port->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
+ proxy->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
return length;
}
@@ -434,12 +434,12 @@ X86IntelMPBusHierarchyParams::create()
Addr
X86ISA::IntelMP::CompatAddrSpaceMod::writeOut(
- FunctionalPort * port, Addr addr, uint8_t &checkSum)
+ PortProxy* proxy, Addr addr, uint8_t &checkSum)
{
- ExtConfigEntry::writeOut(port, addr, checkSum);
- checkSum += writeOutField(port, addr + 2, busID);
- checkSum += writeOutField(port, addr + 3, mod);
- checkSum += writeOutField(port, addr + 4, rangeList);
+ ExtConfigEntry::writeOut(proxy, addr, checkSum);
+ checkSum += writeOutField(proxy, addr + 2, busID);
+ checkSum += writeOutField(proxy, addr + 3, mod);
+ checkSum += writeOutField(proxy, addr + 4, rangeList);
return length;
}
diff --git a/src/arch/x86/bios/intelmp.hh b/src/arch/x86/bios/intelmp.hh
index 117466b48..0ddb62b8d 100644
--- a/src/arch/x86/bios/intelmp.hh
+++ b/src/arch/x86/bios/intelmp.hh
@@ -51,7 +51,7 @@
#include "enums/X86IntelMPTriggerMode.hh"
#include "sim/sim_object.hh"
-class FunctionalPort;
+class PortProxy;
// Config entry types
class X86IntelMPBaseConfigEntryParams;
@@ -93,7 +93,7 @@ class FloatingPointer : public SimObject
public:
- Addr writeOut(FunctionalPort * port, Addr addr);
+ Addr writeOut(PortProxy* proxy, Addr addr);
Addr getTableAddr()
{
@@ -117,7 +117,7 @@ class BaseConfigEntry : public SimObject
public:
- virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+ virtual Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
BaseConfigEntry(Params * p, uint8_t _type);
};
@@ -132,7 +132,7 @@ class ExtConfigEntry : public SimObject
public:
- virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+ virtual Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
ExtConfigEntry(Params * p, uint8_t _type, uint8_t _length);
};
@@ -155,7 +155,7 @@ class ConfigTable : public SimObject
std::vector<ExtConfigEntry *> extEntries;
public:
- Addr writeOut(FunctionalPort * port, Addr addr);
+ Addr writeOut(PortProxy* proxy, Addr addr);
ConfigTable(Params * p);
};
@@ -172,7 +172,7 @@ class Processor : public BaseConfigEntry
uint32_t featureFlags;
public:
- Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+ Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
Processor(Params * p);
};
@@ -186,7 +186,7 @@ class Bus : public BaseConfigEntry
std::string busType;
public:
- Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+ Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
Bus(Params * p);
};
@@ -202,7 +202,7 @@ class IOAPIC : public BaseConfigEntry
uint32_t address;
public:
- Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+ Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
IOAPIC(Params * p);
};
@@ -221,7 +221,7 @@ class IntAssignment : public BaseConfigEntry
uint8_t destApicIntIn;
public:
- Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+ Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
IntAssignment(X86IntelMPBaseConfigEntryParams * p,
Enums::X86IntelMPInterruptType _interruptType,
@@ -269,7 +269,7 @@ class AddrSpaceMapping : public ExtConfigEntry
uint64_t addrLength;
public:
- Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+ Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
AddrSpaceMapping(Params * p);
};
@@ -284,7 +284,7 @@ class BusHierarchy : public ExtConfigEntry
uint8_t parentBus;
public:
- Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+ Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
BusHierarchy(Params * p);
};
@@ -299,7 +299,7 @@ class CompatAddrSpaceMod : public ExtConfigEntry
uint32_t rangeList;
public:
- Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
+ Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
CompatAddrSpaceMod(Params * p);
};
diff --git a/src/arch/x86/bios/smbios.cc b/src/arch/x86/bios/smbios.cc
index c9015df0f..a85ece1ec 100644
--- a/src/arch/x86/bios/smbios.cc
+++ b/src/arch/x86/bios/smbios.cc
@@ -43,7 +43,7 @@
#include "arch/x86/bios/smbios.hh"
#include "arch/x86/isa_traits.hh"
#include "base/types.hh"
-#include "mem/port.hh"
+#include "mem/port_proxy.hh"
#include "params/X86SMBiosBiosInformation.hh"
#include "params/X86SMBiosSMBiosStructure.hh"
#include "params/X86SMBiosSMBiosTable.hh"
@@ -74,15 +74,15 @@ composeBitVector(T vec)
}
uint16_t
-X86ISA::SMBios::SMBiosStructure::writeOut(FunctionalPort * port, Addr addr)
+X86ISA::SMBios::SMBiosStructure::writeOut(PortProxy* proxy, Addr addr)
{
- port->writeBlob(addr, (uint8_t *)(&type), 1);
+ proxy->writeBlob(addr, (uint8_t *)(&type), 1);
uint8_t length = getLength();
- port->writeBlob(addr + 1, (uint8_t *)(&length), 1);
+ proxy->writeBlob(addr + 1, (uint8_t *)(&length), 1);
uint16_t handleGuest = X86ISA::htog(handle);
- port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2);
+ proxy->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2);
return length + getStringLength();
}
@@ -93,7 +93,7 @@ X86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) :
void
X86ISA::SMBios::SMBiosStructure::writeOutStrings(
- FunctionalPort * port, Addr addr)
+ PortProxy* proxy, Addr addr)
{
std::vector<std::string>::iterator it;
Addr offset = 0;
@@ -103,16 +103,16 @@ X86ISA::SMBios::SMBiosStructure::writeOutStrings(
// If there are string fields but none of them are used, that's a
// special case which is handled by this if.
if (strings.size() == 0 && stringFields) {
- port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
+ proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
offset++;
} else {
for (it = strings.begin(); it != strings.end(); it++) {
- port->writeBlob(addr + offset,
+ proxy->writeBlob(addr + offset,
(uint8_t *)it->c_str(), it->length() + 1);
offset += it->length() + 1;
}
}
- port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
+ proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
}
int
@@ -172,32 +172,32 @@ X86ISA::SMBios::BiosInformation::BiosInformation(Params * p) :
}
uint16_t
-X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr)
+X86ISA::SMBios::BiosInformation::writeOut(PortProxy* proxy, Addr addr)
{
- uint8_t size = SMBiosStructure::writeOut(port, addr);
+ uint8_t size = SMBiosStructure::writeOut(proxy, addr);
- port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
- port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
+ proxy->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
+ proxy->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment);
- port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2);
+ proxy->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2);
- port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
- port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
+ proxy->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
+ proxy->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
uint64_t characteristicsGuest = X86ISA::htog(characteristics);
- port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8);
+ proxy->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8);
uint16_t characteristicExtBytesGuest =
X86ISA::htog(characteristicExtBytes);
- port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
+ proxy->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2);
- port->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
- port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
- port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
- port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
+ proxy->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
+ proxy->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
+ proxy->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
+ proxy->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
- writeOutStrings(port, addr + getLength());
+ writeOutStrings(proxy, addr + getLength());
return size;
}
@@ -214,7 +214,7 @@ X86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) :
}
void
-X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
+X86ISA::SMBios::SMBiosTable::writeOut(PortProxy* proxy, Addr addr,
Addr &headerSize, Addr &structSize)
{
headerSize = 0x1F;
@@ -224,26 +224,26 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
*/
uint8_t mainChecksum = 0;
- port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
+ proxy->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4);
for (int i = 0; i < 4; i++)
mainChecksum += smbiosHeader.anchorString[i];
// The checksum goes here, but we're figuring it out as we go.
- port->writeBlob(addr + 0x5,
+ proxy->writeBlob(addr + 0x5,
(uint8_t *)(&smbiosHeader.entryPointLength), 1);
mainChecksum += smbiosHeader.entryPointLength;
- port->writeBlob(addr + 0x6,
+ proxy->writeBlob(addr + 0x6,
(uint8_t *)(&smbiosHeader.majorVersion), 1);
mainChecksum += smbiosHeader.majorVersion;
- port->writeBlob(addr + 0x7,
+ proxy->writeBlob(addr + 0x7,
(uint8_t *)(&smbiosHeader.minorVersion), 1);
mainChecksum += smbiosHeader.minorVersion;
// Maximum structure size goes here, but we'll figure it out later.
- port->writeBlob(addr + 0xA,
+ proxy->writeBlob(addr + 0xA,
(uint8_t *)(&smbiosHeader.entryPointRevision), 1);
mainChecksum += smbiosHeader.entryPointRevision;
- port->writeBlob(addr + 0xB,
+ proxy->writeBlob(addr + 0xB,
(uint8_t *)(&smbiosHeader.formattedArea), 5);
for (int i = 0; i < 5; i++)
mainChecksum += smbiosHeader.formattedArea[i];
@@ -253,7 +253,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
*/
uint8_t intChecksum = 0;
- port->writeBlob(addr + 0x10,
+ proxy->writeBlob(addr + 0x10,
(uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
for (int i = 0; i < 5; i++)
intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
@@ -263,20 +263,20 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
uint32_t tableAddrGuest =
X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr);
- port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4);
+ proxy->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4);
for (int i = 0; i < 4; i++) {
intChecksum += tableAddrGuest;
tableAddrGuest >>= 8;
}
uint16_t numStructs = X86ISA::gtoh(structures.size());
- port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2);
+ proxy->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2);
for (int i = 0; i < 2; i++) {
intChecksum += numStructs;
numStructs >>= 8;
}
- port->writeBlob(addr + 0x1E,
+ proxy->writeBlob(addr + 0x1E,
(uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
1);
intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
@@ -290,7 +290,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
uint16_t maxSize = 0;
std::vector<SMBiosStructure *>::iterator it;
for (it = structures.begin(); it != structures.end(); it++) {
- uint16_t size = (*it)->writeOut(port, base + offset);
+ uint16_t size = (*it)->writeOut(proxy, base + offset);
if (size > maxSize)
maxSize = size;
offset += size;
@@ -303,7 +303,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
*/
maxSize = X86ISA::htog(maxSize);
- port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2);
+ proxy->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2);
for (int i = 0; i < 2; i++) {
mainChecksum += maxSize;
maxSize >>= 8;
@@ -311,7 +311,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
// Set the checksum
mainChecksum = -mainChecksum;
- port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
+ proxy->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
/*
* Intermediate header
@@ -319,14 +319,14 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
uint16_t tableSize = offset;
tableSize = X86ISA::htog(tableSize);
- port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2);
+ proxy->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2);
for (int i = 0; i < 2; i++) {
intChecksum += tableSize;
tableSize >>= 8;
}
intChecksum = -intChecksum;
- port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
+ proxy->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
}
X86ISA::SMBios::BiosInformation *
diff --git a/src/arch/x86/bios/smbios.hh b/src/arch/x86/bios/smbios.hh
index b9c35bd09..9fa6cd6dc 100644
--- a/src/arch/x86/bios/smbios.hh
+++ b/src/arch/x86/bios/smbios.hh
@@ -51,7 +51,7 @@
#include "enums/ExtCharacteristic.hh"
#include "sim/sim_object.hh"
-class FunctionalPort;
+class PortProxy;
class X86SMBiosBiosInformationParams;
class X86SMBiosSMBiosStructureParams;
class X86SMBiosSMBiosTableParams;
@@ -89,7 +89,7 @@ class SMBiosStructure : public SimObject
return 4;
}
- virtual uint16_t writeOut(FunctionalPort * port, Addr addr);
+ virtual uint16_t writeOut(PortProxy* proxy, Addr addr);
protected:
bool stringFields;
@@ -98,7 +98,7 @@ class SMBiosStructure : public SimObject
std::vector<std::string> strings;
- void writeOutStrings(FunctionalPort * port, Addr addr);
+ void writeOutStrings(PortProxy* proxy, Addr addr);
int getStringLength();
@@ -145,7 +145,7 @@ class BiosInformation : public SMBiosStructure
BiosInformation(Params * p);
uint8_t getLength() { return 0x18; }
- uint16_t writeOut(FunctionalPort * port, Addr addr);
+ uint16_t writeOut(PortProxy* proxy, Addr addr);
};
class SMBiosTable : public SimObject
@@ -223,7 +223,7 @@ class SMBiosTable : public SimObject
smbiosHeader.intermediateHeader.tableAddr = addr;
}
- void writeOut(FunctionalPort * port, Addr addr,
+ void writeOut(PortProxy* proxy, Addr addr,
Addr &headerSize, Addr &structSize);
};
diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc
index 28f1ac04d..612244f49 100644
--- a/src/arch/x86/interrupts.cc
+++ b/src/arch/x86/interrupts.cc
@@ -351,25 +351,27 @@ X86ISA::Interrupts::recvResponse(PacketPtr pkt)
}
-void
-X86ISA::Interrupts::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+X86ISA::Interrupts::getAddrRanges()
{
- range_list.clear();
+ AddrRangeList ranges;
Range<Addr> range = RangeEx(x86LocalAPICAddress(initialApicId, 0),
x86LocalAPICAddress(initialApicId, 0) +
PageBytes);
- range_list.push_back(range);
+ ranges.push_back(range);
pioAddr = range.start;
+ return ranges;
}
-void
-X86ISA::Interrupts::getIntAddrRange(AddrRangeList &range_list)
+AddrRangeList
+X86ISA::Interrupts::getIntAddrRange()
{
- range_list.clear();
- range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
- x86InterruptAddress(initialApicId, 0) +
- PhysAddrAPICRangeSize));
+ AddrRangeList ranges;
+ ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
+ x86InterruptAddress(initialApicId, 0) +
+ PhysAddrAPICRangeSize));
+ return ranges;
}
diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh
index 389eb4f42..8567b30f0 100644
--- a/src/arch/x86/interrupts.hh
+++ b/src/arch/x86/interrupts.hh
@@ -220,8 +220,8 @@ class Interrupts : public BasicPioDevice, IntDev
return entry.periodic;
}
- void addressRanges(AddrRangeList &range_list);
- void getIntAddrRange(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
+ AddrRangeList getIntAddrRange();
Port *getPort(const std::string &if_name, int idx = -1)
{
diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc
index 5ccb14394..c6faf391b 100644
--- a/src/arch/x86/linux/syscalls.cc
+++ b/src/arch/x86/linux/syscalls.cc
@@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "x86_64");
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
@@ -81,7 +81,7 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
int code = process->getSyscallArg(tc, index);
uint64_t addr = process->getSyscallArg(tc, index);
uint64_t fsBase, gsBase;
- TranslatingPort *p = tc->getMemPort();
+ SETranslatingPortProxy* p = tc->getMemProxy();
switch(code)
{
//Each of these valid options should actually check addr.
@@ -149,10 +149,10 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t),
numTLSEntries * sizeof(uint64_t));
- if (!userDesc.copyIn(tc->getMemPort()))
+ if (!userDesc.copyIn(tc->getMemProxy()))
return -EFAULT;
- if (!gdt.copyIn(tc->getMemPort()))
+ if (!gdt.copyIn(tc->getMemProxy()))
panic("Failed to copy in GDT for %s.\n", desc->name);
if (userDesc->entry_number == (uint32_t)(-1)) {
@@ -204,9 +204,9 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
gdt[index] = (uint64_t)segDesc;
- if (!userDesc.copyOut(tc->getMemPort()))
+ if (!userDesc.copyOut(tc->getMemProxy()))
return -EFAULT;
- if (!gdt.copyOut(tc->getMemPort()))
+ if (!gdt.copyOut(tc->getMemProxy()))
panic("Failed to copy out GDT for %s.\n", desc->name);
return 0;
diff --git a/src/arch/x86/linux/system.cc b/src/arch/x86/linux/system.cc
index 104f93372..a933868d1 100644
--- a/src/arch/x86/linux/system.cc
+++ b/src/arch/x86/linux/system.cc
@@ -43,7 +43,7 @@
#include "arch/vtophys.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
-#include "mem/physical.hh"
+#include "mem/port_proxy.hh"
#include "params/LinuxX86System.hh"
#include "sim/byteswap.hh"
@@ -67,8 +67,8 @@ LinuxX86System::initState()
// The location of the real mode data structure.
const Addr realModeData = 0x90200;
- // A port to write to memory.
- FunctionalPort * physPort = threadContexts[0]->getPhysPort();
+ // A port proxy to write to memory.
+ PortProxy* physProxy = threadContexts[0]->getPhysProxy();
/*
* Deal with the command line stuff.
@@ -82,14 +82,14 @@ LinuxX86System::initState()
if (commandLine.length() + 1 > realModeData - commandLineBuff)
panic("Command line \"%s\" is longer than %d characters.\n",
commandLine, realModeData - commandLineBuff - 1);
- physPort->writeBlob(commandLineBuff,
+ physProxy->writeBlob(commandLineBuff,
(uint8_t *)commandLine.c_str(), commandLine.length() + 1);
// Generate a pointer of the right size and endianness to put into
// commandLinePointer.
uint32_t guestCommandLineBuff =
X86ISA::htog((uint32_t)commandLineBuff);
- physPort->writeBlob(commandLinePointer,
+ physProxy->writeBlob(commandLinePointer,
(uint8_t *)&guestCommandLineBuff, sizeof(guestCommandLineBuff));
/*
@@ -127,7 +127,7 @@ LinuxX86System::initState()
// A pointer to the buffer for E820 entries.
const Addr e820MapPointer = realModeData + 0x2d0;
- e820Table->writeTo(physPort, e820MapNrPointer, e820MapPointer);
+ e820Table->writeTo(getSystemPort(), e820MapNrPointer, e820MapPointer);
/*
* Pass the location of the real mode data structure to the kernel
diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc
index c80fe10fc..5b1730f0c 100644
--- a/src/arch/x86/pagetable_walker.cc
+++ b/src/arch/x86/pagetable_walker.cc
@@ -154,17 +154,8 @@ Walker::WalkerPort::recvFunctional(PacketPtr pkt)
}
void
-Walker::WalkerPort::recvStatusChange(Status status)
+Walker::WalkerPort::recvRangeChange()
{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("Unexpected recvStatusChange.\n");
}
void
diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh
index b0edc434f..73e185148 100644
--- a/src/arch/x86/pagetable_walker.hh
+++ b/src/arch/x86/pagetable_walker.hh
@@ -63,26 +63,18 @@ namespace X86ISA
{
public:
WalkerPort(const std::string &_name, Walker * _walker) :
- Port(_name, _walker), walker(_walker),
- snoopRangeSent(false)
+ Port(_name, _walker), walker(_walker)
{}
protected:
Walker * walker;
- bool snoopRangeSent;
-
bool recvTiming(PacketPtr pkt);
Tick recvAtomic(PacketPtr pkt);
void recvFunctional(PacketPtr pkt);
- void recvStatusChange(Status status);
+ void recvRangeChange();
void recvRetry();
- void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- {
- resp.clear();
- snoop = true;
- }
+ bool isSnooping() { return true; }
};
friend class WalkerPort;
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index f5ba787c9..32fc8ca70 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -53,7 +53,6 @@
#include "cpu/thread_context.hh"
#include "debug/Stack.hh"
#include "mem/page_table.hh"
-#include "mem/translating_port.hh"
#include "sim/process_impl.hh"
#include "sim/syscall_emul.hh"
#include "sim/system.hh"
diff --git a/src/arch/x86/stacktrace.cc b/src/arch/x86/stacktrace.cc
index e2ec04fa7..e3d30d5cd 100644
--- a/src/arch/x86/stacktrace.cc
+++ b/src/arch/x86/stacktrace.cc
@@ -37,7 +37,7 @@
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "sim/system.hh"
using namespace std;
@@ -48,9 +48,9 @@ namespace X86ISA
{
Addr addr = 0;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
panic("thread info not compiled into kernel\n");
@@ -82,9 +82,9 @@ namespace X86ISA
Addr tsk;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
tsk = vp->readGtoH<Addr>(base + task_off);
return tsk;
@@ -99,9 +99,9 @@ namespace X86ISA
uint16_t pd;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
pd = vp->readGtoH<uint16_t>(task + pid_off);
return pd;
diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc
index d287e3947..ca13fd5ce 100644
--- a/src/arch/x86/system.cc
+++ b/src/arch/x86/system.cc
@@ -48,7 +48,7 @@
#include "base/intmath.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
-#include "mem/physical.hh"
+#include "mem/port_proxy.hh"
#include "params/X86System.hh"
#include "sim/byteswap.hh"
@@ -61,8 +61,6 @@ X86System::X86System(Params *p) :
mpConfigTable(p->intel_mp_table),
rsdp(p->acpi_description_table_pointer)
{
- if (kernel->getArch() == ObjectFile::I386)
- fatal("Loading a 32 bit x86 kernel is not supported.\n");
}
static void
@@ -116,6 +114,9 @@ X86System::initState()
{
System::initState();
+ if (kernel->getArch() == ObjectFile::I386)
+ fatal("Loading a 32 bit x86 kernel is not supported.\n");
+
ThreadContext *tc = threadContexts[0];
// This is the boot strap processor (BSP). Initialize it to look like
// the boot loader has just turned control over to the 64 bit OS. We
@@ -137,8 +138,8 @@ X86System::initState()
const int PDPTBits = 9;
const int PDTBits = 9;
- // Get a port to write the page tables and descriptor tables.
- FunctionalPort * physPort = tc->getPhysPort();
+ // Get a port proxy to write the page tables and descriptor tables.
+ PortProxy* physProxy = tc->getPhysProxy();
/*
* Set up the gdt.
@@ -146,7 +147,7 @@ X86System::initState()
uint8_t numGDTEntries = 0;
// Place holder at selector 0
uint64_t nullDescriptor = 0;
- physPort->writeBlob(GDTBase + numGDTEntries * 8,
+ physProxy->writeBlob(GDTBase + numGDTEntries * 8,
(uint8_t *)(&nullDescriptor), 8);
numGDTEntries++;
@@ -168,7 +169,7 @@ X86System::initState()
//it's beginning in memory and it's actual data, we'll use an
//intermediary.
uint64_t csDescVal = csDesc;
- physPort->writeBlob(GDTBase + numGDTEntries * 8,
+ physProxy->writeBlob(GDTBase + numGDTEntries * 8,
(uint8_t *)(&csDescVal), 8);
numGDTEntries++;
@@ -191,7 +192,7 @@ X86System::initState()
dsDesc.limitHigh = 0xF;
dsDesc.limitLow = 0xFF;
uint64_t dsDescVal = dsDesc;
- physPort->writeBlob(GDTBase + numGDTEntries * 8,
+ physProxy->writeBlob(GDTBase + numGDTEntries * 8,
(uint8_t *)(&dsDescVal), 8);
numGDTEntries++;
@@ -219,7 +220,7 @@ X86System::initState()
tssDesc.limitHigh = 0xF;
tssDesc.limitLow = 0xFF;
uint64_t tssDescVal = tssDesc;
- physPort->writeBlob(GDTBase + numGDTEntries * 8,
+ physProxy->writeBlob(GDTBase + numGDTEntries * 8,
(uint8_t *)(&tssDescVal), 8);
numGDTEntries++;
@@ -249,24 +250,24 @@ X86System::initState()
// read/write, user, not present
uint64_t pml4e = X86ISA::htog(0x6);
for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) {
- physPort->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8);
+ physProxy->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8);
}
// Point to the only PDPT
pml4e = X86ISA::htog(0x7 | PageDirPtrTable);
- physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
+ physProxy->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
// Page Directory Pointer Table
// read/write, user, not present
uint64_t pdpe = X86ISA::htog(0x6);
for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) {
- physPort->writeBlob(PageDirPtrTable + offset,
+ physProxy->writeBlob(PageDirPtrTable + offset,
(uint8_t *)(&pdpe), 8);
}
// Point to the PDTs
for (int table = 0; table < NumPDTs; table++) {
pdpe = X86ISA::htog(0x7 | PageDirTable[table]);
- physPort->writeBlob(PageDirPtrTable + table * 8,
+ physProxy->writeBlob(PageDirPtrTable + table * 8,
(uint8_t *)(&pdpe), 8);
}
@@ -278,7 +279,7 @@ X86System::initState()
for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) {
// read/write, user, present, 4MB
uint64_t pdte = X86ISA::htog(0x87 | base);
- physPort->writeBlob(PageDirTable[table] + offset,
+ physProxy->writeBlob(PageDirTable[table] + offset,
(uint8_t *)(&pdte), 8);
base += pageSize;
}
@@ -341,8 +342,8 @@ void
X86System::writeOutSMBiosTable(Addr header,
Addr &headerSize, Addr &structSize, Addr table)
{
- // Get a port to write the table and header to memory.
- FunctionalPort * physPort = threadContexts[0]->getPhysPort();
+ // Get a port proxy to write the table and header to memory.
+ PortProxy* physProxy = threadContexts[0]->getPhysProxy();
// If the table location isn't specified, just put it after the header.
// The header size as of the 2.5 SMBios specification is 0x1F bytes
@@ -350,7 +351,7 @@ X86System::writeOutSMBiosTable(Addr header,
table = header + 0x1F;
smbiosTable->setTableAddr(table);
- smbiosTable->writeOut(physPort, header, headerSize, structSize);
+ smbiosTable->writeOut(physProxy, header, headerSize, structSize);
// Do some bounds checking to make sure we at least didn't step on
// ourselves.
@@ -362,8 +363,8 @@ void
X86System::writeOutMPTable(Addr fp,
Addr &fpSize, Addr &tableSize, Addr table)
{
- // Get a port to write the table and header to memory.
- FunctionalPort * physPort = threadContexts[0]->getPhysPort();
+ // Get a port proxy to write the table and header to memory.
+ PortProxy* physProxy = threadContexts[0]->getPhysProxy();
// If the table location isn't specified and it exists, just put
// it after the floating pointer. The fp size as of the 1.4 Intel MP
@@ -374,9 +375,9 @@ X86System::writeOutMPTable(Addr fp,
mpFloatingPointer->setTableAddr(table);
}
- fpSize = mpFloatingPointer->writeOut(physPort, fp);
+ fpSize = mpFloatingPointer->writeOut(physProxy, fp);
if (mpConfigTable)
- tableSize = mpConfigTable->writeOut(physPort, table);
+ tableSize = mpConfigTable->writeOut(physProxy, table);
else
tableSize = 0;
diff --git a/src/base/debug.cc b/src/base/debug.cc
index 71675aada..ba154f377 100644
--- a/src/base/debug.cc
+++ b/src/base/debug.cc
@@ -134,7 +134,7 @@ struct AllFlags : public Flag
FlagsMap::iterator end = allFlags().end();
for (; i != end; ++i)
if (i->second != this)
- i->second->enable();
+ i->second->disable();
}
};
diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
index 1b1841a45..80800e862 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -414,15 +414,15 @@ ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
}
bool
-ElfObject::loadSections(Port *memPort, Addr addrMask)
+ElfObject::loadSections(PortProxy* memProxy, Addr addrMask)
{
- if (!ObjectFile::loadSections(memPort, addrMask))
+ if (!ObjectFile::loadSections(memProxy, addrMask))
return false;
vector<Segment>::iterator extraIt;
for (extraIt = extraSegments.begin();
extraIt != extraSegments.end(); extraIt++) {
- if (!loadSection(&(*extraIt), memPort, addrMask)) {
+ if (!loadSection(&(*extraIt), memProxy, addrMask)) {
return false;
}
}
diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh
index fe75927c5..afb61c21d 100644
--- a/src/base/loader/elf_object.hh
+++ b/src/base/loader/elf_object.hh
@@ -65,7 +65,7 @@ class ElfObject : public ObjectFile
public:
virtual ~ElfObject() {}
- bool loadSections(Port *memPort,
+ bool loadSections(PortProxy *memProxy,
Addr addrMask = std::numeric_limits<Addr>::max());
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max());
diff --git a/src/base/loader/hex_file.cc b/src/base/loader/hex_file.cc
index 854834b2b..d38c0fb62 100755
--- a/src/base/loader/hex_file.cc
+++ b/src/base/loader/hex_file.cc
@@ -36,7 +36,7 @@
#include "base/loader/hex_file.hh"
#include "base/loader/symtab.hh"
#include "base/cprintf.hh"
-#include "mem/translating_port.hh"
+#include "mem/port_proxy.hh"
using namespace std;
/*
@@ -59,7 +59,7 @@ HexFile::~HexFile()
}
bool
-HexFile::loadSections(Port *memPort)
+HexFile::loadSections(PortProxy* memProxy)
{
char Line[64];
Addr MemAddr;
@@ -71,7 +71,7 @@ HexFile::loadSections(Port *memPort)
parseLine(Line, &MemAddr, &Data);
if (MemAddr != 0) {
// Now, write to memory
- memPort->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
+ memProxy->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
}
}
return true;
diff --git a/src/base/loader/hex_file.hh b/src/base/loader/hex_file.hh
index 87a7eb0f3..514a02a1e 100755
--- a/src/base/loader/hex_file.hh
+++ b/src/base/loader/hex_file.hh
@@ -37,7 +37,7 @@
#include "base/types.hh"
-class Port;
+class PortProxy;
class HexFile
{
@@ -52,7 +52,7 @@ class HexFile
virtual ~HexFile();
void close();
- bool loadSections(Port *memPort);
+ bool loadSections(PortProxy* memProxy);
};
#endif // __BASE_LOADER_HEX_FILE_HH__
diff --git a/src/base/loader/object_file.cc b/src/base/loader/object_file.cc
index 9dcbd7936..eaf0443bf 100644
--- a/src/base/loader/object_file.cc
+++ b/src/base/loader/object_file.cc
@@ -45,7 +45,7 @@
#include "base/loader/raw_object.hh"
#include "base/loader/symtab.hh"
#include "base/cprintf.hh"
-#include "mem/translating_port.hh"
+#include "mem/port_proxy.hh"
using namespace std;
@@ -65,16 +65,16 @@ ObjectFile::~ObjectFile()
bool
-ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
+ObjectFile::loadSection(Section *sec, PortProxy* memProxy, Addr addrMask)
{
if (sec->size != 0) {
Addr addr = sec->baseAddr & addrMask;
if (sec->fileImage) {
- memPort->writeBlob(addr, sec->fileImage, sec->size);
+ memProxy->writeBlob(addr, sec->fileImage, sec->size);
}
else {
// no image: must be bss
- memPort->memsetBlob(addr, 0, sec->size);
+ memProxy->memsetBlob(addr, 0, sec->size);
}
}
return true;
@@ -82,11 +82,11 @@ ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
bool
-ObjectFile::loadSections(Port *memPort, Addr addrMask)
+ObjectFile::loadSections(PortProxy* memProxy, Addr addrMask)
{
- return (loadSection(&text, memPort, addrMask)
- && loadSection(&data, memPort, addrMask)
- && loadSection(&bss, memPort, addrMask));
+ return (loadSection(&text, memProxy, addrMask)
+ && loadSection(&data, memProxy, addrMask)
+ && loadSection(&bss, memProxy, addrMask));
}
diff --git a/src/base/loader/object_file.hh b/src/base/loader/object_file.hh
index bffab0cc5..ce58a2c4f 100644
--- a/src/base/loader/object_file.hh
+++ b/src/base/loader/object_file.hh
@@ -37,7 +37,7 @@
#include "base/types.hh"
-class Port;
+class PortProxy;
class SymbolTable;
class ObjectFile
@@ -83,7 +83,7 @@ class ObjectFile
void close();
- virtual bool loadSections(Port *memPort, Addr addrMask =
+ virtual bool loadSections(PortProxy *memProxy, Addr addrMask =
std::numeric_limits<Addr>::max());
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
std::numeric_limits<Addr>::max()) = 0;
@@ -111,7 +111,7 @@ class ObjectFile
Section data;
Section bss;
- bool loadSection(Section *sec, Port *memPort, Addr addrMask);
+ bool loadSection(Section *sec, PortProxy* memProxy, Addr addrMask);
void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
public:
diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc
index 021ef3684..7b38753e2 100644
--- a/src/base/remote_gdb.cc
+++ b/src/base/remote_gdb.cc
@@ -132,8 +132,8 @@
#include "cpu/thread_context.hh"
#include "debug/GDBAll.hh"
#include "mem/port.hh"
-#include "mem/translating_port.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "sim/full_system.hh"
#include "sim/system.hh"
@@ -461,10 +461,10 @@ BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
if (FullSystem) {
- VirtualPort *port = context->getVirtPort();
+ FSTranslatingPortProxy *port = context->getVirtProxy();
port->readBlob(vaddr, (uint8_t*)data, size);
} else {
- TranslatingPort *port = context->getMemPort();
+ SETranslatingPortProxy *port = context->getMemProxy();
port->readBlob(vaddr, (uint8_t*)data, size);
}
@@ -504,10 +504,10 @@ BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
DPRINTFNR("\n");
}
if (FullSystem) {
- VirtualPort *port = context->getVirtPort();
+ FSTranslatingPortProxy *port = context->getVirtProxy();
port->writeBlob(vaddr, (uint8_t*)data, size);
} else {
- TranslatingPort *port = context->getMemPort();
+ SETranslatingPortProxy *port = context->getMemProxy();
port->writeBlob(vaddr, (uint8_t*)data, size);
delete port;
}
diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh
index 7c1228e59..899c7c29e 100644
--- a/src/base/remote_gdb.hh
+++ b/src/base/remote_gdb.hh
@@ -216,7 +216,7 @@ class BaseRemoteGDB
bool insertSoftBreak(Addr addr, size_t len);
bool removeSoftBreak(Addr addr, size_t len);
- bool insertHardBreak(Addr addr, size_t len);
+ virtual bool insertHardBreak(Addr addr, size_t len);
bool removeHardBreak(Addr addr, size_t len);
protected:
diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py
index 50a8501e2..19464acbc 100644
--- a/src/cpu/BaseCPU.py
+++ b/src/cpu/BaseCPU.py
@@ -138,9 +138,12 @@ class BaseCPU(MemObject):
tracer = Param.InstTracer(default_tracer, "Instruction tracer")
- _cached_ports = []
+ icache_port = Port("Instruction Port")
+ dcache_port = Port("Data Port")
+ _cached_ports = ['icache_port', 'dcache_port']
+
if buildEnv['TARGET_ISA'] in ['x86', 'arm']:
- _cached_ports = ["itb.walker.port", "dtb.walker.port"]
+ _cached_ports += ["itb.walker.port", "dtb.walker.port"]
_uncached_ports = []
if buildEnv['TARGET_ISA'] == 'x86':
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index a0785ac10..d174995a9 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2011 Regents of the University of California
* All rights reserved.
@@ -470,3 +482,36 @@ BaseCPU::traceFunctionsInternal(Addr pc)
functionEntryTick = curTick();
}
}
+
+bool
+BaseCPU::CpuPort::recvTiming(PacketPtr pkt)
+{
+ panic("BaseCPU doesn't expect recvTiming callback!");
+ return true;
+}
+
+void
+BaseCPU::CpuPort::recvRetry()
+{
+ panic("BaseCPU doesn't expect recvRetry callback!");
+}
+
+Tick
+BaseCPU::CpuPort::recvAtomic(PacketPtr pkt)
+{
+ panic("BaseCPU doesn't expect recvAtomic callback!");
+ return curTick();
+}
+
+void
+BaseCPU::CpuPort::recvFunctional(PacketPtr pkt)
+{
+ // No internal storage to update (in the general case). In the
+ // long term this should never be called, but that assumed a split
+ // into master/slave and request/response.
+}
+
+void
+BaseCPU::CpuPort::recvRangeChange()
+{
+}
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index a4ffb4716..41c79dff6 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2011 Regents of the University of California
* All rights reserved.
@@ -92,6 +104,42 @@ class BaseCPU : public MemObject
// therefore no setCpuId() method is provided
int _cpuId;
+ /**
+ * Define a base class for the CPU ports (instruction and data)
+ * that is refined in the subclasses. This class handles the
+ * common cases, i.e. the functional accesses and the status
+ * changes and address range queries. The default behaviour for
+ * both atomic and timing access is to panic and the corresponding
+ * subclasses have to override these methods.
+ */
+ class CpuPort : public Port
+ {
+ public:
+
+ /**
+ * Create a CPU port with a name and a structural owner.
+ *
+ * @param _name port name including the owner
+ * @param _name structural owner of this port
+ */
+ CpuPort(const std::string& _name, MemObject* _owner) :
+ Port(_name, _owner)
+ { }
+
+ protected:
+
+ virtual bool recvTiming(PacketPtr pkt);
+
+ virtual Tick recvAtomic(PacketPtr pkt);
+
+ virtual void recvRetry();
+
+ void recvFunctional(PacketPtr pkt);
+
+ void recvRangeChange();
+
+ };
+
public:
/** Reads this CPU's ID. */
int cpuId() { return _cpuId; }
diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh
index 6c3c50a9c..178ded80e 100644
--- a/src/cpu/checker/thread_context.hh
+++ b/src/cpu/checker/thread_context.hh
@@ -98,12 +98,12 @@ class CheckerThreadContext : public ThreadContext
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
- TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
+ PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
- VirtualPort *getVirtPort()
- { return actualTC->getVirtPort(); }
+ FSTranslatingPortProxy* getVirtProxy()
+ { return actualTC->getVirtProxy(); }
- FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
+ SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
Status status() const { return actualTC->status(); }
diff --git a/src/cpu/inorder/InOrderCPU.py b/src/cpu/inorder/InOrderCPU.py
index 4766a1ac1..40af48b19 100644
--- a/src/cpu/inorder/InOrderCPU.py
+++ b/src/cpu/inorder/InOrderCPU.py
@@ -44,9 +44,6 @@ class InOrderCPU(BaseCPU):
fetchMemPort = Param.String("icache_port" , "Name of Memory Port to get instructions from")
dataMemPort = Param.String("dcache_port" , "Name of Memory Port to get data from")
- icache_port = Port("Instruction Port")
- dcache_port = Port("Data Port")
- _cached_ports = ['icache_port', 'dcache_port']
fetchBuffSize = Param.Unsigned(4, "Fetch Buffer Size (Number of Cache Blocks Stored)")
memBlockSize = Param.Unsigned(64, "Memory Block Size")
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index 010bdb512..5a14e92a7 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -54,7 +54,6 @@
#include "debug/RefCount.hh"
#include "debug/SkedCache.hh"
#include "debug/Quiesce.hh"
-#include "mem/translating_port.hh"
#include "params/InOrderCPU.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"
@@ -758,6 +757,8 @@ InOrderCPU::init()
for (ThreadID tid = 0; tid < numThreads; tid++) {
ThreadContext *src_tc = threadContexts[tid];
TheISA::initCPU(src_tc, src_tc->contextId());
+ // Initialise the ThreadContext's memory proxies
+ thread[tid]->initMemProxies(thread[tid]->getTC());
}
}
@@ -860,7 +861,6 @@ InOrderCPU::getInterrupts()
return interrupts->getInterrupt(threadContexts[0]);
}
-
void
InOrderCPU::processInterrupts(Fault interrupt)
{
@@ -880,16 +880,6 @@ InOrderCPU::processInterrupts(Fault interrupt)
}
void
-InOrderCPU::updateMemPorts()
-{
- // Update all ThreadContext's memory ports (Functional/Virtual
- // Ports)
- ThreadID size = thread.size();
- for (ThreadID i = 0; i < size; ++i)
- thread[i]->connectMemPorts(thread[i]->getTC());
-}
-
-void
InOrderCPU::trapContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
{
scheduleCpuEvent(Trap, fault, tid, inst, delay);
diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh
index bbd02e027..7d22bc902 100644
--- a/src/cpu/inorder/cpu.hh
+++ b/src/cpu/inorder/cpu.hh
@@ -428,10 +428,6 @@ class InOrderCPU : public BaseCPU
/** Halts the CPU. */
void halt() { panic("Halt not implemented!\n"); }
- /** Update the Virt and Phys ports of all ThreadContexts to
- * reflect change in memory connections. */
- void updateMemPorts();
-
/** Check if this address is a valid instruction address. */
bool validInstAddr(Addr addr) { return true; }
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
index 90ed83d68..0ab9f0579 100644
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ b/src/cpu/inorder/resources/cache_unit.cc
@@ -82,17 +82,8 @@ CacheUnit::CachePort::recvFunctional(PacketPtr pkt)
}
void
-CacheUnit::CachePort::recvStatusChange(Status status)
+CacheUnit::CachePort::recvRangeChange()
{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("CacheUnit::CachePort doesn't expect recvStatusChange callback!");
}
bool
@@ -145,18 +136,6 @@ CacheUnit::tlb()
}
-void
-CacheUnit::CachePort::setPeer(Port *port)
-{
- Port::setPeer(port);
-
- // Update the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- if (cachePortUnit->resName == "dcache_port") {
- cachePortUnit->cpu->updateMemPorts();
- }
-}
-
Port *
CacheUnit::getPort(const string &if_name, int idx)
{
diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh
index a8dde512b..2155c920c 100644
--- a/src/cpu/inorder/resources/cache_unit.hh
+++ b/src/cpu/inorder/resources/cache_unit.hh
@@ -90,13 +90,9 @@ class CacheUnit : public Resource
CachePort(CacheUnit *_cachePortUnit)
: Port(_cachePortUnit->name() + "-cache-port",
(MemObject*)_cachePortUnit->cpu),
- cachePortUnit(_cachePortUnit), snoopRangeSent(false)
+ cachePortUnit(_cachePortUnit)
{ }
- bool snoopRangeSent;
-
- void setPeer(Port *port);
-
protected:
/** Atomic version of receive. Panics. */
Tick recvAtomic(PacketPtr pkt);
@@ -104,13 +100,8 @@ class CacheUnit : public Resource
/** Functional version of receive.*/
void recvFunctional(PacketPtr pkt);
- /** Receives status change. Other than range changing, panics. */
- void recvStatusChange(Status status);
-
- /** Returns the address ranges of this device. */
- void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = true; }
+ /** Receives range changes. */
+ void recvRangeChange();
/** Timing version of receive */
bool recvTiming(PacketPtr pkt);
diff --git a/src/cpu/inorder/thread_context.cc b/src/cpu/inorder/thread_context.cc
index 5f141a1b3..acfcf0939 100644
--- a/src/cpu/inorder/thread_context.cc
+++ b/src/cpu/inorder/thread_context.cc
@@ -38,10 +38,10 @@
using namespace TheISA;
-VirtualPort *
-InOrderThreadContext::getVirtPort()
+FSTranslatingPortProxy*
+InOrderThreadContext::getVirtProxy()
{
- return thread->getVirtPort();
+ return thread->getVirtProxy();
}
void
diff --git a/src/cpu/inorder/thread_context.hh b/src/cpu/inorder/thread_context.hh
index 84d62137e..7fe0fb5ef 100644
--- a/src/cpu/inorder/thread_context.hh
+++ b/src/cpu/inorder/thread_context.hh
@@ -117,8 +117,12 @@ class InOrderThreadContext : public ThreadContext
TheISA::Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; }
- void connectMemPorts(ThreadContext *tc)
- { thread->connectMemPorts(tc); }
+ PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
+
+ FSTranslatingPortProxy* getVirtProxy();
+
+ void initMemProxies(ThreadContext *tc)
+ { thread->initMemProxies(tc); }
/** Dumps the function profiling information.
* @todo: Implement.
@@ -142,14 +146,11 @@ class InOrderThreadContext : public ThreadContext
return this->thread->quiesceEvent;
}
+ SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
+
/** Returns a pointer to this thread's process. */
Process *getProcessPtr() { return thread->getProcessPtr(); }
- TranslatingPort *getMemPort() { return thread->getMemPort(); }
-
- VirtualPort *getVirtPort();
- FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
-
/** Returns this thread's status. */
Status status() const { return thread->status(); }
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
index 1d8950a73..ffc817e81 100644
--- a/src/cpu/o3/O3CPU.py
+++ b/src/cpu/o3/O3CPU.py
@@ -49,9 +49,6 @@ class DerivO3CPU(BaseCPU):
checker.dtb = Parent.dtb
cachePorts = Param.Unsigned(200, "Cache Ports")
- icache_port = Port("Instruction Port")
- dcache_port = Port("Data Port")
- _cached_ports = BaseCPU._cached_ports + ['icache_port', 'dcache_port']
decodeToFetchDelay = Param.Unsigned(1, "Decode to fetch delay")
renameToFetchDelay = Param.Unsigned(1 ,"Rename to fetch delay")
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 5d3af6c70..ef08c96f4 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* Copyright (c) 2011 Regents of the University of California
* All rights reserved.
@@ -76,6 +88,42 @@ BaseO3CPU::regStats()
BaseCPU::regStats();
}
+template<class Impl>
+bool
+FullO3CPU<Impl>::IcachePort::recvTiming(PacketPtr pkt)
+{
+ DPRINTF(O3CPU, "Fetch unit received timing\n");
+ if (pkt->isResponse()) {
+ // We shouldn't ever get a block in ownership state
+ assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
+
+ fetch->processCacheCompletion(pkt);
+ }
+ //else Snooped a coherence request, just return
+ return true;
+}
+
+template<class Impl>
+void
+FullO3CPU<Impl>::IcachePort::recvRetry()
+{
+ fetch->recvRetry();
+}
+
+template <class Impl>
+bool
+FullO3CPU<Impl>::DcachePort::recvTiming(PacketPtr pkt)
+{
+ return lsq->recvTiming(pkt);
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::DcachePort::recvRetry()
+{
+ lsq->recvRetry();
+}
+
template <class Impl>
FullO3CPU<Impl>::TickEvent::TickEvent(FullO3CPU<Impl> *c)
: Event(CPU_Tick_Pri), cpu(c)
@@ -191,6 +239,9 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
TheISA::NumMiscRegs * numThreads,
TheISA::ZeroReg),
+ icachePort(&fetch, this),
+ dcachePort(&iew.ldstQueue, this),
+
timeBuffer(params->backComSize, params->forwardComSize),
fetchQueue(params->backComSize, params->forwardComSize),
decodeQueue(params->backComSize, params->forwardComSize),
@@ -215,6 +266,7 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
if (params->checker) {
BaseCPU *temp_checker = params->checker;
checker = dynamic_cast<Checker<DynInstPtr> *>(temp_checker);
+ checker->setIcachePort(&icachePort);
checker->setSystem(params->system);
} else {
checker = NULL;
@@ -524,9 +576,9 @@ Port *
FullO3CPU<Impl>::getPort(const std::string &if_name, int idx)
{
if (if_name == "dcache_port")
- return iew.getDcachePort();
+ return &dcachePort;
else if (if_name == "icache_port")
- return fetch.getIcachePort();
+ return &icachePort;
else
panic("No Such Port\n");
}
@@ -600,10 +652,19 @@ FullO3CPU<Impl>::init()
for (ThreadID tid = 0; tid < numThreads; ++tid)
thread[tid]->inSyscall = true;
+ // this CPU could still be unconnected if we are restoring from a
+ // checkpoint and this CPU is to be switched in, thus we can only
+ // do this here if the instruction port is actually connected, if
+ // not we have to do it as part of takeOverFrom
+ if (icachePort.isConnected())
+ fetch.setIcache();
+
if (FullSystem) {
for (ThreadID tid = 0; tid < numThreads; tid++) {
ThreadContext *src_tc = threadContexts[tid];
TheISA::initCPU(src_tc, src_tc->contextId());
+ // Initialise the ThreadContext's memory proxies
+ thread[tid]->initMemProxies(thread[tid]->getTC());
}
}
@@ -969,17 +1030,6 @@ FullO3CPU<Impl>::processInterrupts(Fault interrupt)
template <class Impl>
void
-FullO3CPU<Impl>::updateMemPorts()
-{
- // Update all ThreadContext's memory ports (Functional/Virtual
- // Ports)
- ThreadID size = thread.size();
- for (ThreadID i = 0; i < size; ++i)
- thread[i]->connectMemPorts(thread[i]->getTC());
-}
-
-template <class Impl>
-void
FullO3CPU<Impl>::trap(Fault fault, ThreadID tid, StaticInstPtr inst)
{
// Pass the thread's TC into the invoke method.
@@ -1166,7 +1216,7 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
activityRec.reset();
- BaseCPU::takeOverFrom(oldCPU, fetch.getIcachePort(), iew.getDcachePort());
+ BaseCPU::takeOverFrom(oldCPU, &icachePort, &dcachePort);
fetch.takeOverFrom();
decode.takeOverFrom();
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 7580106ad..165144c1b 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* Copyright (c) 2011 Regents of the University of California
* All rights reserved.
@@ -117,6 +129,68 @@ class FullO3CPU : public BaseO3CPU
Status _threadStatus[Impl::MaxThreads];
private:
+
+ /**
+ * IcachePort class for instruction fetch.
+ */
+ class IcachePort : public CpuPort
+ {
+ protected:
+ /** Pointer to fetch. */
+ DefaultFetch<Impl> *fetch;
+
+ public:
+ /** Default constructor. */
+ IcachePort(DefaultFetch<Impl> *_fetch, FullO3CPU<Impl>* _cpu)
+ : CpuPort(_fetch->name() + "-iport", _cpu), fetch(_fetch)
+ { }
+
+ protected:
+
+ /** Timing version of receive. Handles setting fetch to the
+ * proper status to start fetching. */
+ virtual bool recvTiming(PacketPtr pkt);
+
+ /** Handles doing a retry of a failed fetch. */
+ virtual void recvRetry();
+ };
+
+ /**
+ * DcachePort class for the load/store queue.
+ */
+ class DcachePort : public CpuPort
+ {
+ protected:
+
+ /** Pointer to LSQ. */
+ LSQ<Impl> *lsq;
+
+ public:
+ /** Default constructor. */
+ DcachePort(LSQ<Impl> *_lsq, FullO3CPU<Impl>* _cpu)
+ : CpuPort(_lsq->name() + "-dport", _cpu), lsq(_lsq)
+ { }
+
+ protected:
+
+ /** Timing version of receive. Handles writing back and
+ * completing the load or store that has returned from
+ * memory. */
+ virtual bool recvTiming(PacketPtr pkt);
+
+ /** Handles doing a retry of the previous send. */
+ virtual void recvRetry();
+
+ /**
+ * As this CPU requires snooping to maintain the load store queue
+ * change the behaviour from the base CPU port.
+ *
+ * @return true since we have to snoop
+ */
+ virtual bool isSnooping()
+ { return true; }
+ };
+
class TickEvent : public Event
{
private:
@@ -391,10 +465,6 @@ class FullO3CPU : public BaseO3CPU
/** Halts the CPU. */
void halt() { panic("Halt not implemented!\n"); }
- /** Update the Virt and Phys ports of all ThreadContexts to
- * reflect change in memory connections. */
- void updateMemPorts();
-
/** Check if this address is a valid instruction address. */
bool validInstAddr(Addr addr) { return true; }
@@ -565,6 +635,12 @@ class FullO3CPU : public BaseO3CPU
TheISA::ISA isa[Impl::MaxThreads];
+ /** Instruction port. Note that it has to appear after the fetch stage. */
+ IcachePort icachePort;
+
+ /** Data port. Note that it has to appear after the iew stages */
+ DcachePort dcachePort;
+
public:
/** Enum to give each stage a specific index, so when calling
* activateStage() or deactivateStage(), they can specify which stage
@@ -701,8 +777,11 @@ class FullO3CPU : public BaseO3CPU
data, store_idx);
}
+ /** Used by the fetch unit to get a hold of the instruction port. */
+ Port* getIcachePort() { return &icachePort; }
+
/** Get the dcache port (used to find block size for translations). */
- Port *getDcachePort() { return this->iew.ldstQueue.getDcachePort(); }
+ Port* getDcachePort() { return &dcachePort; }
Addr lockAddr;
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index d09d7f680..f5d275593 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2010-2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -85,48 +85,6 @@ class DefaultFetch
typedef TheISA::MachInst MachInst;
typedef TheISA::ExtMachInst ExtMachInst;
- /** IcachePort class for DefaultFetch. Handles doing the
- * communication with the cache/memory.
- */
- class IcachePort : public Port
- {
- protected:
- /** Pointer to fetch. */
- DefaultFetch<Impl> *fetch;
-
- public:
- /** Default constructor. */
- IcachePort(DefaultFetch<Impl> *_fetch)
- : Port(_fetch->name() + "-iport", _fetch->cpu), fetch(_fetch)
- { }
-
- bool snoopRangeSent;
-
- virtual void setPeer(Port *port);
-
- protected:
- /** Atomic version of receive. Panics. */
- virtual Tick recvAtomic(PacketPtr pkt);
-
- /** Functional version of receive. Panics. */
- virtual void recvFunctional(PacketPtr pkt);
-
- /** Receives status change. Other than range changing, panics. */
- virtual void recvStatusChange(Status status);
-
- /** Returns the address ranges of this device. */
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = true; }
-
- /** Timing version of receive. Handles setting fetch to the
- * proper status to start fetching. */
- virtual bool recvTiming(PacketPtr pkt);
-
- /** Handles doing a retry of a failed fetch. */
- virtual void recvRetry();
- };
-
class FetchTranslation : public BaseTLB::Translation
{
protected:
@@ -248,9 +206,6 @@ class DefaultFetch
/** Registers statistics. */
void regStats();
- /** Returns the icache port. */
- Port *getIcachePort() { return icachePort; }
-
/** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
@@ -266,6 +221,9 @@ class DefaultFetch
/** Tells the fetch stage that the Icache is set. */
void setIcache();
+ /** Handles retrying the fetch access. */
+ void recvRetry();
+
/** Processes cache completion event. */
void processCacheCompletion(PacketPtr pkt);
@@ -389,9 +347,6 @@ class DefaultFetch
StaticInstPtr curMacroop, TheISA::PCState thisPC,
TheISA::PCState nextPC, bool trace);
- /** Handles retrying the fetch access. */
- void recvRetry();
-
/** Returns the appropriate thread to fetch, given the fetch policy. */
ThreadID getFetchingThread(FetchPriority &fetch_priority);
@@ -440,9 +395,6 @@ class DefaultFetch
/** Wire used to write any information heading to decode. */
typename TimeBuffer<FetchStruct>::wire toDecode;
- /** Icache interface. */
- IcachePort *icachePort;
-
/** BPredUnit. */
BPredUnit branchPred;
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 28fd434fe..1b82f8a4c 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2010-2011 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -69,68 +69,6 @@
using namespace std;
template<class Impl>
-void
-DefaultFetch<Impl>::IcachePort::setPeer(Port *port)
-{
- Port::setPeer(port);
-
- fetch->setIcache();
-}
-
-template<class Impl>
-Tick
-DefaultFetch<Impl>::IcachePort::recvAtomic(PacketPtr pkt)
-{
- panic("DefaultFetch doesn't expect recvAtomic callback!");
- return curTick();
-}
-
-template<class Impl>
-void
-DefaultFetch<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
-{
- DPRINTF(Fetch, "DefaultFetch doesn't update its state from a "
- "functional call.\n");
-}
-
-template<class Impl>
-void
-DefaultFetch<Impl>::IcachePort::recvStatusChange(Status status)
-{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("DefaultFetch doesn't expect recvStatusChange callback!");
-}
-
-template<class Impl>
-bool
-DefaultFetch<Impl>::IcachePort::recvTiming(PacketPtr pkt)
-{
- DPRINTF(Fetch, "Received timing\n");
- if (pkt->isResponse()) {
- // We shouldn't ever get a block in ownership state
- assert(!(pkt->memInhibitAsserted() && !pkt->sharedAsserted()));
-
- fetch->processCacheCompletion(pkt);
- }
- //else Snooped a coherence request, just return
- return true;
-}
-
-template<class Impl>
-void
-DefaultFetch<Impl>::IcachePort::recvRetry()
-{
- fetch->recvRetry();
-}
-
-template<class Impl>
DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
: cpu(_cpu),
branchPred(params),
@@ -189,17 +127,6 @@ DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
// Get the size of an instruction.
instSize = sizeof(TheISA::MachInst);
-
- // Name is finally available, so create the port.
- icachePort = new IcachePort(this);
-
- icachePort->snoopRangeSent = false;
-
-#if USE_CHECKER
- if (cpu->checker) {
- cpu->checker->setIcachePort(icachePort);
- }
-#endif
}
template <class Impl>
@@ -402,8 +329,10 @@ template<class Impl>
void
DefaultFetch<Impl>::setIcache()
{
+ assert(cpu->getIcachePort()->isConnected());
+
// Size of cache block.
- cacheBlkSize = icachePort->peerBlockSize();
+ cacheBlkSize = cpu->getIcachePort()->peerBlockSize();
// Create mask to get rid of offset bits.
cacheBlkMask = (cacheBlkSize - 1);
@@ -494,6 +423,10 @@ template <class Impl>
void
DefaultFetch<Impl>::takeOverFrom()
{
+ // the instruction port is now connected so we can get the block
+ // size
+ setIcache();
+
// Reset all state
for (ThreadID i = 0; i < Impl::MaxThreads; ++i) {
stalls[i].decode = 0;
@@ -684,7 +617,7 @@ DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req)
fetchedCacheLines++;
// Access the cache.
- if (!icachePort->sendTiming(data_pkt)) {
+ if (!cpu->getIcachePort()->sendTiming(data_pkt)) {
assert(retryPkt == NULL);
assert(retryTid == InvalidThreadID);
DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid);
@@ -1403,7 +1336,7 @@ DefaultFetch<Impl>::recvRetry()
assert(retryTid != InvalidThreadID);
assert(fetchStatus[retryTid] == IcacheWaitRetry);
- if (icachePort->sendTiming(retryPkt)) {
+ if (cpu->getIcachePort()->sendTiming(retryPkt)) {
fetchStatus[retryTid] = IcacheWaitResponse;
retryPkt = NULL;
retryTid = InvalidThreadID;
diff --git a/src/cpu/o3/iew.hh b/src/cpu/o3/iew.hh
index 2c5858a51..0d7e0f68f 100644
--- a/src/cpu/o3/iew.hh
+++ b/src/cpu/o3/iew.hh
@@ -138,9 +138,6 @@ class DefaultIEW
/** Initializes stage; sends back the number of free IQ and LSQ entries. */
void initStage();
- /** Returns the dcache port. */
- Port *getDcachePort() { return ldstQueue.getDcachePort(); }
-
/** Sets main time buffer used for backwards communication. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index 1974af08f..db127a2da 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -65,13 +77,6 @@ class LSQ {
/** Registers statistics of each LSQ unit. */
void regStats();
- /** Returns dcache port.
- * @todo: Dcache port needs to be moved up to this level for SMT
- * to work. For now it just returns the port from one of the
- * threads.
- */
- Port *getDcachePort() { return &dcachePort; }
-
/** Sets the pointer to the list of active threads. */
void setActiveThreads(std::list<ThreadID> *at_ptr);
/** Switches out the LSQ. */
@@ -281,61 +286,25 @@ class LSQ {
Fault write(RequestPtr req, RequestPtr sreqLow, RequestPtr sreqHigh,
uint8_t *data, int store_idx);
+ /**
+ * Retry the previous send that failed.
+ */
+ void recvRetry();
+
+ /**
+ * Handles writing back and completing the load or store that has
+ * returned from memory.
+ *
+ * @param pkt Response packet from the memory sub-system
+ */
+ bool recvTiming(PacketPtr pkt);
+
/** The CPU pointer. */
O3CPU *cpu;
/** The IEW stage pointer. */
IEW *iewStage;
- /** DcachePort class for this LSQ. Handles doing the
- * communication with the cache/memory.
- */
- class DcachePort : public Port
- {
- protected:
- /** Pointer to LSQ. */
- LSQ *lsq;
-
- public:
- /** Default constructor. */
- DcachePort(LSQ *_lsq)
- : Port(_lsq->name() + "-dport", _lsq->cpu), lsq(_lsq)
- { }
-
- bool snoopRangeSent;
-
- virtual void setPeer(Port *port);
-
- protected:
- /** Atomic version of receive. Panics. */
- virtual Tick recvAtomic(PacketPtr pkt);
-
- /** Functional version of receive. Panics. */
- virtual void recvFunctional(PacketPtr pkt);
-
- /** Receives status change. Other than range changing, panics. */
- virtual void recvStatusChange(Status status);
-
- /** Returns the address ranges of this device. */
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = true; }
-
- /** Timing version of receive. Handles writing back and
- * completing the load or store that has returned from
- * memory. */
- virtual bool recvTiming(PacketPtr pkt);
-
- /** Handles doing a retry of the previous send. */
- virtual void recvRetry();
- };
-
- /** D-cache port. */
- DcachePort dcachePort;
-
- /** Tell the CPU to update the Phys and Virt ports. */
- void updateMemPorts() { cpu->updateMemPorts(); }
-
protected:
/** The LSQ policy for SMT mode. */
LSQPolicy lsqPolicy;
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index 8b1638c70..f1642be9c 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2005-2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -40,96 +52,14 @@
using namespace std;
-template<class Impl>
-void
-LSQ<Impl>::DcachePort::setPeer(Port *port)
-{
- Port::setPeer(port);
-
- // Update the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- lsq->updateMemPorts();
-}
-
-template <class Impl>
-Tick
-LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
-{
- panic("O3CPU model does not work with atomic mode!");
- return curTick();
-}
-
-template <class Impl>
-void
-LSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
-{
- DPRINTF(LSQ, "LSQ doesn't update things on a recvFunctional.\n");
-}
-
-template <class Impl>
-void
-LSQ<Impl>::DcachePort::recvStatusChange(Status status)
-{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
- panic("O3CPU doesn't expect recvStatusChange callback!");
-}
-
-template <class Impl>
-bool
-LSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
-{
- if (pkt->isError())
- DPRINTF(LSQ, "Got error packet back for address: %#X\n", pkt->getAddr());
- if (pkt->isResponse()) {
- lsq->thread[pkt->req->threadId()].completeDataAccess(pkt);
- } else {
- DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
- pkt->cmdString());
-
- // must be a snoop
- if (pkt->isInvalidate()) {
- DPRINTF(LSQ, "received invalidation for addr:%#x\n", pkt->getAddr());
- for (ThreadID tid = 0; tid < lsq->numThreads; tid++) {
- lsq->thread[tid].checkSnoop(pkt);
- }
- }
- // to provide stronger consistency model
- }
- return true;
-}
-
-template <class Impl>
-void
-LSQ<Impl>::DcachePort::recvRetry()
-{
- if (lsq->retryTid == -1)
- {
- //Squashed, so drop it
- return;
- }
- int curr_retry_tid = lsq->retryTid;
- // Speculatively clear the retry Tid. This will get set again if
- // the LSQUnit was unable to complete its access.
- lsq->retryTid = -1;
- lsq->thread[curr_retry_tid].recvRetry();
-}
-
template <class Impl>
LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
- : cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this),
+ : cpu(cpu_ptr), iewStage(iew_ptr),
LQEntries(params->LQEntries),
SQEntries(params->SQEntries),
numThreads(params->numThreads),
retryTid(-1)
{
- dcachePort.snoopRangeSent = false;
-
//**********************************************/
//************ Handle SMT Parameters ***********/
//**********************************************/
@@ -181,7 +111,7 @@ LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
for (ThreadID tid = 0; tid < numThreads; tid++) {
thread[tid].init(cpu, iew_ptr, params, this,
maxLQEntries, maxSQEntries, tid);
- thread[tid].setDcachePort(&dcachePort);
+ thread[tid].setDcachePort(cpu_ptr->getDcachePort());
}
}
@@ -371,6 +301,48 @@ LSQ<Impl>::violation()
return false;
}
+template <class Impl>
+void
+LSQ<Impl>::recvRetry()
+{
+ if (retryTid == InvalidThreadID)
+ {
+ //Squashed, so drop it
+ return;
+ }
+ int curr_retry_tid = retryTid;
+ // Speculatively clear the retry Tid. This will get set again if
+ // the LSQUnit was unable to complete its access.
+ retryTid = -1;
+ thread[curr_retry_tid].recvRetry();
+}
+
+template <class Impl>
+bool
+LSQ<Impl>::recvTiming(PacketPtr pkt)
+{
+ if (pkt->isError())
+ DPRINTF(LSQ, "Got error packet back for address: %#X\n",
+ pkt->getAddr());
+ if (pkt->isResponse()) {
+ thread[pkt->req->threadId()].completeDataAccess(pkt);
+ } else {
+ DPRINTF(LSQ, "received pkt for addr:%#x %s\n", pkt->getAddr(),
+ pkt->cmdString());
+
+ // must be a snoop
+ if (pkt->isInvalidate()) {
+ DPRINTF(LSQ, "received invalidation for addr:%#x\n",
+ pkt->getAddr());
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ thread[tid].checkSnoop(pkt);
+ }
+ }
+ // to provide stronger consistency model
+ }
+ return true;
+}
+
template<class Impl>
int
LSQ<Impl>::getCount()
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index 815c9cb64..ff6ca0093 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -96,17 +96,18 @@ class O3ThreadContext : public ThreadContext
virtual TheISA::Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; }
- virtual void connectMemPorts(ThreadContext *tc)
- { thread->connectMemPorts(tc); }
-
/** Returns a pointer to this thread's process. */
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
- virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
+ virtual PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
+
+ virtual FSTranslatingPortProxy* getVirtProxy();
- virtual VirtualPort *getVirtPort();
+ virtual void initMemProxies(ThreadContext *tc)
+ { thread->initMemProxies(tc); }
- virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+ virtual SETranslatingPortProxy* getMemProxy()
+ { return thread->getMemProxy(); }
/** Returns this thread's status. */
virtual Status status() const { return thread->status(); }
diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh
index 15fc397dc..5ba454458 100755
--- a/src/cpu/o3/thread_context_impl.hh
+++ b/src/cpu/o3/thread_context_impl.hh
@@ -49,10 +49,10 @@
#include "debug/O3CPU.hh"
template <class Impl>
-VirtualPort *
-O3ThreadContext<Impl>::getVirtPort()
+FSTranslatingPortProxy*
+O3ThreadContext<Impl>::getVirtProxy()
{
- return thread->getVirtPort();
+ return thread->getVirtProxy();
}
template <class Impl>
diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh
index 36df58ab5..ff43ad6cb 100644
--- a/src/cpu/ozone/cpu.hh
+++ b/src/cpu/ozone/cpu.hh
@@ -114,12 +114,12 @@ class OzoneCPU : public BaseCPU
Process *getProcessPtr() { return thread->getProcessPtr(); }
- TranslatingPort *getMemPort() { return thread->getMemPort(); }
+ PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
- VirtualPort *getVirtPort()
- { return thread->getVirtPort(); }
+ FSTranslatingPortProxy* getVirtProxy()
+ { return thread->getVirtProxy(); }
- FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+ SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
Status status() const { return thread->status(); }
diff --git a/src/cpu/ozone/cpu_impl.hh b/src/cpu/ozone/cpu_impl.hh
index e2f5dc10c..f532078fe 100644
--- a/src/cpu/ozone/cpu_impl.hh
+++ b/src/cpu/ozone/cpu_impl.hh
@@ -186,25 +186,7 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
frontEnd->renameTable.copyFrom(thread.renameTable);
backEnd->renameTable.copyFrom(thread.renameTable);
- if (FullSystem) {
- Port *mem_port;
- FunctionalPort *phys_port;
- VirtualPort *virt_port;
- phys_port = new FunctionalPort(csprintf("%s-%d-funcport",
- name(), 0));
- mem_port = system->physmem->getPort("functional");
- mem_port->setPeer(phys_port);
- phys_port->setPeer(mem_port);
-
- virt_port = new VirtualPort(csprintf("%s-%d-vport",
- name(), 0));
- mem_port = system->physmem->getPort("functional");
- mem_port->setPeer(virt_port);
- virt_port->setPeer(mem_port);
-
- thread.setPhysPort(phys_port);
- thread.setVirtPort(virt_port);
- }
+ thread.connectMemPorts(tc);
DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
}
diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh
index 1d200ef7d..41b86aab8 100644
--- a/src/cpu/ozone/front_end.hh
+++ b/src/cpu/ozone/front_end.hh
@@ -87,13 +87,8 @@ class FrontEnd
/** Functional version of receive. Panics. */
virtual void recvFunctional(PacketPtr pkt);
- /** Receives status change. Other than range changing, panics. */
- virtual void recvStatusChange(Status status);
-
- /** Returns the address ranges of this device. */
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = true; }
+ /** Receives range change. */
+ virtual void recvRangeChange();
/** Timing version of receive. Handles setting fetch to the
* proper status to start fetching. */
diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh
index 88576de3d..e7255d75f 100644
--- a/src/cpu/ozone/front_end_impl.hh
+++ b/src/cpu/ozone/front_end_impl.hh
@@ -64,12 +64,8 @@ FrontEnd<Impl>::IcachePort::recvFunctional(PacketPtr pkt)
template<class Impl>
void
-FrontEnd<Impl>::IcachePort::recvStatusChange(Status status)
+FrontEnd<Impl>::IcachePort::recvRangeChange()
{
- if (status == RangeChange)
- return;
-
- panic("FrontEnd doesn't expect recvStatusChange callback!");
}
template<class Impl>
diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh
index 34461b9d0..dd573e5e0 100644
--- a/src/cpu/ozone/lw_lsq.hh
+++ b/src/cpu/ozone/lw_lsq.hh
@@ -255,11 +255,13 @@ class OzoneLWLSQ {
virtual void recvFunctional(PacketPtr pkt);
- virtual void recvStatusChange(Status status);
+ virtual void recvRangeChange();
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = true; }
+ /**
+ * Is a snooper due to LSQ maintenance
+ */
+ virtual bool isSnooping()
+ { return true; }
virtual bool recvTiming(PacketPtr pkt);
diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh
index 3bee83176..811d66567 100644
--- a/src/cpu/ozone/lw_lsq_impl.hh
+++ b/src/cpu/ozone/lw_lsq_impl.hh
@@ -77,12 +77,8 @@ OzoneLWLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt)
template <class Impl>
void
-OzoneLWLSQ<Impl>::DcachePort::recvStatusChange(Status status)
+OzoneLWLSQ<Impl>::DcachePort::recvRangeChange()
{
- if (status == RangeChange)
- return;
-
- panic("O3CPU doesn't expect recvStatusChange callback!");
}
template <class Impl>
diff --git a/src/cpu/simple/AtomicSimpleCPU.py b/src/cpu/simple/AtomicSimpleCPU.py
index a4d807f86..93cd02ba7 100644
--- a/src/cpu/simple/AtomicSimpleCPU.py
+++ b/src/cpu/simple/AtomicSimpleCPU.py
@@ -34,8 +34,4 @@ class AtomicSimpleCPU(BaseSimpleCPU):
width = Param.Int(1, "CPU width")
simulate_data_stalls = Param.Bool(False, "Simulate dcache stall cycles")
simulate_inst_stalls = Param.Bool(False, "Simulate icache stall cycles")
- icache_port = Port("Instruction Port")
- dcache_port = Port("Data Port")
physmem_port = Port("Physical Memory Port")
- _cached_ports = BaseSimpleCPU._cached_ports + \
- ['icache_port', 'dcache_port']
diff --git a/src/cpu/simple/TimingSimpleCPU.py b/src/cpu/simple/TimingSimpleCPU.py
index 8d6888f72..61491b087 100644
--- a/src/cpu/simple/TimingSimpleCPU.py
+++ b/src/cpu/simple/TimingSimpleCPU.py
@@ -31,6 +31,3 @@ from BaseSimpleCPU import BaseSimpleCPU
class TimingSimpleCPU(BaseSimpleCPU):
type = 'TimingSimpleCPU'
- icache_port = Port("Instruction Port")
- dcache_port = Port("Data Port")
- _cached_ports = BaseSimpleCPU._cached_ports + ['icache_port', 'dcache_port']
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index fed94ffd8..2c12b244b 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -92,10 +92,12 @@ AtomicSimpleCPU::init()
TheISA::initCPU(tc, tc->contextId());
}
}
+
+ // Initialise the ThreadContext's memory proxies
+ tcBase()->initMemProxies(tcBase());
+
if (hasPhysMemPort) {
- bool snoop = false;
- AddrRangeList pmAddrList;
- physmemPort.getPeerAddressRanges(pmAddrList, snoop);
+ AddrRangeList pmAddrList = physmemPort.getPeer()->getAddrRanges();
physMemAddr = *pmAddrList.begin();
}
// Atomic doesn't do MT right now, so contextId == threadId
@@ -104,59 +106,6 @@ AtomicSimpleCPU::init()
data_write_req.setThreadContext(_cpuId, 0); // Add thread ID here too
}
-bool
-AtomicSimpleCPU::CpuPort::recvTiming(PacketPtr pkt)
-{
- panic("AtomicSimpleCPU doesn't expect recvTiming callback!");
- return true;
-}
-
-Tick
-AtomicSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt)
-{
- //Snooping a coherence request, just return
- return 0;
-}
-
-void
-AtomicSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
-{
- //No internal storage to update, just return
- return;
-}
-
-void
-AtomicSimpleCPU::CpuPort::recvStatusChange(Status status)
-{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("AtomicSimpleCPU doesn't expect recvStatusChange callback!");
-}
-
-void
-AtomicSimpleCPU::CpuPort::recvRetry()
-{
- panic("AtomicSimpleCPU doesn't expect recvRetry callback!");
-}
-
-void
-AtomicSimpleCPU::DcachePort::setPeer(Port *port)
-{
- Port::setPeer(port);
-
- if (FullSystem) {
- // Update the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- cpu->tcBase()->connectMemPorts(cpu->tcBase());
- }
-}
-
AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
: BaseSimpleCPU(p), tickEvent(this), width(p->width), locked(false),
simulate_data_stalls(p->simulate_data_stalls),
@@ -165,10 +114,6 @@ AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
physmemPort(name() + "-iport", this), hasPhysMemPort(false)
{
_status = Idle;
-
- icachePort.snoopRangeSent = false;
- dcachePort.snoopRangeSent = false;
-
}
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index 246afa0b2..77a9d6b0d 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -64,47 +64,31 @@ class AtomicSimpleCPU : public BaseSimpleCPU
// main simulation loop (one cycle)
void tick();
- class CpuPort : public Port
+ /**
+ * An AtomicCPUPort overrides the default behaviour of the
+ * recvAtomic and ignores the packet instead of panicking.
+ */
+ class AtomicCPUPort : public CpuPort
{
+
public:
- CpuPort(const std::string &_name, AtomicSimpleCPU *_cpu)
- : Port(_name, _cpu), cpu(_cpu)
+ AtomicCPUPort(const std::string &_name, BaseCPU* _cpu)
+ : CpuPort(_name, _cpu)
{ }
- bool snoopRangeSent;
-
protected:
- AtomicSimpleCPU *cpu;
-
- virtual bool recvTiming(PacketPtr pkt);
-
- virtual Tick recvAtomic(PacketPtr pkt);
-
- virtual void recvFunctional(PacketPtr pkt);
-
- virtual void recvStatusChange(Status status);
-
- virtual void recvRetry();
-
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = true; }
+ virtual Tick recvAtomic(PacketPtr pkt)
+ {
+ // Snooping a coherence request, just return
+ return 0;
+ }
};
- CpuPort icachePort;
- class DcachePort : public CpuPort
- {
- public:
- DcachePort(const std::string &_name, AtomicSimpleCPU *_cpu)
- : CpuPort(_name, _cpu)
- { }
-
- virtual void setPeer(Port *port);
- };
- DcachePort dcachePort;
+ AtomicCPUPort icachePort;
+ AtomicCPUPort dcachePort;
CpuPort physmemPort;
bool hasPhysMemPort;
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 983672c27..fd02e8300 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -82,53 +82,24 @@ TimingSimpleCPU::init()
TheISA::initCPU(tc, _cpuId);
}
}
-}
-
-Tick
-TimingSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt)
-{
- panic("TimingSimpleCPU doesn't expect recvAtomic callback!");
- return curTick();
-}
-void
-TimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
-{
- //No internal storage to update, jusst return
- return;
+ // Initialise the ThreadContext's memory proxies
+ tcBase()->initMemProxies(tcBase());
}
void
-TimingSimpleCPU::CpuPort::recvStatusChange(Status status)
-{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("TimingSimpleCPU doesn't expect recvStatusChange callback!");
-}
-
-
-void
-TimingSimpleCPU::CpuPort::TickEvent::schedule(PacketPtr _pkt, Tick t)
+TimingSimpleCPU::TimingCPUPort::TickEvent::schedule(PacketPtr _pkt, Tick t)
{
pkt = _pkt;
cpu->schedule(this, t);
}
TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p)
- : BaseSimpleCPU(p), fetchTranslation(this), icachePort(this, p->clock),
- dcachePort(this, p->clock), fetchEvent(this)
+ : BaseSimpleCPU(p), fetchTranslation(this), icachePort(this),
+ dcachePort(this), fetchEvent(this)
{
_status = Idle;
- icachePort.snoopRangeSent = false;
- dcachePort.snoopRangeSent = false;
-
ifetch_pkt = dcache_pkt = NULL;
drainEvent = NULL;
previousTick = 0;
@@ -874,18 +845,6 @@ TimingSimpleCPU::completeDrain()
drainEvent->process();
}
-void
-TimingSimpleCPU::DcachePort::setPeer(Port *port)
-{
- Port::setPeer(port);
-
- if (FullSystem) {
- // Update the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- cpu->tcBase()->connectMemPorts(cpu->tcBase());
- }
-}
-
bool
TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
{
@@ -903,7 +862,7 @@ TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
// faster than a CPU we could get two responses before
// next_tick expires
if (!retryEvent.scheduled())
- schedule(retryEvent, next_tick);
+ cpu->schedule(retryEvent, next_tick);
return false;
}
}
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index 4301dfca7..dce3c58ff 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -137,31 +137,23 @@ class TimingSimpleCPU : public BaseSimpleCPU
// This function always implicitly uses dcache_pkt.
bool handleWritePacket();
- class CpuPort : public Port
+ /**
+ * A TimingCPUPort overrides the default behaviour of the
+ * recvTiming and recvRetry and implements events for the
+ * scheduling of handling of incoming packets in the following
+ * cycle.
+ */
+ class TimingCPUPort : public CpuPort
{
- protected:
- TimingSimpleCPU *cpu;
- Tick lat;
-
public:
- CpuPort(const std::string &_name, TimingSimpleCPU *_cpu, Tick _lat)
- : Port(_name, _cpu), cpu(_cpu), lat(_lat), retryEvent(this)
+ TimingCPUPort(const std::string& _name, TimingSimpleCPU* _cpu)
+ : CpuPort(_name, _cpu), cpu(_cpu), retryEvent(this)
{ }
- bool snoopRangeSent;
-
protected:
- virtual Tick recvAtomic(PacketPtr pkt);
-
- virtual void recvFunctional(PacketPtr pkt);
-
- virtual void recvStatusChange(Status status);
-
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = false; }
+ TimingSimpleCPU* cpu;
struct TickEvent : public Event
{
@@ -169,7 +161,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
TimingSimpleCPU *cpu;
CpuPort *port;
- TickEvent(TimingSimpleCPU *_cpu) : cpu(_cpu) {}
+ TickEvent(TimingSimpleCPU *_cpu) : pkt(NULL), cpu(_cpu) {}
const char *description() const { return "Timing CPU tick"; }
void schedule(PacketPtr _pkt, Tick t);
};
@@ -177,12 +169,13 @@ class TimingSimpleCPU : public BaseSimpleCPU
EventWrapper<Port, &Port::sendRetry> retryEvent;
};
- class IcachePort : public CpuPort
+ class IcachePort : public TimingCPUPort
{
public:
- IcachePort(TimingSimpleCPU *_cpu, Tick _lat)
- : CpuPort(_cpu->name() + "-iport", _cpu, _lat), tickEvent(_cpu)
+ IcachePort(TimingSimpleCPU *_cpu)
+ : TimingCPUPort(_cpu->name() + "-iport", _cpu),
+ tickEvent(_cpu)
{ }
protected:
@@ -204,16 +197,14 @@ class TimingSimpleCPU : public BaseSimpleCPU
};
- class DcachePort : public CpuPort
+ class DcachePort : public TimingCPUPort
{
public:
- DcachePort(TimingSimpleCPU *_cpu, Tick _lat)
- : CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu)
+ DcachePort(TimingSimpleCPU *_cpu)
+ : TimingCPUPort(_cpu->name() + "-dport", _cpu), tickEvent(_cpu)
{ }
- virtual void setPeer(Port *port);
-
protected:
virtual bool recvTiming(PacketPtr pkt);
diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc
index edde884e7..a12ab8e8a 100644
--- a/src/cpu/simple_thread.cc
+++ b/src/cpu/simple_thread.cc
@@ -47,13 +47,14 @@
#include "cpu/quiesce_event.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
-#include "mem/translating_port.hh"
-#include "mem/vport.hh"
#include "params/BaseCPU.hh"
+#include "mem/fs_translating_port_proxy.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"
#include "sim/serialize.hh"
#include "sim/sim_exit.hh"
+#include "sim/process.hh"
#include "sim/system.hh"
using namespace std;
@@ -106,8 +107,6 @@ SimpleThread::SimpleThread()
SimpleThread::~SimpleThread()
{
- delete physPort;
- delete virtPort;
delete tc;
}
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index ffa89a967..f2132dc36 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -57,7 +57,6 @@ class BaseCPU;
class FunctionProfile;
class ProfileNode;
-class FunctionalPort;
class PhysicalPort;
class TranslatingPort;
@@ -195,13 +194,13 @@ class SimpleThread : public ThreadState
System *getSystemPtr() { return system; }
- FunctionalPort *getPhysPort() { return physPort; }
+ PortProxy* getPhysProxy() { return physProxy; }
/** Return a virtual port. This port cannot be cached locally in an object.
* After a CPU switch it may point to the wrong memory object which could
* mean stale data.
*/
- VirtualPort *getVirtPort() { return virtPort; }
+ FSTranslatingPortProxy* getVirtProxy() { return virtProxy; }
Status status() const { return _status; }
diff --git a/src/cpu/testers/memtest/memtest.cc b/src/cpu/testers/memtest/memtest.cc
index ef23825cd..d70dc96e6 100644
--- a/src/cpu/testers/memtest/memtest.cc
+++ b/src/cpu/testers/memtest/memtest.cc
@@ -84,17 +84,8 @@ MemTest::CpuPort::recvFunctional(PacketPtr pkt)
}
void
-MemTest::CpuPort::recvStatusChange(Status status)
+MemTest::CpuPort::recvRangeChange()
{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("MemTest doesn't expect recvStatusChange callback!");
}
void
@@ -149,9 +140,6 @@ MemTest::MemTest(const Params *p)
atomic(p->atomic),
suppress_func_warnings(p->suppress_func_warnings)
{
- cachePort.snoopRangeSent = false;
- funcPort.snoopRangeSent = true;
-
id = TESTER_ALLOCATOR++;
// Needs to be masked off once we know the block size.
diff --git a/src/cpu/testers/memtest/memtest.hh b/src/cpu/testers/memtest/memtest.hh
index 292e7d83d..1a59914fd 100644
--- a/src/cpu/testers/memtest/memtest.hh
+++ b/src/cpu/testers/memtest/memtest.hh
@@ -93,8 +93,6 @@ class MemTest : public MemObject
: Port(_name, _memtest), memtest(_memtest)
{ }
- bool snoopRangeSent;
-
protected:
virtual bool recvTiming(PacketPtr pkt);
@@ -103,20 +101,14 @@ class MemTest : public MemObject
virtual void recvFunctional(PacketPtr pkt);
- virtual void recvStatusChange(Status status);
+ virtual void recvRangeChange();
virtual void recvRetry();
-
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = false; }
};
CpuPort cachePort;
CpuPort funcPort;
- bool snoopRangeSent;
-
class MemTestSenderState : public Packet::SenderState, public FastAlloc
{
public:
diff --git a/src/cpu/testers/networktest/networktest.cc b/src/cpu/testers/networktest/networktest.cc
index d78f976be..56fcc46c4 100644
--- a/src/cpu/testers/networktest/networktest.cc
+++ b/src/cpu/testers/networktest/networktest.cc
@@ -81,17 +81,8 @@ NetworkTest::CpuPort::recvFunctional(PacketPtr pkt)
}
void
-NetworkTest::CpuPort::recvStatusChange(Status status)
+NetworkTest::CpuPort::recvRangeChange()
{
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
-
- panic("NetworkTest doesn't expect recvStatusChange callback!");
}
void
@@ -124,8 +115,6 @@ NetworkTest::NetworkTest(const Params *p)
injRate(p->inj_rate),
precision(p->precision)
{
- cachePort.snoopRangeSent = false;
-
// set up counters
noResponseCycles = 0;
schedule(tickEvent, 0);
diff --git a/src/cpu/testers/networktest/networktest.hh b/src/cpu/testers/networktest/networktest.hh
index 6d9d1edad..c277cfbab 100644
--- a/src/cpu/testers/networktest/networktest.hh
+++ b/src/cpu/testers/networktest/networktest.hh
@@ -89,8 +89,6 @@ class NetworkTest : public MemObject
: Port(_name, _networktest), networktest(_networktest)
{ }
- bool snoopRangeSent;
-
protected:
virtual bool recvTiming(PacketPtr pkt);
@@ -99,19 +97,13 @@ class NetworkTest : public MemObject
virtual void recvFunctional(PacketPtr pkt);
- virtual void recvStatusChange(Status status);
+ virtual void recvRangeChange();
virtual void recvRetry();
-
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = false; }
};
CpuPort cachePort;
- bool snoopRangeSent;
-
class NetworkTestSenderState : public Packet::SenderState, public FastAlloc
{
public:
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index f7879ea60..261ace7cf 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -49,9 +49,9 @@ class BaseCPU;
class Checkpoint;
class Decoder;
class EndQuiesceEvent;
-class TranslatingPort;
-class FunctionalPort;
-class VirtualPort;
+class SETranslatingPortProxy;
+class FSTranslatingPortProxy;
+class PortProxy;
class Process;
class System;
namespace TheISA {
@@ -126,15 +126,21 @@ class ThreadContext
virtual TheISA::Kernel::Statistics *getKernelStats() = 0;
- virtual void connectMemPorts(ThreadContext *tc) = 0;
+ virtual PortProxy* getPhysProxy() = 0;
- virtual Process *getProcessPtr() = 0;
+ virtual FSTranslatingPortProxy* getVirtProxy() = 0;
- virtual TranslatingPort *getMemPort() = 0;
+ /**
+ * Initialise the physical and virtual port proxies and tie them to
+ * the data port of the CPU.
+ *
+ * tc ThreadContext for the virtual-to-physical translation
+ */
+ virtual void initMemProxies(ThreadContext *tc) = 0;
- virtual VirtualPort *getVirtPort() = 0;
+ virtual SETranslatingPortProxy *getMemProxy() = 0;
- virtual FunctionalPort *getPhysPort() = 0;
+ virtual Process *getProcessPtr() = 0;
virtual Status status() const = 0;
@@ -288,15 +294,15 @@ class ProxyThreadContext : public ThreadContext
TheISA::Kernel::Statistics *getKernelStats()
{ return actualTC->getKernelStats(); }
- void connectMemPorts(ThreadContext *tc) { actualTC->connectMemPorts(tc); }
+ PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
- Process *getProcessPtr() { return actualTC->getProcessPtr(); }
+ FSTranslatingPortProxy* getVirtProxy() { return actualTC->getVirtProxy(); }
- TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
+ void initMemProxies(ThreadContext *tc) { actualTC->initMemProxies(tc); }
- VirtualPort *getVirtPort() { return actualTC->getVirtPort(); }
+ SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
- FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
+ Process *getProcessPtr() { return actualTC->getProcessPtr(); }
Status status() const { return actualTC->status(); }
diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc
index ef81271a8..574be7b6d 100644
--- a/src/cpu/thread_state.cc
+++ b/src/cpu/thread_state.cc
@@ -34,27 +34,31 @@
#include "cpu/profile.hh"
#include "cpu/quiesce_event.hh"
#include "cpu/thread_state.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "mem/port.hh"
-#include "mem/translating_port.hh"
-#include "mem/vport.hh"
+#include "mem/port_proxy.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "sim/full_system.hh"
#include "sim/serialize.hh"
+#include "sim/system.hh"
ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid, Process *_process)
: numInst(0), numLoad(0), _status(ThreadContext::Halted),
baseCpu(cpu), _threadId(_tid), lastActivate(0), lastSuspend(0),
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
- kernelStats(NULL), process(_process), port(NULL), virtPort(NULL),
- physPort(NULL), funcExeInst(0), storeCondFailures(0)
+ kernelStats(NULL), process(_process), physProxy(NULL), virtProxy(NULL),
+ proxy(NULL), funcExeInst(0), storeCondFailures(0)
{
}
ThreadState::~ThreadState()
{
- if (port) {
- delete port->getPeer();
- delete port;
- }
+ if (physProxy != NULL)
+ delete physProxy;
+ if (virtProxy != NULL)
+ delete virtProxy;
+ if (proxy != NULL)
+ delete proxy;
}
void
@@ -93,38 +97,16 @@ ThreadState::unserialize(Checkpoint *cp, const std::string &section)
}
void
-ThreadState::connectPhysPort()
-{
- // @todo: For now this disregards any older port that may have
- // already existed. Fix this memory leak once the bus port IDs
- // for functional ports is resolved.
- if (physPort)
- physPort->removeConn();
- else
- physPort = new FunctionalPort(csprintf("%s-%d-funcport",
- baseCpu->name(), _threadId));
- connectToMemFunc(physPort);
-}
-
-void
-ThreadState::connectVirtPort(ThreadContext *tc)
-{
- // @todo: For now this disregards any older port that may have
- // already existed. Fix this memory leak once the bus port IDs
- // for functional ports is resolved.
- if (virtPort)
- virtPort->removeConn();
- else
- virtPort = new VirtualPort(csprintf("%s-%d-vport",
- baseCpu->name(), _threadId), tc);
- connectToMemFunc(virtPort);
-}
-
-void
-ThreadState::connectMemPorts(ThreadContext *tc)
+ThreadState::initMemProxies(ThreadContext *tc)
{
- connectPhysPort();
- connectVirtPort(tc);
+ // Note that this only refers to the port on the CPU side and can
+ // safely be done at init() time even if the CPU is not connected
+ // (i.e. due to restoring from a checkpoint and later switching
+ // in.
+ if (physProxy == NULL)
+ physProxy = new PortProxy(*baseCpu->getPort("dcache_port"));
+ if (virtProxy == NULL)
+ virtProxy = new FSTranslatingPortProxy(tc);
}
void
@@ -141,35 +123,16 @@ ThreadState::profileSample()
profile->sample(profileNode, profilePC);
}
-TranslatingPort *
-ThreadState::getMemPort()
+SETranslatingPortProxy *
+ThreadState::getMemProxy()
{
- if (port != NULL)
- return port;
-
- /* Use this port to for syscall emulation writes to memory. */
- port = new TranslatingPort(csprintf("%s-%d-funcport", baseCpu->name(),
- _threadId), process, TranslatingPort::NextPage);
-
- connectToMemFunc(port);
-
- return port;
-}
-
-void
-ThreadState::connectToMemFunc(Port *port)
-{
- Port *dcache_port, *func_mem_port;
-
- dcache_port = baseCpu->getPort("dcache_port");
- assert(dcache_port != NULL);
-
- MemObject *mem_object = dcache_port->getPeer()->getOwner();
- assert(mem_object != NULL);
+ if (proxy != NULL)
+ return proxy;
- func_mem_port = mem_object->getPort("functional");
- assert(func_mem_port != NULL);
+ /* Use this port proxy to for syscall emulation writes to memory. */
+ proxy = new SETranslatingPortProxy(*process->system->getSystemPort(),
+ process,
+ SETranslatingPortProxy::NextPage);
- func_mem_port->setPeer(port);
- port->setPeer(func_mem_port);
+ return proxy;
}
diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh
index 972ca895d..30bb64ed7 100644
--- a/src/cpu/thread_state.hh
+++ b/src/cpu/thread_state.hh
@@ -49,8 +49,9 @@ namespace TheISA {
};
class Checkpoint;
-class Port;
-class TranslatingPort;
+class PortProxy;
+class SETranslatingPort;
+class FSTranslatingPort;
/**
* Struct for holding general thread state that is needed across CPU
@@ -83,11 +84,13 @@ struct ThreadState {
Tick readLastSuspend() { return lastSuspend; }
- void connectPhysPort();
-
- void connectVirtPort(ThreadContext *tc);
-
- void connectMemPorts(ThreadContext *tc);
+ /**
+ * Initialise the physical and virtual port proxies and tie them to
+ * the data port of the CPU.
+ *
+ * tc ThreadContext for the virtual-to-physical translation
+ */
+ void initMemProxies(ThreadContext *tc);
void dumpFuncProfile();
@@ -99,17 +102,13 @@ struct ThreadState {
TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; }
- Process *getProcessPtr() { return process; }
-
- TranslatingPort *getMemPort();
+ PortProxy* getPhysProxy() { return physProxy; }
- void setMemPort(TranslatingPort *_port) { port = _port; }
+ FSTranslatingPortProxy* getVirtProxy() { return virtProxy; }
- VirtualPort *getVirtPort() { return virtPort; }
-
- FunctionalPort *getPhysPort() { return physPort; }
+ Process *getProcessPtr() { return process; }
- void setPhysPort(FunctionalPort *port) { physPort = port; }
+ SETranslatingPortProxy* getMemProxy();
/** Reads the number of instructions functionally executed and
* committed.
@@ -128,9 +127,6 @@ struct ThreadState {
void setStatus(Status new_status) { _status = new_status; }
public:
- /** Connects port to the functional port of the memory object
- * below the CPU. */
- void connectToMemFunc(Port *port);
/** Number of instructions committed. */
Counter numInst;
@@ -177,15 +173,14 @@ struct ThreadState {
protected:
Process *process;
- TranslatingPort *port;
-
- /** A functional port, outgoing only, for functional accesse to virtual
- * addresses. */
- VirtualPort *virtPort;
-
- /** A functional port outgoing only for functional accesses to physical
+ /** A port proxy outgoing only for functional accesses to physical
* addresses.*/
- FunctionalPort *physPort;
+ PortProxy *physProxy;
+
+ /** A translating port proxy, outgoing only, for functional
+ * accesse to virtual addresses. */
+ FSTranslatingPortProxy* virtProxy;
+ SETranslatingPortProxy* proxy;
public:
/*
diff --git a/src/dev/Device.py b/src/dev/Device.py
index 9cd41fe09..c32946277 100644
--- a/src/dev/Device.py
+++ b/src/dev/Device.py
@@ -45,7 +45,7 @@ class BasicPioDevice(PioDevice):
class DmaDevice(PioDevice):
type = 'DmaDevice'
abstract = True
- dma = Port(Self.pio.peerObj.port, "DMA port")
+ dma = Port("DMA port")
min_backoff_delay = Param.Latency('4ns',
"min time between a nack packet being received and the next request made by the device")
max_backoff_delay = Param.Latency('10us',
diff --git a/src/dev/Pci.py b/src/dev/Pci.py
index 2f9f93a59..95cb3916f 100644
--- a/src/dev/Pci.py
+++ b/src/dev/Pci.py
@@ -43,7 +43,7 @@ class PciDevice(DmaDevice):
type = 'PciDevice'
abstract = True
platform = Param.Platform(Parent.any, "Platform this device is part of.")
- config = Port(Self.pio.peerObj.port, "PCI configuration space port")
+ config = Port("PCI configuration space port")
pci_bus = Param.Int("PCI bus")
pci_dev = Param.Int("PCI device number")
pci_func = Param.Int("PCI function code")
diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py
index 11905ae79..dc2219cd1 100644
--- a/src/dev/arm/RealView.py
+++ b/src/dev/arm/RealView.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 ARM Limited
+# Copyright (c) 2009-2011 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@@ -178,12 +178,18 @@ class RealViewPBX(RealView):
rtc_fake = AmbaFake(pio_addr=0x10017000, amba_id=0x41031)
- # Attach I/O devices that are on chip
- def attachOnChipIO(self, bus):
+ # Attach I/O devices that are on chip and also set the appropriate
+ # ranges for the bridge
+ def attachOnChipIO(self, bus, bridge):
self.gic.pio = bus.port
self.l2x0_fake.pio = bus.port
self.a9scu.pio = bus.port
self.local_cpu_timer.pio = bus.port
+ # Bridge ranges based on excluding what is part of on-chip I/O
+ # (gic, l2x0, a9scu, local_cpu_timer)
+ bridge.ranges = [AddrRange(self.realview_io.pio_addr,
+ self.a9scu.pio_addr - 1),
+ AddrRange(self.flash_fake.pio_addr, Addr.max)]
# Attach I/O devices to specified bus object. Can't do this
# earlier, since the bus object itself is typically defined at the
@@ -194,9 +200,12 @@ class RealViewPBX(RealView):
self.timer0.pio = bus.port
self.timer1.pio = bus.port
self.clcd.pio = bus.port
+ self.clcd.dma = bus.port
self.kmi0.pio = bus.port
self.kmi1.pio = bus.port
self.cf_ctrl.pio = bus.port
+ self.cf_ctrl.config = bus.port
+ self.cf_ctrl.dma = bus.port
self.dmac_fake.pio = bus.port
self.uart1_fake.pio = bus.port
self.uart2_fake.pio = bus.port
@@ -249,10 +258,16 @@ class RealViewEB(RealView):
- # Attach I/O devices that are on chip
- def attachOnChipIO(self, bus):
+ # Attach I/O devices that are on chip and also set the appropriate
+ # ranges for the bridge
+ def attachOnChipIO(self, bus, bridge):
self.gic.pio = bus.port
self.l2x0_fake.pio = bus.port
+ # Bridge ranges based on excluding what is part of on-chip I/O
+ # (gic, l2x0)
+ bridge.ranges = [AddrRange(self.realview_io.pio_addr,
+ self.gic.cpu_addr - 1),
+ AddrRange(self.flash_fake.pio_addr, Addr.max)]
# Attach I/O devices to specified bus object. Can't do this
# earlier, since the bus object itself is typically defined at the
@@ -263,6 +278,7 @@ class RealViewEB(RealView):
self.timer0.pio = bus.port
self.timer1.pio = bus.port
self.clcd.pio = bus.port
+ self.clcd.dma = bus.port
self.kmi0.pio = bus.port
self.kmi1.pio = bus.port
self.dmac_fake.pio = bus.port
@@ -330,10 +346,15 @@ class VExpress_ELT(RealView):
usb_fake = IsaFake(pio_addr=0xFB000000, pio_size=0x1ffff)
- # Attach I/O devices that are on chip
- def attachOnChipIO(self, bus):
+ # Attach I/O devices that are on chip and also set the appropriate
+ # ranges for the bridge
+ def attachOnChipIO(self, bus, bridge):
self.gic.pio = bus.port
self.a9scu.pio = bus.port
+ # Bridge ranges based on excluding what is part of on-chip I/O
+ # (gic, a9scu)
+ bridge.ranges = [AddrRange(self.pci_cfg_base, self.a9scu.pio_addr - 1),
+ AddrRange(self.local_cpu_timer.pio_addr, Addr.max)]
# Attach I/O devices to specified bus object. Can't do this
# earlier, since the bus object itself is typically defined at the
@@ -348,13 +369,20 @@ class VExpress_ELT(RealView):
self.elba_timer0.pio = bus.port
self.elba_timer1.pio = bus.port
self.clcd.pio = bus.port
+ self.clcd.dma = bus.port
self.kmi0.pio = bus.port
self.kmi1.pio = bus.port
self.elba_kmi0.pio = bus.port
self.elba_kmi1.pio = bus.port
self.cf_ctrl.pio = bus.port
+ self.cf_ctrl.config = bus.port
+ self.cf_ctrl.dma = bus.port
self.ide.pio = bus.port
+ self.ide.config = bus.port
+ self.ide.dma = bus.port
self.ethernet.pio = bus.port
+ self.ethernet.config = bus.port
+ self.ethernet.dma = bus.port
self.pciconfig.pio = bus.default
bus.use_default_range = True
diff --git a/src/dev/arm/gic.cc b/src/dev/arm/gic.cc
index 67520f865..f686c2a13 100644
--- a/src/dev/arm/gic.cc
+++ b/src/dev/arm/gic.cc
@@ -705,12 +705,13 @@ Gic::postInt(uint32_t cpu, Tick when)
eventq->schedule(postIntEvent[cpu], when);
}
-void
-Gic::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+Gic::getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeSize(distAddr, DIST_SIZE));
- range_list.push_back(RangeSize(cpuAddr, CPU_SIZE));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(distAddr, DIST_SIZE));
+ ranges.push_back(RangeSize(cpuAddr, CPU_SIZE));
+ return ranges;
}
diff --git a/src/dev/arm/gic.hh b/src/dev/arm/gic.hh
index 6988d6ed1..67d48cd86 100644
--- a/src/dev/arm/gic.hh
+++ b/src/dev/arm/gic.hh
@@ -261,7 +261,7 @@ class Gic : public PioDevice
/** Return the address ranges used by the Gic
* This is the distributor address + all cpu addresses
*/
- virtual void addressRanges(AddrRangeList &range_list);
+ virtual AddrRangeList getAddrRanges();
/** A PIO read to the device, immediately split up into
* readDistributor() or readCpu()
diff --git a/src/dev/arm/pl111.cc b/src/dev/arm/pl111.cc
index 958f07aa7..263a3b620 100644
--- a/src/dev/arm/pl111.cc
+++ b/src/dev/arm/pl111.cc
@@ -735,11 +735,12 @@ Pl111::generateInterrupt()
}
}
-void
-Pl111::addressRanges(AddrRangeList& range_list)
+AddrRangeList
+Pl111::getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeSize(pioAddr, pioSize));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(pioAddr, pioSize));
+ return ranges;
}
Pl111 *
diff --git a/src/dev/arm/pl111.hh b/src/dev/arm/pl111.hh
index f36dc6810..b2dc1f640 100644
--- a/src/dev/arm/pl111.hh
+++ b/src/dev/arm/pl111.hh
@@ -325,10 +325,12 @@ class Pl111: public AmbaDmaDevice
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
- /** return the address ranges that this device responds to.
- * @param range_list range list to populate with ranges
+ /**
+ * Determine the address ranges that this device responds to.
+ *
+ * @return a list of non-overlapping address ranges
*/
- void addressRanges(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
};
#endif
diff --git a/src/dev/copy_engine.hh b/src/dev/copy_engine.hh
index dfe469588..581d3c80b 100644
--- a/src/dev/copy_engine.hh
+++ b/src/dev/copy_engine.hh
@@ -85,7 +85,6 @@ class CopyEngine : public PciDev
void init();
std::string name() { assert(ce); return ce->name() + csprintf("-chan%d", channelId); }
- virtual void addressRanges(AddrRangeList &range_list) { range_list.clear(); }
virtual Tick read(PacketPtr pkt)
{ panic("CopyEngineChannel has no I/O access\n");}
virtual Tick write(PacketPtr pkt)
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc
index 0ad53f09e..840343dce 100644
--- a/src/dev/io_device.cc
+++ b/src/dev/io_device.cc
@@ -47,13 +47,10 @@ PioPort::recvAtomic(PacketPtr pkt)
return pkt->isRead() ? device->read(pkt) : device->write(pkt);
}
-void
-PioPort::getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
+AddrRangeList
+PioPort::getAddrRanges()
{
- snoop = false;
- device->addressRanges(resp);
- for (AddrRangeIter i = resp.begin(); i != resp.end(); i++)
- DPRINTF(BusAddrRanges, "Adding Range %#x-%#x\n", i->start, i->end);
+ return device->getAddrRanges();
}
@@ -72,7 +69,7 @@ PioDevice::init()
{
if (!pioPort)
panic("Pio port of %s not connected to anything!", name());
- pioPort->sendStatusChange(Port::RangeChange);
+ pioPort->sendRangeChange();
}
Port *
@@ -105,13 +102,14 @@ BasicPioDevice::BasicPioDevice(const Params *p)
pioDelay(p->pio_latency)
{}
-void
-BasicPioDevice::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+BasicPioDevice::getAddrRanges()
{
assert(pioSize != 0);
- range_list.clear();
+ AddrRangeList ranges;
DPRINTF(BusAddrRanges, "registering range: %#x-%#x\n", pioAddr, pioSize);
- range_list.push_back(RangeSize(pioAddr, pioSize));
+ ranges.push_back(RangeSize(pioAddr, pioSize));
+ return ranges;
}
@@ -121,7 +119,7 @@ DmaPort::DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff,
pendingCount(0), actionInProgress(0), drainEvent(NULL),
backoffTime(0), minBackoffDelay(min_backoff),
maxBackoffDelay(max_backoff), inRetry(false), recvSnoops(recv_snoops),
- snoopRangeSent(false), backoffEvent(this)
+ backoffEvent(this)
{ }
bool
@@ -136,7 +134,7 @@ DmaPort::recvTiming(PacketPtr pkt)
else if (backoffTime < maxBackoffDelay)
backoffTime <<= 1;
- reschedule(backoffEvent, curTick() + backoffTime, true);
+ device->reschedule(backoffEvent, curTick() + backoffTime, true);
DPRINTF(DMA, "Backoff time set to %d ticks\n", backoffTime);
@@ -164,7 +162,8 @@ DmaPort::recvTiming(PacketPtr pkt)
if (state->totBytes == state->numBytes) {
if (state->completionEvent) {
if (state->delay)
- schedule(state->completionEvent, curTick() + state->delay);
+ device->schedule(state->completionEvent,
+ curTick() + state->delay);
else
state->completionEvent->process();
}
@@ -234,7 +233,7 @@ DmaPort::recvRetry()
if (transmitList.size() && backoffTime && !inRetry) {
DPRINTF(DMA, "Scheduling backoff for %d\n", curTick()+backoffTime);
if (!backoffEvent.scheduled())
- schedule(backoffEvent, backoffTime + curTick());
+ device->schedule(backoffEvent, backoffTime + curTick());
}
DPRINTF(DMA, "TransmitList: %d, backoffTime: %d inRetry: %d es: %d\n",
transmitList.size(), backoffTime, inRetry,
@@ -320,7 +319,7 @@ DmaPort::sendDma()
!backoffEvent.scheduled()) {
DPRINTF(DMA, "-- Scheduling backoff timer for %d\n",
backoffTime+curTick());
- schedule(backoffEvent, backoffTime + curTick());
+ device->schedule(backoffEvent, backoffTime + curTick());
}
} else if (state == Enums::atomic) {
transmitList.pop_front();
@@ -342,7 +341,8 @@ DmaPort::sendDma()
if (state->totBytes == state->numBytes) {
if (state->completionEvent) {
assert(!state->completionEvent->scheduled());
- schedule(state->completionEvent, curTick() + lat + state->delay);
+ device->schedule(state->completionEvent,
+ curTick() + lat + state->delay);
}
delete state;
delete pkt->req;
diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh
index 083ab43cb..ea2364f33 100644
--- a/src/dev/io_device.hh
+++ b/src/dev/io_device.hh
@@ -50,7 +50,7 @@ class System;
* The PioPort class is a programmed i/o port that all devices that are
* sensitive to an address range use. The port takes all the memory
* access types and roles them into one read() and write() call that the device
- * must respond to. The device must also provide the addressRanges() function
+ * must respond to. The device must also provide getAddrRanges() function
* with which it returns the address ranges it is interested in.
*/
class PioPort : public SimpleTimingPort
@@ -61,8 +61,7 @@ class PioPort : public SimpleTimingPort
virtual Tick recvAtomic(PacketPtr pkt);
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual AddrRangeList getAddrRanges();
public:
@@ -132,9 +131,6 @@ class DmaPort : public Port
/** Port accesses a cache which requires snooping */
bool recvSnoops;
- /** Records snoop response so we only reply once to a status change */
- bool snoopRangeSent;
-
virtual bool recvTiming(PacketPtr pkt);
virtual Tick recvAtomic(PacketPtr pkt)
{
@@ -149,25 +145,16 @@ class DmaPort : public Port
panic("dma port shouldn't be used for pio access.");
}
- virtual void recvStatusChange(Status status)
+ virtual void recvRangeChange()
{
- if (recvSnoops) {
- if (status == RangeChange) {
- if (!snoopRangeSent) {
- snoopRangeSent = true;
- sendStatusChange(Port::RangeChange);
- }
- return;
- }
- panic("Unexpected recvStatusChange\n");
- }
+ // DMA port is a master with a single slave so there is no choice and
+ // thus no need to worry about any address changes
}
virtual void recvRetry() ;
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { resp.clear(); snoop = recvSnoops; }
+ virtual bool isSnooping()
+ { return recvSnoops; }
void queueDma(PacketPtr pkt, bool front = false);
void sendDma();
@@ -191,7 +178,7 @@ class DmaPort : public Port
/**
* This device is the base class which all devices senstive to an address range
* inherit from. There are three pure virtual functions which all devices must
- * implement addressRanges(), read(), and write(). The magic do choose which
+ * implement getAddrRanges(), read(), and write(). The magic do choose which
* mode we are in, etc is handled by the PioPort so the device doesn't have to
* bother.
*/
@@ -204,7 +191,13 @@ class PioDevice : public MemObject
* that it sees. */
PioPort *pioPort;
- virtual void addressRanges(AddrRangeList &range_list) = 0;
+ /**
+ * Every PIO device is obliged to provide an implementation that
+ * returns the address ranges the device responds to.
+ *
+ * @return a list of non-overlapping address ranges
+ */
+ virtual AddrRangeList getAddrRanges() = 0;
/** Pure virtual function that the device must implement. Called
* when a read command is recieved by the port.
@@ -263,10 +256,12 @@ class BasicPioDevice : public PioDevice
return dynamic_cast<const Params *>(_params);
}
- /** return the address ranges that this device responds to.
- * @param range_list range list to populate with ranges
+ /**
+ * Determine the address ranges that this device responds to.
+ *
+ * @return a list of non-overlapping address ranges
*/
- void addressRanges(AddrRangeList &range_list);
+ virtual AddrRangeList getAddrRanges();
};
diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc
index a7bc6d0ab..eb6eb6353 100644
--- a/src/dev/ns_gige.cc
+++ b/src/dev/ns_gige.cc
@@ -465,16 +465,16 @@ NSGigE::write(PacketPtr pkt)
reg & CFGR_DUPSTS ||
reg & CFGR_RESERVED ||
reg & CFGR_T64ADDR ||
- reg & CFGR_PCI64_DET)
-
- // First clear all writable bits
- regs.config &= CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |
- CFGR_RESERVED | CFGR_T64ADDR |
- CFGR_PCI64_DET;
- // Now set the appropriate writable bits
- regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |
- CFGR_RESERVED | CFGR_T64ADDR |
- CFGR_PCI64_DET);
+ reg & CFGR_PCI64_DET) {
+ // First clear all writable bits
+ regs.config &= CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |
+ CFGR_RESERVED | CFGR_T64ADDR |
+ CFGR_PCI64_DET;
+ // Now set the appropriate writable bits
+ regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |
+ CFGR_RESERVED | CFGR_T64ADDR |
+ CFGR_PCI64_DET);
+ }
// all these #if 0's are because i don't THINK the kernel needs to
// have these implemented. if there is a problem relating to one of
diff --git a/src/dev/pciconfigall.cc b/src/dev/pciconfigall.cc
index 55b439857..e7130e11d 100644
--- a/src/dev/pciconfigall.cc
+++ b/src/dev/pciconfigall.cc
@@ -86,11 +86,12 @@ PciConfigAll::write(PacketPtr pkt)
}
-void
-PciConfigAll::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+PciConfigAll::getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeSize(pioAddr, params()->size));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(pioAddr, params()->size));
+ return ranges;
}
diff --git a/src/dev/pciconfigall.hh b/src/dev/pciconfigall.hh
index b3f6d1472..e594838fa 100644
--- a/src/dev/pciconfigall.hh
+++ b/src/dev/pciconfigall.hh
@@ -80,7 +80,7 @@ class PciConfigAll : public PioDevice
virtual Tick write(PacketPtr pkt);
- void addressRanges(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
private:
Addr pioAddr;
diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc
index ac315341a..42c803553 100644
--- a/src/dev/pcidev.cc
+++ b/src/dev/pcidev.cc
@@ -72,13 +72,13 @@ PciDev::PciConfigPort::recvAtomic(PacketPtr pkt)
return pkt->isRead() ? device->readConfig(pkt) : device->writeConfig(pkt);
}
-void
-PciDev::PciConfigPort::getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
+AddrRangeList
+PciDev::PciConfigPort::getAddrRanges()
{
- snoop = false;;
+ AddrRangeList ranges;
if (configAddr != ULL(-1))
- resp.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1));
+ ranges.push_back(RangeSize(configAddr, PCI_CONFIG_SIZE+1));
+ return ranges;
}
@@ -150,9 +150,9 @@ PciDev::PciDev(const Params *p)
void
PciDev::init()
{
- if (!configPort)
- panic("pci config port not connected to anything!");
- configPort->sendStatusChange(Port::RangeChange);
+ if (!configPort && !configPort->isConnected())
+ panic("PCI config port on %s not connected to anything!\n", name());
+ configPort->sendRangeChange();
PioDevice::init();
}
@@ -207,14 +207,15 @@ PciDev::readConfig(PacketPtr pkt)
}
-void
-PciDev::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+PciDev::getAddrRanges()
{
+ AddrRangeList ranges;
int x = 0;
- range_list.clear();
for (x = 0; x < 6; x++)
if (BARAddrs[x] != 0)
- range_list.push_back(RangeSize(BARAddrs[x],BARSize[x]));
+ ranges.push_back(RangeSize(BARAddrs[x],BARSize[x]));
+ return ranges;
}
Tick
@@ -301,7 +302,7 @@ PciDev::writeConfig(PacketPtr pkt)
BARAddrs[barnum] = BAR_IO_SPACE(he_old_bar) ?
platform->calcPciIOAddr(he_new_bar) :
platform->calcPciMemAddr(he_new_bar);
- pioPort->sendStatusChange(Port::RangeChange);
+ pioPort->sendRangeChange();
}
}
config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) |
@@ -354,7 +355,7 @@ PciDev::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
UNSERIALIZE_ARRAY(config.data,
sizeof(config.data) / sizeof(config.data[0]));
- pioPort->sendStatusChange(Port::RangeChange);
+ pioPort->sendRangeChange();
}
diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh
index dae005a97..c0c3df0a6 100644
--- a/src/dev/pcidev.hh
+++ b/src/dev/pcidev.hh
@@ -65,8 +65,7 @@ class PciDev : public DmaDevice
virtual Tick recvAtomic(PacketPtr pkt);
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual AddrRangeList getAddrRanges();
Platform *platform;
@@ -187,10 +186,12 @@ class PciDev : public DmaDevice
interruptLine()
{ return letoh(config.interruptLine); }
- /** return the address ranges that this device responds to.
- * @params range_list range list to populate with ranges
+ /**
+ * Determine the address ranges that this device responds to.
+ *
+ * @return a list of non-overlapping address ranges
*/
- void addressRanges(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
/**
* Constructor for PCI Dev. This function copies data from the
diff --git a/src/dev/simple_disk.cc b/src/dev/simple_disk.cc
index 4bf24b1cd..9cec638b8 100644
--- a/src/dev/simple_disk.cc
+++ b/src/dev/simple_disk.cc
@@ -46,7 +46,7 @@
#include "debug/SimpleDiskData.hh"
#include "dev/disk_image.hh"
#include "dev/simple_disk.hh"
-#include "mem/port.hh"
+#include "mem/port_proxy.hh"
#include "sim/system.hh"
using namespace std;
@@ -70,7 +70,7 @@ SimpleDisk::read(Addr addr, baddr_t block, int count) const
for (int i = 0, j = 0; i < count; i += SectorSize, j++)
image->read(data + i, block + j);
- system->functionalPort->writeBlob(addr, data, count);
+ system->physProxy->writeBlob(addr, data, count);
DPRINTF(SimpleDisk, "read block=%#x len=%d\n", (uint64_t)block, count);
DDUMP(SimpleDiskData, data, count);
diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc
index b87dfa704..741442918 100644
--- a/src/dev/sinic.cc
+++ b/src/dev/sinic.cc
@@ -1714,7 +1714,7 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
if (transmitTick)
schedule(txEvent, curTick() + transmitTick);
- pioPort->sendStatusChange(Port::RangeChange);
+ pioPort->sendRangeChange();
}
diff --git a/src/dev/sparc/iob.cc b/src/dev/sparc/iob.cc
index 008e063e0..757c50a24 100644
--- a/src/dev/sparc/iob.cc
+++ b/src/dev/sparc/iob.cc
@@ -323,12 +323,13 @@ Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
return true;
}
-void
-Iob::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+Iob::getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeSize(iobManAddr, iobManSize));
- range_list.push_back(RangeSize(iobJBusAddr, iobJBusSize));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(iobManAddr, iobManSize));
+ ranges.push_back(RangeSize(iobJBusAddr, iobJBusSize));
+ return ranges;
}
diff --git a/src/dev/sparc/iob.hh b/src/dev/sparc/iob.hh
index 7391b1ccd..d6a47ce19 100644
--- a/src/dev/sparc/iob.hh
+++ b/src/dev/sparc/iob.hh
@@ -141,7 +141,7 @@ class Iob : public PioDevice
bool receiveJBusInterrupt(int cpu_id, int source, uint64_t d0,
uint64_t d1);
- void addressRanges(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc
index 877e9fb47..671d5505f 100644
--- a/src/dev/uart8250.cc
+++ b/src/dev/uart8250.cc
@@ -286,16 +286,14 @@ Uart8250::dataAvailable()
}
-void
-Uart8250::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+Uart8250::getAddrRanges()
{
- assert(pioSize != 0);
- range_list.clear();
- range_list.push_back(RangeSize(pioAddr, pioSize));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(pioAddr, pioSize));
+ return ranges;
}
-
-
void
Uart8250::serialize(ostream &os)
{
diff --git a/src/dev/uart8250.hh b/src/dev/uart8250.hh
index 79c31d5cf..f31def2ea 100644
--- a/src/dev/uart8250.hh
+++ b/src/dev/uart8250.hh
@@ -100,7 +100,7 @@ class Uart8250 : public Uart
virtual Tick read(PacketPtr pkt);
virtual Tick write(PacketPtr pkt);
- virtual void addressRanges(AddrRangeList &range_list);
+ virtual AddrRangeList getAddrRanges();
/**
* Inform the uart that there is data available.
diff --git a/src/dev/x86/SouthBridge.py b/src/dev/x86/SouthBridge.py
index c23ecf01c..baff35e0b 100644
--- a/src/dev/x86/SouthBridge.py
+++ b/src/dev/x86/SouthBridge.py
@@ -105,6 +105,8 @@ class SouthBridge(SimObject):
self.cmos.pio = bus.port
self.dma1.pio = bus.port
self.ide.pio = bus.port
+ self.ide.config = bus.port
+ self.ide.dma = bus.port
self.keyboard.pio = bus.port
self.pic1.pio = bus.port
self.pic2.pio = bus.port
diff --git a/src/dev/x86/i8042.cc b/src/dev/x86/i8042.cc
index a0786c95c..746a08778 100644
--- a/src/dev/x86/i8042.cc
+++ b/src/dev/x86/i8042.cc
@@ -43,12 +43,13 @@ const uint8_t CommandAck = 0xfa;
const uint8_t CommandNack = 0xfe;
const uint8_t BatSuccessful = 0xaa;
-void
-X86ISA::I8042::addressRanges(AddrRangeList &range_list)
+AddrRangeList
+X86ISA::I8042::getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeSize(dataPort, 1));
- range_list.push_back(RangeSize(commandPort, 1));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(dataPort, 1));
+ ranges.push_back(RangeSize(commandPort, 1));
+ return ranges;
}
void
diff --git a/src/dev/x86/i8042.hh b/src/dev/x86/i8042.hh
index be12c4e96..61220b45d 100644
--- a/src/dev/x86/i8042.hh
+++ b/src/dev/x86/i8042.hh
@@ -255,7 +255,7 @@ class I8042 : public BasicPioDevice
commandByte.keyboardFullInt = 1;
}
- void addressRanges(AddrRangeList &range_list);
+ AddrRangeList getAddrRanges();
Tick read(PacketPtr pkt);
diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh
index 00ba2800d..dfef059c3 100644
--- a/src/dev/x86/i82094aa.hh
+++ b/src/dev/x86/i82094aa.hh
@@ -101,19 +101,21 @@ class I82094AA : public PioDevice, public IntDev
Tick read(PacketPtr pkt);
Tick write(PacketPtr pkt);
- void addressRanges(AddrRangeList &range_list)
+ AddrRangeList getAddrRanges()
{
- range_list.clear();
- range_list.push_back(RangeEx(pioAddr, pioAddr + 4));
- range_list.push_back(RangeEx(pioAddr + 16, pioAddr + 20));
+ AddrRangeList ranges;
+ ranges.push_back(RangeEx(pioAddr, pioAddr + 4));
+ ranges.push_back(RangeEx(pioAddr + 16, pioAddr + 20));
+ return ranges;
}
- void getIntAddrRange(AddrRangeList &range_list)
+ AddrRangeList getIntAddrRange()
{
- range_list.clear();
- range_list.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
- x86InterruptAddress(initialApicId, 0) +
- PhysAddrAPICRangeSize));
+ AddrRangeList ranges;
+ ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
+ x86InterruptAddress(initialApicId, 0) +
+ PhysAddrAPICRangeSize));
+ return ranges;
}
void writeReg(uint8_t offset, uint32_t value);
diff --git a/src/dev/x86/intdev.cc b/src/dev/x86/intdev.cc
index 0c0fa73cf..a991005bc 100644
--- a/src/dev/x86/intdev.cc
+++ b/src/dev/x86/intdev.cc
@@ -54,7 +54,7 @@ X86ISA::IntDev::init()
if (!intPort) {
panic("Int port not connected to anything!");
}
- intPort->sendStatusChange(Port::RangeChange);
+ intPort->sendRangeChange();
}
X86ISA::IntSourcePin *
diff --git a/src/dev/x86/intdev.hh b/src/dev/x86/intdev.hh
index 1b3efdbb5..9713d042b 100644
--- a/src/dev/x86/intdev.hh
+++ b/src/dev/x86/intdev.hh
@@ -63,10 +63,9 @@ class IntDev
{
}
- void getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
+ AddrRangeList getAddrRanges()
{
- snoop = false;
- device->getIntAddrRange(resp);
+ return device->getIntAddrRange();
}
Tick recvMessage(PacketPtr pkt)
@@ -134,8 +133,8 @@ class IntDev
return 0;
}
- virtual void
- getIntAddrRange(AddrRangeList &range_list)
+ virtual AddrRangeList
+ getIntAddrRange()
{
panic("intAddrRange not implemented.\n");
}
diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh
index 8b8091f0d..3b9bbd2bf 100644
--- a/src/kern/tru64/tru64.hh
+++ b/src/kern/tru64/tru64.hh
@@ -62,7 +62,7 @@ typedef struct stat global_stat;
typedef struct statfs global_statfs;
typedef struct dirent global_dirent;
-class TranslatingPort;
+class SETranslatingPortProxy;
///
/// This class encapsulates the types, structures, constants,
@@ -397,7 +397,8 @@ class Tru64 : public OperatingSystem
/// memory space. Used by statfs() and fstatfs().
template <class T>
static void
- copyOutStatfsBuf(TranslatingPort *mem, Addr addr, global_statfs *host)
+ copyOutStatfsBuf(SETranslatingPortProxy *mem, Addr addr,
+ global_statfs *host)
{
using namespace TheISA;
@@ -446,7 +447,7 @@ class Tru64 : public OperatingSystem
// just pass basep through uninterpreted.
TypedBufferArg<int64_t> basep(tgt_basep);
- basep.copyIn(tc->getMemPort());
+ basep.copyIn(tc->getMemProxy());
long host_basep = (off_t)htog((int64_t)*basep);
int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep);
@@ -473,7 +474,7 @@ class Tru64 : public OperatingSystem
tgt_dp->d_reclen = tgt_bufsize;
tgt_dp->d_namlen = namelen;
strcpy(tgt_dp->d_name, host_dp->d_name);
- tgt_dp.copyOut(tc->getMemPort());
+ tgt_dp.copyOut(tc->getMemProxy());
tgt_buf_ptr += tgt_bufsize;
host_buf_ptr += host_dp->d_reclen;
@@ -482,7 +483,7 @@ class Tru64 : public OperatingSystem
delete [] host_buf;
*basep = htog((int64_t)host_basep);
- basep.copyOut(tc->getMemPort());
+ basep.copyOut(tc->getMemProxy());
return tgt_buf_ptr - tgt_buf;
#endif
@@ -498,7 +499,7 @@ class Tru64 : public OperatingSystem
int index = 0;
TypedBufferArg<Tru64::sigcontext> sc(process->getSyscallArg(tc, index));
- sc.copyIn(tc->getMemPort());
+ sc.copyIn(tc->getMemProxy());
// Restore state from sigcontext structure.
// Note that we'll advance PC <- NPC before the end of the cycle,
@@ -533,7 +534,7 @@ class Tru64 : public OperatingSystem
int index = 0;
TypedBufferArg<Tru64::vm_stack> argp(process->getSyscallArg(tc, index));
- argp.copyIn(tc->getMemPort());
+ argp.copyIn(tc->getMemProxy());
int stack_size =
gtoh(argp->rsize) + gtoh(argp->ysize) + gtoh(argp->gsize);
@@ -560,7 +561,7 @@ class Tru64 : public OperatingSystem
process->allocateMem(rounded_stack_base, rounded_stack_size);
argp->address = gtoh(rounded_stack_base);
- argp.copyOut(tc->getMemPort());
+ argp.copyOut(tc->getMemProxy());
return 0;
}
@@ -584,7 +585,7 @@ class Tru64 : public OperatingSystem
attrp(process->getSyscallArg(tc, index));
TypedBufferArg<Addr> configptr_ptr(process->getSyscallArg(tc, index));
- attrp.copyIn(tc->getMemPort());
+ attrp.copyIn(tc->getMemProxy());
if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) {
cerr << "nxm_task_init: thread library version mismatch! "
@@ -678,10 +679,10 @@ class Tru64 : public OperatingSystem
int size = cur_addr - base_addr;
process->allocateMem(base_addr, roundUp(size, VMPageSize));
- config.copyOut(tc->getMemPort());
- slot_state.copyOut(tc->getMemPort());
- rad_state.copyOut(tc->getMemPort());
- configptr_ptr.copyOut(tc->getMemPort());
+ config.copyOut(tc->getMemProxy());
+ slot_state.copyOut(tc->getMemProxy());
+ rad_state.copyOut(tc->getMemProxy());
+ configptr_ptr.copyOut(tc->getMemProxy());
return 0;
}
@@ -720,7 +721,7 @@ class Tru64 : public OperatingSystem
int thread_index = process->getSyscallArg(tc, index);
// get attribute args
- attrp.copyIn(tc->getMemPort());
+ attrp.copyIn(tc->getMemProxy());
if (gtoh(attrp->version) != NXM_LIB_VERSION) {
cerr << "nxm_thread_create: thread library version mismatch! "
@@ -745,7 +746,7 @@ class Tru64 : public OperatingSystem
TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000,
rad_state_size);
- rad_state.copyIn(tc->getMemPort());
+ rad_state.copyIn(tc->getMemProxy());
uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset);
@@ -756,7 +757,7 @@ class Tru64 : public OperatingSystem
// This is supposed to be a port number. Make something up.
*kidp = htog(99);
- kidp.copyOut(tc->getMemPort());
+ kidp.copyOut(tc->getMemProxy());
return 0;
} else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) {
@@ -770,7 +771,7 @@ class Tru64 : public OperatingSystem
ssp->nxm_u.pth_id = attrp->pthid;
ssp->nxm_u.nxm_active = htog(uniq_val | 1);
- rad_state.copyOut(tc->getMemPort());
+ rad_state.copyOut(tc->getMemProxy());
Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info);
int slot_state_size =
@@ -780,7 +781,7 @@ class Tru64 : public OperatingSystem
slot_state(slot_state_addr,
slot_state_size);
- slot_state.copyIn(tc->getMemPort());
+ slot_state.copyIn(tc->getMemProxy());
if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) {
cerr << "nxm_thread_createFunc: requested VP slot "
@@ -792,7 +793,7 @@ class Tru64 : public OperatingSystem
// doesn't work anyway
slot_state[thread_index] = Tru64::NXM_SLOT_BOUND;
- slot_state.copyOut(tc->getMemPort());
+ slot_state.copyOut(tc->getMemProxy());
// Find a free simulator thread context.
ThreadContext *tc = process->findFreeContext();
@@ -804,7 +805,7 @@ class Tru64 : public OperatingSystem
// and get away with just sticking the thread index
// here.
*kidp = htog(thread_index);
- kidp.copyOut(tc->getMemPort());
+ kidp.copyOut(tc->getMemProxy());
return 0;
}
@@ -945,12 +946,12 @@ class Tru64 : public OperatingSystem
TypedBufferArg<uint64_t> lockp(uaddr);
- lockp.copyIn(tc->getMemPort());
+ lockp.copyIn(tc->getMemProxy());
if (gtoh(*lockp) == 0) {
// lock is free: grab it
*lockp = htog(1);
- lockp.copyOut(tc->getMemPort());
+ lockp.copyOut(tc->getMemProxy());
} else {
// lock is busy: disable until free
process->waitList.push_back(Process::WaitRec(uaddr, tc));
@@ -964,7 +965,7 @@ class Tru64 : public OperatingSystem
{
TypedBufferArg<uint64_t> lockp(uaddr);
- lockp.copyIn(tc->getMemPort());
+ lockp.copyIn(tc->getMemProxy());
assert(*lockp != 0);
// Check for a process waiting on the lock.
@@ -973,7 +974,7 @@ class Tru64 : public OperatingSystem
// clear lock field if no waiting context is taking over the lock
if (num_waiting == 0) {
*lockp = 0;
- lockp.copyOut(tc->getMemPort());
+ lockp.copyOut(tc->getMemProxy());
}
}
@@ -1004,12 +1005,12 @@ class Tru64 : public OperatingSystem
Addr uaddr = process->getSyscallArg(tc, index);
TypedBufferArg<uint64_t> lockp(uaddr);
- lockp.copyIn(tc->getMemPort());
+ lockp.copyIn(tc->getMemProxy());
if (gtoh(*lockp) == 0) {
// lock is free: grab it
*lockp = htog(1);
- lockp.copyOut(tc->getMemPort());
+ lockp.copyOut(tc->getMemProxy());
return 0;
} else {
return 1;
@@ -1070,7 +1071,7 @@ class Tru64 : public OperatingSystem
TypedBufferArg<uint64_t> lockp(lock_addr);
// user is supposed to acquire lock before entering
- lockp.copyIn(tc->getMemPort());
+ lockp.copyIn(tc->getMemProxy());
assert(gtoh(*lockp) != 0);
m5_unlock_mutex(lock_addr, process, tc);
@@ -1159,13 +1160,13 @@ class Tru64_F64 : public Tru64
typedef F64_stat tgt_stat;
/*
- static void copyOutStatBuf(TranslatingPort *mem, Addr addr,
+ static void copyOutStatBuf(SETranslatingPortProxy *mem, Addr addr,
global_stat *host)
{
Tru64::copyOutStatBuf<Tru64::F64_stat>(mem, addr, host);
}*/
- static void copyOutStatfsBuf(TranslatingPort *mem, Addr addr,
+ static void copyOutStatfsBuf(SETranslatingPortProxy *mem, Addr addr,
global_statfs *host)
{
Tru64::copyOutStatfsBuf<Tru64::F64_statfs>(mem, addr, host);
@@ -1205,13 +1206,13 @@ class Tru64_PreF64 : public Tru64
typedef pre_F64_stat tgt_stat;
/*
- static void copyOutStatBuf(TranslatingPort *mem, Addr addr,
+ static void copyOutStatBuf(SETranslatingPortProxy *mem, Addr addr,
global_stat *host)
{
Tru64::copyOutStatBuf<Tru64::pre_F64_stat>(mem, addr, host);
}*/
- static void copyOutStatfsBuf(TranslatingPort *mem, Addr addr,
+ static void copyOutStatfsBuf(SETranslatingPortProxy *mem, Addr addr,
global_statfs *host)
{
Tru64::copyOutStatfsBuf<Tru64::pre_F64_statfs>(mem, addr, host);
diff --git a/src/kern/tru64/tru64_events.cc b/src/kern/tru64/tru64_events.cc
index 216f81b86..5638a2350 100644
--- a/src/kern/tru64/tru64_events.cc
+++ b/src/kern/tru64/tru64_events.cc
@@ -57,12 +57,12 @@ BadAddrEvent::process(ThreadContext *tc)
uint64_t a0 = tc->readIntReg(16);
- AddrRangeList resp;
- bool snoop;
AddrRangeIter iter;
bool found = false;
- tc->getPhysPort()->getPeerAddressRanges(resp, snoop);
+ Port* dataPort = tc->getCpuPtr()->getPort("dcache_port");
+
+ AddrRangeList resp = dataPort->getPeer()->getAddrRanges();
for (iter = resp.begin(); iter != resp.end(); iter++) {
if (*iter == (K0Seg2Phys(a0) & PAddrImplMask))
found = true;
diff --git a/src/mem/Bridge.py b/src/mem/Bridge.py
index b48e1684d..38b344613 100644
--- a/src/mem/Bridge.py
+++ b/src/mem/Bridge.py
@@ -31,16 +31,12 @@ from MemObject import MemObject
class Bridge(MemObject):
type = 'Bridge'
- side_a = Port('Side A port')
- side_b = Port('Side B port')
- req_size_a = Param.Int(16, "The number of requests to buffer")
- req_size_b = Param.Int(16, "The number of requests to buffer")
- resp_size_a = Param.Int(16, "The number of requests to buffer")
- resp_size_b = Param.Int(16, "The number of requests to buffer")
+ slave = Port('Slave port')
+ master = Port('Master port')
+ req_size = Param.Int(16, "The number of requests to buffer")
+ resp_size = Param.Int(16, "The number of requests to buffer")
delay = Param.Latency('0ns', "The latency of this bridge")
nack_delay = Param.Latency('0ns', "The latency of this bridge")
write_ack = Param.Bool(False, "Should this bridge ack writes")
- filter_ranges_a = VectorParam.AddrRange([],
- "What addresses shouldn't be passed through the side of the bridge")
- filter_ranges_b = VectorParam.AddrRange([],
- "What addresses shouldn't be passed through the side of the bridge")
+ ranges = VectorParam.AddrRange([AllMemory],
+ "Address ranges to pass through the bridge")
diff --git a/src/mem/SConscript b/src/mem/SConscript
index 8418a4f51..09cc93c77 100644
--- a/src/mem/SConscript
+++ b/src/mem/SConscript
@@ -41,14 +41,14 @@ Source('mport.cc')
Source('packet.cc')
Source('port.cc')
Source('tport.cc')
-Source('vport.cc')
+Source('fs_translating_port_proxy.cc')
+Source('se_translating_port_proxy.cc')
if env['TARGET_ISA'] != 'no':
SimObject('PhysicalMemory.py')
Source('dram.cc')
Source('page_table.cc')
Source('physical.cc')
- Source('translating_port.cc')
DebugFlag('Bus')
DebugFlag('BusAddrRanges')
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc
index 9e5e64069..b48662118 100644
--- a/src/mem/bridge.cc
+++ b/src/mem/bridge.cc
@@ -1,5 +1,16 @@
-
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -28,58 +39,67 @@
*
* Authors: Ali Saidi
* Steve Reinhardt
+ * Andreas Hansson
*/
/**
* @file
- * Definition of a simple bus bridge without buffering.
+ * Implementation of a memory-mapped bus bridge that connects a master
+ * and a slave through a request and response queue.
*/
-#include <algorithm>
-
-#include "base/range_ops.hh"
#include "base/trace.hh"
#include "debug/BusBridge.hh"
#include "mem/bridge.hh"
#include "params/Bridge.hh"
-Bridge::BridgePort::BridgePort(const std::string &_name,
- Bridge *_bridge, BridgePort *_otherPort,
- int _delay, int _nack_delay, int _req_limit,
- int _resp_limit,
- std::vector<Range<Addr> > filter_ranges)
- : Port(_name, _bridge), bridge(_bridge), otherPort(_otherPort),
- delay(_delay), nackDelay(_nack_delay), filterRanges(filter_ranges),
- outstandingResponses(0), queuedRequests(0), inRetry(false),
- reqQueueLimit(_req_limit), respQueueLimit(_resp_limit), sendEvent(this)
+Bridge::BridgeSlavePort::BridgeSlavePort(const std::string &_name,
+ Bridge* _bridge,
+ BridgeMasterPort* _masterPort,
+ int _delay, int _nack_delay,
+ int _resp_limit,
+ std::vector<Range<Addr> > _ranges)
+ : Port(_name, _bridge), bridge(_bridge), masterPort(_masterPort),
+ delay(_delay), nackDelay(_nack_delay),
+ ranges(_ranges.begin(), _ranges.end()),
+ outstandingResponses(0), inRetry(false),
+ respQueueLimit(_resp_limit), sendEvent(this)
+{
+}
+
+Bridge::BridgeMasterPort::BridgeMasterPort(const std::string &_name,
+ Bridge* _bridge,
+ BridgeSlavePort* _slavePort,
+ int _delay, int _req_limit)
+ : Port(_name, _bridge), bridge(_bridge), slavePort(_slavePort),
+ delay(_delay), inRetry(false), reqQueueLimit(_req_limit), sendEvent(this)
{
}
Bridge::Bridge(Params *p)
: MemObject(p),
- portA(p->name + "-portA", this, &portB, p->delay, p->nack_delay,
- p->req_size_a, p->resp_size_a, p->filter_ranges_a),
- portB(p->name + "-portB", this, &portA, p->delay, p->nack_delay,
- p->req_size_b, p->resp_size_b, p->filter_ranges_b),
+ slavePort(p->name + "-slave", this, &masterPort, p->delay,
+ p->nack_delay, p->resp_size, p->ranges),
+ masterPort(p->name + "-master", this, &slavePort, p->delay, p->req_size),
ackWrites(p->write_ack), _params(p)
{
if (ackWrites)
panic("No support for acknowledging writes\n");
}
-Port *
+Port*
Bridge::getPort(const std::string &if_name, int idx)
{
- BridgePort *port;
+ Port* port;
- if (if_name == "side_a")
- port = &portA;
- else if (if_name == "side_b")
- port = &portB;
+ if (if_name == "slave")
+ port = &slavePort;
+ else if (if_name == "master")
+ port = &masterPort;
else
return NULL;
- if (port->getPeer() != NULL && !port->getPeer()->isDefaultPort())
+ if (port->getPeer() != NULL)
panic("bridge side %s already connected to %s.",
if_name, port->getPeer()->name());
return port;
@@ -89,106 +109,133 @@ Bridge::getPort(const std::string &if_name, int idx)
void
Bridge::init()
{
- // Make sure that both sides are connected to.
- if (!portA.isConnected() || !portB.isConnected())
+ // make sure both sides are connected and have the same block size
+ if (!slavePort.isConnected() || !masterPort.isConnected())
fatal("Both ports of bus bridge are not connected to a bus.\n");
- if (portA.peerBlockSize() != portB.peerBlockSize())
- fatal("port A size %d, port B size %d \n " \
+ if (slavePort.peerBlockSize() != masterPort.peerBlockSize())
+ fatal("Slave port size %d, master port size %d \n " \
"Busses don't have the same block size... Not supported.\n",
- portA.peerBlockSize(), portB.peerBlockSize());
+ slavePort.peerBlockSize(), masterPort.peerBlockSize());
+
+ // notify the master side of our address ranges
+ slavePort.sendRangeChange();
+}
+
+bool
+Bridge::BridgeSlavePort::respQueueFull()
+{
+ return outstandingResponses == respQueueLimit;
}
bool
-Bridge::BridgePort::respQueueFull()
+Bridge::BridgeMasterPort::reqQueueFull()
{
- assert(outstandingResponses >= 0 && outstandingResponses <= respQueueLimit);
- return outstandingResponses >= respQueueLimit;
+ return requestQueue.size() == reqQueueLimit;
}
bool
-Bridge::BridgePort::reqQueueFull()
+Bridge::BridgeMasterPort::recvTiming(PacketPtr pkt)
{
- assert(queuedRequests >= 0 && queuedRequests <= reqQueueLimit);
- return queuedRequests >= reqQueueLimit;
+ // should only see responses on the master side
+ assert(pkt->isResponse());
+
+ // all checks are done when the request is accepted on the slave
+ // side, so we are guaranteed to have space for the response
+
+ DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n",
+ pkt->getSrc(), pkt->getDest(), pkt->getAddr());
+
+ DPRINTF(BusBridge, "Request queue size: %d\n", requestQueue.size());
+
+ slavePort->queueForSendTiming(pkt);
+
+ return true;
}
-/** Function called by the port when the bus is receiving a Timing
- * transaction.*/
bool
-Bridge::BridgePort::recvTiming(PacketPtr pkt)
+Bridge::BridgeSlavePort::recvTiming(PacketPtr pkt)
{
+ // should only see requests on the slave side
+ assert(pkt->isRequest());
+
DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n",
- pkt->getSrc(), pkt->getDest(), pkt->getAddr());
+ pkt->getSrc(), pkt->getDest(), pkt->getAddr());
- DPRINTF(BusBridge, "Local queue size: %d outreq: %d outresp: %d\n",
- sendQueue.size(), queuedRequests, outstandingResponses);
- DPRINTF(BusBridge, "Remote queue size: %d outreq: %d outresp: %d\n",
- otherPort->sendQueue.size(), otherPort->queuedRequests,
- otherPort->outstandingResponses);
+ DPRINTF(BusBridge, "Response queue size: %d outresp: %d\n",
+ responseQueue.size(), outstandingResponses);
- if (pkt->isRequest() && otherPort->reqQueueFull()) {
- DPRINTF(BusBridge, "Remote queue full, nacking\n");
+ if (masterPort->reqQueueFull()) {
+ DPRINTF(BusBridge, "Request queue full, nacking\n");
nackRequest(pkt);
return true;
}
if (pkt->needsResponse()) {
if (respQueueFull()) {
- DPRINTF(BusBridge, "Local queue full, no space for response, nacking\n");
- DPRINTF(BusBridge, "queue size: %d outreq: %d outstanding resp: %d\n",
- sendQueue.size(), queuedRequests, outstandingResponses);
+ DPRINTF(BusBridge,
+ "Response queue full, no space for response, nacking\n");
+ DPRINTF(BusBridge,
+ "queue size: %d outstanding resp: %d\n",
+ responseQueue.size(), outstandingResponses);
nackRequest(pkt);
return true;
} else {
DPRINTF(BusBridge, "Request Needs response, reserving space\n");
+ assert(outstandingResponses != respQueueLimit);
++outstandingResponses;
}
}
- otherPort->queueForSendTiming(pkt);
+ masterPort->queueForSendTiming(pkt);
return true;
}
void
-Bridge::BridgePort::nackRequest(PacketPtr pkt)
+Bridge::BridgeSlavePort::nackRequest(PacketPtr pkt)
{
// Nack the packet
pkt->makeTimingResponse();
pkt->setNacked();
- //put it on the list to send
+ // The Nack packets are stored in the response queue just like any
+ // other response, but they do not occupy any space as this is
+ // tracked by the outstandingResponses, this guarantees space for
+ // the Nack packets, but implicitly means we have an (unrealistic)
+ // unbounded Nack queue.
+
+ // put it on the list to send
Tick readyTime = curTick() + nackDelay;
PacketBuffer *buf = new PacketBuffer(pkt, readyTime, true);
// nothing on the list, add it and we're done
- if (sendQueue.empty()) {
+ if (responseQueue.empty()) {
assert(!sendEvent.scheduled());
- schedule(sendEvent, readyTime);
- sendQueue.push_back(buf);
+ bridge->schedule(sendEvent, readyTime);
+ responseQueue.push_back(buf);
return;
}
assert(sendEvent.scheduled() || inRetry);
// does it go at the end?
- if (readyTime >= sendQueue.back()->ready) {
- sendQueue.push_back(buf);
+ if (readyTime >= responseQueue.back()->ready) {
+ responseQueue.push_back(buf);
return;
}
// ok, somewhere in the middle, fun
- std::list<PacketBuffer*>::iterator i = sendQueue.begin();
- std::list<PacketBuffer*>::iterator end = sendQueue.end();
- std::list<PacketBuffer*>::iterator begin = sendQueue.begin();
+ std::list<PacketBuffer*>::iterator i = responseQueue.begin();
+ std::list<PacketBuffer*>::iterator end = responseQueue.end();
+ std::list<PacketBuffer*>::iterator begin = responseQueue.begin();
bool done = false;
while (i != end && !done) {
if (readyTime < (*i)->ready) {
if (i == begin)
- reschedule(sendEvent, readyTime);
- sendQueue.insert(i,buf);
+ bridge->reschedule(sendEvent, readyTime);
+ responseQueue.insert(i,buf);
done = true;
}
i++;
@@ -196,51 +243,60 @@ Bridge::BridgePort::nackRequest(PacketPtr pkt)
assert(done);
}
-
void
-Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
+Bridge::BridgeMasterPort::queueForSendTiming(PacketPtr pkt)
{
- 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, "response, new dest %d\n", pkt->getDest());
- delete buf;
+ Tick readyTime = curTick() + delay;
+ PacketBuffer *buf = new PacketBuffer(pkt, readyTime);
+
+ // If we're about to put this packet at the head of the queue, we
+ // need to schedule an event to do the transmit. Otherwise there
+ // should already be an event scheduled for sending the head
+ // packet.
+ if (requestQueue.empty()) {
+ bridge->schedule(sendEvent, readyTime);
}
+ assert(requestQueue.size() != reqQueueLimit);
- if (pkt->isRequest()) {
- ++queuedRequests;
- }
+ requestQueue.push_back(buf);
+}
+void
+Bridge::BridgeSlavePort::queueForSendTiming(PacketPtr pkt)
+{
+ // 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, "response, new dest %d\n", pkt->getDest());
+ delete buf;
Tick readyTime = curTick() + delay;
- PacketBuffer *buf = new PacketBuffer(pkt, readyTime);
+ buf = new PacketBuffer(pkt, readyTime);
// If we're about to put this packet at the head of the queue, we
// need to schedule an event to do the transmit. Otherwise there
// should already be an event scheduled for sending the head
// packet.
- if (sendQueue.empty()) {
- schedule(sendEvent, readyTime);
+ if (responseQueue.empty()) {
+ bridge->schedule(sendEvent, readyTime);
}
- sendQueue.push_back(buf);
+ responseQueue.push_back(buf);
}
void
-Bridge::BridgePort::trySend()
+Bridge::BridgeMasterPort::trySend()
{
- assert(!sendQueue.empty());
+ assert(!requestQueue.empty());
- PacketBuffer *buf = sendQueue.front();
+ PacketBuffer *buf = requestQueue.front();
assert(buf->ready <= curTick());
@@ -249,110 +305,195 @@ Bridge::BridgePort::trySend()
DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
buf->origSrc, pkt->getDest(), pkt->getAddr());
- bool wasReq = pkt->isRequest();
- bool was_nacked_here = buf->nackedHere;
-
// If the send was successful, make sure sender state was set to NULL
// otherwise we could get a NACK back of a packet that didn't expect a
// response and we would try to use freed memory.
Packet::SenderState *old_sender_state = pkt->senderState;
- if (pkt->isRequest() && !buf->expectResponse)
+ if (!buf->expectResponse)
pkt->senderState = NULL;
if (sendTiming(pkt)) {
// send successful
- sendQueue.pop_front();
- buf->pkt = NULL; // we no longer own packet, so it's not safe to look at it
+ requestQueue.pop_front();
+ // we no longer own packet, so it's not safe to look at it
+ buf->pkt = NULL;
- if (buf->expectResponse) {
- // Must wait for response
- DPRINTF(BusBridge, " successful: awaiting response (%d)\n",
- outstandingResponses);
- } else {
+ if (!buf->expectResponse) {
// no response expected... deallocate packet buffer now.
DPRINTF(BusBridge, " successful: no response expected\n");
delete buf;
}
- if (wasReq)
- --queuedRequests;
- else if (!was_nacked_here)
+ // If there are more packets to send, schedule event to try again.
+ if (!requestQueue.empty()) {
+ buf = requestQueue.front();
+ DPRINTF(BusBridge, "Scheduling next send\n");
+ bridge->schedule(sendEvent, std::max(buf->ready, curTick() + 1));
+ }
+ } else {
+ DPRINTF(BusBridge, " unsuccessful\n");
+ pkt->senderState = old_sender_state;
+ inRetry = true;
+ }
+
+ DPRINTF(BusBridge, "trySend: request queue size: %d\n",
+ requestQueue.size());
+}
+
+void
+Bridge::BridgeSlavePort::trySend()
+{
+ assert(!responseQueue.empty());
+
+ PacketBuffer *buf = responseQueue.front();
+
+ assert(buf->ready <= curTick());
+
+ PacketPtr pkt = buf->pkt;
+
+ DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
+ buf->origSrc, pkt->getDest(), pkt->getAddr());
+
+ bool was_nacked_here = buf->nackedHere;
+
+ // no need to worry about the sender state since we are not
+ // modifying it
+
+ if (sendTiming(pkt)) {
+ DPRINTF(BusBridge, " successful\n");
+ // send successful
+ responseQueue.pop_front();
+ // this is a response... deallocate packet buffer now.
+ delete buf;
+
+ if (!was_nacked_here) {
+ assert(outstandingResponses != 0);
--outstandingResponses;
+ }
// If there are more packets to send, schedule event to try again.
- if (!sendQueue.empty()) {
- buf = sendQueue.front();
+ if (!responseQueue.empty()) {
+ buf = responseQueue.front();
DPRINTF(BusBridge, "Scheduling next send\n");
- schedule(sendEvent, std::max(buf->ready, curTick() + 1));
+ bridge->schedule(sendEvent, std::max(buf->ready, curTick() + 1));
}
} else {
DPRINTF(BusBridge, " unsuccessful\n");
- pkt->senderState = old_sender_state;
inRetry = true;
}
- DPRINTF(BusBridge, "trySend: queue size: %d outreq: %d outstanding resp: %d\n",
- sendQueue.size(), queuedRequests, outstandingResponses);
+ DPRINTF(BusBridge, "trySend: queue size: %d outstanding resp: %d\n",
+ responseQueue.size(), outstandingResponses);
}
+void
+Bridge::BridgeMasterPort::recvRetry()
+{
+ inRetry = false;
+ Tick nextReady = requestQueue.front()->ready;
+ if (nextReady <= curTick())
+ trySend();
+ else
+ bridge->schedule(sendEvent, nextReady);
+}
void
-Bridge::BridgePort::recvRetry()
+Bridge::BridgeSlavePort::recvRetry()
{
inRetry = false;
- Tick nextReady = sendQueue.front()->ready;
+ Tick nextReady = responseQueue.front()->ready;
if (nextReady <= curTick())
trySend();
else
- schedule(sendEvent, nextReady);
+ bridge->schedule(sendEvent, nextReady);
}
-/** Function called by the port when the bus is receiving a Atomic
- * transaction.*/
Tick
-Bridge::BridgePort::recvAtomic(PacketPtr pkt)
+Bridge::BridgeMasterPort::recvAtomic(PacketPtr pkt)
{
- return delay + otherPort->sendAtomic(pkt);
+ // master port should never receive any atomic access (panic only
+ // works once the other side, i.e. the busses, respects this)
+ //
+ //panic("Master port on %s got a recvAtomic\n", bridge->name());
+ return 0;
+}
+
+Tick
+Bridge::BridgeSlavePort::recvAtomic(PacketPtr pkt)
+{
+ return delay + masterPort->sendAtomic(pkt);
}
-/** Function called by the port when the bus is receiving a Functional
- * transaction.*/
void
-Bridge::BridgePort::recvFunctional(PacketPtr pkt)
+Bridge::BridgeMasterPort::recvFunctional(PacketPtr pkt)
+{
+ // master port should never receive any functional access (panic
+ // only works once the other side, i.e. the busses, respect this)
+
+ // panic("Master port on %s got a recvFunctional\n", bridge->name());
+}
+
+void
+Bridge::BridgeSlavePort::recvFunctional(PacketPtr pkt)
{
std::list<PacketBuffer*>::iterator i;
pkt->pushLabel(name());
- for (i = sendQueue.begin(); i != sendQueue.end(); ++i) {
+ // check the response queue
+ for (i = responseQueue.begin(); i != responseQueue.end(); ++i) {
if (pkt->checkFunctional((*i)->pkt)) {
pkt->makeResponse();
return;
}
}
+ // also check the master port's request queue
+ if (masterPort->checkFunctional(pkt)) {
+ return;
+ }
+
pkt->popLabel();
// fall through if pkt still not satisfied
- otherPort->sendFunctional(pkt);
+ masterPort->sendFunctional(pkt);
}
-/** Function called by the port when the bus is receiving a status change.*/
+bool
+Bridge::BridgeMasterPort::checkFunctional(PacketPtr pkt)
+{
+ bool found = false;
+ std::list<PacketBuffer*>::iterator i = requestQueue.begin();
+
+ while(i != requestQueue.end() && !found) {
+ if (pkt->checkFunctional((*i)->pkt)) {
+ pkt->makeResponse();
+ found = true;
+ }
+ ++i;
+ }
+
+ return found;
+}
+
+/** Function called by the port when the bridge is receiving a range change.*/
void
-Bridge::BridgePort::recvStatusChange(Port::Status status)
+Bridge::BridgeMasterPort::recvRangeChange()
{
- otherPort->sendStatusChange(status);
+ // no need to forward as the bridge has a fixed set of ranges
}
void
-Bridge::BridgePort::getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
+Bridge::BridgeSlavePort::recvRangeChange()
+{
+ // is a slave port so do nothing
+}
+
+AddrRangeList
+Bridge::BridgeSlavePort::getAddrRanges()
{
- otherPort->getPeerAddressRanges(resp, snoop);
- FilterRangeList(filterRanges, resp);
- // we don't allow snooping across bridges
- snoop = false;
+ return ranges;
}
Bridge *
diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh
index 732717dd4..d389c0a5e 100644
--- a/src/mem/bridge.hh
+++ b/src/mem/bridge.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -27,11 +39,13 @@
*
* Authors: Ali Saidi
* Steve Reinhardt
+ * Andreas Hansson
*/
/**
* @file
- * Declaration of a simple bus bridge object with no buffering
+ * Declaration of a memory-mapped bus bridge that connects a master
+ * and a slave through a request and response queue.
*/
#ifndef __MEM_BRIDGE_HH__
@@ -49,90 +63,232 @@
#include "params/Bridge.hh"
#include "sim/eventq.hh"
+/**
+ * A bridge is used to interface two different busses (or in general a
+ * memory-mapped master and slave), with buffering for requests and
+ * responses. The bridge has a fixed delay for packets passing through
+ * it and responds to a fixed set of address ranges.
+ *
+ * The bridge comprises a slave port and a master port, that buffer
+ * outgoing responses and requests respectively. Buffer space is
+ * reserved when a request arrives, also reserving response space
+ * before forwarding the request. An incoming request is always
+ * accepted (recvTiming returns true), but is potentially NACKed if
+ * there is no request space or response space.
+ */
class Bridge : public MemObject
{
protected:
- /** Declaration of the buses port type, one will be instantiated for each
- of the interfaces connecting to the bus. */
- class BridgePort : public Port
+
+ /**
+ * A packet buffer stores packets along with their sender state
+ * and scheduled time for transmission.
+ */
+ class PacketBuffer : public Packet::SenderState, public FastAlloc {
+
+ public:
+ Tick ready;
+ PacketPtr pkt;
+ bool nackedHere;
+ Packet::SenderState *origSenderState;
+ short origSrc;
+ bool expectResponse;
+
+ PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
+ : ready(t), pkt(_pkt), nackedHere(nack),
+ origSenderState(_pkt->senderState),
+ origSrc(nack ? _pkt->getDest() : _pkt->getSrc() ),
+ expectResponse(_pkt->needsResponse() && !nack)
+
+ {
+ if (!pkt->isResponse() && !nack)
+ pkt->senderState = this;
+ }
+
+ void fixResponse(PacketPtr pkt)
+ {
+ assert(pkt->senderState == this);
+ pkt->setDest(origSrc);
+ pkt->senderState = origSenderState;
+ }
+ };
+
+ // Forward declaration to allow the slave port to have a pointer
+ class BridgeMasterPort;
+
+ /**
+ * The port on the side that receives requests and sends
+ * responses. The slave port has a set of address ranges that it
+ * is responsible for. The slave port also has a buffer for the
+ * responses not yet sent.
+ */
+ class BridgeSlavePort : public Port
{
+
+ private:
+
/** A pointer to the bridge to which this port belongs. */
Bridge *bridge;
/**
- * Pointer to the port on the other side of the bridge
+ * Pointer to the master port on the other side of the bridge
* (connected to the other bus).
*/
- BridgePort *otherPort;
+ BridgeMasterPort* masterPort;
- /** Minimum delay though this bridge. */
+ /** Minimum request delay though this bridge. */
Tick delay;
- /** Min delay to respond to a nack. */
+ /** Min delay to respond with a nack. */
Tick nackDelay;
- /** Pass ranges from one side of the bridge to the other? */
- std::vector<Range<Addr> > filterRanges;
+ /** Address ranges to pass through the bridge */
+ AddrRangeList ranges;
+
+ /**
+ * Response packet queue. Response packets are held in this
+ * queue for a specified delay to model the processing delay
+ * of the bridge.
+ */
+ std::list<PacketBuffer*> responseQueue;
- class PacketBuffer : public Packet::SenderState, public FastAlloc {
+ /** Counter to track the outstanding responses. */
+ unsigned int outstandingResponses;
+
+ /** If we're waiting for a retry to happen. */
+ bool inRetry;
+
+ /** Max queue size for reserved responses. */
+ unsigned int respQueueLimit;
+
+ /**
+ * Is this side blocked from accepting new response packets.
+ *
+ * @return true if the reserved space has reached the set limit
+ */
+ bool respQueueFull();
+
+ /**
+ * Turn the request packet into a NACK response and put it in
+ * the response queue and schedule its transmission.
+ *
+ * @param pkt the request packet to NACK
+ */
+ void nackRequest(PacketPtr pkt);
+
+ /**
+ * Handle send event, scheduled when the packet at the head of
+ * the response queue is ready to transmit (for timing
+ * accesses only).
+ */
+ void trySend();
+
+ /**
+ * Private class for scheduling sending of responses from the
+ * response queue.
+ */
+ class SendEvent : public Event
+ {
+ BridgeSlavePort *port;
public:
- Tick ready;
- PacketPtr pkt;
- bool nackedHere;
- Packet::SenderState *origSenderState;
- short origSrc;
- bool expectResponse;
-
- PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
- : ready(t), pkt(_pkt), nackedHere(nack),
- origSenderState(_pkt->senderState),
- origSrc(nack ? _pkt->getDest() : _pkt->getSrc() ),
- expectResponse(_pkt->needsResponse() && !nack)
-
- {
- if (!pkt->isResponse() && !nack)
- pkt->senderState = this;
- }
-
- void fixResponse(PacketPtr pkt)
- {
- assert(pkt->senderState == this);
- pkt->setDest(origSrc);
- pkt->senderState = origSenderState;
- }
+ SendEvent(BridgeSlavePort *p) : port(p) {}
+ virtual void process() { port->trySend(); }
+ virtual const char *description() const { return "bridge send"; }
};
+ /** Send event for the response queue. */
+ SendEvent sendEvent;
+
+ public:
+
/**
- * Outbound packet queue. Packets are held in this queue for a
- * specified delay to model the processing delay of the
- * bridge.
+ * Constructor for the BridgeSlavePort.
+ *
+ * @param _name the port name including the owner
+ * @param _bridge the structural owner
+ * @param _masterPort the master port on the other side of the bridge
+ * @param _delay the delay from seeing a response to sending it
+ * @param _nack_delay the delay from a NACK to sending the response
+ * @param _resp_limit the size of the response queue
+ * @param _ranges a number of address ranges to forward
*/
- std::list<PacketBuffer*> sendQueue;
+ BridgeSlavePort(const std::string &_name, Bridge *_bridge,
+ BridgeMasterPort* _masterPort, int _delay,
+ int _nack_delay, int _resp_limit,
+ std::vector<Range<Addr> > _ranges);
- int outstandingResponses;
- int queuedRequests;
+ /**
+ * Queue a response packet to be sent out later and also schedule
+ * a send if necessary.
+ *
+ * @param pkt a response to send out after a delay
+ */
+ void queueForSendTiming(PacketPtr pkt);
- /** If we're waiting for a retry to happen.*/
- bool inRetry;
+ protected:
- /** Max queue size for outbound packets */
- int reqQueueLimit;
+ /** When receiving a timing request from the peer port,
+ pass it to the bridge. */
+ virtual bool recvTiming(PacketPtr pkt);
- /** Max queue size for reserved responses. */
- int respQueueLimit;
+ /** When receiving a retry request from the peer port,
+ pass it to the bridge. */
+ virtual void recvRetry();
+
+ /** When receiving a Atomic requestfrom the peer port,
+ pass it to the bridge. */
+ virtual Tick recvAtomic(PacketPtr pkt);
+
+ /** When receiving a Functional request from the peer port,
+ pass it to the bridge. */
+ virtual void recvFunctional(PacketPtr pkt);
/**
- * Is this side blocked from accepting outbound packets?
+ * When receiving a range change on the slave side do nothing.
*/
- bool respQueueFull();
- bool reqQueueFull();
+ virtual void recvRangeChange();
- void queueForSendTiming(PacketPtr pkt);
+ /** When receiving a address range request the peer port,
+ pass it to the bridge. */
+ virtual AddrRangeList getAddrRanges();
+ };
- void finishSend(PacketBuffer *buf);
- void nackRequest(PacketPtr pkt);
+ /**
+ * Port on the side that forwards requests and receives
+ * responses. The master port has a buffer for the requests not
+ * yet sent.
+ */
+ class BridgeMasterPort : public Port
+ {
+
+ private:
+
+ /** A pointer to the bridge to which this port belongs. */
+ Bridge* bridge;
+
+ /**
+ * Pointer to the slave port on the other side of the bridge
+ * (connected to the other bus).
+ */
+ BridgeSlavePort* slavePort;
+
+ /** Minimum delay though this bridge. */
+ Tick delay;
+
+ /**
+ * Request packet queue. Request packets are held in this
+ * queue for a specified delay to model the processing delay
+ * of the bridge.
+ */
+ std::list<PacketBuffer*> requestQueue;
+
+ /** If we're waiting for a retry to happen. */
+ bool inRetry;
+
+ /** Max queue size for request packets */
+ unsigned int reqQueueLimit;
/**
* Handle send event, scheduled when the packet at the head of
@@ -141,24 +297,62 @@ class Bridge : public MemObject
*/
void trySend();
+ /**
+ * Private class for scheduling sending of requests from the
+ * request queue.
+ */
class SendEvent : public Event
{
- BridgePort *port;
+ BridgeMasterPort *port;
public:
- SendEvent(BridgePort *p) : port(p) {}
+ SendEvent(BridgeMasterPort *p) : port(p) {}
virtual void process() { port->trySend(); }
virtual const char *description() const { return "bridge send"; }
};
+ /** Send event for the request queue. */
SendEvent sendEvent;
public:
- /** Constructor for the BusPort.*/
- BridgePort(const std::string &_name, Bridge *_bridge,
- BridgePort *_otherPort, int _delay, int _nack_delay,
- int _req_limit, int _resp_limit,
- std::vector<Range<Addr> > filter_ranges);
+
+ /**
+ * Constructor for the BridgeMasterPort.
+ *
+ * @param _name the port name including the owner
+ * @param _bridge the structural owner
+ * @param _slavePort the slave port on the other side of the bridge
+ * @param _delay the delay from seeing a request to sending it
+ * @param _req_limit the size of the request queue
+ */
+ BridgeMasterPort(const std::string &_name, Bridge *_bridge,
+ BridgeSlavePort* _slavePort, int _delay,
+ int _req_limit);
+
+ /**
+ * Is this side blocked from accepting new request packets.
+ *
+ * @return true if the occupied space has reached the set limit
+ */
+ bool reqQueueFull();
+
+ /**
+ * Queue a request packet to be sent out later and also schedule
+ * a send if necessary.
+ *
+ * @param pkt a request to send out after a delay
+ */
+ void queueForSendTiming(PacketPtr pkt);
+
+ /**
+ * Check a functional request against the packets in our
+ * request queue.
+ *
+ * @param pkt packet to check against
+ *
+ * @return true if we find a match
+ */
+ bool checkFunctional(PacketPtr pkt);
protected:
@@ -178,17 +372,17 @@ class Bridge : public MemObject
pass it to the bridge. */
virtual void recvFunctional(PacketPtr 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,
- bool &snoop);
+ /**
+ * When receiving a range change, pass it through the bridge.
+ */
+ virtual void recvRangeChange();
};
- BridgePort portA, portB;
+ /** Slave port of the bridge. */
+ BridgeSlavePort slavePort;
+
+ /** Master port of the bridge. */
+ BridgeMasterPort masterPort;
/** If this bridge should acknowledge writes. */
bool ackWrites;
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index db71b86b7..a20f90108 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -26,6 +38,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
+ * Andreas Hansson
*/
/**
@@ -33,9 +46,6 @@
* Definition of a bus object.
*/
-#include <algorithm>
-#include <limits>
-
#include "base/misc.hh"
#include "base/trace.hh"
#include "debug/Bus.hh"
@@ -46,8 +56,7 @@
Bus::Bus(const BusParams *p)
: MemObject(p), busId(p->bus_id), clock(p->clock),
headerCycles(p->header_cycles), width(p->width), tickNextIdle(0),
- drainEvent(NULL), busIdle(this), inRetry(false), maxId(0),
- defaultPort(NULL), funcPort(NULL), funcPortId(-4),
+ drainEvent(NULL), busIdle(this), inRetry(false), defaultPortId(-1),
useDefaultRange(p->use_default_range), defaultBlockSize(p->block_size),
cachedBlockSize(0), cachedBlockSizeValid(false)
{
@@ -58,65 +67,44 @@ Bus::Bus(const BusParams *p)
fatal("Bus clock period must be positive\n");
if (headerCycles <= 0)
fatal("Number of header cycles must be positive\n");
- clearBusCache();
clearPortCache();
}
Port *
Bus::getPort(const std::string &if_name, int idx)
{
+ std::string portName;
+ int id = interfaces.size();
if (if_name == "default") {
- if (defaultPort == NULL) {
- defaultPort = new BusPort(csprintf("%s-default",name()), this,
- defaultId);
- cachedBlockSizeValid = false;
- return defaultPort;
+ if (defaultPortId == -1) {
+ defaultPortId = id;
+ portName = csprintf("%s-default", name());
} else
- fatal("Default port already set\n");
- }
- int id;
- if (if_name == "functional") {
- if (!funcPort) {
- id = maxId++;
- funcPort = new BusPort(csprintf("%s-p%d-func", name(), id), this, id);
- funcPortId = id;
- interfaces[id] = funcPort;
- }
- return funcPort;
+ fatal("Default port already set on %s\n", name());
+ } else {
+ portName = csprintf("%s-p%d", name(), id);
}
-
- // if_name ignored? forced to be empty?
- id = maxId++;
- assert(maxId < std::numeric_limits<typeof(maxId)>::max());
- BusPort *bp = new BusPort(csprintf("%s-p%d", name(), id), this, id);
- interfaces[id] = bp;
+ BusPort *bp = new BusPort(portName, this, id);
+ interfaces.push_back(bp);
cachedBlockSizeValid = false;
return bp;
}
void
-Bus::deletePortRefs(Port *p)
-{
-
- BusPort *bp = dynamic_cast<BusPort*>(p);
- if (bp == NULL)
- panic("Couldn't convert Port* to BusPort*\n");
- // If this is our one functional port
- if (funcPort == bp)
- return;
- interfaces.erase(bp->getId());
- clearBusCache();
- delete bp;
-}
-
-/** Get the ranges of anyone other buses that we are connected to. */
-void
Bus::init()
{
- m5::hash_map<short,BusPort*>::iterator intIter;
-
- for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
- intIter->second->sendStatusChange(Port::RangeChange);
+ std::vector<BusPort*>::iterator intIter;
+
+ // iterate over our interfaces and determine which of our neighbours
+ // are snooping and add them as snoopers
+ for (intIter = interfaces.begin(); intIter != interfaces.end();
+ intIter++) {
+ if ((*intIter)->getPeer()->isSnooping()) {
+ DPRINTF(BusAddrRanges, "Adding snooping neighbour %s\n",
+ (*intIter)->getPeer()->name());
+ snoopPorts.push_back(*intIter);
+ }
+ }
}
Bus::BusFreeEvent::BusFreeEvent(Bus *_bus)
@@ -194,16 +182,7 @@ Bus::recvTiming(PacketPtr pkt)
{
short src = pkt->getSrc();
- BusPort *src_port;
- if (src == defaultId)
- src_port = defaultPort;
- else {
- src_port = checkBusCache(src);
- if (src_port == NULL) {
- src_port = interfaces[src];
- updateBusCache(src, src_port);
- }
- }
+ BusPort *src_port = interfaces[src];
// If the bus is busy, or other devices are in line ahead of the current
// one, put this device on the retry list.
@@ -229,8 +208,7 @@ Bus::recvTiming(PacketPtr pkt)
if (dest == Packet::Broadcast) {
dest_port_id = findPort(pkt->getAddr());
- dest_port = (dest_port_id == defaultId) ?
- defaultPort : interfaces[dest_port_id];
+ dest_port = interfaces[dest_port_id];
SnoopIter s_end = snoopPorts.end();
for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
BusPort *p = *s_iter;
@@ -241,20 +219,10 @@ Bus::recvTiming(PacketPtr pkt)
}
}
} else {
- assert(dest < maxId);
+ assert(dest < interfaces.size());
assert(dest != src); // catch infinite loops
dest_port_id = dest;
- if (dest_port_id == defaultId)
- dest_port = defaultPort;
- else {
- dest_port = checkBusCache(dest);
- if (dest_port == NULL) {
- dest_port = interfaces[dest_port_id];
- // updateBusCache(dest_port_id, dest_port);
- }
- }
- dest_port = (dest_port_id == defaultId) ?
- defaultPort : interfaces[dest_port_id];
+ dest_port = interfaces[dest_port_id];
}
if (dest_port_id == src) {
@@ -352,7 +320,7 @@ Bus::findPort(Addr addr)
for (AddrRangeIter i = defaultRange.begin(); i != a_end; i++) {
if (*i == addr) {
DPRINTF(Bus, " found addr %#llx on default\n", addr);
- return defaultId;
+ return defaultPortId;
}
}
@@ -361,7 +329,7 @@ Bus::findPort(Addr addr)
DPRINTF(Bus, "Unable to find destination for addr %#llx, "
"will use default port\n", addr);
- return defaultId;
+ return defaultPortId;
}
@@ -385,16 +353,7 @@ Bus::recvAtomic(PacketPtr pkt)
int orig_src = pkt->getSrc();
int target_port_id = findPort(pkt->getAddr());
- BusPort *target_port;
- if (target_port_id == defaultId)
- target_port = defaultPort;
- else {
- target_port = checkBusCache(target_port_id);
- if (target_port == NULL) {
- target_port = interfaces[target_port_id];
- updateBusCache(target_port_id, target_port);
- }
- }
+ BusPort *target_port = interfaces[target_port_id];
SnoopIter s_end = snoopPorts.end();
for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
@@ -450,7 +409,7 @@ Bus::recvFunctional(PacketPtr pkt)
assert(pkt->getDest() == Packet::Broadcast);
int port_id = findPort(pkt->getAddr());
- Port *port = (port_id == defaultId) ? defaultPort : interfaces[port_id];
+ Port *port = interfaces[port_id];
// The packet may be changed by another bus on snoops, restore the
// id after each
int src_id = pkt->getSrc();
@@ -483,30 +442,25 @@ Bus::recvFunctional(PacketPtr pkt)
}
}
-/** Function called by the port when the bus is receiving a status change.*/
+/** Function called by the port when the bus is receiving a range change.*/
void
-Bus::recvStatusChange(Port::Status status, int id)
+Bus::recvRangeChange(int id)
{
AddrRangeList ranges;
- bool snoops;
AddrRangeIter iter;
- if (inRecvStatusChange.count(id))
+ if (inRecvRangeChange.count(id))
return;
- inRecvStatusChange.insert(id);
-
- assert(status == Port::RangeChange &&
- "The other statuses need to be implemented.");
+ inRecvRangeChange.insert(id);
DPRINTF(BusAddrRanges, "received RangeChange from device id %d\n", id);
clearPortCache();
- if (id == defaultId) {
+ if (id == defaultPortId) {
defaultRange.clear();
// Only try to update these ranges if the user set a default responder.
if (useDefaultRange) {
- defaultPort->getPeerAddressRanges(ranges, snoops);
- assert(snoops == false);
+ AddrRangeList ranges = interfaces[id]->getPeer()->getAddrRanges();
for(iter = ranges.begin(); iter != ranges.end(); iter++) {
defaultRange.push_back(*iter);
DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for default range\n",
@@ -515,7 +469,7 @@ Bus::recvStatusChange(Port::Status status, int id)
}
} else {
- assert((id < maxId && id >= 0) || id == defaultId);
+ assert(id < interfaces.size() && id >= 0);
BusPort *port = interfaces[id];
// Clean out any previously existent ids
@@ -527,20 +481,7 @@ Bus::recvStatusChange(Port::Status status, int id)
portIter++;
}
- for (SnoopIter s_iter = snoopPorts.begin();
- s_iter != snoopPorts.end(); ) {
- if ((*s_iter)->getId() == id)
- s_iter = snoopPorts.erase(s_iter);
- else
- s_iter++;
- }
-
- port->getPeerAddressRanges(ranges, snoops);
-
- if (snoops) {
- DPRINTF(BusAddrRanges, "Adding id %d to snoop list\n", id);
- snoopPorts.push_back(port);
- }
+ ranges = port->getPeer()->getAddrRanges();
for (iter = ranges.begin(); iter != ranges.end(); iter++) {
DPRINTF(BusAddrRanges, "Adding range %#llx - %#llx for id %d\n",
@@ -557,28 +498,25 @@ Bus::recvStatusChange(Port::Status status, int id)
// tell all our peers that our address range has changed.
// Don't tell the device that caused this change, it already knows
- m5::hash_map<short,BusPort*>::iterator intIter;
+ std::vector<BusPort*>::const_iterator intIter;
for (intIter = interfaces.begin(); intIter != interfaces.end(); intIter++)
- if (intIter->first != id && intIter->first != funcPortId)
- intIter->second->sendStatusChange(Port::RangeChange);
+ if ((*intIter)->getId() != id)
+ (*intIter)->sendRangeChange();
- if (id != defaultId && defaultPort)
- defaultPort->sendStatusChange(Port::RangeChange);
- inRecvStatusChange.erase(id);
+ inRecvRangeChange.erase(id);
}
-void
-Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id)
+AddrRangeList
+Bus::getAddrRanges(int id)
{
- resp.clear();
- snoop = false;
+ AddrRangeList ranges;
DPRINTF(BusAddrRanges, "received address range request, returning:\n");
for (AddrRangeIter dflt_iter = defaultRange.begin();
dflt_iter != defaultRange.end(); dflt_iter++) {
- resp.push_back(*dflt_iter);
+ ranges.push_back(*dflt_iter);
DPRINTF(BusAddrRanges, " -- Dflt: %#llx : %#llx\n",dflt_iter->start,
dflt_iter->end);
}
@@ -601,12 +539,21 @@ Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id)
}
}
if (portIter->second != id && !subset) {
- resp.push_back(portIter->first);
+ ranges.push_back(portIter->first);
DPRINTF(BusAddrRanges, " -- %#llx : %#llx\n",
portIter->first.start, portIter->first.end);
}
}
+ return ranges;
+}
+
+bool
+Bus::isSnooping(int id)
+{
+ // in essence, answer the question if there are other snooping
+ // ports rather than the port that is asking
+ bool snoop = false;
for (SnoopIter s_iter = snoopPorts.begin(); s_iter != snoopPorts.end();
s_iter++) {
if ((*s_iter)->getId() != id) {
@@ -614,6 +561,7 @@ Bus::addressRanges(AddrRangeList &resp, bool &snoop, int id)
break;
}
}
+ return snoop;
}
unsigned
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 17d22ec83..5b8b373a5 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -27,6 +39,7 @@
*
* Authors: Ron Dreslinski
* Ali Saidi
+ * Andreas Hansson
*/
/**
@@ -79,7 +92,16 @@ class Bus : public MemObject
void onRetryList(bool newVal)
{ _onRetryList = newVal; }
- int getId() { return id; }
+ int getId() const { return id; }
+
+ /**
+ * Determine if this port should be considered a snooper. This
+ * is determined by the bus.
+ *
+ * @return a boolean that is true if this port is snooping
+ */
+ virtual bool isSnooping()
+ { return bus->isSnooping(id); }
protected:
@@ -98,10 +120,10 @@ class Bus : public MemObject
virtual void recvFunctional(PacketPtr pkt)
{ pkt->setSrc(id); bus->recvFunctional(pkt); }
- /** When reciving a status changefrom the peer port (at id),
+ /** When reciving a range change from the peer port (at id),
pass it to the bus. */
- virtual void recvStatusChange(Status status)
- { bus->recvStatusChange(status, id); }
+ virtual void recvRangeChange()
+ { bus->recvRangeChange(id); }
/** When reciving a retry from the peer port (at id),
pass it to the bus. */
@@ -112,9 +134,8 @@ class Bus : public MemObject
// downstream from this bus, yes? That is, the union of all
// the 'owned' address ranges of all the other interfaces on
// this bus...
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { bus->addressRanges(resp, snoop, id); }
+ virtual AddrRangeList getAddrRanges()
+ { return bus->getAddrRanges(id); }
// Ask the bus to ask everyone on the bus what their block size is and
// take the max of it. This might need to be changed a bit if we ever
@@ -147,9 +168,6 @@ class Bus : public MemObject
Event * drainEvent;
-
- static const int defaultId = -3; //Make it unique from Broadcast
-
typedef range_map<Addr,int>::iterator PortIter;
range_map<Addr, int> portMap;
@@ -174,8 +192,8 @@ class Bus : public MemObject
* requests. */
void recvRetry(int id);
- /** Function called by the port when the bus is recieving a status change.*/
- void recvStatusChange(Port::Status status, int id);
+ /** Function called by the port when the bus is recieving a range change.*/
+ void recvRangeChange(int id);
/** Find which port connected to this bus (if any) should be given a packet
* with this address.
@@ -238,12 +256,23 @@ class Bus : public MemObject
portCache[0].valid = false;
}
- /** 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.
+ /**
+ * Return the address ranges this port is responsible for.
+ *
+ * @param id id of the bus port that made the request
+ *
+ * @return a list of non-overlapping address ranges
+ */
+ AddrRangeList getAddrRanges(int id);
+
+ /**
+ * Determine if the bus port is snooping or not.
+ *
+ * @param id id of the bus port that made the request
+ *
+ * @return a boolean indicating if this port is snooping or not
*/
- void addressRanges(AddrRangeList &resp, bool &snoop, int id);
+ bool isSnooping(int id);
/** Calculate the timing parameters for the packet. Updates the
* firstWordTime and finishTime fields of the packet object.
@@ -264,14 +293,11 @@ class Bus : public MemObject
BusFreeEvent busIdle;
bool inRetry;
- std::set<int> inRecvStatusChange;
+ std::set<int> inRecvRangeChange;
- /** max number of bus ids we've handed out so far */
- short maxId;
-
- /** An array of pointers to the peer port interfaces
+ /** An ordered vector of pointers to the peer port interfaces
connected to this bus.*/
- m5::hash_map<short,BusPort*> interfaces;
+ std::vector<BusPort*> interfaces;
/** An array of pointers to ports that retry should be called on because the
* original send failed for whatever reason.*/
@@ -300,10 +326,7 @@ class Bus : public MemObject
}
/** Port that handles requests that don't match any of the interfaces.*/
- BusPort *defaultPort;
-
- BusPort *funcPort;
- int funcPortId;
+ short defaultPortId;
/** If true, use address range provided by default device. Any
address not handled by another port and not in default device's
@@ -315,59 +338,10 @@ class Bus : public MemObject
unsigned cachedBlockSize;
bool cachedBlockSizeValid;
- // Cache for the peer port interfaces
- struct BusCache {
- bool valid;
- short id;
- BusPort *port;
- };
-
- BusCache busCache[3];
-
- // Checks the peer port interfaces cache for the port id and returns
- // a pointer to the matching port
- inline BusPort* checkBusCache(short id) {
- if (busCache[0].valid && id == busCache[0].id) {
- return busCache[0].port;
- }
- if (busCache[1].valid && id == busCache[1].id) {
- return busCache[1].port;
- }
- if (busCache[2].valid && id == busCache[2].id) {
- return busCache[2].port;
- }
-
- return NULL;
- }
-
- // Replaces the earliest entry in the cache with a new entry
- inline void updateBusCache(short id, BusPort *port) {
- busCache[2].valid = busCache[1].valid;
- busCache[2].id = busCache[1].id;
- busCache[2].port = busCache[1].port;
-
- busCache[1].valid = busCache[0].valid;
- busCache[1].id = busCache[0].id;
- busCache[1].port = busCache[0].port;
-
- busCache[0].valid = true;
- busCache[0].id = id;
- busCache[0].port = port;
- }
-
- // Invalidates the cache. Needs to be called in constructor.
- inline void clearBusCache() {
- busCache[2].valid = false;
- busCache[1].valid = false;
- busCache[0].valid = false;
- }
-
-
public:
/** A function used to return the port associated with this bus object. */
virtual Port *getPort(const std::string &if_name, int idx = -1);
- virtual void deletePortRefs(Port *p);
virtual void init();
virtual void startup();
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index 09e3d0869..2b7fa4b9f 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -71,11 +71,9 @@ BaseCache::BaseCache(const Params *p)
}
void
-BaseCache::CachePort::recvStatusChange(Port::Status status)
+BaseCache::CachePort::recvRangeChange() const
{
- if (status == Port::RangeChange) {
- otherPort->sendStatusChange(Port::RangeChange);
- }
+ otherPort->sendRangeChange();
}
@@ -127,7 +125,7 @@ BaseCache::CachePort::clearBlocked()
mustSendRetry = false;
SendRetryEvent *ev = new SendRetryEvent(this, true);
// @TODO: need to find a better time (next bus cycle?)
- schedule(ev, curTick() + 1);
+ cache->schedule(ev, curTick() + 1);
}
}
@@ -137,7 +135,7 @@ BaseCache::init()
{
if (!cpuSidePort || !memSidePort)
panic("Cache not hooked up on both sides\n");
- cpuSidePort->sendStatusChange(Port::RangeChange);
+ cpuSidePort->sendRangeChange();
}
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index 8c39a2400..fded6fca6 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -105,7 +105,7 @@ class BaseCache : public MemObject
CachePort(const std::string &_name, BaseCache *_cache,
const std::string &_label);
- virtual void recvStatusChange(Status status);
+ virtual void recvRangeChange() const;
virtual unsigned deviceBlockSize() const;
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index 1ed138bb5..b5c95b301 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -78,8 +90,7 @@ class Cache : public BaseCache
return static_cast<Cache<TagStore> *>(cache);
}
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual AddrRangeList getAddrRanges();
virtual bool recvTiming(PacketPtr pkt);
@@ -106,8 +117,7 @@ class Cache : public BaseCache
void processSendEvent();
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual bool isSnooping();
virtual bool recvTiming(PacketPtr pkt);
@@ -204,7 +214,6 @@ class Cache : public BaseCache
Cache(const Params *p, TagStore *tags, BasePrefetcher *prefetcher);
virtual Port *getPort(const std::string &if_name, int idx = -1);
- virtual void deletePortRefs(Port *p);
void regStats();
@@ -225,10 +234,9 @@ class Cache : public BaseCache
/**
* Performs the access specified by the request.
* @param pkt The request to perform.
- * @return The result of the access.
+ * @param fromCpuSide from the CPU side port or the memory side port
*/
- void functionalAccess(PacketPtr pkt, CachePort *incomingPort,
- CachePort *otherSidePort);
+ void functionalAccess(PacketPtr pkt, bool fromCpuSide);
/**
* Handles a response (cache line fill/write ack) from the bus.
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index a56495abb..13484eb79 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2010-2012 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -103,30 +103,13 @@ Cache<TagStore>::getPort(const std::string &if_name, int idx)
return cpuSidePort;
} else if (if_name == "mem_side") {
return memSidePort;
- } else if (if_name == "functional") {
- CpuSidePort *funcPort =
- new CpuSidePort(name() + "-cpu_side_funcport", this,
- "CpuSideFuncPort");
- funcPort->setOtherPort(memSidePort);
- return funcPort;
- } else {
+ } else {
panic("Port name %s unrecognized\n", if_name);
}
}
template<class TagStore>
void
-Cache<TagStore>::deletePortRefs(Port *p)
-{
- if (cpuSidePort == p || memSidePort == p)
- panic("Can only delete functional ports\n");
-
- delete p;
-}
-
-
-template<class TagStore>
-void
Cache<TagStore>::cmpAndSwap(BlkType *blk, PacketPtr pkt)
{
uint64_t overwrite_val;
@@ -768,9 +751,7 @@ Cache<TagStore>::atomicAccess(PacketPtr pkt)
template<class TagStore>
void
-Cache<TagStore>::functionalAccess(PacketPtr pkt,
- CachePort *incomingPort,
- CachePort *otherSidePort)
+Cache<TagStore>::functionalAccess(PacketPtr pkt, bool fromCpuSide)
{
Addr blk_addr = blockAlign(pkt->getAddr());
BlkType *blk = tags->findBlock(pkt->getAddr());
@@ -796,10 +777,10 @@ Cache<TagStore>::functionalAccess(PacketPtr pkt,
(mshr && mshr->inService && mshr->isPendingDirty()));
bool done = have_dirty
- || incomingPort->checkFunctional(pkt)
+ || cpuSidePort->checkFunctional(pkt)
|| mshrQueue.checkFunctional(pkt, blk_addr)
|| writeBuffer.checkFunctional(pkt, blk_addr)
- || otherSidePort->checkFunctional(pkt);
+ || memSidePort->checkFunctional(pkt);
DPRINTF(Cache, "functional %s %x %s%s%s\n",
pkt->cmdString(), pkt->getAddr(),
@@ -812,7 +793,15 @@ Cache<TagStore>::functionalAccess(PacketPtr pkt,
if (done) {
pkt->makeResponse();
} else {
- otherSidePort->sendFunctional(pkt);
+ // if it came as a request from the CPU side then make sure it
+ // continues towards the memory side
+ if (fromCpuSide) {
+ memSidePort->sendFunctional(pkt);
+ } else if (forwardSnoops) {
+ // if it came from the memory side, it must be a snoop request
+ // and we should only forward it if we are forwarding snoops
+ cpuSidePort->sendFunctional(pkt);
+ }
}
}
@@ -1559,14 +1548,15 @@ Cache<TagStore>::nextMSHRReadyTime()
///////////////
template<class TagStore>
-void
+AddrRangeList
Cache<TagStore>::CpuSidePort::
-getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
+getAddrRanges()
{
// CPU side port doesn't snoop; it's a target only. It can
// potentially respond to any address.
- snoop = false;
- resp.push_back(myCache()->getAddrRange());
+ AddrRangeList ranges;
+ ranges.push_back(myCache()->getAddrRange());
+ return ranges;
}
@@ -1598,7 +1588,7 @@ template<class TagStore>
void
Cache<TagStore>::CpuSidePort::recvFunctional(PacketPtr pkt)
{
- myCache()->functionalAccess(pkt, this, otherPort);
+ myCache()->functionalAccess(pkt, true);
}
@@ -1617,14 +1607,13 @@ CpuSidePort::CpuSidePort(const std::string &_name, Cache<TagStore> *_cache,
///////////////
template<class TagStore>
-void
-Cache<TagStore>::MemSidePort::
-getDeviceAddressRanges(AddrRangeList &resp, bool &snoop)
+bool
+Cache<TagStore>::MemSidePort::isSnooping()
{
// Memory-side port always snoops, but never passes requests
// through to targets on the cpu side (so we don't add anything to
// the address range list).
- snoop = true;
+ return true;
}
@@ -1670,7 +1659,7 @@ template<class TagStore>
void
Cache<TagStore>::MemSidePort::recvFunctional(PacketPtr pkt)
{
- myCache()->functionalAccess(pkt, this, otherPort);
+ myCache()->functionalAccess(pkt, false);
}
@@ -1723,7 +1712,7 @@ Cache<TagStore>::MemSidePort::sendPacket()
// @TODO: need to facotr in prefetch requests here somehow
if (nextReady != MaxTick) {
DPRINTF(CachePort, "more packets to send @ %d\n", nextReady);
- schedule(sendEvent, std::max(nextReady, curTick() + 1));
+ cache->schedule(sendEvent, std::max(nextReady, curTick() + 1));
} else {
// no more to send right now: if we're draining, we may be done
if (drainEvent && !sendEvent->scheduled()) {
diff --git a/src/mem/vport.cc b/src/mem/fs_translating_port_proxy.cc
index ab061c019..c0898a003 100644
--- a/src/mem/vport.cc
+++ b/src/mem/fs_translating_port_proxy.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -26,6 +38,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
+ * Andreas Hansson
*/
/**
@@ -34,49 +47,81 @@
*/
#include "base/chunk_generator.hh"
-#include "config/the_isa.hh"
+#include "cpu/base.hh"
#include "cpu/thread_context.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
+
+using namespace TheISA;
+
+FSTranslatingPortProxy::FSTranslatingPortProxy(ThreadContext *tc)
+ : PortProxy(*(tc->getCpuPtr()->getPort("dcache_port"))), _tc(tc)
+{
+}
+
+FSTranslatingPortProxy::FSTranslatingPortProxy(Port &port)
+ : PortProxy(port), _tc(NULL)
+{
+}
+
+FSTranslatingPortProxy::~FSTranslatingPortProxy()
+{
+}
void
-VirtualPort::readBlob(Addr addr, uint8_t *p, int size)
+FSTranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size)
{
Addr paddr;
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
- gen.next())
+ gen.next())
{
- if (tc)
- paddr = TheISA::vtophys(tc,gen.addr());
+ if (_tc)
+ paddr = TheISA::vtophys(_tc,gen.addr());
else
paddr = TheISA::vtophys(gen.addr());
- FunctionalPort::readBlob(paddr, p, gen.size());
+ PortProxy::readBlob(paddr, p, gen.size());
p += gen.size();
}
}
void
-VirtualPort::writeBlob(Addr addr, uint8_t *p, int size)
+FSTranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size)
{
Addr paddr;
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
- gen.next())
+ gen.next())
{
- if (tc)
- paddr = TheISA::vtophys(tc,gen.addr());
+ if (_tc)
+ paddr = TheISA::vtophys(_tc,gen.addr());
else
paddr = TheISA::vtophys(gen.addr());
- FunctionalPort::writeBlob(paddr, p, gen.size());
+ PortProxy::writeBlob(paddr, p, gen.size());
p += gen.size();
}
}
void
+FSTranslatingPortProxy::memsetBlob(Addr address, uint8_t v, int size)
+{
+ Addr paddr;
+ for (ChunkGenerator gen(address, size, TheISA::PageBytes); !gen.done();
+ gen.next())
+ {
+ if (_tc)
+ paddr = TheISA::vtophys(_tc,gen.addr());
+ else
+ paddr = TheISA::vtophys(gen.addr());
+
+ PortProxy::memsetBlob(paddr, v, gen.size());
+ }
+}
+
+void
CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
{
uint8_t *dst = (uint8_t *)dest;
- VirtualPort *vp = tc->getVirtPort();
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
vp->readBlob(src, dst, cplen);
}
@@ -85,7 +130,7 @@ void
CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
{
uint8_t *src = (uint8_t *)source;
- VirtualPort *vp = tc->getVirtPort();
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
vp->writeBlob(dest, src, cplen);
}
@@ -93,21 +138,25 @@ CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
void
CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
{
- int len = 0;
char *start = dst;
- VirtualPort *vp = tc->getVirtPort();
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
- do {
- vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
- } while (len < maxlen && start[len++] != 0 );
+ bool foundNull = false;
+ while ((dst - start + 1) < maxlen && !foundNull) {
+ vp->readBlob(vaddr++, (uint8_t*)dst, 1);
+ if (dst == '\0')
+ foundNull = true;
+ dst++;
+ }
- dst[len] = 0;
+ if (!foundNull)
+ *dst = '\0';
}
void
CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
{
- VirtualPort *vp = tc->getVirtPort();
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();
gen.next())
{
diff --git a/src/mem/vport.hh b/src/mem/fs_translating_port_proxy.hh
index 7cf24587c..826def902 100644
--- a/src/mem/vport.hh
+++ b/src/mem/fs_translating_port_proxy.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -26,44 +38,49 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
+ * Andreas Hansson
*/
/**
* @file
- * Virtual Port Object Declaration. These ports incorporate some translation
- * into their access methods. Thus you can use one to read and write data
- * to/from virtual addresses.
+ * TranslatingPortProxy Object Declaration for FS.
+ *
+ * Port proxies are used when non structural entities need access to
+ * the memory system. Proxy objects replace the previous
+ * FunctionalPort, TranslatingPort and VirtualPort objects, which
+ * provided the same functionality as the proxies, but were instances
+ * of ports not corresponding to real structural ports of the
+ * simulated system. Via the port proxies all the accesses go through
+ * an actual port and thus are transparent to a potentially
+ * distributed memory and automatically adhere to the memory map of
+ * the system.
*/
-#ifndef __MEM_VPORT_HH__
-#define __MEM_VPORT_HH__
+#ifndef __MEM_FS_PORT_PROXY_HH__
+#define __MEM_FS_PORT_PROXY_HH__
#include "arch/vtophys.hh"
-#include "mem/port_impl.hh"
+#include "mem/port_proxy.hh"
-/** A class that translates a virtual address to a physical address and then
- * calls the above read/write functions. If a thread context is provided the
- * address can alway be translated, If not it can only be translated if it is a
- * simple address masking operation (such as alpha super page accesses).
+/**
+ * A TranslatingPortProxy in FS mode translates a virtual address to a
+ * physical address and then calls the read/write functions of the
+ * port. If a thread context is provided the address can alway be
+ * translated, If not it can only be translated if it is a simple
+ * address masking operation (such as alpha super page accesses).
*/
-
-
-class VirtualPort : public FunctionalPort
+class FSTranslatingPortProxy : public PortProxy
{
private:
- ThreadContext *tc;
+ ThreadContext* _tc;
public:
- VirtualPort(const std::string &_name, ThreadContext *_tc = NULL)
- : FunctionalPort(_name), tc(_tc)
- {}
- /** Return true if we have an thread context. This is used to
- * prevent someone from accidently deleting the cpus statically
- * allocated vport.
- * @return true if a thread context isn't valid
- */
- bool nullThreadContext() { return tc != NULL; }
+ FSTranslatingPortProxy(ThreadContext* tc);
+
+ FSTranslatingPortProxy(Port &port);
+
+ virtual ~FSTranslatingPortProxy();
/** Version of readblob that translates virt->phys and deals
* with page boundries. */
@@ -72,13 +89,16 @@ class VirtualPort : public FunctionalPort
/** Version of writeBlob that translates virt->phys and deals
* with page boundries. */
virtual void writeBlob(Addr addr, uint8_t *p, int size);
-};
+ /**
+ * Fill size bytes starting at addr with byte value val.
+ */
+ virtual void memsetBlob(Addr address, uint8_t v, int size);
+};
void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen);
void CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen);
void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
-#endif //__MEM_VPORT_HH__
-
+#endif //__MEM_FS_PORT_PROXY_HH__
diff --git a/src/mem/mem_object.cc b/src/mem/mem_object.cc
index 20a1b4cd8..111d3718c 100644
--- a/src/mem/mem_object.cc
+++ b/src/mem/mem_object.cc
@@ -34,9 +34,3 @@ MemObject::MemObject(const Params *params)
: SimObject(params)
{
}
-
-void
-MemObject::deletePortRefs(Port *p)
-{
- panic("This object does not support port deletion\n");
-}
diff --git a/src/mem/mem_object.hh b/src/mem/mem_object.hh
index b8bf4b939..5865fc935 100644
--- a/src/mem/mem_object.hh
+++ b/src/mem/mem_object.hh
@@ -56,10 +56,6 @@ class MemObject : public SimObject
public:
/** Additional function to return the Port of a memory object. */
virtual Port *getPort(const std::string &if_name, int idx = -1) = 0;
-
- /** Tell object that this port is about to disappear, so it should remove it
- * from any structures that it's keeping it in. */
- virtual void deletePortRefs(Port *p) ;
};
#endif //__MEM_MEM_OBJECT_HH__
diff --git a/src/mem/packet.cc b/src/mem/packet.cc
index 64f4fcd14..4c3a785dc 100644
--- a/src/mem/packet.cc
+++ b/src/mem/packet.cc
@@ -168,6 +168,9 @@ MemCmd::commandInfo[] =
{ SET2(IsRequest, IsPrint), InvalidCmd, "PrintReq" },
/* Flush Request */
{ SET3(IsRequest, IsFlush, NeedsExclusive), InvalidCmd, "FlushReq" },
+ /* Invalidation Request */
+ { SET3(NeedsExclusive, IsInvalidate, IsRequest),
+ InvalidCmd, "InvalidationReq" },
};
bool
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index 6347c21ea..e49ce7577 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -108,6 +108,7 @@ class MemCmd
// Fake simulator-only commands
PrintReq, // Print state matching address
FlushReq, //request for a cache flush
+ InvalidationReq, // request for address to be invalidated from lsq
NUM_MEM_CMDS
};
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index d5c4e892f..09ed8b292 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2010-2011 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -115,7 +115,7 @@ PhysicalMemory::init()
for (PortIterator pi = ports.begin(); pi != ports.end(); ++pi) {
if (*pi)
- (*pi)->sendStatusChange(Port::RangeChange);
+ (*pi)->sendRangeChange();
}
}
@@ -125,6 +125,65 @@ PhysicalMemory::~PhysicalMemory()
munmap((char*)pmemAddr, size());
}
+void
+PhysicalMemory::regStats()
+{
+ using namespace Stats;
+
+ bytesRead
+ .name(name() + ".bytes_read")
+ .desc("Number of bytes read from this memory")
+ ;
+ bytesInstRead
+ .name(name() + ".bytes_inst_read")
+ .desc("Number of instructions bytes read from this memory")
+ ;
+ bytesWritten
+ .name(name() + ".bytes_written")
+ .desc("Number of bytes written to this memory")
+ ;
+ numReads
+ .name(name() + ".num_reads")
+ .desc("Number of read requests responded to by this memory")
+ ;
+ numWrites
+ .name(name() + ".num_writes")
+ .desc("Number of write requests responded to by this memory")
+ ;
+ numOther
+ .name(name() + ".num_other")
+ .desc("Number of other requests responded to by this memory")
+ ;
+ bwRead
+ .name(name() + ".bw_read")
+ .desc("Total read bandwidth from this memory (bytes/s)")
+ .precision(0)
+ .prereq(bytesRead)
+ ;
+ bwInstRead
+ .name(name() + ".bw_inst_read")
+ .desc("Instruction read bandwidth from this memory (bytes/s)")
+ .precision(0)
+ .prereq(bytesInstRead)
+ ;
+ bwWrite
+ .name(name() + ".bw_write")
+ .desc("Write bandwidth from this memory (bytes/s)")
+ .precision(0)
+ .prereq(bytesWritten)
+ ;
+ bwTotal
+ .name(name() + ".bw_total")
+ .desc("Total bandwidth to/from this memory (bytes/s)")
+ .precision(0)
+ .prereq(bwTotal)
+ ;
+ bwRead = bytesRead / simSeconds;
+ bwInstRead = bytesInstRead / simSeconds;
+ bwWrite = bytesWritten / simSeconds;
+ bwTotal = (bytesRead + bytesWritten) / simSeconds;
+}
+
unsigned
PhysicalMemory::deviceBlockSize() const
{
@@ -303,6 +362,7 @@ PhysicalMemory::doAtomicAccess(PacketPtr pkt)
assert(!pkt->req->isInstFetch());
TRACE_PACKET("Read/Write");
+ numOther++;
} else if (pkt->isRead()) {
assert(!pkt->isWrite());
if (pkt->isLLSC()) {
@@ -311,12 +371,18 @@ PhysicalMemory::doAtomicAccess(PacketPtr pkt)
if (pmemAddr)
memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
TRACE_PACKET(pkt->req->isInstFetch() ? "IFetch" : "Read");
+ numReads++;
+ bytesRead += pkt->getSize();
+ if (pkt->req->isInstFetch())
+ bytesInstRead += pkt->getSize();
} else if (pkt->isWrite()) {
if (writeOK(pkt)) {
if (pmemAddr)
memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
assert(!pkt->req->isInstFetch());
TRACE_PACKET("Write");
+ numWrites++;
+ bytesWritten += pkt->getSize();
}
} else if (pkt->isInvalidate()) {
//upgrade or invalidate
@@ -371,13 +437,6 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
Port *
PhysicalMemory::getPort(const std::string &if_name, int idx)
{
- // Accept request for "functional" port for backwards compatibility
- // with places where this function is called from C++. I'd prefer
- // to move all these into Python someday.
- if (if_name == "functional") {
- return new MemoryPort(csprintf("%s-functional", name()), this);
- }
-
if (if_name != "port") {
panic("PhysicalMemory::getPort: unknown port %s requested", if_name);
}
@@ -397,36 +456,30 @@ PhysicalMemory::getPort(const std::string &if_name, int idx)
return port;
}
-
-void
-PhysicalMemory::recvStatusChange(Port::Status status)
-{
-}
-
PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name,
PhysicalMemory *_memory)
: SimpleTimingPort(_name, _memory), memory(_memory)
{ }
void
-PhysicalMemory::MemoryPort::recvStatusChange(Port::Status status)
+PhysicalMemory::MemoryPort::recvRangeChange()
{
- memory->recvStatusChange(status);
+ // memory is a slave and thus should never have to worry about its
+ // neighbours address ranges
}
-void
-PhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
+AddrRangeList
+PhysicalMemory::MemoryPort::getAddrRanges()
{
- memory->getAddressRanges(resp, snoop);
+ return memory->getAddrRanges();
}
-void
-PhysicalMemory::getAddressRanges(AddrRangeList &resp, bool &snoop)
+AddrRangeList
+PhysicalMemory::getAddrRanges()
{
- snoop = false;
- resp.clear();
- resp.push_back(RangeSize(start(), size()));
+ AddrRangeList ranges;
+ ranges.push_back(RangeSize(start(), size()));
+ return ranges;
}
unsigned
diff --git a/src/mem/physical.hh b/src/mem/physical.hh
index cd6d809e2..b447237c7 100644
--- a/src/mem/physical.hh
+++ b/src/mem/physical.hh
@@ -38,11 +38,13 @@
#include <string>
#include "base/range.hh"
+#include "base/statistics.hh"
#include "mem/mem_object.hh"
#include "mem/packet.hh"
#include "mem/tport.hh"
#include "params/PhysicalMemory.hh"
#include "sim/eventq.hh"
+#include "sim/stats.hh"
//
// Functional model for a contiguous block of physical memory. (i.e. RAM)
@@ -65,10 +67,9 @@ class PhysicalMemory : public MemObject
virtual void recvFunctional(PacketPtr pkt);
- virtual void recvStatusChange(Status status);
+ virtual void recvRangeChange();
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop);
+ virtual AddrRangeList getAddrRanges();
virtual unsigned deviceBlockSize() const;
};
@@ -155,6 +156,28 @@ class PhysicalMemory : public MemObject
uint64_t _size;
uint64_t _start;
+
+ /** Number of total bytes read from this memory */
+ Stats::Scalar bytesRead;
+ /** Number of instruction bytes read from this memory */
+ Stats::Scalar bytesInstRead;
+ /** Number of bytes written to this memory */
+ Stats::Scalar bytesWritten;
+ /** Number of read requests */
+ Stats::Scalar numReads;
+ /** Number of write requests */
+ Stats::Scalar numWrites;
+ /** Number of other requests */
+ Stats::Scalar numOther;
+ /** Read bandwidth from this memory */
+ Stats::Formula bwRead;
+ /** Read bandwidth from this memory */
+ Stats::Formula bwInstRead;
+ /** Write bandwidth from this memory */
+ Stats::Formula bwWrite;
+ /** Total bandwidth from this memory */
+ Stats::Formula bwTotal;
+
public:
uint64_t size() { return _size; }
uint64_t start() { return _start; }
@@ -172,7 +195,7 @@ class PhysicalMemory : public MemObject
public:
unsigned deviceBlockSize() const;
- void getAddressRanges(AddrRangeList &resp, bool &snoop);
+ AddrRangeList getAddrRanges();
virtual Port *getPort(const std::string &if_name, int idx = -1);
void virtual init();
unsigned int drain(Event *de);
@@ -181,9 +204,13 @@ class PhysicalMemory : public MemObject
Tick doAtomicAccess(PacketPtr pkt);
void doFunctionalAccess(PacketPtr pkt);
virtual Tick calculateLatency(PacketPtr pkt);
- void recvStatusChange(Port::Status status);
public:
+ /**
+ * Register Statistics
+ */
+ void regStats();
+
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
diff --git a/src/mem/port.cc b/src/mem/port.cc
index c87785a49..fb1715db6 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -40,61 +40,8 @@
#include "mem/mem_object.hh"
#include "mem/port.hh"
-class DefaultPeerPort : public Port
-{
- protected:
- void blowUp() const
- {
- fatal("%s: Unconnected port!", peer->name());
- }
-
- public:
- DefaultPeerPort()
- : Port("default_port", NULL)
- { }
-
- bool recvTiming(PacketPtr)
- {
- blowUp();
- return false;
- }
-
- Tick recvAtomic(PacketPtr)
- {
- blowUp();
- return 0;
- }
-
- void recvFunctional(PacketPtr)
- {
- blowUp();
- }
-
- void recvStatusChange(Status)
- {
- blowUp();
- }
-
- unsigned
- deviceBlockSize() const
- {
- blowUp();
- return 0;
- }
-
- void getDeviceAddressRanges(AddrRangeList &, bool &)
- {
- blowUp();
- }
-
- bool isDefaultPort() const { return true; }
-};
-
-DefaultPeerPort defaultPeerPort;
-
Port::Port(const std::string &_name, MemObject *_owner)
- : EventManager(_owner), portName(_name), peer(&defaultPeerPort),
- owner(_owner)
+ : portName(_name), peer(NULL), owner(_owner)
{
}
@@ -113,19 +60,10 @@ Port::setPeer(Port *port)
void
Port::setOwner(MemObject *_owner)
{
- eventq = _owner->queue();
owner = _owner;
}
void
-Port::removeConn()
-{
- if (peer->getOwner())
- peer->getOwner()->deletePortRefs(peer);
- peer = NULL;
-}
-
-void
Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd)
{
Request req;
diff --git a/src/mem/port.hh b/src/mem/port.hh
index bb74bf497..98b3ad5f1 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -47,10 +59,8 @@
#include "base/types.hh"
#include "mem/packet.hh"
#include "mem/request.hh"
-#include "sim/eventq.hh"
-/** This typedef is used to clean up the parameter list of
- * getDeviceAddressRanges() and getPeerAddressRanges(). It's declared
+/** This typedef is used to clean up getAddrRanges(). It's declared
* outside the Port object since it's also used by some mem objects.
* Eventually we should move this typedef to wherever Addr is
* defined.
@@ -59,7 +69,6 @@
typedef std::list<Range<Addr> > AddrRangeList;
typedef std::list<Range<Addr> >::iterator AddrRangeIter;
-class EventQueue;
class MemObject;
/**
@@ -73,7 +82,7 @@ class MemObject;
* Send accessor functions are being called from the device the port is
* associated with, and it will call the peer recv. accessor function.
*/
-class Port : public EventManager
+class Port
{
protected:
/** Descriptive name (for DPRINTF output) */
@@ -103,13 +112,6 @@ class Port : public EventManager
virtual ~Port();
- // mey be better to use subclasses & RTTI?
- /** Holds the ports status. Currently just that a range recomputation needs
- * to be done. */
- enum Status {
- RangeChange
- };
-
void setName(const std::string &name)
{ portName = name; }
@@ -125,13 +127,7 @@ class Port : public EventManager
/** Function to return the owner of this port. */
MemObject *getOwner() { return owner; }
- /** Inform the peer port to delete itself and notify it's owner about it's
- * demise. */
- void removeConn();
-
- virtual bool isDefaultPort() const { return false; }
-
- bool isConnected() { return peer && !peer->isDefaultPort(); }
+ bool isConnected() { return peer != NULL; }
protected:
@@ -147,8 +143,8 @@ class Port : public EventManager
/** Called to recive a functional call from the peer port. */
virtual void recvFunctional(PacketPtr pkt) = 0;
- /** Called to recieve a status change from the peer port. */
- virtual void recvStatusChange(Status status) = 0;
+ /** Called to recieve an address range change from the peer port. */
+ virtual void recvRangeChange() = 0;
/** Called by a peer port if the send was unsuccesful, and had to
wait. This shouldn't be valid for response paths (IO Devices).
@@ -163,17 +159,31 @@ class Port : public EventManager
*/
virtual unsigned deviceBlockSize() const { return 0; }
- /** The peer port is requesting us to reply with a list of the ranges we
- are responsible for.
- @param resp is a list of ranges responded to
- @param snoop is a list of ranges snooped
- */
- virtual void getDeviceAddressRanges(AddrRangeList &resp,
- bool &snoop)
- { panic("??"); }
-
public:
+ /**
+ * Get a list of the non-overlapping address ranges we are
+ * responsible for. The default implementation returns an empty
+ * list and thus no address ranges. Any slave port must override
+ * this function and return a populated list with at least one
+ * item.
+ *
+ * @return a list of ranges responded to
+ */
+ virtual AddrRangeList getAddrRanges()
+ { AddrRangeList ranges; return ranges; }
+
+ /**
+ * Determine if this port is snooping or not. The default
+ * implementation returns false and thus tells the neighbour we
+ * are not snooping. Any port that is to snoop (e.g. a cache
+ * connected to a bus) has to override this function.
+ *
+ * @return true if the port should be considered a snooper
+ */
+ virtual bool isSnooping()
+ { return false; }
+
/** Function called by associated memory device (cache, memory, iodevice)
in order to send a timing request to the port. Simply calls the peer
port receive function.
@@ -201,10 +211,11 @@ class Port : public EventManager
void sendFunctional(PacketPtr pkt)
{ return peer->recvFunctional(pkt); }
- /** Called by the associated device to send a status change to the device
- connected to the peer interface.
- */
- void sendStatusChange(Status status) {peer->recvStatusChange(status); }
+ /**
+ * Called by the associated device to send a status range to the
+ * peer interface.
+ */
+ void sendRangeChange() const { peer->recvRangeChange(); }
/** When a timing access doesn't return a success, some time later the
Retry will be sent.
@@ -216,12 +227,6 @@ class Port : public EventManager
*/
unsigned peerBlockSize() const { return peer->deviceBlockSize(); }
- /** Called by the associated device if it wishes to find out the address
- ranges connected to the peer ports devices.
- */
- void getPeerAddressRanges(AddrRangeList &resp, bool &snoop)
- { peer->getDeviceAddressRanges(resp, snoop); }
-
/** This function is a wrapper around sendFunctional()
that breaks a larger, arbitrarily aligned access into
appropriate chunks. The default implementation can use
@@ -255,48 +260,4 @@ class Port : public EventManager
void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd);
};
-/** A simple functional port that is only meant for one way communication to
- * physical memory. It is only meant to be used to load data into memory before
- * the simulation begins.
- */
-
-class FunctionalPort : public Port
-{
- public:
- FunctionalPort(const std::string &_name, MemObject *_owner = NULL)
- : Port(_name, _owner)
- {}
-
- protected:
- virtual bool recvTiming(PacketPtr pkt) { panic("FuncPort is UniDir");
- M5_DUMMY_RETURN }
- virtual Tick recvAtomic(PacketPtr pkt) { panic("FuncPort is UniDir");
- M5_DUMMY_RETURN }
- virtual void recvFunctional(PacketPtr pkt) { panic("FuncPort is UniDir"); }
- virtual void recvStatusChange(Status status) {}
-
- public:
- /** a write function that also does an endian conversion. */
- template <typename T>
- inline void writeHtoG(Addr addr, T d);
-
- /** a read function that also does an endian conversion. */
- template <typename T>
- inline T readGtoH(Addr addr);
-
- template <typename T>
- inline void write(Addr addr, T d)
- {
- writeBlob(addr, (uint8_t*)&d, sizeof(T));
- }
-
- template <typename T>
- inline T read(Addr addr)
- {
- T d;
- readBlob(addr, (uint8_t*)&d, sizeof(T));
- return d;
- }
-};
-
#endif //__MEM_PORT_HH__
diff --git a/src/mem/port_proxy.hh b/src/mem/port_proxy.hh
new file mode 100644
index 000000000..31ad4c1cd
--- /dev/null
+++ b/src/mem/port_proxy.hh
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Hansson
+ */
+
+/**
+ * @file
+ * PortProxy Object Declaration.
+ *
+ * Port proxies are used when non structural entities need access to
+ * the memory system. Proxy objects replace the previous
+ * FunctionalPort, TranslatingPort and VirtualPort objects, which
+ * provided the same functionality as the proxies, but were instances
+ * of ports not corresponding to real structural ports of the
+ * simulated system. Via the port proxies all the accesses go through
+ * an actual port and thus are transparent to a potentially
+ * distributed memory and automatically adhere to the memory map of
+ * the system.
+ */
+
+#ifndef __MEM_PORT_PROXY_HH__
+#define __MEM_PORT_PROXY_HH__
+
+#include "config/the_isa.hh"
+#if THE_ISA != NO_ISA
+ #include "arch/isa_traits.hh"
+#endif
+
+#include "base/types.hh"
+#include "mem/port.hh"
+#include "sim/byteswap.hh"
+
+/**
+ * This object is a proxy for a structural port,
+ * to be used for debug accesses.
+ *
+ * This proxy object is used when non structural entities
+ * (e.g. thread contexts, object file loaders) need access to the
+ * memory system. It calls the corresponding functions on the underlying
+ * structural port, and provides templatized convenience access functions.
+ *
+ * The addresses are interpreted as physical addresses.
+ *
+ * @sa SETranslatingProxy
+ * @sa FSTranslatingProxy
+ */
+class PortProxy
+{
+ protected:
+ Port &_port;
+
+ public:
+ PortProxy(Port &port) : _port(port) { }
+ virtual ~PortProxy() { }
+
+ public:
+ /**
+ * Read size bytes memory at address and store in p.
+ */
+ virtual void readBlob(Addr address, uint8_t* p, int size)
+ { _port.readBlob(address, p, size); }
+
+ /**
+ * Write size bytes from p to address.
+ */
+ virtual void writeBlob(Addr address, uint8_t* p, int size)
+ { _port.writeBlob(address, p, size); }
+
+ /**
+ * Fill size bytes starting at addr with byte value val.
+ */
+ virtual void memsetBlob(Addr address, uint8_t v, int size)
+ { _port.memsetBlob(address, v, size); }
+
+ /**
+ * Read sizeof(T) bytes from address and return as object T.
+ */
+ template <typename T>
+ T read(Addr address);
+
+ /**
+ * Write object T to address. Writes sizeof(T) bytes.
+ */
+ template <typename T>
+ void write(Addr address, T data);
+
+#if THE_ISA != NO_ISA
+ /**
+ * Read sizeof(T) bytes from address and return as object T.
+ * Performs Guest to Host endianness transform.
+ */
+ template <typename T>
+ T readGtoH(Addr address);
+
+ /**
+ * Write object T to address. Writes sizeof(T) bytes.
+ * Performs Host to Guest endianness transform.
+ */
+ template <typename T>
+ void writeHtoG(Addr address, T data);
+#endif
+};
+
+
+template <typename T>
+T
+PortProxy::read(Addr address)
+{
+ T data;
+ readBlob(address, (uint8_t*)&data, sizeof(T));
+ return data;
+}
+
+template <typename T>
+void
+PortProxy::write(Addr address, T data)
+{
+ writeBlob(address, (uint8_t*)&data, sizeof(T));
+}
+
+#if THE_ISA != NO_ISA
+template <typename T>
+T
+PortProxy::readGtoH(Addr address)
+{
+ T data;
+ readBlob(address, (uint8_t*)&data, sizeof(T));
+ return TheISA::gtoh(data);
+}
+
+template <typename T>
+void
+PortProxy::writeHtoG(Addr address, T data)
+{
+ data = TheISA::htog(data);
+ writeBlob(address, (uint8_t*)&data, sizeof(T));
+}
+#endif
+
+#endif // __MEM_PORT_PROXY_HH__
diff --git a/src/mem/protocol/MESI_CMP_directory-L1cache.sm b/src/mem/protocol/MESI_CMP_directory-L1cache.sm
index f0be1fd34..934405786 100644
--- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm
+++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm
@@ -27,14 +27,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-machine(L1Cache, "MSI Directory L1 Cache CMP")
+machine(L1Cache, "MESI Directory L1 Cache CMP")
: Sequencer * sequencer,
CacheMemory * L1IcacheMemory,
CacheMemory * L1DcacheMemory,
int l2_select_num_bits,
int l1_request_latency = 2,
int l1_response_latency = 2,
- int to_l2_latency = 1
+ int to_l2_latency = 1,
+ bool send_evictions
{
// NODE L1 CACHE
// From this node's L1 cache TO the network
@@ -67,7 +68,6 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
IS_I, AccessPermission:Busy, desc="L1 idle, issued GETS, saw Inv before data because directory doesn't block on GETS hit";
M_I, AccessPermission:Busy, desc="L1 replacing, waiting for ACK";
- E_I, AccessPermission:Busy, desc="L1 replacing, waiting for ACK";
SINK_WB_ACK, AccessPermission:Busy, desc="This is to sink WB_Acks from L2";
}
@@ -544,6 +544,12 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
}
}
+ action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") {
+ if (send_evictions) {
+ DPRINTF(RubySlicc, "Sending invalidation for %s to the CPU\n", address);
+ sequencer.evictionCallback(address);
+ }
+ }
action(g_issuePUTX, "g", desc="send data to the L2 cache") {
enqueue(requestIntraChipL1Network_out, RequestMsg, latency=l1_response_latency) {
@@ -696,7 +702,7 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
//*****************************************************
// Transitions for Load/Store/Replacement/WriteBack from transient states
- transition({IS, IM, IS_I, M_I, E_I, SM}, {Load, Ifetch, Store, L1_Replacement}) {
+ transition({IS, IM, IS_I, M_I, SM}, {Load, Ifetch, Store, L1_Replacement}) {
z_recycleMandatoryQueue;
}
@@ -748,10 +754,12 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
}
transition(S, L1_Replacement, I) {
+ forward_eviction_to_cpu;
ff_deallocateL1CacheBlock;
}
transition(S, Inv, I) {
+ forward_eviction_to_cpu;
fi_sendInvAck;
l_popRequestQueue;
}
@@ -770,6 +778,7 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
transition(E, L1_Replacement, M_I) {
// silent E replacement??
+ forward_eviction_to_cpu;
i_allocateTBE;
g_issuePUTX; // send data, but hold in case forwarded request
ff_deallocateL1CacheBlock;
@@ -777,11 +786,13 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
transition(E, Inv, I) {
// don't send data
+ forward_eviction_to_cpu;
fi_sendInvAck;
l_popRequestQueue;
}
transition(E, Fwd_GETX, I) {
+ forward_eviction_to_cpu;
d_sendDataToRequestor;
l_popRequestQueue;
}
@@ -804,6 +815,7 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
}
transition(M, L1_Replacement, M_I) {
+ forward_eviction_to_cpu;
i_allocateTBE;
g_issuePUTX; // send data, but hold in case forwarded request
ff_deallocateL1CacheBlock;
@@ -815,6 +827,7 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
}
transition(M, Inv, I) {
+ forward_eviction_to_cpu;
f_sendDataToL2;
l_popRequestQueue;
}
@@ -825,6 +838,7 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
}
transition(M, Fwd_GETX, I) {
+ forward_eviction_to_cpu;
d_sendDataToRequestor;
l_popRequestQueue;
}
@@ -866,7 +880,6 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
o_popIncomingResponseQueue;
}
-
transition(IS, DataS_fromL1, S) {
u_writeDataToL1Cache;
j_sendUnblock;
@@ -935,7 +948,6 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
transition(SINK_WB_ACK, {Load, Store, Ifetch, L1_Replacement}){
z_recycleMandatoryQueue;
-
}
transition(SINK_WB_ACK, Inv){
@@ -948,6 +960,3 @@ machine(L1Cache, "MSI Directory L1 Cache CMP")
o_popIncomingResponseQueue;
}
}
-
-
-
diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm
index b11fddd95..2f2e4e3d7 100644
--- a/src/mem/protocol/MI_example-cache.sm
+++ b/src/mem/protocol/MI_example-cache.sm
@@ -3,7 +3,8 @@ machine(L1Cache, "MI Example L1 Cache")
: Sequencer * sequencer,
CacheMemory * cacheMemory,
int cache_response_latency = 12,
- int issue_latency = 2
+ int issue_latency = 2,
+ bool send_evictions
{
// NETWORK BUFFERS
@@ -54,7 +55,6 @@ machine(L1Cache, "MI Example L1 Cache")
DataBlock DataBlk, desc="Data in the block";
}
-
// TBE fields
structure(TBE, desc="...") {
State TBEState, desc="Transient state";
@@ -70,7 +70,6 @@ machine(L1Cache, "MI Example L1 Cache")
// STRUCTURES
-
TBETable TBEs, template_hack="<L1Cache_TBE>";
// PROTOTYPES
@@ -249,7 +248,6 @@ machine(L1Cache, "MI Example L1 Cache")
}
}
-
action(e_sendData, "e", desc="Send data from cache to requestor") {
peek(forwardRequestNetwork_in, RequestMsg) {
enqueue(responseNetwork_out, ResponseMsg, latency=cache_response_latency) {
@@ -353,13 +351,18 @@ machine(L1Cache, "MI Example L1 Cache")
}
}
+ action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") {
+ if (send_evictions) {
+ DPRINTF(RubySlicc, "Sending invalidation for %s to the CPU\n", address);
+ sequencer.evictionCallback(address);
+ }
+ }
action(v_allocateTBE, "v", desc="Allocate TBE") {
TBEs.allocate(address);
set_tbe(TBEs[address]);
}
-
action(w_deallocateTBE, "w", desc="Deallocate TBE") {
TBEs.deallocate(address);
unset_tbe();
@@ -435,6 +438,7 @@ machine(L1Cache, "MI Example L1 Cache")
transition(M, Fwd_GETX, I) {
e_sendData;
+ forward_eviction_to_cpu;
o_popForwardedRequestQueue;
}
@@ -446,6 +450,7 @@ machine(L1Cache, "MI Example L1 Cache")
v_allocateTBE;
b_issuePUT;
x_copyDataFromCacheToTBE;
+ forward_eviction_to_cpu;
h_deallocateL1CacheBlock;
}
@@ -474,4 +479,3 @@ machine(L1Cache, "MI Example L1 Cache")
o_popForwardedRequestQueue;
}
}
-
diff --git a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
index 2845d1ad1..7a5cc6511 100644
--- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
@@ -37,7 +37,8 @@ machine(L1Cache, "Directory protocol")
CacheMemory * L1IcacheMemory,
CacheMemory * L1DcacheMemory,
int l2_select_num_bits,
- int request_latency = 2
+ int request_latency = 2,
+ bool send_evictions
{
// NODE L1 CACHE
@@ -530,7 +531,6 @@ machine(L1Cache, "Directory protocol")
}
}
-
action(ee_sendDataExclusive, "\e", desc="Send data from cache to requestor, don't keep a shared copy") {
peek(requestNetwork_in, RequestMsg) {
assert(is_valid(cache_entry));
@@ -689,7 +689,6 @@ machine(L1Cache, "Directory protocol")
useTimerTable.set(address, 50);
}
-
action(ub_dmaUnblockL2Cache, "ub", desc="Send dma ack to l2 cache") {
peek(requestNetwork_in, RequestMsg) {
enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
@@ -775,7 +774,6 @@ machine(L1Cache, "Directory protocol")
}
}
-
// L2 will usually request data for a writeback
action(qq_sendWBDataFromTBEToL2, "\q", desc="Send data from TBE to L2") {
enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
@@ -811,7 +809,6 @@ machine(L1Cache, "Directory protocol")
//assert(in_msg.Dirty == false);
}
}
-
}
action(v_writeDataToCacheVerify, "v", desc="Write data to cache, assert it was same as before") {
@@ -844,7 +841,12 @@ machine(L1Cache, "Directory protocol")
}
}
-
+ action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") {
+ if (send_evictions) {
+ DPRINTF(RubySlicc, "Sending invalidation for %s to the CPU\n", address);
+ sequencer.evictionCallback(address);
+ }
+ }
action(uu_profileMiss, "\u", desc="Profile the demand miss") {
peek(mandatoryQueue_in, RubyRequest) {
@@ -931,11 +933,13 @@ machine(L1Cache, "Directory protocol")
transition(S, L1_Replacement, SI) {
i_allocateTBE;
dd_issuePUTS;
+ forward_eviction_to_cpu;
kk_deallocateL1CacheBlock;
}
transition(S, Inv, I) {
f_sendAck;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
@@ -966,11 +970,13 @@ machine(L1Cache, "Directory protocol")
transition(O, L1_Replacement, OI) {
i_allocateTBE;
dd_issuePUTO;
+ forward_eviction_to_cpu;
kk_deallocateL1CacheBlock;
}
transition(O, Fwd_GETX, I) {
ee_sendDataExclusive;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
@@ -999,16 +1005,19 @@ machine(L1Cache, "Directory protocol")
transition(MM, L1_Replacement, MI) {
i_allocateTBE;
d_issuePUTX;
+ forward_eviction_to_cpu;
kk_deallocateL1CacheBlock;
}
transition(MM, Fwd_GETX, I) {
ee_sendDataExclusive;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
transition(MM, Fwd_GETS, I) {
ee_sendDataExclusive;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
@@ -1037,12 +1046,14 @@ machine(L1Cache, "Directory protocol")
transition(M, L1_Replacement, MI) {
i_allocateTBE;
d_issuePUTX;
+ forward_eviction_to_cpu;
kk_deallocateL1CacheBlock;
}
transition(M, Fwd_GETX, I) {
// e_sendData;
ee_sendDataExclusive;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
@@ -1080,6 +1091,7 @@ machine(L1Cache, "Directory protocol")
// Transitions from SM
transition(SM, Inv, IM) {
f_sendAck;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm
index 66789b594..7cc41cc20 100644
--- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm
+++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm
@@ -43,7 +43,8 @@ machine(L1Cache, "Token protocol")
int retry_threshold = 1,
int fixed_timeout_latency = 100,
bool dynamic_timeout_enabled = true,
- bool no_mig_atomic = true
+ bool no_mig_atomic = true,
+ bool send_evictions
{
// From this node's L1 cache TO the network
@@ -1398,7 +1399,6 @@ machine(L1Cache, "Token protocol")
}
}
-
action(q_updateTokensFromResponse, "q", desc="Update the token count based on the incoming response message") {
peek(responseNetwork_in, ResponseMsg) {
assert(is_valid(cache_entry));
@@ -1522,6 +1522,13 @@ machine(L1Cache, "Token protocol")
}
}
+ action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") {
+ if (send_evictions) {
+ DPRINTF(RubySlicc, "Sending invalidation for %s to the CPU\n", address);
+ sequencer.evictionCallback(address);
+ }
+ }
+
action(uu_profileMiss, "\u", desc="Profile the demand miss") {
peek(mandatoryQueue_in, RubyRequest) {
if (L1DcacheMemory.isTagPresent(address)) {
@@ -1572,7 +1579,6 @@ machine(L1Cache, "Token protocol")
zz_stallAndWaitMandatoryQueue;
}
-
// Lockdowns
transition({NP, I, S, O, M, MM, M_W, MM_W, IM, SM, OM, IS}, Own_Lock_or_Unlock) {
l_popPersistentQueue;
@@ -1702,6 +1708,7 @@ machine(L1Cache, "Token protocol")
transition(S, L1_Replacement, I) {
ta_traceStalledAddress;
cc_sharedReplacement; // Only needed in some cases
+ forward_eviction_to_cpu;
gg_deallocateL1CacheBlock;
ka_wakeUpAllDependents;
}
@@ -1709,6 +1716,7 @@ machine(L1Cache, "Token protocol")
transition(S, {Transient_GETX, Transient_Local_GETX}, I) {
t_sendAckWithCollectedTokens;
p_informL2AboutTokenLoss;
+ forward_eviction_to_cpu
m_popRequestQueue;
}
@@ -1729,6 +1737,7 @@ machine(L1Cache, "Token protocol")
transition({S, S_L}, Persistent_GETX, I_L) {
e_sendAckWithCollectedTokens;
p_informL2AboutTokenLoss;
+ forward_eviction_to_cpu
l_popPersistentQueue;
}
@@ -1780,6 +1789,7 @@ machine(L1Cache, "Token protocol")
transition(O, L1_Replacement, I) {
ta_traceStalledAddress;
c_ownedReplacement;
+ forward_eviction_to_cpu
gg_deallocateL1CacheBlock;
ka_wakeUpAllDependents;
}
@@ -1787,12 +1797,14 @@ machine(L1Cache, "Token protocol")
transition(O, {Transient_GETX, Transient_Local_GETX}, I) {
dd_sendDataWithAllTokens;
p_informL2AboutTokenLoss;
+ forward_eviction_to_cpu
m_popRequestQueue;
}
transition(O, Persistent_GETX, I_L) {
ee_sendDataWithAllTokens;
p_informL2AboutTokenLoss;
+ forward_eviction_to_cpu
l_popPersistentQueue;
}
@@ -1803,6 +1815,7 @@ machine(L1Cache, "Token protocol")
transition(O, Persistent_GETS_Last_Token, I_L) {
fo_sendDataWithOwnerToken;
+ forward_eviction_to_cpu
l_popPersistentQueue;
}
@@ -1867,6 +1880,7 @@ machine(L1Cache, "Token protocol")
transition(MM, L1_Replacement, I) {
ta_traceStalledAddress;
c_ownedReplacement;
+ forward_eviction_to_cpu
gg_deallocateL1CacheBlock;
ka_wakeUpAllDependents;
}
@@ -1874,6 +1888,7 @@ machine(L1Cache, "Token protocol")
transition(MM, {Transient_GETX, Transient_Local_GETX, Transient_GETS, Transient_Local_GETS}, I) {
dd_sendDataWithAllTokens;
p_informL2AboutTokenLoss;
+ forward_eviction_to_cpu
m_popRequestQueue;
}
@@ -1885,6 +1900,7 @@ machine(L1Cache, "Token protocol")
transition(MM, {Persistent_GETX, Persistent_GETS}, I_L) {
ee_sendDataWithAllTokens;
p_informL2AboutTokenLoss;
+ forward_eviction_to_cpu
l_popPersistentQueue;
}
@@ -1934,6 +1950,7 @@ machine(L1Cache, "Token protocol")
transition(M, L1_Replacement, I) {
ta_traceStalledAddress;
c_ownedReplacement;
+ forward_eviction_to_cpu
gg_deallocateL1CacheBlock;
ka_wakeUpAllDependents;
}
@@ -1941,6 +1958,7 @@ machine(L1Cache, "Token protocol")
transition(M, {Transient_GETX, Transient_Local_GETX}, I) {
dd_sendDataWithAllTokens;
p_informL2AboutTokenLoss;
+ forward_eviction_to_cpu
m_popRequestQueue;
}
@@ -1961,6 +1979,7 @@ machine(L1Cache, "Token protocol")
transition(M, Persistent_GETX, I_L) {
ee_sendDataWithAllTokens;
p_informL2AboutTokenLoss;
+ forward_eviction_to_cpu
l_popPersistentQueue;
}
@@ -1990,22 +2009,21 @@ machine(L1Cache, "Token protocol")
transition(M_W, Use_TimeoutStarverX, I_L) {
s_deallocateTBE;
ee_sendDataWithAllTokens;
+ forward_eviction_to_cpu;
p_informL2AboutTokenLoss;
jj_unsetUseTimer;
}
-
-
// migratory
transition(MM_W, {Use_TimeoutStarverX, Use_TimeoutStarverS}, I_L) {
s_deallocateTBE;
ee_sendDataWithAllTokens;
+ forward_eviction_to_cpu;
p_informL2AboutTokenLoss;
jj_unsetUseTimer;
}
-
// Transient_GETX and Transient_GETS in transient states
transition(OM, {Transient_GETX, Transient_Local_GETX, Transient_GETS, Transient_GETS_Last_Token, Transient_Local_GETS_Last_Token, Transient_Local_GETS}) {
m_popRequestQueue; // Even if we have the data, we can pretend we don't have it yet.
@@ -2040,6 +2058,7 @@ machine(L1Cache, "Token protocol")
transition({SM, SM_L}, Persistent_GETX, IM_L) {
e_sendAckWithCollectedTokens;
+ forward_eviction_to_cpu
l_popPersistentQueue;
}
@@ -2054,6 +2073,7 @@ machine(L1Cache, "Token protocol")
transition(OM, Persistent_GETX, IM_L) {
ee_sendDataWithAllTokens;
+ forward_eviction_to_cpu
l_popPersistentQueue;
}
@@ -2120,6 +2140,7 @@ machine(L1Cache, "Token protocol")
transition({IM, SM}, {Transient_GETX, Transient_Local_GETX}, IM) { // We don't have the data yet, but we might have collected some tokens. We give them up here to avoid livelock
t_sendAckWithCollectedTokens;
+ forward_eviction_to_cpu;
m_popRequestQueue;
}
@@ -2336,7 +2357,6 @@ machine(L1Cache, "Token protocol")
kd_wakeUpDependents;
}
-
// Own_Lock_or_Unlock
transition(I_L, Own_Lock_or_Unlock, I) {
@@ -2364,4 +2384,3 @@ machine(L1Cache, "Token protocol")
kd_wakeUpDependents;
}
}
-
diff --git a/src/mem/protocol/MOESI_hammer-cache.sm b/src/mem/protocol/MOESI_hammer-cache.sm
index ce16a8777..219096d26 100644
--- a/src/mem/protocol/MOESI_hammer-cache.sm
+++ b/src/mem/protocol/MOESI_hammer-cache.sm
@@ -41,7 +41,8 @@ machine(L1Cache, "AMD Hammer-like protocol")
int cache_response_latency = 10,
int issue_latency = 2,
int l2_cache_hit_latency = 10,
- bool no_mig_atomic = true
+ bool no_mig_atomic = true,
+ bool send_evictions
{
// NETWORK BUFFERS
@@ -1207,6 +1208,13 @@ machine(L1Cache, "AMD Hammer-like protocol")
unset_cache_entry();
}
+ action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") {
+ if (send_evictions) {
+ DPRINTF(RubySlicc, "Sending invalidation for %s to the CPU\n", address);
+ sequencer.evictionCallback(address);
+ }
+ }
+
action(uu_profileMiss, "\u", desc="Profile the demand miss") {
peek(mandatoryQueue_in, RubyRequest) {
if (L1IcacheMemory.isTagPresent(address)) {
@@ -1486,17 +1494,20 @@ machine(L1Cache, "AMD Hammer-like protocol")
i_allocateTBE;
bf_issueGETF;
uu_profileMiss;
+ forward_eviction_to_cpu;
gg_deallocateL1CacheBlock;
k_popMandatoryQueue;
}
transition(S, L2_Replacement, I) {
+ forward_eviction_to_cpu;
rr_deallocateL2CacheBlock;
ka_wakeUpAllDependents;
}
transition(S, {Other_GETX, Invalidate}, I) {
f_sendAck;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
@@ -1528,6 +1539,7 @@ machine(L1Cache, "AMD Hammer-like protocol")
bf_issueGETF;
p_decrementNumberOfMessagesByOne;
uu_profileMiss;
+ forward_eviction_to_cpu;
gg_deallocateL1CacheBlock;
k_popMandatoryQueue;
}
@@ -1535,12 +1547,14 @@ machine(L1Cache, "AMD Hammer-like protocol")
transition(O, L2_Replacement, OI) {
i_allocateTBE;
d_issuePUT;
+ forward_eviction_to_cpu;
rr_deallocateL2CacheBlock;
ka_wakeUpAllDependents;
}
transition(O, {Other_GETX, Invalidate}, I) {
e_sendData;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
@@ -1569,6 +1583,7 @@ machine(L1Cache, "AMD Hammer-like protocol")
i_allocateTBE;
bf_issueGETF;
p_decrementNumberOfMessagesByOne;
+ forward_eviction_to_cpu;
gg_deallocateL1CacheBlock;
k_popMandatoryQueue;
}
@@ -1582,17 +1597,20 @@ machine(L1Cache, "AMD Hammer-like protocol")
transition(MM, L2_Replacement, MI) {
i_allocateTBE;
d_issuePUT;
+ forward_eviction_to_cpu;
rr_deallocateL2CacheBlock;
ka_wakeUpAllDependents;
}
transition(MM, {Other_GETX, Invalidate}, I) {
c_sendExclusiveData;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
transition(MM, Other_GETS, I) {
c_sendExclusiveData;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
@@ -1625,12 +1643,14 @@ machine(L1Cache, "AMD Hammer-like protocol")
transition(M, L2_Replacement, MI) {
i_allocateTBE;
d_issuePUT;
+ forward_eviction_to_cpu;
rr_deallocateL2CacheBlock;
ka_wakeUpAllDependents;
}
transition(M, {Other_GETX, Invalidate}, I) {
c_sendExclusiveData;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
@@ -1700,11 +1720,13 @@ machine(L1Cache, "AMD Hammer-like protocol")
transition(SM, {Other_GETX, Invalidate}, IM) {
f_sendAck;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
transition(SM_F, {Other_GETX, Invalidate}, IM_F) {
f_sendAck;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
@@ -1754,12 +1776,14 @@ machine(L1Cache, "AMD Hammer-like protocol")
transition(OM, {Other_GETX, Invalidate}, IM) {
e_sendData;
pp_incrementNumberOfMessagesByOne;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
transition(OM_F, {Other_GETX, Invalidate}, IM_F) {
q_sendDataFromTBEToCache;
pp_incrementNumberOfMessagesByOne;
+ forward_eviction_to_cpu;
l_popForwardQueue;
}
diff --git a/src/mem/protocol/MOESI_hammer-dir.sm b/src/mem/protocol/MOESI_hammer-dir.sm
index a20619d46..dfb62e844 100644
--- a/src/mem/protocol/MOESI_hammer-dir.sm
+++ b/src/mem/protocol/MOESI_hammer-dir.sm
@@ -87,7 +87,7 @@ machine(Directory, "AMD Hammer-like protocol")
O_DR_B, AccessPermission:Busy, desc="Owner, Dma Read waiting for cache responses";
WB, AccessPermission:Busy, desc="Blocked on a writeback";
WB_O_W, AccessPermission:Busy, desc="Blocked on memory write, will go to O";
- WB_E_W, AccessPermission:Busy, desc="Blocked on memory write, will go to E";
+ WB_E_W, AccessPermission:Read_Write, desc="Blocked on memory write, will go to E";
NO_F, AccessPermission:Busy, desc="Blocked on a flush";
NO_F_W, AccessPermission:Busy, desc="Not Owner, Blocked, waiting for Dram";
diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm
index c76e0fe3e..3b90dab20 100644
--- a/src/mem/protocol/RubySlicc_Types.sm
+++ b/src/mem/protocol/RubySlicc_Types.sm
@@ -107,6 +107,7 @@ structure (Sequencer, external = "yes") {
void writeCallback(Address, GenericMachineType, DataBlock, Time, Time, Time);
void checkCoherence(Address);
void profileNack(Address, int, int, uint64);
+ void evictionCallback(Address);
}
structure(RubyRequest, desc="...", interface="Message", external="yes") {
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index 64faf6aed..b60ca2a07 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * Copyright (c) 2011 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -93,14 +94,6 @@ RubyPort::getPort(const std::string &if_name, int idx)
return physMemPort;
}
- if (if_name == "functional") {
- // Calls for the functional port only want to access
- // functional memory. Therefore, directly pass these calls
- // ports to physmem.
- assert(physmem != NULL);
- return physmem->getPort(if_name, idx);
- }
-
return NULL;
}
@@ -464,8 +457,11 @@ RubyPort::M5Port::recvFunctional(PacketPtr pkt)
// turn packet around to go back to requester if response expected
if (needsResponse) {
pkt->setFunctionalResponseStatus(accessSucceeded);
- DPRINTF(RubyPort, "Sending packet back over port\n");
- sendFunctional(pkt);
+
+ // @todo There should not be a reverse call since the response is
+ // communicated through the packet pointer
+ // DPRINTF(RubyPort, "Sending packet back over port\n");
+ // sendFunctional(pkt);
}
DPRINTF(RubyPort, "Functional access %s!\n",
accessSucceeded ? "successful":"failed");
@@ -668,9 +664,8 @@ RubyPort::PioPort::sendTiming(PacketPtr pkt)
bool
RubyPort::M5Port::isPhysMemAddress(Addr addr)
{
- AddrRangeList physMemAddrList;
- bool snoop = false;
- ruby_port->physMemPort->getPeerAddressRanges(physMemAddrList, snoop);
+ AddrRangeList physMemAddrList =
+ ruby_port->physMemPort->getPeer()->getAddrRanges();
for (AddrRangeIter iter = physMemAddrList.begin();
iter != physMemAddrList.end();
iter++) {
@@ -688,3 +683,14 @@ RubyPort::M5Port::deviceBlockSize() const
{
return (unsigned) RubySystem::getBlockSizeBytes();
}
+
+void
+RubyPort::ruby_eviction_callback(const Address& address)
+{
+ DPRINTF(RubyPort, "Sending invalidations.\n");
+ Request req(address.getAddress(), 0, 0);
+ for (CpuPortIter it = cpu_ports.begin(); it != cpu_ports.end(); it++) {
+ Packet *pkt = new Packet(&req, MemCmd::InvalidationReq, -1);
+ (*it)->sendTiming(pkt);
+ }
+}
diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh
index d8dbe0cda..2ffdef3d9 100644
--- a/src/mem/ruby/system/RubyPort.hh
+++ b/src/mem/ruby/system/RubyPort.hh
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2009 Advanced Micro Devices, Inc.
+ * Copyright (c) 2011 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,6 +59,7 @@ class RubyPort : public MemObject
RubySystem*_system, bool _access_phys_mem);
bool sendTiming(PacketPtr pkt);
void hitCallback(PacketPtr pkt);
+ void evictionCallback(const Address& address);
unsigned deviceBlockSize() const;
bool onRetryList()
@@ -129,8 +131,8 @@ class RubyPort : public MemObject
protected:
const std::string m_name;
void ruby_hit_callback(PacketPtr pkt);
- void hit(PacketPtr pkt);
void testDrainComplete();
+ void ruby_eviction_callback(const Address& address);
int m_version;
AbstractController* m_controller;
diff --git a/src/mem/port_impl.hh b/src/mem/ruby/system/RubyPortProxy.cc
index bc9592164..29a693ca6 100644
--- a/src/mem/port_impl.hh
+++ b/src/mem/ruby/system/RubyPortProxy.cc
@@ -1,6 +1,15 @@
/*
- * Copyright (c) 2006 The Regents of The University of Michigan
- * All rights reserved.
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -25,29 +34,37 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Ali Saidi
+ * Authors: Andreas Hansson
*/
-#include "arch/isa_traits.hh"
-#include "config/the_isa.hh"
-#include "mem/port.hh"
-#include "sim/byteswap.hh"
+#include "mem/ruby/system/RubyPortProxy.hh"
-template <typename T>
-void
-FunctionalPort::writeHtoG(Addr addr, T d)
+RubyPortProxy::RubyPortProxy(const RubyPortProxyParams* p) :
+ RubyPort(p) {
+}
+
+RubyPortProxy::~RubyPortProxy()
{
- d = TheISA::htog(d);
- writeBlob(addr, (uint8_t*)&d, sizeof(T));
}
+void
+RubyPortProxy::init()
+{
+ // Merely override to not care about the m_controller being NULL
+}
-template <typename T>
-T
-FunctionalPort::readGtoH(Addr addr)
+RequestStatus
+RubyPortProxy::makeRequest(PacketPtr pkt)
{
- T d;
- readBlob(addr, (uint8_t*)&d, sizeof(T));
- return TheISA::gtoh(d);
+ // This sequencer should only be used through the functional
+ // accesses made by the system port and so simply fail if this
+ // happens.
+ panic("RubyPortProxy::makeRequest should not be called");
+ return RequestStatus_NULL;
}
+RubyPortProxy*
+RubyPortProxyParams::create()
+{
+ return new RubyPortProxy(this);
+}
diff --git a/src/mem/ruby/system/RubyPortProxy.hh b/src/mem/ruby/system/RubyPortProxy.hh
new file mode 100644
index 000000000..8f88541e5
--- /dev/null
+++ b/src/mem/ruby/system/RubyPortProxy.hh
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Hansson
+ */
+
+/**
+ * @file
+ * RobyPortProxy for connecting system port to Ruby
+ *
+ * A trivial wrapper that allows the system port to connect to Ruby
+ * and use nothing but functional accesses.
+ */
+
+#ifndef __MEM_RUBY_SYSTEM_RUBYPORTPROXY_HH__
+#define __MEM_RUBY_SYSTEM_RUBYPORTPROXY_HH__
+
+#include "mem/ruby/system/RubyPort.hh"
+#include "params/RubyPortProxy.hh"
+
+class RubyPortProxy : public RubyPort
+{
+
+ public:
+
+ /**
+ * Create a new RubyPortProxy.
+ *
+ * @param p Parameters inherited from the RubyPort
+ */
+ RubyPortProxy(const RubyPortProxyParams* p);
+
+ /**
+ * Destruct a RubyPortProxy.
+ */
+ virtual ~RubyPortProxy();
+
+ /**
+ * Initialise a RubyPortProxy by doing nothing and avoid
+ * involving the super class.
+ */
+ void init();
+
+ /**
+ * Pure virtual member in the super class that we are forced to
+ * implement even if it is never used (since there are only
+ * functional accesses).
+ *
+ * @param pkt The packet to serve to Ruby
+ * @returns always a NULL status
+ */
+ RequestStatus makeRequest(PacketPtr pkt);
+
+ /**
+ * Pure virtual member in the super class that we are forced to
+ * implement even if it is never used (since there are only
+ * functional accesses).
+ *
+ * @returns always 0
+ */
+ int outstandingCount() const { return 0; }
+
+ /**
+ * Pure virtual member in the super class that we are forced to
+ * implement even if it is never used (since there are only
+ * functional accesses).
+ *
+ * @returns always false
+ */
+ bool isDeadlockEventScheduled() const { return false; }
+
+ /**
+ * Pure virtual member in the super class that we are forced to
+ * implement even if it is never used (since there are only
+ * functional accesses).
+ */
+ void descheduleDeadlockEvent() { }
+
+};
+
+#endif // __MEM_RUBY_SYSTEM_RUBYPORTPROXY_HH__
diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript
index 66d7d95bb..cbb1da3b1 100644
--- a/src/mem/ruby/system/SConscript
+++ b/src/mem/ruby/system/SConscript
@@ -49,6 +49,7 @@ Source('WireBuffer.cc')
Source('MemoryNode.cc')
Source('PersistentTable.cc')
Source('RubyPort.cc')
+Source('RubyPortProxy.cc')
Source('Sequencer.cc')
Source('System.cc')
Source('TimerTable.cc')
diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc
index 3f9ceb34d..1cd54d45c 100644
--- a/src/mem/ruby/system/Sequencer.cc
+++ b/src/mem/ruby/system/Sequencer.cc
@@ -733,3 +733,9 @@ Sequencer::checkCoherence(const Address& addr)
g_system_ptr->checkGlobalCoherenceInvariant(addr);
#endif
}
+
+void
+Sequencer::evictionCallback(const Address& address)
+{
+ ruby_eviction_callback(address);
+}
diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh
index 4a6d46c01..e262e32e8 100644
--- a/src/mem/ruby/system/Sequencer.hh
+++ b/src/mem/ruby/system/Sequencer.hh
@@ -117,6 +117,7 @@ class Sequencer : public RubyPort, public Consumer
void markRemoved();
void removeRequest(SequencerRequest* request);
+ void evictionCallback(const Address& address);
private:
void issueRequest(PacketPtr pkt, RubyRequestType type);
@@ -181,4 +182,3 @@ operator<<(std::ostream& out, const Sequencer& obj)
}
#endif // __MEM_RUBY_SYSTEM_SEQUENCER_HH__
-
diff --git a/src/mem/ruby/system/Sequencer.py b/src/mem/ruby/system/Sequencer.py
index 5d56dc000..ddf760f7b 100644
--- a/src/mem/ruby/system/Sequencer.py
+++ b/src/mem/ruby/system/Sequencer.py
@@ -44,6 +44,9 @@ class RubyPort(MemObject):
access_phys_mem = Param.Bool(True,
"should the rubyport atomically update phys_mem")
ruby_system = Param.RubySystem("")
+
+class RubyPortProxy(RubyPort):
+ type = 'RubyPortProxy'
class RubySequencer(RubyPort):
type = 'RubySequencer'
diff --git a/src/mem/translating_port.cc b/src/mem/se_translating_port_proxy.cc
index 7d3123012..0f7ecb491 100644
--- a/src/mem/translating_port.cc
+++ b/src/mem/se_translating_port_proxy.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2001-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -27,6 +39,7 @@
*
* Authors: Ron Dreslinski
* Steve Reinhardt
+ * Andreas Hansson
*/
#include <string>
@@ -35,22 +48,22 @@
#include "base/chunk_generator.hh"
#include "config/the_isa.hh"
#include "mem/page_table.hh"
-#include "mem/port.hh"
-#include "mem/translating_port.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "sim/process.hh"
using namespace TheISA;
-TranslatingPort::TranslatingPort(const std::string &_name, Process *p,
- AllocType alloc)
- : FunctionalPort(_name), pTable(p->pTable), process(p), allocating(alloc)
+SETranslatingPortProxy::SETranslatingPortProxy(Port& port, Process *p,
+ AllocType alloc)
+ : PortProxy(port), pTable(p->pTable), process(p),
+ allocating(alloc)
{ }
-TranslatingPort::~TranslatingPort()
+SETranslatingPortProxy::~SETranslatingPortProxy()
{ }
bool
-TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
+SETranslatingPortProxy::tryReadBlob(Addr addr, uint8_t *p, int size)
{
int prevSize = 0;
@@ -60,7 +73,7 @@ TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
if (!pTable->translate(gen.addr(),paddr))
return false;
- Port::readBlob(paddr, p + prevSize, gen.size());
+ PortProxy::readBlob(paddr, p + prevSize, gen.size());
prevSize += gen.size();
}
@@ -68,7 +81,7 @@ TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
}
void
-TranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
+SETranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size)
{
if (!tryReadBlob(addr, p, size))
fatal("readBlob(0x%x, ...) failed", addr);
@@ -76,7 +89,7 @@ TranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
bool
-TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
+SETranslatingPortProxy::tryWriteBlob(Addr addr, uint8_t *p, int size)
{
int prevSize = 0;
@@ -98,7 +111,7 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
pTable->translate(gen.addr(), paddr);
}
- Port::writeBlob(paddr, p + prevSize, gen.size());
+ PortProxy::writeBlob(paddr, p + prevSize, gen.size());
prevSize += gen.size();
}
@@ -107,14 +120,14 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
void
-TranslatingPort::writeBlob(Addr addr, uint8_t *p, int size)
+SETranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size)
{
if (!tryWriteBlob(addr, p, size))
fatal("writeBlob(0x%x, ...) failed", addr);
}
bool
-TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size)
+SETranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t val, int size)
{
for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
Addr paddr;
@@ -128,14 +141,15 @@ TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size)
return false;
}
}
- Port::memsetBlob(paddr, val, gen.size());
+
+ PortProxy::memsetBlob(paddr, val, gen.size());
}
return true;
}
void
-TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size)
+SETranslatingPortProxy::memsetBlob(Addr addr, uint8_t val, int size)
{
if (!tryMemsetBlob(addr, val, size))
fatal("memsetBlob(0x%x, ...) failed", addr);
@@ -143,7 +157,7 @@ TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size)
bool
-TranslatingPort::tryWriteString(Addr addr, const char *str)
+SETranslatingPortProxy::tryWriteString(Addr addr, const char *str)
{
uint8_t c;
@@ -156,21 +170,21 @@ TranslatingPort::tryWriteString(Addr addr, const char *str)
if (!pTable->translate(vaddr++, paddr))
return false;
- Port::writeBlob(paddr, &c, 1);
+ PortProxy::writeBlob(paddr, &c, 1);
} while (c);
return true;
}
void
-TranslatingPort::writeString(Addr addr, const char *str)
+SETranslatingPortProxy::writeString(Addr addr, const char *str)
{
if (!tryWriteString(addr, str))
fatal("writeString(0x%x, ...) failed", addr);
}
bool
-TranslatingPort::tryReadString(std::string &str, Addr addr)
+SETranslatingPortProxy::tryReadString(std::string &str, Addr addr)
{
uint8_t c;
@@ -182,7 +196,7 @@ TranslatingPort::tryReadString(std::string &str, Addr addr)
if (!pTable->translate(vaddr++, paddr))
return false;
- Port::readBlob(paddr, &c, 1);
+ PortProxy::readBlob(paddr, &c, 1);
str += c;
} while (c);
@@ -190,7 +204,7 @@ TranslatingPort::tryReadString(std::string &str, Addr addr)
}
void
-TranslatingPort::readString(std::string &str, Addr addr)
+SETranslatingPortProxy::readString(std::string &str, Addr addr)
{
if (!tryReadString(str, addr))
fatal("readString(0x%x, ...) failed", addr);
diff --git a/src/mem/translating_port.hh b/src/mem/se_translating_port_proxy.hh
index 438d8fe61..71e8b4f50 100644
--- a/src/mem/translating_port.hh
+++ b/src/mem/se_translating_port_proxy.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2001-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -27,18 +39,33 @@
*
* Authors: Ron Dreslinski
* Ali Saidi
+ * Andreas Hansson
*/
-#ifndef __MEM_TRANSLATING_PROT_HH__
-#define __MEM_TRANSLATING_PROT_HH__
-
-#include "mem/port.hh"
+#ifndef __MEM_SE_TRANSLATING_PORT_PROXY_HH__
+#define __MEM_SE_TRANSLATING_PORT_PROXY_HH__
-class PageTable;
-class Process;
+#include "mem/page_table.hh"
+#include "mem/port_proxy.hh"
+#include "sim/process.hh"
-class TranslatingPort : public FunctionalPort
+/**
+ * @file
+ * TranslatingPortProxy Object Declaration for SE.
+ *
+ * Port proxies are used when non structural entities need access to
+ * the memory system. Proxy objects replace the previous
+ * FunctionalPort, TranslatingPort and VirtualPort objects, which
+ * provided the same functionality as the proxies, but were instances
+ * of ports not corresponding to real structural ports of the
+ * simulated system. Via the port proxies all the accesses go through
+ * an actual port and thus are transparent to a potentially
+ * distributed memory and automatically adhere to the memory map of
+ * the system.
+ */
+class SETranslatingPortProxy : public PortProxy
{
+
public:
enum AllocType {
Always,
@@ -52,8 +79,8 @@ class TranslatingPort : public FunctionalPort
AllocType allocating;
public:
- TranslatingPort(const std::string &_name, Process *p, AllocType alloc);
- virtual ~TranslatingPort();
+ SETranslatingPortProxy(Port& port, Process* p, AllocType alloc);
+ virtual ~SETranslatingPortProxy();
bool tryReadBlob(Addr addr, uint8_t *p, int size);
bool tryWriteBlob(Addr addr, uint8_t *p, int size);
@@ -69,4 +96,4 @@ class TranslatingPort : public FunctionalPort
void readString(std::string &str, Addr addr);
};
-#endif
+#endif // __MEM_SE_TRANSLATING_PORT_PROXY_HH__
diff --git a/src/mem/tport.cc b/src/mem/tport.cc
index 8e02215f2..7b1fdb850 100644
--- a/src/mem/tport.cc
+++ b/src/mem/tport.cc
@@ -29,12 +29,13 @@
*/
#include "debug/Bus.hh"
+#include "mem/mem_object.hh"
#include "mem/tport.hh"
using namespace std;
SimpleTimingPort::SimpleTimingPort(string pname, MemObject *_owner)
- : Port(pname, _owner), sendEvent(0), drainEvent(NULL),
+ : Port(pname, _owner), sendEvent(NULL), drainEvent(NULL),
waitingOnRetry(false)
{
sendEvent = new EventWrapper<SimpleTimingPort,
@@ -104,6 +105,20 @@ SimpleTimingPort::recvTiming(PacketPtr pkt)
return true;
}
+void
+SimpleTimingPort::schedSendEvent(Tick when)
+{
+ if (waitingOnRetry) {
+ assert(!sendEvent->scheduled());
+ return;
+ }
+
+ if (!sendEvent->scheduled()) {
+ owner->schedule(sendEvent, when);
+ } else if (sendEvent->when() > when) {
+ owner->reschedule(sendEvent, when);
+ }
+}
void
SimpleTimingPort::schedSendTiming(PacketPtr pkt, Tick when)
@@ -153,7 +168,7 @@ SimpleTimingPort::sendDeferredPacket()
if (success) {
if (!transmitList.empty() && !sendEvent->scheduled()) {
Tick time = transmitList.front().tick;
- schedule(sendEvent, time <= curTick() ? curTick()+1 : time);
+ owner->schedule(sendEvent, time <= curTick() ? curTick()+1 : time);
}
if (transmitList.empty() && drainEvent && !sendEvent->scheduled()) {
diff --git a/src/mem/tport.hh b/src/mem/tport.hh
index f081d8656..eaf5acd5d 100644
--- a/src/mem/tport.hh
+++ b/src/mem/tport.hh
@@ -106,21 +106,14 @@ class SimpleTimingPort : public Port
Tick deferredPacketReadyTime()
{ return transmitList.empty() ? MaxTick : transmitList.front().tick; }
- void
- schedSendEvent(Tick when)
- {
- if (waitingOnRetry) {
- assert(!sendEvent->scheduled());
- return;
- }
-
- if (!sendEvent->scheduled()) {
- schedule(sendEvent, when);
- } else if (sendEvent->when() > when) {
- reschedule(sendEvent, when);
- }
- }
-
+ /**
+ * Schedule a send even if not already waiting for a retry. If the
+ * requested time is before an already scheduled send event it
+ * will be rescheduled.
+ *
+ * @param when
+ */
+ void schedSendEvent(Tick when);
/** Schedule a sendTiming() event to be called in the future.
* @param pkt packet to send
@@ -146,10 +139,13 @@ class SimpleTimingPort : public Port
bool recvTiming(PacketPtr pkt);
/**
- * Simple ports generally don't care about any status
- * changes... can always override this in cases where that's not
- * true. */
- virtual void recvStatusChange(Status status) { }
+ * Simple ports are generally used as slave ports (i.e. the
+ * respond to requests) and thus do not expect to receive any
+ * range changes (as the neighbouring port has a master role and
+ * do not have any address ranges. A subclass can override the
+ * default behaviuor if needed.
+ */
+ virtual void recvRangeChange() { }
public:
diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py
index 47ca32af2..84d70d663 100644
--- a/src/python/m5/SimObject.py
+++ b/src/python/m5/SimObject.py
@@ -273,8 +273,6 @@ class MetaSimObject(type):
assert(not hasattr(port, 'name'))
port.name = name
cls._ports[name] = port
- if hasattr(port, 'default'):
- cls._cls_get_port_ref(name).connect(port.default)
# same as _get_port_ref, effectively, but for classes
def _cls_get_port_ref(cls, attr):
diff --git a/src/python/m5/params.py b/src/python/m5/params.py
index 05fe9b774..dfc703a40 100644
--- a/src/python/m5/params.py
+++ b/src/python/m5/params.py
@@ -1488,13 +1488,10 @@ class VectorPortRef(object):
# logical port in the SimObject class, not a particular port on a
# SimObject instance. The latter are represented by PortRef objects.
class Port(object):
- # Port("description") or Port(default, "description")
+ # Port("description")
def __init__(self, *args):
if len(args) == 1:
self.desc = args[0]
- elif len(args) == 2:
- self.default = args[0]
- self.desc = args[1]
else:
raise TypeError, 'wrong number of arguments'
# self.name is set by SimObject class on assignment
diff --git a/src/sim/System.py b/src/sim/System.py
index 39505c01a..73124ecb9 100644
--- a/src/sim/System.py
+++ b/src/sim/System.py
@@ -37,8 +37,9 @@ from PhysicalMemory import *
class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing']
-class System(SimObject):
+class System(MemObject):
type = 'System'
+ system_port = Port("System port")
@classmethod
def export_method_cxx_predecls(cls, code):
diff --git a/src/sim/arguments.hh b/src/sim/arguments.hh
index ef94cbb25..5c7941562 100644
--- a/src/sim/arguments.hh
+++ b/src/sim/arguments.hh
@@ -36,7 +36,7 @@
#include "arch/vtophys.hh"
#include "base/refcnt.hh"
#include "base/types.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
class ThreadContext;
diff --git a/src/sim/process.cc b/src/sim/process.cc
index c400b72ee..45362fe1b 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -44,7 +44,7 @@
#include "cpu/thread_context.hh"
#include "mem/page_table.hh"
#include "mem/physical.hh"
-#include "mem/translating_port.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "params/LiveProcess.hh"
#include "params/Process.hh"
#include "sim/debug.hh"
@@ -234,12 +234,8 @@ Process::initState()
// mark this context as active so it will start ticking.
tc->activate(0);
- Port *mem_port;
- mem_port = system->physmem->getPort("functional");
- initVirtMem = new TranslatingPort("process init port", this,
- TranslatingPort::Always);
- mem_port->setPeer(initVirtMem);
- initVirtMem->setPeer(mem_port);
+ initVirtMem = new SETranslatingPortProxy(*system->getSystemPort(), this,
+ SETranslatingPortProxy::Always);
}
// map simulator fd sim_fd to target fd tgt_fd
diff --git a/src/sim/process.hh b/src/sim/process.hh
index f738bb38a..3896492b7 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -48,7 +48,7 @@ class LiveProcessParams;
class SyscallDesc;
class System;
class ThreadContext;
-class TranslatingPort;
+class SETranslatingPortProxy;
template<class IntType>
struct AuxVector
@@ -123,7 +123,7 @@ class Process : public SimObject
protected:
/// Memory object for initialization (image loading)
- TranslatingPort *initVirtMem;
+ SETranslatingPortProxy *initVirtMem;
public:
PageTable *pTable;
diff --git a/src/sim/process_impl.hh b/src/sim/process_impl.hh
index 944c55ec0..401e16f52 100644
--- a/src/sim/process_impl.hh
+++ b/src/sim/process_impl.hh
@@ -35,7 +35,7 @@
#include <string>
#include <vector>
-#include "mem/translating_port.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "sim/byteswap.hh"
//This needs to be templated for cases where 32 bit pointers are needed.
@@ -43,21 +43,21 @@ template<class AddrType>
void
copyStringArray(std::vector<std::string> &strings,
AddrType array_ptr, AddrType data_ptr,
- TranslatingPort* memPort)
+ SETranslatingPortProxy* memProxy)
{
AddrType data_ptr_swap;
for (std::vector<std::string>::size_type i = 0; i < strings.size(); ++i) {
data_ptr_swap = htog(data_ptr);
- memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap,
+ memProxy->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap,
sizeof(AddrType));
- memPort->writeString(data_ptr, strings[i].c_str());
+ memProxy->writeString(data_ptr, strings[i].c_str());
array_ptr += sizeof(AddrType);
data_ptr += strings[i].size() + 1;
}
// add NULL terminator
data_ptr = 0;
- memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType));
+ memProxy->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType));
}
#endif
diff --git a/src/sim/stat_control.cc b/src/sim/stat_control.cc
index 7cf77174f..eb5fe1307 100644
--- a/src/sim/stat_control.cc
+++ b/src/sim/stat_control.cc
@@ -53,6 +53,7 @@ using namespace std;
Stats::Formula simSeconds;
Stats::Value simTicks;
+Stats::Value finalTick;
Stats::Value simFreq;
namespace Stats {
@@ -85,6 +86,12 @@ statElapsedTicks()
return curTick() - startTick;
}
+Tick
+statFinalTick()
+{
+ return curTick();
+}
+
SimTicksReset simTicksReset;
struct Global
@@ -126,6 +133,13 @@ Global::Global()
.desc("Number of ticks simulated")
;
+ finalTick
+ .functor(statFinalTick)
+ .name("final_tick")
+ .desc("Number of ticks from beginning of simulation \
+(restored from checkpoints and never reset)")
+ ;
+
hostInstRate
.name("host_inst_rate")
.desc("Simulator instruction rate (inst/s)")
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index 203eaff2a..dc8a9a5c8 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -171,7 +171,7 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
// if the address is already there, zero it out
else {
uint8_t zero = 0;
- TranslatingPort *tp = tc->getMemPort();
+ SETranslatingPortProxy *tp = tc->getMemProxy();
// split non-page aligned accesses
Addr next_page = roundUp(gen.addr(), VMPageSize);
@@ -221,7 +221,7 @@ readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
if (bytes_read != -1)
- bufArg.copyOut(tc->getMemPort());
+ bufArg.copyOut(tc->getMemProxy());
return bytes_read;
}
@@ -235,7 +235,7 @@ writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
int nbytes = p->getSyscallArg(tc, index);
BufferArg bufArg(bufPtr, nbytes);
- bufArg.copyIn(tc->getMemPort());
+ bufArg.copyIn(tc->getMemProxy());
int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
@@ -284,7 +284,7 @@ _llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
// target platform
BufferArg result_buf(result_ptr, sizeof(result));
memcpy(result_buf.bufferPtr(), &result, sizeof(result));
- result_buf.copyOut(tc->getMemPort());
+ result_buf.copyOut(tc->getMemProxy());
return 0;
}
@@ -313,7 +313,7 @@ gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
strncpy((char *)name.bufferPtr(), hostname, name_len);
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
@@ -346,7 +346,7 @@ getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
}
}
- buf.copyOut(tc->getMemPort());
+ buf.copyOut(tc->getMemProxy());
return (result == -1) ? -errno : result;
}
@@ -358,7 +358,7 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
+ if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
return (TheISA::IntReg)-EFAULT;
// Adjust path for current working directory
@@ -371,7 +371,7 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
- buf.copyOut(tc->getMemPort());
+ buf.copyOut(tc->getMemProxy());
return (result == -1) ? -errno : result;
}
@@ -382,7 +382,7 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
+ if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
return (TheISA::IntReg)-EFAULT;
// Adjust path for current working directory
@@ -399,7 +399,7 @@ mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
+ if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
return (TheISA::IntReg)-EFAULT;
// Adjust path for current working directory
@@ -417,12 +417,12 @@ renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
string old_name;
int index = 0;
- if (!tc->getMemPort()->tryReadString(old_name, p->getSyscallArg(tc, index)))
+ if (!tc->getMemProxy()->tryReadString(old_name, p->getSyscallArg(tc, index)))
return -EFAULT;
string new_name;
- if (!tc->getMemPort()->tryReadString(new_name, p->getSyscallArg(tc, index)))
+ if (!tc->getMemProxy()->tryReadString(new_name, p->getSyscallArg(tc, index)))
return -EFAULT;
// Adjust path for current working directory
@@ -439,7 +439,7 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
+ if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
return -EFAULT;
off_t length = p->getSyscallArg(tc, index);
@@ -474,7 +474,7 @@ truncate64Func(SyscallDesc *desc, int num,
int index = 0;
string path;
- if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, index)))
+ if (!tc->getMemProxy()->tryReadString(path, process->getSyscallArg(tc, index)))
return -EFAULT;
int64_t length = process->getSyscallArg(tc, index, 64);
@@ -527,7 +527,7 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
+ if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
return -EFAULT;
/* XXX endianess */
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index 5c480272d..45c87f0ab 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -62,7 +62,7 @@
#include "cpu/thread_context.hh"
#include "debug/SyscallVerbose.hh"
#include "mem/page_table.hh"
-#include "mem/translating_port.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "sim/byteswap.hh"
#include "sim/process.hh"
#include "sim/syscallreturn.hh"
@@ -121,18 +121,18 @@ class BaseBufferArg {
//
// copy data into simulator space (read from target memory)
//
- virtual bool copyIn(TranslatingPort *memport)
+ virtual bool copyIn(SETranslatingPortProxy* memproxy)
{
- memport->readBlob(addr, bufPtr, size);
+ memproxy->readBlob(addr, bufPtr, size);
return true; // no EFAULT detection for now
}
//
// copy data out of simulator space (write to target memory)
//
- virtual bool copyOut(TranslatingPort *memport)
+ virtual bool copyOut(SETranslatingPortProxy* memproxy)
{
- memport->writeBlob(addr, bufPtr, size);
+ memproxy->writeBlob(addr, bufPtr, size);
return true; // no EFAULT detection for now
}
@@ -464,7 +464,7 @@ convertStat64Buf(target_stat &tgt, host_stat64 *host, bool fakeTTY = false)
//Here are a couple convenience functions
template<class OS>
static void
-copyOutStatBuf(TranslatingPort * mem, Addr addr,
+copyOutStatBuf(SETranslatingPortProxy* mem, Addr addr,
hst_stat *host, bool fakeTTY = false)
{
typedef TypedBufferArg<typename OS::tgt_stat> tgt_stat_buf;
@@ -475,7 +475,7 @@ copyOutStatBuf(TranslatingPort * mem, Addr addr,
template<class OS>
static void
-copyOutStat64Buf(TranslatingPort * mem, Addr addr,
+copyOutStat64Buf(SETranslatingPortProxy* mem, Addr addr,
hst_stat64 *host, bool fakeTTY = false)
{
typedef TypedBufferArg<typename OS::tgt_stat64> tgt_stat_buf;
@@ -530,7 +530,7 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index)))
return -EFAULT;
@@ -594,7 +594,7 @@ sysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
sysinfo->uptime=seconds_since_epoch;
sysinfo->totalram=process->system->memSize();
- sysinfo.copyOut(tc->getMemPort());
+ sysinfo.copyOut(tc->getMemProxy());
return 0;
}
@@ -608,7 +608,7 @@ chmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
@@ -714,7 +714,7 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
@@ -729,7 +729,7 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+ copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
@@ -744,7 +744,7 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index)))
return -EFAULT;
Addr bufPtr = process->getSyscallArg(tc, index);
@@ -763,7 +763,7 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+ copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
@@ -794,7 +794,7 @@ fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
+ copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (fd == 1));
return 0;
}
@@ -809,7 +809,7 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
@@ -824,7 +824,7 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+ copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
@@ -838,7 +838,7 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
@@ -858,7 +858,7 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+ copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
@@ -884,7 +884,7 @@ fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
+ copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (fd == 1));
return 0;
}
@@ -899,7 +899,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
@@ -914,7 +914,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
+ OS::copyOutStatfsBuf(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
@@ -939,7 +939,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
+ OS::copyOutStatfsBuf(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
@@ -958,7 +958,7 @@ writevFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
return -EBADF;
}
- TranslatingPort *p = tc->getMemPort();
+ SETranslatingPortProxy *p = tc->getMemProxy();
uint64_t tiov_base = process->getSyscallArg(tc, index);
size_t count = process->getSyscallArg(tc, index);
struct iovec hiov[count];
@@ -1103,7 +1103,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
break;
}
- rlp.copyOut(tc->getMemPort());
+ rlp.copyOut(tc->getMemProxy());
return 0;
}
@@ -1121,7 +1121,7 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
tp->tv_sec = TheISA::htog(tp->tv_sec);
tp->tv_usec = TheISA::htog(tp->tv_usec);
- tp.copyOut(tc->getMemPort());
+ tp.copyOut(tc->getMemProxy());
return 0;
}
@@ -1136,14 +1136,14 @@ utimesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
TypedBufferArg<typename OS::timeval [2]>
tp(process->getSyscallArg(tc, index));
- tp.copyIn(tc->getMemPort());
+ tp.copyIn(tc->getMemProxy());
struct timeval hostTimeval[2];
for (int i = 0; i < 2; ++i)
@@ -1209,7 +1209,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
who);
}
- rup.copyOut(tc->getMemPort());
+ rup.copyOut(tc->getMemProxy());
return 0;
}
@@ -1234,7 +1234,7 @@ timesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
bufp->tms_utime = htog(bufp->tms_utime);
// Write back
- bufp.copyOut(tc->getMemPort());
+ bufp.copyOut(tc->getMemProxy());
// Return clock ticks since system boot
return clocks;
@@ -1255,7 +1255,7 @@ timeFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
if(taddr != 0) {
typename OS::time_t t = sec;
t = htog(t);
- TranslatingPort *p = tc->getMemPort();
+ SETranslatingPortProxy *p = tc->getMemProxy();
p->writeBlob(taddr, (uint8_t*)&t, (int)sizeof(typename OS::time_t));
}
return sec;
diff --git a/src/sim/system.cc b/src/sim/system.cc
index d3bee1ad1..14c44d063 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2011-2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -57,9 +57,9 @@
#include "debug/Loader.hh"
#include "debug/WorkItems.hh"
#include "kern/kernel_stats.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "mem/mem_object.hh"
#include "mem/physical.hh"
-#include "mem/vport.hh"
#include "params/System.hh"
#include "sim/byteswap.hh"
#include "sim/debug.hh"
@@ -74,7 +74,9 @@ vector<System *> System::systemList;
int System::numSystemsRunning = 0;
System::System(Params *p)
- : SimObject(p), physmem(p->physmem), _numContexts(0), pagePtr(0),
+ : MemObject(p), _systemPort("system_port", this),
+ physmem(p->physmem),
+ _numContexts(0),
init_param(p->init_param),
loadAddrMask(p->load_addr_mask),
nextPID(0),
@@ -104,68 +106,12 @@ System::System(Params *p)
if (!debugSymbolTable)
debugSymbolTable = new SymbolTable;
-
/**
- * Get a functional port to memory
- */
- Port *mem_port;
- functionalPort = new FunctionalPort(name() + "-fport");
- mem_port = physmem->getPort("functional");
- functionalPort->setPeer(mem_port);
- mem_port->setPeer(functionalPort);
-
- virtPort = new VirtualPort(name() + "-fport");
- mem_port = physmem->getPort("functional");
- virtPort->setPeer(mem_port);
- mem_port->setPeer(virtPort);
-
-
- /**
- * Load the kernel code into memory
+ * Get a port proxy to memory
*/
- if (params()->kernel == "") {
- inform("No kernel set for full system simulation. "
- "Assuming you know what you're doing...\n");
- } else {
- // Load kernel code
- kernel = createObjectFile(params()->kernel);
- inform("kernel located at: %s", params()->kernel);
-
- if (kernel == NULL)
- fatal("Could not load kernel file %s", params()->kernel);
-
- // Load program sections into memory
- kernel->loadSections(functionalPort, loadAddrMask);
-
- // setup entry points
- kernelStart = kernel->textBase();
- kernelEnd = kernel->bssBase() + kernel->bssSize();
- kernelEntry = kernel->entryPoint();
-
- // load symbols
- if (!kernel->loadGlobalSymbols(kernelSymtab))
- fatal("could not load kernel symbols\n");
-
- if (!kernel->loadLocalSymbols(kernelSymtab))
- fatal("could not load kernel local symbols\n");
-
- if (!kernel->loadGlobalSymbols(debugSymbolTable))
- fatal("could not load kernel symbols\n");
-
- if (!kernel->loadLocalSymbols(debugSymbolTable))
- fatal("could not load kernel local symbols\n");
-
- DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
- DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd);
- DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
- DPRINTF(Loader, "Kernel loaded...\n");
- }
+ physProxy = new PortProxy(*getSystemPort());
+ virtProxy = new FSTranslatingPortProxy(*getSystemPort());
}
-
- // increment the number of running systms
- numSystemsRunning++;
-
- activeCpus.clear();
}
System::~System()
@@ -178,6 +124,21 @@ System::~System()
}
void
+System::init()
+{
+ // check that the system port is connected
+ if (!_systemPort.isConnected())
+ panic("System port on %s is not connected.\n", name());
+}
+
+Port*
+System::getPort(const std::string &if_name, int idx)
+{
+ // no need to distinguish at the moment (besides checking)
+ return &_systemPort;
+}
+
+void
System::setMemoryMode(Enums::MemoryMode mode)
{
assert(getState() == Drained);
@@ -261,6 +222,59 @@ System::initState()
int i;
for (i = 0; i < threadContexts.size(); i++)
TheISA::startupCPU(threadContexts[i], i);
+ // Moved from the constructor to here since it relies on the
+ // address map being resolved in the interconnect
+ /**
+ * Load the kernel code into memory
+ */
+ if (params()->kernel == "") {
+ inform("No kernel set for full system simulation. "
+ "Assuming you know what you're doing...\n");
+ } else {
+ // Load kernel code
+ kernel = createObjectFile(params()->kernel);
+ inform("kernel located at: %s", params()->kernel);
+
+ if (kernel == NULL)
+ fatal("Could not load kernel file %s", params()->kernel);
+
+ // Load program sections into memory
+ kernel->loadSections(physProxy, loadAddrMask);
+
+ // setup entry points
+ kernelStart = kernel->textBase();
+ kernelEnd = kernel->bssBase() + kernel->bssSize();
+ kernelEntry = kernel->entryPoint();
+
+ // load symbols
+ if (!kernel->loadGlobalSymbols(kernelSymtab))
+ fatal("could not load kernel symbols\n");
+
+ if (!kernel->loadLocalSymbols(kernelSymtab))
+ fatal("could not load kernel local symbols\n");
+
+ if (!kernel->loadGlobalSymbols(debugSymbolTable))
+ fatal("could not load kernel symbols\n");
+
+ if (!kernel->loadLocalSymbols(debugSymbolTable))
+ fatal("could not load kernel local symbols\n");
+
+ DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
+ DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd);
+ DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
+ DPRINTF(Loader, "Kernel loaded...\n");
+ }
+ }
+
+ // increment the number of running systms
+ numSystemsRunning++;
+
+ activeCpus.clear();
+
+ if (FullSystem) {
+ int i;
+ for (i = 0; i < threadContexts.size(); i++)
+ TheISA::startupCPU(threadContexts[i], i);
}
}
diff --git a/src/sim/system.hh b/src/sim/system.hh
index d675eb727..eb192fb99 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2011 Regents of the University of California
* All rights reserved.
@@ -44,24 +56,81 @@
#include "cpu/pc_event.hh"
#include "enums/MemoryMode.hh"
#include "kern/system_events.hh"
+#include "mem/mem_object.hh"
#include "mem/port.hh"
#include "params/System.hh"
-#include "sim/sim_object.hh"
class BaseCPU;
class BaseRemoteGDB;
-class FunctionalPort;
+class FSTranslatingPortProxy;
class GDBListener;
class ObjectFile;
class PhysicalMemory;
class Platform;
+class PortProxy;
class ThreadContext;
class VirtualPort;
-class System : public SimObject
+class System : public MemObject
{
+ private:
+
+ /**
+ * Private class for the system port which is only used as a
+ * master for debug access and for non-structural entities that do
+ * not have a port of their own.
+ */
+ class SystemPort : public Port
+ {
+ public:
+
+ /**
+ * Create a system port with a name and an owner.
+ */
+ SystemPort(const std::string &_name, MemObject *_owner)
+ : Port(_name, _owner)
+ { }
+ bool recvTiming(PacketPtr pkt)
+ { panic("SystemPort does not receive timing!\n"); return false; }
+ Tick recvAtomic(PacketPtr pkt)
+ { panic("SystemPort does not receive atomic!\n"); return 0; }
+ void recvFunctional(PacketPtr pkt)
+ { panic("SystemPort does not receive functional!\n"); }
+
+ /**
+ * The system port is a master port connected to a single
+ * slave and thus do not care about what ranges the slave
+ * covers (as there is nothing to choose from).
+ */
+ void recvRangeChange() { }
+
+ };
+
+ SystemPort _systemPort;
+
public:
+ /**
+ * After all objects have been created and all ports are
+ * connected, check that the system port is connected.
+ */
+ virtual void init();
+
+ /**
+ * Get a pointer to the system port that can be used by
+ * non-structural simulation objects like processes or threads, or
+ * external entities like loaders and debuggers, etc, to access
+ * the memory system.
+ *
+ * @return a pointer to the system port we own
+ */
+ Port* getSystemPort() { return &_systemPort; }
+
+ /**
+ * Additional function to return the Port of a memory object.
+ */
+ Port *getPort(const std::string &if_name, int idx = -1);
+
static const char *MemoryModeStrings[3];
Enums::MemoryMode
@@ -112,8 +181,8 @@ class System : public SimObject
/** Port to physical memory used for writing object files into ram at
* boot.*/
- FunctionalPort *functionalPort;
- VirtualPort *virtPort;
+ PortProxy* physProxy;
+ FSTranslatingPortProxy* virtProxy;
/** kernel symbol table */
SymbolTable *kernelSymtab;
diff --git a/src/sim/vptr.hh b/src/sim/vptr.hh
index 2033339f9..eee575b6b 100644
--- a/src/sim/vptr.hh
+++ b/src/sim/vptr.hh
@@ -33,7 +33,7 @@
#include "arch/isa_traits.hh"
#include "arch/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
class ThreadContext;
@@ -71,8 +71,8 @@ class VPtr
if (!ptr)
return;
- VirtualPort *port = tc->getVirtPort();
- port->readBlob(ptr, buffer, sizeof(T));
+ FSTranslatingPortProxy* proxy = tc->getVirtProxy();
+ proxy->readBlob(ptr, buffer, sizeof(T));
}
bool