-# 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
self.console = binary('console')
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
+ self.system_port = self.membus.port
+
return self
def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
self.hypervisor_desc_bin = binary('1up-hv.bin')
self.partition_desc_bin = binary('1up-md.bin')
+ self.system_port = self.membus.port
+
return self
def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
self.terminal = Terminal()
self.vncserver = VncServer()
+ self.system_port = self.membus.port
+
return self
self.console = binary('mips/console')
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
+ self.system_port = self.membus.port
+
return self
def x86IOAddress(port):
# connect the io bus
x86_sys.pc.attachIO(x86_sys.iobus)
+ x86_sys.system_port = x86_sys.membus.port
+
def connectX86RubySystem(x86_sys):
# North Bridge
x86_sys.piobus = Bus(bus_id=0)
+# 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) 2006-2008 The Regents of The University of Michigan
# All rights reserved.
#
options.use_map = True
Ruby.create_system(options, system)
assert(options.num_cpus == len(system.ruby._cpu_ruby_ports))
+ system.system_port = system.ruby._sys_port_proxy.port
else:
+ system.system_port = system.membus.port
system.physmem.port = system.membus.port
CacheConfig.config_cache(options, system)
+# 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) 2006-2007 The Regents of The University of Michigan
# Copyright (c) 2009 Advanced Micro Devices, Inc.
# All rights reserved.
print "Error: could not create sytem for ruby protocol %s" % protocol
raise
+ # Create a port proxy for connecting the system port. This is
+ # independent of the protocol and kept in the protocol-agnostic
+ # part (i.e. here).
+ sys_port_proxy = RubyPortProxy(version = 0,
+ physMemPort = system.physmem.port,
+ physmem = system.physmem,
+ ruby_system = ruby)
+ # Give the system port proxy a SimObject parent without creating a
+ # full-fledged controller
+ system.sys_port_proxy = sys_port_proxy
+
#
# Set the network classes based on the command line options
#
ruby.profiler = ruby_profiler
ruby.mem_size = total_mem_size
ruby._cpu_ruby_ports = cpu_sequencers
+ ruby._sys_port_proxy = sys_port_proxy
ruby.random_seed = options.random_seed
#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
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
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;
}
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;
}
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;
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;
/**
* 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
* 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));
/**
* 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");
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
Tick cpuFreq = tc->getCpuPtr()->frequency();
Tick intrFreq = platform->intrFrequency();
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
}
}
LinuxAlphaSystem(Params *p);
~LinuxAlphaSystem();
+ /**
+ * Initialise the system
+ */
+ virtual void initState();
+
void setDelayLoop(ThreadContext *tc);
};
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);
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;
#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;
: 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))
Addr tsk;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
tsk = vp->readGtoH<Addr>(base + task_off);
return tsk;
uint16_t pd;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
pd = vp->readGtoH<uint16_t>(task + pid_off);
return pd;
#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"
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))
* 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()));
}
/**
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.
// 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) {
{
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");
}
~AlphaSystem();
public:
+
+ /**
+ * Initialise the state of the system.
+ */
+ virtual void initState();
+
/**
* Serialization stuff
*/
strcpy(name->version, "732");
strcpy(name->machine, "alpha");
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
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;
}
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;
}
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;
}
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;
}
#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;
{
Addr addr = 0;
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
- virtPort->write(addr, (uint32_t)0);
+ virtProxy->write(addr, (uint32_t)0);
}
#ifdef DEBUG
#if FULL_SYSTEM
#include "arch/alpha/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#endif
namespace AlphaISA {
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;
#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);
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();
}
#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);
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;
}
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;
// 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));
}
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[] =
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[] =
{
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
#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;
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.
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");
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);
#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"
#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;
{
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");
#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;
: 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");
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
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);
}
}
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
#if FULL_SYSTEM
#include "arch/arm/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#endif
#include "arch/arm/tlb.hh"
}
} 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
#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;
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;
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;
}
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:
// 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;
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
Tick cpuFreq = tc->getCpuPtr()->frequency();
Tick intrFreq = platform->intrFrequency();
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
}
}
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);
Addr tsk;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
tsk = vp->readGtoH<Addr>(base + task_off);
return tsk;
uint16_t pd;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
pd = vp->readGtoH<uint16_t>(task + pid_off);
return pd;
#if FULL_SYSTEM
#include "arch/mips/registers.hh"
#include "arch/mips/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#endif
return tc->readIntReg(FirstArgumentReg + number);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
- VirtualPort *vp = tc->getVirtPort();
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
uint64_t arg = vp->read<uint64_t>(sp +
(number - 4) * sizeof(uint64_t));
return arg;
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;
}
#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"
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;
}
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;
}
#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"
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 *)®Val, 4)) {
warn("Failed to save register to the stack when "
"flushing windows.\n");
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 *)®Val, 8)) {
warn("Failed to save register to the stack when "
"flushing windows.\n");
strcpy(name->version, "Generic_118558-21");
strcpy(name->machine, "sun4u");
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
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;
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.
// 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))
SparcSystem(Params *p);
~SparcSystem();
+ virtual void initState();
+
/**
* Serialization stuff
*/
/** 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; }
#include "arch/sparc/utility.hh"
#if FULL_SYSTEM
#include "arch/sparc/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#endif
namespace SparcISA {
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;
#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;
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;
#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
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) {
}
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;
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++)
}
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.
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;
}
}
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;
}
{}
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;
}
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;
};
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
#include "enums/X86IntelMPTriggerMode.hh"
#include "sim/sim_object.hh"
-class FunctionalPort;
+class PortProxy;
// Config entry types
class X86IntelMPBaseConfigEntryParams;
public:
- Addr writeOut(FunctionalPort * port, Addr addr);
+ Addr writeOut(PortProxy* proxy, Addr addr);
Addr getTableAddr()
{
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);
};
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);
};
std::vector<ExtConfigEntry *> extEntries;
public:
- Addr writeOut(FunctionalPort * port, Addr addr);
+ Addr writeOut(PortProxy* proxy, Addr addr);
ConfigTable(Params * p);
};
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);
};
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);
};
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);
};
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,
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);
};
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);
};
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);
};
#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"
}
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();
}
void
X86ISA::SMBios::SMBiosStructure::writeOutStrings(
- FunctionalPort * port, Addr addr)
+ PortProxy* proxy, Addr addr)
{
std::vector<std::string>::iterator it;
Addr offset = 0;
// 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
}
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;
}
}
void
-X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
+X86ISA::SMBios::SMBiosTable::writeOut(PortProxy* proxy, Addr addr,
Addr &headerSize, Addr &structSize)
{
headerSize = 0x1F;
*/
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];
*/
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];
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;
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;
*/
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;
// Set the checksum
mainChecksum = -mainChecksum;
- port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
+ proxy->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
/*
* Intermediate header
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 *
#include "enums/ExtCharacteristic.hh"
#include "sim/sim_object.hh"
-class FunctionalPort;
+class PortProxy;
class X86SMBiosBiosInformationParams;
class X86SMBiosSMBiosStructureParams;
class X86SMBiosSMBiosTableParams;
return 4;
}
- virtual uint16_t writeOut(FunctionalPort * port, Addr addr);
+ virtual uint16_t writeOut(PortProxy* proxy, Addr addr);
protected:
bool stringFields;
std::vector<std::string> strings;
- void writeOutStrings(FunctionalPort * port, Addr addr);
+ void writeOutStrings(PortProxy* proxy, Addr addr);
int getStringLength();
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
smbiosHeader.intermediateHeader.tableAddr = addr;
}
- void writeOut(FunctionalPort * port, Addr addr,
+ void writeOut(PortProxy* proxy, Addr addr,
Addr &headerSize, Addr &structSize);
};
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;
}
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.
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)) {
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;
#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"
// 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.
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));
/*
// 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
#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"
#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;
{
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");
Addr tsk;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
tsk = vp->readGtoH<Addr>(base + task_off);
return tsk;
uint16_t pd;
- VirtualPort *vp;
+ FSTranslatingPortProxy* vp;
- vp = tc->getVirtPort();
+ vp = tc->getVirtProxy();
pd = vp->readGtoH<uint16_t>(task + pid_off);
return pd;
#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"
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
{
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
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.
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++;
//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++;
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++;
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++;
// 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);
}
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;
}
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
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.
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
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;
}
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;
}
}
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());
#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;
/*
}
bool
-HexFile::loadSections(Port *memPort)
+HexFile::loadSections(PortProxy* memProxy)
{
char Line[64];
Addr MemAddr;
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;
#include "base/types.hh"
-class Port;
+class PortProxy;
class HexFile
{
virtual ~HexFile();
void close();
- bool loadSections(Port *memPort);
+ bool loadSections(PortProxy* memProxy);
};
#endif // __BASE_LOADER_HEX_FILE_HH__
#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;
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;
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));
}
#include "base/types.hh"
-class Port;
+class PortProxy;
class SymbolTable;
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;
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:
#if FULL_SYSTEM
#include "arch/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#endif
#include "base/intmath.hh"
#include "cpu/thread_context.hh"
#include "debug/GDBAll.hh"
#include "mem/port.hh"
-#include "mem/translating_port.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "sim/system.hh"
using namespace std;
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
#if FULL_SYSTEM
- VirtualPort *port = context->getVirtPort();
+ FSTranslatingPortProxy *port = context->getVirtProxy();
#else
- TranslatingPort *port = context->getMemPort();
+ SETranslatingPortProxy *port = context->getMemProxy();
#endif
port->readBlob(vaddr, (uint8_t*)data, size);
DPRINTFNR("\n");
}
#if FULL_SYSTEM
- VirtualPort *port = context->getVirtPort();
+ FSTranslatingPortProxy *port = context->getVirtProxy();
#else
- TranslatingPort *port = context->getMemPort();
+ SETranslatingPortProxy *port = context->getMemProxy();
#endif
port->writeBlob(vaddr, (uint8_t*)data, size);
#if !FULL_SYSTEM
TheISA::Kernel::Statistics *getKernelStats()
{ return actualTC->getKernelStats(); }
- FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
+ PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
- VirtualPort *getVirtPort()
- { return actualTC->getVirtPort(); }
+ FSTranslatingPortProxy* getVirtProxy()
+ { return actualTC->getVirtProxy(); }
#else
- TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
+ SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
#endif
#include "debug/RefCount.hh"
#include "debug/SkedCache.hh"
#include "debug/Quiesce.hh"
-#include "mem/translating_port.hh"
#include "params/InOrderCPU.hh"
#include "sim/process.hh"
#include "sim/stat_control.hh"
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());
}
#endif
trap(interrupt, threadContexts[0]->contextId(), dummyBufferInst);
}
-
-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());
-}
#endif
void
/** 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; }
}
-void
-CacheUnit::CachePort::setPeer(Port *port)
-{
- Port::setPeer(port);
-
-#if FULL_SYSTEM
- // Update the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- if (cachePortUnit->resName == "dcache_port") {
- cachePortUnit->cpu->updateMemPorts();
- }
-
-#endif
-}
-
Port *
CacheUnit::getPort(const string &if_name, int idx)
{
bool snoopRangeSent;
- void setPeer(Port *port);
-
protected:
/** Atomic version of receive. Panics. */
Tick recvAtomic(PacketPtr pkt);
#if FULL_SYSTEM
-VirtualPort *
-InOrderThreadContext::getVirtPort()
+FSTranslatingPortProxy*
+InOrderThreadContext::getVirtProxy()
{
- return thread->getVirtPort();
+ return thread->getVirtProxy();
}
TheISA::Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; }
- FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+ PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
- VirtualPort *getVirtPort();
+ FSTranslatingPortProxy* getVirtProxy();
- void connectMemPorts(ThreadContext *tc)
- { thread->connectMemPorts(tc); }
+ void initMemProxies(ThreadContext *tc)
+ { thread->initMemProxies(tc); }
/** Dumps the function profiling information.
* @todo: Implement.
return this->thread->quiesceEvent;
}
#else
- TranslatingPort *getMemPort() { return thread->getMemPort(); }
+ SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
/** Returns a pointer to this thread's process. */
Process *getProcessPtr() { return thread->getProcessPtr(); }
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());
}
#endif
this->trap(interrupt, 0, NULL);
}
-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());
-}
#endif
template <class Impl>
/** 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; }
bool snoopRangeSent;
- virtual void setPeer(Port *port);
-
protected:
/** Atomic version of receive. Panics. */
virtual Tick recvAtomic(PacketPtr pkt);
/** D-cache port. */
DcachePort dcachePort;
-#if FULL_SYSTEM
- /** Tell the CPU to update the Phys and Virt ports. */
- void updateMemPorts() { cpu->updateMemPorts(); }
-#endif
-
protected:
/** The LSQ policy for SMT mode. */
LSQPolicy lsqPolicy;
using namespace std;
-template<class Impl>
-void
-LSQ<Impl>::DcachePort::setPeer(Port *port)
-{
- Port::setPeer(port);
-
-#if FULL_SYSTEM
- // Update the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- lsq->updateMemPorts();
-#endif
-}
-
template <class Impl>
Tick
LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
virtual TheISA::Kernel::Statistics *getKernelStats()
{ return thread->kernelStats; }
- virtual FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+ virtual PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
- virtual VirtualPort *getVirtPort();
+ virtual FSTranslatingPortProxy* getVirtProxy();
- virtual void connectMemPorts(ThreadContext *tc) { thread->connectMemPorts(tc); }
+ virtual void initMemProxies(ThreadContext *tc)
+ { thread->initMemProxies(tc); }
#else
- virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
+ virtual SETranslatingPortProxy* getMemProxy()
+ { return thread->getMemProxy(); }
/** Returns a pointer to this thread's process. */
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
#if FULL_SYSTEM
template <class Impl>
-VirtualPort *
-O3ThreadContext<Impl>::getVirtPort()
+FSTranslatingPortProxy*
+O3ThreadContext<Impl>::getVirtProxy()
{
- return thread->getVirtPort();
+ return thread->getVirtProxy();
}
template <class Impl>
TheISA::Kernel::Statistics *getKernelStats()
{ return thread->getKernelStats(); }
- FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
+ PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
- VirtualPort *getVirtPort()
- { return thread->getVirtPort(); }
+ FSTranslatingPortProxy* getVirtProxy()
+ { return thread->getVirtProxy(); }
#else
- TranslatingPort *getMemPort() { return thread->getMemPort(); }
+ SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
Process *getProcessPtr() { return thread->getProcessPtr(); }
#endif
backEnd->renameTable.copyFrom(thread.renameTable);
#if FULL_SYSTEM
- 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);
#endif
DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
// initialize CPU, including PC
TheISA::initCPU(tc, tc->contextId());
}
+
+ // Initialise the ThreadContext's memory proxies
+ tcBase()->initMemProxies(tcBase());
#endif
if (hasPhysMemPort) {
bool snoop = false;
panic("AtomicSimpleCPU doesn't expect recvRetry callback!");
}
-void
-AtomicSimpleCPU::DcachePort::setPeer(Port *port)
-{
- Port::setPeer(port);
-
-#if FULL_SYSTEM
- // Update the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- cpu->tcBase()->connectMemPorts(cpu->tcBase());
-#endif
-}
-
AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
: BaseSimpleCPU(p), tickEvent(this), width(p->width), locked(false),
simulate_data_stalls(p->simulate_data_stalls),
};
CpuPort icachePort;
- class DcachePort : public CpuPort
- {
- public:
- DcachePort(const std::string &_name, AtomicSimpleCPU *_cpu)
- : CpuPort(_name, _cpu)
- { }
-
- virtual void setPeer(Port *port);
- };
- DcachePort dcachePort;
+ CpuPort dcachePort;
CpuPort physmemPort;
bool hasPhysMemPort;
// initialize CPU, including PC
TheISA::initCPU(tc, _cpuId);
}
+
+ // Initialise the ThreadContext's memory proxies
+ tcBase()->initMemProxies(tcBase());
#endif
}
drainEvent->process();
}
-void
-TimingSimpleCPU::DcachePort::setPeer(Port *port)
-{
- Port::setPeer(port);
-
-#if FULL_SYSTEM
- // Update the ThreadContext's memory ports (Functional/Virtual
- // Ports)
- cpu->tcBase()->connectMemPorts(cpu->tcBase());
-#endif
-}
-
bool
TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
{
: CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu)
{ }
- virtual void setPeer(Port *port);
-
protected:
virtual bool recvTiming(PacketPtr pkt);
#include "base/trace.hh"
#include "cpu/profile.hh"
#include "cpu/quiesce_event.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#include "sim/serialize.hh"
#include "sim/sim_exit.hh"
#else
-#include "mem/translating_port.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "sim/process.hh"
#include "sim/system.hh"
#endif
SimpleThread::~SimpleThread()
{
-#if FULL_SYSTEM
- delete physPort;
- delete virtPort;
-#endif
delete tc;
}
System *getSystemPtr() { return system; }
#if FULL_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; }
#endif
Status status() const { return _status; }
class Checkpoint;
class Decoder;
class EndQuiesceEvent;
-class TranslatingPort;
-class FunctionalPort;
-class VirtualPort;
+class SETranslatingPortProxy;
+class FSTranslatingPortProxy;
+class PortProxy;
class Process;
class System;
namespace TheISA {
#if FULL_SYSTEM
virtual TheISA::Kernel::Statistics *getKernelStats() = 0;
- virtual FunctionalPort *getPhysPort() = 0;
+ virtual PortProxy* getPhysProxy() = 0;
- virtual VirtualPort *getVirtPort() = 0;
+ virtual FSTranslatingPortProxy* getVirtProxy() = 0;
- virtual void connectMemPorts(ThreadContext *tc) = 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;
#else
- virtual TranslatingPort *getMemPort() = 0;
+ virtual SETranslatingPortProxy *getMemProxy() = 0;
virtual Process *getProcessPtr() = 0;
#endif
TheISA::Kernel::Statistics *getKernelStats()
{ return actualTC->getKernelStats(); }
- FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
+ PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
- VirtualPort *getVirtPort() { return actualTC->getVirtPort(); }
+ FSTranslatingPortProxy* getVirtProxy() { return actualTC->getVirtProxy(); }
- void connectMemPorts(ThreadContext *tc) { actualTC->connectMemPorts(tc); }
+ void initMemProxies(ThreadContext *tc) { actualTC->initMemProxies(tc); }
#else
- TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
+ SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
#endif
#include "cpu/base.hh"
#include "cpu/profile.hh"
#include "cpu/thread_state.hh"
-#include "mem/port.hh"
-#include "mem/translating_port.hh"
+#include "mem/port_proxy.hh"
+#include "mem/se_translating_port_proxy.hh"
#include "sim/serialize.hh"
+#include "sim/system.hh"
#if FULL_SYSTEM
#include "arch/kernel_stats.hh"
#include "cpu/quiesce_event.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#endif
#if FULL_SYSTEM
baseCpu(cpu), _threadId(_tid), lastActivate(0), lastSuspend(0),
#if FULL_SYSTEM
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
- kernelStats(NULL), physPort(NULL), virtPort(NULL),
+ kernelStats(NULL), physProxy(NULL), virtProxy(NULL),
#else
- port(NULL), process(_process),
+ proxy(NULL), process(_process),
#endif
funcExeInst(0), storeCondFailures(0)
{
ThreadState::~ThreadState()
{
-#if !FULL_SYSTEM
- if (port) {
- delete port->getPeer();
- delete port;
+#if FULL_SYSTEM
+ if (physProxy != NULL) {
+ delete physProxy;
+ }
+ if (virtProxy != NULL) {
+ delete virtProxy;
+ }
+#else
+ if (proxy != NULL) {
+ delete proxy;
}
#endif
}
#if FULL_SYSTEM
void
-ThreadState::connectMemPorts(ThreadContext *tc)
+ThreadState::initMemProxies(ThreadContext *tc)
{
- connectPhysPort();
- connectVirtPort(tc);
-}
-
-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);
+ // 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
}
#else
-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);
+ if (proxy != NULL)
+ return proxy;
- connectToMemFunc(port);
+ /* Use this port proxy to for syscall emulation writes to memory. */
+ proxy = new SETranslatingPortProxy(*process->system->getSystemPort(),
+ process,
+ SETranslatingPortProxy::NextPage);
- return port;
+ return proxy;
}
#endif
-
-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);
-
- func_mem_port = mem_object->getPort("functional");
- assert(func_mem_port != NULL);
-
- func_mem_port->setPeer(port);
- port->setPeer(func_mem_port);
-}
#endif
class Checkpoint;
-class Port;
-class TranslatingPort;
+class PortProxy;
+class SETranslatingPort;
+class FSTranslatingPort;
/**
* Struct for holding general thread state that is needed across CPU
Tick readLastSuspend() { return lastSuspend; }
#if FULL_SYSTEM
- void connectMemPorts(ThreadContext *tc);
-
- void connectPhysPort();
-
- void connectVirtPort(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();
TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; }
- FunctionalPort *getPhysPort() { return physPort; }
+ PortProxy* getPhysProxy() { return physProxy; }
- void setPhysPort(FunctionalPort *port) { physPort = port; }
-
- VirtualPort *getVirtPort() { return virtPort; }
+ FSTranslatingPortProxy* getVirtProxy() { return virtProxy; }
#else
Process *getProcessPtr() { return process; }
- TranslatingPort *getMemPort();
-
- void setMemPort(TranslatingPort *_port) { port = _port; }
+ SETranslatingPortProxy* getMemProxy();
#endif
/** Reads the number of instructions functionally executed and
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;
TheISA::Kernel::Statistics *kernelStats;
protected:
- /** 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 functional port, outgoing only, for functional accesse to virtual
- * addresses. */
- VirtualPort *virtPort;
+ /** A translating port proxy, outgoing only, for functional
+ * accesse to virtual addresses. */
+ FSTranslatingPortProxy* virtProxy;
#else
- TranslatingPort *port;
+ SETranslatingPortProxy* proxy;
Process *process;
#endif
#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;
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);
typedef struct statfs global_statfs;
typedef struct dirent global_dirent;
-class TranslatingPort;
+class SETranslatingPortProxy;
///
/// This class encapsulates the types, structures, constants,
/// 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;
// 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);
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;
delete [] host_buf;
*basep = htog((int64_t)host_basep);
- basep.copyOut(tc->getMemPort());
+ basep.copyOut(tc->getMemProxy());
return tgt_buf_ptr - tgt_buf;
#endif
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,
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);
process->allocateMem(rounded_stack_base, rounded_stack_size);
argp->address = gtoh(rounded_stack_base);
- argp.copyOut(tc->getMemPort());
+ argp.copyOut(tc->getMemProxy());
return 0;
}
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! "
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;
}
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! "
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);
// 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) {
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 =
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 "
// 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();
// and get away with just sticking the thread index
// here.
*kidp = htog(thread_index);
- kidp.copyOut(tc->getMemPort());
+ kidp.copyOut(tc->getMemProxy());
return 0;
}
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));
{
TypedBufferArg<uint64_t> lockp(uaddr);
- lockp.copyIn(tc->getMemPort());
+ lockp.copyIn(tc->getMemProxy());
assert(*lockp != 0);
// Check for a process waiting on the lock.
// 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());
}
}
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;
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);
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);
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);
AddrRangeIter iter;
bool found = false;
- tc->getPhysPort()->getPeerAddressRanges(resp, snoop);
+ Port* dataPort = tc->getCpuPtr()->getPort("dcache_port");
+
+ dataPort->getPeerAddressRanges(resp, snoop);
for (iter = resp.begin(); iter != resp.end(); iter++) {
if (*iter == (K0Seg2Phys(a0) & PAddrImplMask))
found = true;
Source('physical.cc')
if env['FULL_SYSTEM']:
- Source('vport.cc')
+ Source('fs_translating_port_proxy.cc')
elif env['TARGET_ISA'] != 'no':
Source('page_table.cc')
- Source('translating_port.cc')
+ Source('se_translating_port_proxy.cc')
DebugFlag('Bus')
DebugFlag('BusAddrRanges')
--- /dev/null
+/*
+ * 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.
+ *
+ * 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: Ali Saidi
+ * Andreas Hansson
+ */
+
+/**
+ * @file
+ * Port object definitions.
+ */
+
+#include "base/chunk_generator.hh"
+#include "cpu/base.hh"
+#include "cpu/thread_context.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
+FSTranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size)
+{
+ Addr paddr;
+ for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
+ gen.next())
+ {
+ if (_tc)
+ paddr = TheISA::vtophys(_tc,gen.addr());
+ else
+ paddr = TheISA::vtophys(gen.addr());
+
+ PortProxy::readBlob(paddr, p, gen.size());
+ p += gen.size();
+ }
+}
+
+void
+FSTranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size)
+{
+ Addr paddr;
+ for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
+ gen.next())
+ {
+ if (_tc)
+ paddr = TheISA::vtophys(_tc,gen.addr());
+ else
+ paddr = TheISA::vtophys(gen.addr());
+
+ 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;
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
+
+ vp->readBlob(src, dst, cplen);
+}
+
+void
+CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
+{
+ uint8_t *src = (uint8_t *)source;
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
+
+ vp->writeBlob(dest, src, cplen);
+}
+
+void
+CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
+{
+ int len = 0;
+ char *start = dst;
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
+
+ do {
+ vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
+ } while (len < maxlen && start[len++] != 0 );
+
+ dst[len] = 0;
+}
+
+void
+CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
+{
+ FSTranslatingPortProxy* vp = tc->getVirtProxy();
+ for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();
+ gen.next())
+ {
+ vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
+ src += gen.size();
+ }
+}
--- /dev/null
+/*
+ * 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.
+ *
+ * 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: Ali Saidi
+ * Andreas Hansson
+ */
+
+/**
+ * @file
+ * 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_FS_PORT_PROXY_HH__
+#define __MEM_FS_PORT_PROXY_HH__
+
+#include "arch/vtophys.hh"
+#include "mem/port_proxy.hh"
+
+/**
+ * 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 FSTranslatingPortProxy : public PortProxy
+{
+ private:
+ ThreadContext* _tc;
+
+ public:
+
+ FSTranslatingPortProxy(ThreadContext* tc);
+
+ FSTranslatingPortProxy(Port &port);
+
+ virtual ~FSTranslatingPortProxy();
+
+ /** Version of readblob that translates virt->phys and deals
+ * with page boundries. */
+ virtual void readBlob(Addr addr, uint8_t *p, int size);
+
+ /** 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_FS_PORT_PROXY_HH__
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__
+++ /dev/null
-/*
- * Copyright (c) 2006 The Regents of The University of Michigan
- * All rights reserved.
- *
- * 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: Ali Saidi
- */
-
-#include "arch/isa_traits.hh"
-#include "config/the_isa.hh"
-#include "mem/port.hh"
-#include "sim/byteswap.hh"
-
-template <typename T>
-void
-FunctionalPort::writeHtoG(Addr addr, T d)
-{
- d = TheISA::htog(d);
- writeBlob(addr, (uint8_t*)&d, sizeof(T));
-}
-
-
-template <typename T>
-T
-FunctionalPort::readGtoH(Addr addr)
-{
- T d;
- readBlob(addr, (uint8_t*)&d, sizeof(T));
- return TheISA::gtoh(d);
-}
-
--- /dev/null
+/*
+ * 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__
// 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");
--- /dev/null
+/*
+ * 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
+ */
+
+#include "mem/ruby/system/RubyPortProxy.hh"
+
+RubyPortProxy::RubyPortProxy(const RubyPortProxyParams* p) :
+ RubyPort(p) {
+}
+
+RubyPortProxy::~RubyPortProxy()
+{
+}
+
+void
+RubyPortProxy::init()
+{
+ // Merely override to not care about the m_controller being NULL
+}
+
+RequestStatus
+RubyPortProxy::makeRequest(PacketPtr pkt)
+{
+ // 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);
+}
--- /dev/null
+/*
+ * 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__
Source('MemoryNode.cc')
Source('PersistentTable.cc')
Source('RubyPort.cc')
+Source('RubyPortProxy.cc')
Source('Sequencer.cc')
Source('System.cc')
Source('TimerTable.cc')
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'
--- /dev/null
+/*
+ * 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.
+ *
+ * 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: Ron Dreslinski
+ * Steve Reinhardt
+ * Andreas Hansson
+ */
+
+#include <string>
+
+#include "base/chunk_generator.hh"
+#include "config/the_isa.hh"
+#include "mem/page_table.hh"
+#include "mem/se_translating_port_proxy.hh"
+#include "sim/process.hh"
+
+using namespace TheISA;
+
+SETranslatingPortProxy::SETranslatingPortProxy(Port& port, Process *p,
+ AllocType alloc)
+ : PortProxy(port), pTable(p->pTable), process(p),
+ allocating(alloc)
+{ }
+
+SETranslatingPortProxy::~SETranslatingPortProxy()
+{ }
+
+bool
+SETranslatingPortProxy::tryReadBlob(Addr addr, uint8_t *p, int size)
+{
+ Addr paddr;
+ int prevSize = 0;
+
+ for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
+
+ if (!pTable->translate(gen.addr(),paddr))
+ return false;
+
+ PortProxy::readBlob(paddr, p + prevSize, gen.size());
+ prevSize += gen.size();
+ }
+
+ return true;
+}
+
+void
+SETranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size)
+{
+ if (!tryReadBlob(addr, p, size))
+ fatal("readBlob(0x%x, ...) failed", addr);
+}
+
+
+bool
+SETranslatingPortProxy::tryWriteBlob(Addr addr, uint8_t *p, int size)
+{
+
+ Addr paddr;
+ int prevSize = 0;
+
+ for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
+
+ if (!pTable->translate(gen.addr(), paddr)) {
+ if (allocating == Always) {
+ process->allocateMem(roundDown(gen.addr(), VMPageSize),
+ VMPageSize);
+ } else if (allocating == NextPage) {
+ // check if we've accessed the next page on the stack
+ if (!process->fixupStackFault(gen.addr()))
+ panic("Page table fault when accessing virtual address %#x "
+ "during functional write\n", gen.addr());
+ } else {
+ return false;
+ }
+ pTable->translate(gen.addr(), paddr);
+ }
+
+ PortProxy::writeBlob(paddr, p + prevSize, gen.size());
+ prevSize += gen.size();
+ }
+
+ return true;
+}
+
+
+void
+SETranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size)
+{
+ if (!tryWriteBlob(addr, p, size))
+ fatal("writeBlob(0x%x, ...) failed", addr);
+}
+
+bool
+SETranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t val, int size)
+{
+ Addr paddr;
+
+ for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
+
+ if (!pTable->translate(gen.addr(), paddr)) {
+ if (allocating == Always) {
+ process->allocateMem(roundDown(gen.addr(), VMPageSize),
+ VMPageSize);
+ pTable->translate(gen.addr(), paddr);
+ } else {
+ return false;
+ }
+ }
+
+ PortProxy::memsetBlob(paddr, val, gen.size());
+ }
+
+ return true;
+}
+
+void
+SETranslatingPortProxy::memsetBlob(Addr addr, uint8_t val, int size)
+{
+ if (!tryMemsetBlob(addr, val, size))
+ fatal("memsetBlob(0x%x, ...) failed", addr);
+}
+
+
+bool
+SETranslatingPortProxy::tryWriteString(Addr addr, const char *str)
+{
+ Addr paddr,vaddr;
+ uint8_t c;
+
+ vaddr = addr;
+
+ do {
+ c = *str++;
+ if (!pTable->translate(vaddr++,paddr))
+ return false;
+
+ PortProxy::writeBlob(paddr, &c, 1);
+ } while (c);
+
+ return true;
+}
+
+void
+SETranslatingPortProxy::writeString(Addr addr, const char *str)
+{
+ if (!tryWriteString(addr, str))
+ fatal("writeString(0x%x, ...) failed", addr);
+}
+
+bool
+SETranslatingPortProxy::tryReadString(std::string &str, Addr addr)
+{
+ Addr paddr,vaddr;
+ uint8_t c;
+
+ vaddr = addr;
+
+ do {
+ if (!pTable->translate(vaddr++,paddr))
+ return false;
+
+ PortProxy::readBlob(paddr, &c, 1);
+ str += c;
+ } while (c);
+
+ return true;
+}
+
+void
+SETranslatingPortProxy::readString(std::string &str, Addr addr)
+{
+ if (!tryReadString(str, addr))
+ fatal("readString(0x%x, ...) failed", addr);
+}
+
--- /dev/null
+/*
+ * 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.
+ *
+ * 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: Ron Dreslinski
+ * Ali Saidi
+ * Andreas Hansson
+ */
+
+#ifndef __MEM_SE_TRANSLATING_PORT_PROXY_HH__
+#define __MEM_SE_TRANSLATING_PORT_PROXY_HH__
+
+#include "mem/page_table.hh"
+#include "mem/port_proxy.hh"
+#include "sim/process.hh"
+
+/**
+ * @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,
+ Never,
+ NextPage
+ };
+
+ private:
+ PageTable *pTable;
+ Process *process;
+ AllocType allocating;
+
+ public:
+ 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);
+ bool tryMemsetBlob(Addr addr, uint8_t val, int size);
+ bool tryWriteString(Addr addr, const char *str);
+ bool tryReadString(std::string &str, Addr addr);
+
+ virtual void readBlob(Addr addr, uint8_t *p, int size);
+ virtual void writeBlob(Addr addr, uint8_t *p, int size);
+ virtual void memsetBlob(Addr addr, uint8_t val, int size);
+
+ void writeString(Addr addr, const char *str);
+ void readString(std::string &str, Addr addr);
+};
+
+#endif // __MEM_SE_TRANSLATING_PORT_PROXY_HH__
+++ /dev/null
-/*
- * Copyright (c) 2001-2005 The Regents of The University of Michigan
- * All rights reserved.
- *
- * 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: Ron Dreslinski
- * Steve Reinhardt
- */
-
-#include <string>
-
-#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 "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)
-{ }
-
-TranslatingPort::~TranslatingPort()
-{ }
-
-bool
-TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
-{
- Addr paddr;
- int prevSize = 0;
-
- for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
-
- if (!pTable->translate(gen.addr(),paddr))
- return false;
-
- Port::readBlob(paddr, p + prevSize, gen.size());
- prevSize += gen.size();
- }
-
- return true;
-}
-
-void
-TranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
-{
- if (!tryReadBlob(addr, p, size))
- fatal("readBlob(0x%x, ...) failed", addr);
-}
-
-
-bool
-TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
-{
-
- Addr paddr;
- int prevSize = 0;
-
- for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
-
- if (!pTable->translate(gen.addr(), paddr)) {
- if (allocating == Always) {
- process->allocateMem(roundDown(gen.addr(), VMPageSize),
- VMPageSize);
- } else if (allocating == NextPage) {
- // check if we've accessed the next page on the stack
- if (!process->fixupStackFault(gen.addr()))
- panic("Page table fault when accessing virtual address %#x "
- "during functional write\n", gen.addr());
- } else {
- return false;
- }
- pTable->translate(gen.addr(), paddr);
- }
-
- Port::writeBlob(paddr, p + prevSize, gen.size());
- prevSize += gen.size();
- }
-
- return true;
-}
-
-
-void
-TranslatingPort::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)
-{
- Addr paddr;
-
- for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
-
- if (!pTable->translate(gen.addr(), paddr)) {
- if (allocating == Always) {
- process->allocateMem(roundDown(gen.addr(), VMPageSize),
- VMPageSize);
- pTable->translate(gen.addr(), paddr);
- } else {
- return false;
- }
- }
-
- Port::memsetBlob(paddr, val, gen.size());
- }
-
- return true;
-}
-
-void
-TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size)
-{
- if (!tryMemsetBlob(addr, val, size))
- fatal("memsetBlob(0x%x, ...) failed", addr);
-}
-
-
-bool
-TranslatingPort::tryWriteString(Addr addr, const char *str)
-{
- Addr paddr,vaddr;
- uint8_t c;
-
- vaddr = addr;
-
- do {
- c = *str++;
- if (!pTable->translate(vaddr++,paddr))
- return false;
-
- Port::writeBlob(paddr, &c, 1);
- } while (c);
-
- return true;
-}
-
-void
-TranslatingPort::writeString(Addr addr, const char *str)
-{
- if (!tryWriteString(addr, str))
- fatal("writeString(0x%x, ...) failed", addr);
-}
-
-bool
-TranslatingPort::tryReadString(std::string &str, Addr addr)
-{
- Addr paddr,vaddr;
- uint8_t c;
-
- vaddr = addr;
-
- do {
- if (!pTable->translate(vaddr++,paddr))
- return false;
-
- Port::readBlob(paddr, &c, 1);
- str += c;
- } while (c);
-
- return true;
-}
-
-void
-TranslatingPort::readString(std::string &str, Addr addr)
-{
- if (!tryReadString(str, addr))
- fatal("readString(0x%x, ...) failed", addr);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2001-2005 The Regents of The University of Michigan
- * All rights reserved.
- *
- * 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: Ron Dreslinski
- * Ali Saidi
- */
-
-#ifndef __MEM_TRANSLATING_PROT_HH__
-#define __MEM_TRANSLATING_PROT_HH__
-
-#include "mem/port.hh"
-
-class PageTable;
-class Process;
-
-class TranslatingPort : public FunctionalPort
-{
- public:
- enum AllocType {
- Always,
- Never,
- NextPage
- };
-
- private:
- PageTable *pTable;
- Process *process;
- AllocType allocating;
-
- public:
- TranslatingPort(const std::string &_name,
- Process *p, AllocType alloc);
- virtual ~TranslatingPort();
-
- bool tryReadBlob(Addr addr, uint8_t *p, int size);
- bool tryWriteBlob(Addr addr, uint8_t *p, int size);
- bool tryMemsetBlob(Addr addr, uint8_t val, int size);
- bool tryWriteString(Addr addr, const char *str);
- bool tryReadString(std::string &str, Addr addr);
-
- virtual void readBlob(Addr addr, uint8_t *p, int size);
- virtual void writeBlob(Addr addr, uint8_t *p, int size);
- virtual void memsetBlob(Addr addr, uint8_t val, int size);
-
- void writeString(Addr addr, const char *str);
- void readString(std::string &str, Addr addr);
-};
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2006 The Regents of The University of Michigan
- * All rights reserved.
- *
- * 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: Ali Saidi
- */
-
-/**
- * @file
- * Port object definitions.
- */
-
-#include "base/chunk_generator.hh"
-#include "config/the_isa.hh"
-#include "cpu/thread_context.hh"
-#include "mem/vport.hh"
-
-void
-VirtualPort::readBlob(Addr addr, uint8_t *p, int size)
-{
- Addr paddr;
- for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
- gen.next())
- {
- if (tc)
- paddr = TheISA::vtophys(tc,gen.addr());
- else
- paddr = TheISA::vtophys(gen.addr());
-
- FunctionalPort::readBlob(paddr, p, gen.size());
- p += gen.size();
- }
-}
-
-void
-VirtualPort::writeBlob(Addr addr, uint8_t *p, int size)
-{
- Addr paddr;
- for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
- gen.next())
- {
- if (tc)
- paddr = TheISA::vtophys(tc,gen.addr());
- else
- paddr = TheISA::vtophys(gen.addr());
-
- FunctionalPort::writeBlob(paddr, p, gen.size());
- p += gen.size();
- }
-}
-
-void
-CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
-{
- uint8_t *dst = (uint8_t *)dest;
- VirtualPort *vp = tc->getVirtPort();
-
- vp->readBlob(src, dst, cplen);
-}
-
-void
-CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
-{
- uint8_t *src = (uint8_t *)source;
- VirtualPort *vp = tc->getVirtPort();
-
- vp->writeBlob(dest, src, cplen);
-}
-
-void
-CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
-{
- int len = 0;
- char *start = dst;
- VirtualPort *vp = tc->getVirtPort();
-
- do {
- vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
- } while (len < maxlen && start[len++] != 0 );
-
- dst[len] = 0;
-}
-
-void
-CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
-{
- VirtualPort *vp = tc->getVirtPort();
- for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();
- gen.next())
- {
- vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
- src += gen.size();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2006 The Regents of The University of Michigan
- * All rights reserved.
- *
- * 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: Ali Saidi
- */
-
-/**
- * @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.
- */
-
-#ifndef __MEM_VPORT_HH__
-#define __MEM_VPORT_HH__
-
-#include "arch/vtophys.hh"
-#include "config/full_system.hh"
-#include "mem/port_impl.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).
- */
-
-
-class VirtualPort : public FunctionalPort
-{
- private:
- 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; }
-
- /** Version of readblob that translates virt->phys and deals
- * with page boundries. */
- virtual void readBlob(Addr addr, uint8_t *p, int size);
-
- /** Version of writeBlob that translates virt->phys and deals
- * with page boundries. */
- virtual void writeBlob(Addr addr, uint8_t *p, 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__
-
#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;
#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"
// 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
class SyscallDesc;
class System;
class ThreadContext;
-class TranslatingPort;
+class SETranslatingPortProxy;
template<class IntType>
struct AuxVector
protected:
/// Memory object for initialization (image loading)
- TranslatingPort *initVirtMem;
+ SETranslatingPortProxy *initVirtMem;
public:
PageTable *pTable;
#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.
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));
}
// 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);
int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
if (bytes_read != -1)
- bufArg.copyOut(tc->getMemPort());
+ bufArg.copyOut(tc->getMemProxy());
return bytes_read;
}
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);
// 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;
}
strncpy((char *)name.bufferPtr(), hostname, name_len);
- name.copyOut(tc->getMemPort());
+ name.copyOut(tc->getMemProxy());
return 0;
}
}
}
- buf.copyOut(tc->getMemPort());
+ buf.copyOut(tc->getMemProxy());
return (result == -1) ? -errno : result;
}
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
int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
- buf.copyOut(tc->getMemPort());
+ buf.copyOut(tc->getMemProxy());
return (result == -1) ? -errno : result;
}
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
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
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
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);
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);
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 */
#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/system.hh"
//
// 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
}
//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;
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;
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index)))
return -EFAULT;
sysinfo->uptime=seconds_since_epoch;
sysinfo->totalram=process->system->memSize();
- sysinfo.copyOut(tc->getMemPort());
+ sysinfo.copyOut(tc->getMemProxy());
return 0;
}
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+ copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
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);
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+ copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
+ copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (fd == 1));
return 0;
}
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+ copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
if (result < 0)
return -errno;
- copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
+ copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
if (result < 0)
return -errno;
- copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
+ copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (fd == 1));
return 0;
}
std::string path;
int index = 0;
- if (!tc->getMemPort()->tryReadString(path,
+ if (!tc->getMemProxy()->tryReadString(path,
process->getSyscallArg(tc, index))) {
return -EFAULT;
}
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
+ OS::copyOutStatfsBuf(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
+ OS::copyOutStatfsBuf(tc->getMemProxy(), bufPtr, &hostBuf);
return 0;
}
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];
break;
}
- rlp.copyOut(tc->getMemPort());
+ rlp.copyOut(tc->getMemProxy());
return 0;
}
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;
}
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)
who);
}
- rup.copyOut(tc->getMemPort());
+ rup.copyOut(tc->getMemProxy());
return 0;
}
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;
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;
#if FULL_SYSTEM
#include "arch/vtophys.hh"
#include "kern/kernel_stats.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
#else
#include "params/System.hh"
#endif
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");
- }
-#endif // FULL_SYSTEM
-
- // increment the number of running systms
- numSystemsRunning++;
-
- activeCpus.clear();
+ physProxy = new PortProxy(*getSystemPort());
+ virtProxy = new FSTranslatingPortProxy(*getSystemPort());
+#endif
}
System::~System()
delete workItemStats[j];
}
+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)
{
void
System::initState()
{
+ // Moved from the constructor to here since it relies on the
+ // address map being resolved in the interconnect
+#if FULL_SYSTEM
+ /**
+ * 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");
+ }
+#endif // FULL_SYSTEM
+
+ // increment the number of running systms
+ numSystemsRunning++;
+
+ activeCpus.clear();
+
#if FULL_SYSTEM
int i;
for (i = 0; i < threadContexts.size(); i++)
#if FULL_SYSTEM
class Platform;
-class FunctionalPort;
-class VirtualPort;
+class PortProxy;
+class FSTranslatingPortProxy;
#endif
class GDBListener;
class BaseRemoteGDB;
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
/** 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;
#include "arch/isa_traits.hh"
#include "arch/vtophys.hh"
-#include "mem/vport.hh"
+#include "mem/fs_translating_port_proxy.hh"
class ThreadContext;
if (!ptr)
return;
- VirtualPort *port = tc->getVirtPort();
- port->readBlob(ptr, buffer, sizeof(T));
+ FSTranslatingPortProxy* proxy = tc->getVirtProxy();
+ proxy->readBlob(ptr, buffer, sizeof(T));
}
bool
system = System(cpu = cpu,
physmem = PhysicalMemory(),
membus = Bus())
+system.system_port = system.membus.port
system.physmem.port = system.membus.port
cpu.connectAllPorts(system.membus)
#
ruby_port.access_phys_mem = False
+
+# Connect the system port for loading of binaries etc
+system.system_port = system.ruby._sys_port_proxy.port
+
# -----------------------
# run simulation
# -----------------------
cpu.l1c.mem_side = system.toL2Bus.port
system.funcmem.port = cpu.functional
+system.system_port = system.membus.port
+
# connect memory to membus
system.physmem.port = system.membus.port
# connect memory to membus
system.physmem.port = system.membus.port
+# connect system port to membus
+system.system_port = system.membus.port
# -----------------------
# run simulation
system = System(cpu = cpu,
physmem = PhysicalMemory(),
membus = Bus())
+system.system_port = system.membus.port
system.physmem.port = system.membus.port
cpu.connectAllPorts(system.membus)
#
ruby_port.access_phys_mem = False
+# Connect the system port for loading of binaries etc
+system.system_port = system.ruby._sys_port_proxy.port
+
# -----------------------
# run simulation
# -----------------------
# connect memory to membus
system.physmem.port = system.membus.port
+# connect system port to membus
+system.system_port = system.membus.port
# -----------------------
# run simulation
system = System(cpu = AtomicSimpleCPU(cpu_id=0),
physmem = PhysicalMemory(),
membus = Bus())
+system.system_port = system.membus.port
system.physmem.port = system.membus.port
system.cpu.connectAllPorts(system.membus)
system.cpu.clock = '2GHz'
cpu.icache_port = system.ruby._cpu_ruby_ports[i].port
cpu.dcache_port = system.ruby._cpu_ruby_ports[i].port
+# Connect the system port for loading of binaries etc
+system.system_port = system.ruby._sys_port_proxy.port
+
# -----------------------
# run simulation
# -----------------------
cpu.connectAllPorts(system.toL2Bus, system.membus)
cpu.clock = '2GHz'
+system.system_port = system.membus.port
+
# connect memory to membus
system.physmem.port = system.membus.port
cpu.icache_port = system.ruby._cpu_ruby_ports[0].port
cpu.dcache_port = system.ruby._cpu_ruby_ports[0].port
+# Connect the system port for loading of binaries etc
+system.system_port = system.ruby._sys_port_proxy.port
+
# -----------------------
# run simulation
# -----------------------
system = System(cpu = cpu,
physmem = PhysicalMemory(),
membus = Bus())
+system.system_port = system.membus.port
system.physmem.port = system.membus.port
cpu.connectAllPorts(system.membus)
cpu.clock = '2GHz'