MEM: Add port proxies instead of non-structural ports
Port proxies are used to replace non-structural ports, and thus enable all ports in the system to correspond to a structural entity. This has the advantage of accessing memory through the normal memory subsystem and thus allowing any constellation of distributed memories, address maps, etc. Most accesses are done through the "system port" that is used for loading binaries, debugging etc. For the entities that belong to the CPU, e.g. threads and thread contexts, they wrap the CPU data port in a port proxy. The following replacements are made: FunctionalPort > PortProxy TranslatingPort > SETranslatingPortProxy VirtualPort > FSTranslatingPortProxy --HG-- rename : src/mem/vport.cc => src/mem/fs_translating_port_proxy.cc rename : src/mem/vport.hh => src/mem/fs_translating_port_proxy.hh rename : src/mem/translating_port.cc => src/mem/se_translating_port_proxy.cc rename : src/mem/translating_port.hh => src/mem/se_translating_port_proxy.hh
This commit is contained in:
parent
06c39a154c
commit
f85286b3de
115 changed files with 1255 additions and 934 deletions
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2010 ARM Limited
|
# Copyright (c) 2010-2012 ARM Limited
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# The license below extends only to copyright in the software and shall
|
# The license below extends only to copyright in the software and shall
|
||||||
|
@ -91,6 +91,8 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
||||||
self.console = binary('console')
|
self.console = binary('console')
|
||||||
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
||||||
|
|
||||||
|
self.system_port = self.membus.port
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
|
def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
|
||||||
|
@ -183,6 +185,8 @@ def makeSparcSystem(mem_mode, mdesc = None):
|
||||||
self.hypervisor_desc_bin = binary('1up-hv.bin')
|
self.hypervisor_desc_bin = binary('1up-hv.bin')
|
||||||
self.partition_desc_bin = binary('1up-md.bin')
|
self.partition_desc_bin = binary('1up-md.bin')
|
||||||
|
|
||||||
|
self.system_port = self.membus.port
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
|
def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
|
||||||
|
@ -263,6 +267,8 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
|
||||||
self.terminal = Terminal()
|
self.terminal = Terminal()
|
||||||
self.vncserver = VncServer()
|
self.vncserver = VncServer()
|
||||||
|
|
||||||
|
self.system_port = self.membus.port
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
@ -301,6 +307,8 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
||||||
self.console = binary('mips/console')
|
self.console = binary('mips/console')
|
||||||
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
self.boot_osflags = 'root=/dev/hda1 console=ttyS0'
|
||||||
|
|
||||||
|
self.system_port = self.membus.port
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def x86IOAddress(port):
|
def x86IOAddress(port):
|
||||||
|
@ -320,6 +328,8 @@ def connectX86ClassicSystem(x86_sys):
|
||||||
# connect the io bus
|
# connect the io bus
|
||||||
x86_sys.pc.attachIO(x86_sys.iobus)
|
x86_sys.pc.attachIO(x86_sys.iobus)
|
||||||
|
|
||||||
|
x86_sys.system_port = x86_sys.membus.port
|
||||||
|
|
||||||
def connectX86RubySystem(x86_sys):
|
def connectX86RubySystem(x86_sys):
|
||||||
# North Bridge
|
# North Bridge
|
||||||
x86_sys.piobus = Bus(bus_id=0)
|
x86_sys.piobus = Bus(bus_id=0)
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
# 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
|
# Copyright (c) 2006-2008 The Regents of The University of Michigan
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
|
@ -179,7 +191,9 @@ if options.ruby:
|
||||||
options.use_map = True
|
options.use_map = True
|
||||||
Ruby.create_system(options, system)
|
Ruby.create_system(options, system)
|
||||||
assert(options.num_cpus == len(system.ruby._cpu_ruby_ports))
|
assert(options.num_cpus == len(system.ruby._cpu_ruby_ports))
|
||||||
|
system.system_port = system.ruby._sys_port_proxy.port
|
||||||
else:
|
else:
|
||||||
|
system.system_port = system.membus.port
|
||||||
system.physmem.port = system.membus.port
|
system.physmem.port = system.membus.port
|
||||||
CacheConfig.config_cache(options, system)
|
CacheConfig.config_cache(options, system)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
# 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) 2006-2007 The Regents of The University of Michigan
|
||||||
# Copyright (c) 2009 Advanced Micro Devices, Inc.
|
# Copyright (c) 2009 Advanced Micro Devices, Inc.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
@ -82,6 +94,17 @@ def create_system(options, system, piobus = None, dma_devices = []):
|
||||||
print "Error: could not create sytem for ruby protocol %s" % protocol
|
print "Error: could not create sytem for ruby protocol %s" % protocol
|
||||||
raise
|
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
|
# Set the network classes based on the command line options
|
||||||
#
|
#
|
||||||
|
@ -159,4 +182,5 @@ def create_system(options, system, piobus = None, dma_devices = []):
|
||||||
ruby.profiler = ruby_profiler
|
ruby.profiler = ruby_profiler
|
||||||
ruby.mem_size = total_mem_size
|
ruby.mem_size = total_mem_size
|
||||||
ruby._cpu_ruby_ports = cpu_sequencers
|
ruby._cpu_ruby_ports = cpu_sequencers
|
||||||
|
ruby._sys_port_proxy = sys_port_proxy
|
||||||
ruby.random_seed = options.random_seed
|
ruby.random_seed = options.random_seed
|
||||||
|
|
|
@ -41,9 +41,7 @@
|
||||||
#include "arch/vtophys.hh"
|
#include "arch/vtophys.hh"
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "mem/port.hh"
|
|
||||||
#include "mem/vport.hh"
|
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
#define TIMER_FREQUENCY 1193180
|
#define TIMER_FREQUENCY 1193180
|
||||||
|
@ -78,8 +76,8 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
|
||||||
ppc_vaddr = (Addr)tc->readIntReg(17);
|
ppc_vaddr = (Addr)tc->readIntReg(17);
|
||||||
timer_vaddr = (Addr)tc->readIntReg(18);
|
timer_vaddr = (Addr)tc->readIntReg(18);
|
||||||
|
|
||||||
virtPort->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
|
virtProxy->write(ppc_vaddr, (uint32_t)SimClock::Frequency);
|
||||||
virtPort->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
virtProxy->write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -56,7 +56,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "alpha");
|
strcpy(name->machine, "alpha");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// I don't think this exactly matches the HW FPCR
|
||||||
*fpcr = 0;
|
*fpcr = 0;
|
||||||
fpcr.copyOut(tc->getMemPort());
|
fpcr.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
case 14: { // SSI_IEEE_FP_CONTROL
|
case 14: { // SSI_IEEE_FP_CONTROL
|
||||||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// 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): "
|
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
||||||
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -64,6 +64,17 @@ using namespace Linux;
|
||||||
LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
||||||
: AlphaSystem(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;
|
Addr addr = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,8 +89,9 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
||||||
* Since we aren't using a bootloader, we have to copy the
|
* Since we aren't using a bootloader, we have to copy the
|
||||||
* kernel arguments directly into the kernel's memory.
|
* kernel arguments directly into the kernel's memory.
|
||||||
*/
|
*/
|
||||||
virtPort->writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
|
virtProxy->writeBlob(CommandLine(),
|
||||||
params()->boot_osflags.length()+1);
|
(uint8_t*)params()->boot_osflags.c_str(),
|
||||||
|
params()->boot_osflags.length()+1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find the address of the est_cycle_freq variable and insert it
|
* find the address of the est_cycle_freq variable and insert it
|
||||||
|
@ -87,8 +99,8 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
||||||
* calculated it by using the PIT, RTC, etc.
|
* calculated it by using the PIT, RTC, etc.
|
||||||
*/
|
*/
|
||||||
if (kernelSymtab->findAddress("est_cycle_freq", addr))
|
if (kernelSymtab->findAddress("est_cycle_freq", addr))
|
||||||
virtPort->write(addr, (uint64_t)(SimClock::Frequency /
|
virtProxy->write(addr, (uint64_t)(SimClock::Frequency /
|
||||||
p->boot_cpu_frequency));
|
params()->boot_cpu_frequency));
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,7 +110,7 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
|
||||||
* 255 ASNs.
|
* 255 ASNs.
|
||||||
*/
|
*/
|
||||||
if (kernelSymtab->findAddress("dp264_mv", addr))
|
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
|
else
|
||||||
panic("could not find dp264_mv\n");
|
panic("could not find dp264_mv\n");
|
||||||
|
|
||||||
|
@ -165,9 +177,9 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
|
||||||
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
|
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
|
||||||
Tick cpuFreq = tc->getCpuPtr()->frequency();
|
Tick cpuFreq = tc->getCpuPtr()->frequency();
|
||||||
Tick intrFreq = platform->intrFrequency();
|
Tick intrFreq = platform->intrFrequency();
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,11 @@ class LinuxAlphaSystem : public AlphaSystem
|
||||||
LinuxAlphaSystem(Params *p);
|
LinuxAlphaSystem(Params *p);
|
||||||
~LinuxAlphaSystem();
|
~LinuxAlphaSystem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the system
|
||||||
|
*/
|
||||||
|
virtual void initState();
|
||||||
|
|
||||||
void setDelayLoop(ThreadContext *tc);
|
void setDelayLoop(ThreadContext *tc);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ class ThreadInfo
|
||||||
if (!addr)
|
if (!addr)
|
||||||
addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
|
addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
|
||||||
|
|
||||||
FunctionalPort *p = tc->getPhysPort();
|
PortProxy* p = tc->getPhysProxy();
|
||||||
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
||||||
|
|
||||||
return sp & ~ULL(0x3fff);
|
return sp & ~ULL(0x3fff);
|
||||||
|
|
|
@ -192,7 +192,7 @@ RemoteGDB::acc(Addr va, size_t len)
|
||||||
|
|
||||||
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
|
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
|
||||||
PageTableEntry pte =
|
PageTableEntry pte =
|
||||||
kernel_pte_lookup(context->getPhysPort(), ptbr, va);
|
kernel_pte_lookup(context->getPhysProxy(), ptbr, va);
|
||||||
if (!pte.valid()) {
|
if (!pte.valid()) {
|
||||||
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
|
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -48,7 +48,7 @@ ProcessInfo::ProcessInfo(ThreadContext *_tc)
|
||||||
: tc(_tc)
|
: tc(_tc)
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
|
||||||
|
|
||||||
if (!symtab->findAddress("thread_info_size", addr))
|
if (!symtab->findAddress("thread_info_size", addr))
|
||||||
|
@ -81,9 +81,9 @@ ProcessInfo::task(Addr ksp) const
|
||||||
|
|
||||||
Addr tsk;
|
Addr tsk;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||||
|
|
||||||
return tsk;
|
return tsk;
|
||||||
|
@ -98,9 +98,9 @@ ProcessInfo::pid(Addr ksp) const
|
||||||
|
|
||||||
uint16_t pd;
|
uint16_t pd;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||||
|
|
||||||
return pd;
|
return pd;
|
||||||
|
|
|
@ -38,8 +38,7 @@
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "debug/Loader.hh"
|
#include "debug/Loader.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "mem/vport.hh"
|
|
||||||
#include "params/AlphaSystem.hh"
|
#include "params/AlphaSystem.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
|
@ -64,11 +63,30 @@ AlphaSystem::AlphaSystem(Params *p)
|
||||||
pal = createObjectFile(params()->pal);
|
pal = createObjectFile(params()->pal);
|
||||||
if (pal == NULL)
|
if (pal == NULL)
|
||||||
fatal("Could not load PALcode file %s", params()->pal);
|
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
|
// Load program sections into memory
|
||||||
pal->loadSections(functionalPort, loadAddrMask);
|
pal->loadSections(physProxy, loadAddrMask);
|
||||||
console->loadSections(functionalPort, loadAddrMask);
|
console->loadSections(physProxy, loadAddrMask);
|
||||||
|
|
||||||
// load symbols
|
// load symbols
|
||||||
if (!console->loadGlobalSymbols(consoleSymtab))
|
if (!console->loadGlobalSymbols(consoleSymtab))
|
||||||
|
@ -101,8 +119,8 @@ AlphaSystem::AlphaSystem(Params *p)
|
||||||
* others do.)
|
* others do.)
|
||||||
*/
|
*/
|
||||||
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
|
||||||
virtPort->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
|
virtProxy->writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
|
||||||
strlen(params()->boot_osflags.c_str()));
|
strlen(params()->boot_osflags.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,23 +130,13 @@ AlphaSystem::AlphaSystem(Params *p)
|
||||||
if (consoleSymtab->findAddress("m5_rpb", addr)) {
|
if (consoleSymtab->findAddress("m5_rpb", addr)) {
|
||||||
uint64_t data;
|
uint64_t data;
|
||||||
data = htog(params()->system_type);
|
data = htog(params()->system_type);
|
||||||
virtPort->write(addr+0x50, data);
|
virtProxy->write(addr+0x50, data);
|
||||||
data = htog(params()->system_rev);
|
data = htog(params()->system_rev);
|
||||||
virtPort->write(addr+0x58, data);
|
virtProxy->write(addr+0x58, data);
|
||||||
} else
|
} else
|
||||||
panic("could not find hwrpb\n");
|
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
|
* This function fixes up addresses that are used to match PCs for
|
||||||
* hooking simulator events on to target function executions.
|
* hooking simulator events on to target function executions.
|
||||||
|
@ -170,8 +178,8 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
|
||||||
// lda gp,Y(gp): opcode 8, Ra = 29, rb = 29
|
// lda gp,Y(gp): opcode 8, Ra = 29, rb = 29
|
||||||
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
|
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
|
||||||
|
|
||||||
uint32_t i1 = virtPort->read<uint32_t>(addr);
|
uint32_t i1 = virtProxy->read<uint32_t>(addr);
|
||||||
uint32_t i2 = virtPort->read<uint32_t>(addr + sizeof(MachInst));
|
uint32_t i2 = virtProxy->read<uint32_t>(addr + sizeof(MachInst));
|
||||||
|
|
||||||
if ((i1 & inst_mask) == gp_ldah_pattern &&
|
if ((i1 & inst_mask) == gp_ldah_pattern &&
|
||||||
(i2 & inst_mask) == gp_lda_pattern) {
|
(i2 & inst_mask) == gp_lda_pattern) {
|
||||||
|
@ -188,7 +196,7 @@ AlphaSystem::setAlphaAccess(Addr access)
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
|
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
|
||||||
virtPort->write(addr, htog(Phys2K0Seg(access)));
|
virtProxy->write(addr, htog(Phys2K0Seg(access)));
|
||||||
} else {
|
} else {
|
||||||
panic("could not find m5AlphaAccess\n");
|
panic("could not find m5AlphaAccess\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,12 @@ class AlphaSystem : public System
|
||||||
~AlphaSystem();
|
~AlphaSystem();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the state of the system.
|
||||||
|
*/
|
||||||
|
virtual void initState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialization stuff
|
* Serialization stuff
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "732");
|
strcpy(name->version, "732");
|
||||||
strcpy(name->machine, "alpha");
|
strcpy(name->machine, "alpha");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,21 +74,21 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
case AlphaTru64::GSI_MAX_CPU: {
|
case AlphaTru64::GSI_MAX_CPU: {
|
||||||
TypedBufferArg<uint32_t> max_cpu(bufPtr);
|
TypedBufferArg<uint32_t> max_cpu(bufPtr);
|
||||||
*max_cpu = htog((uint32_t)process->numCpus());
|
*max_cpu = htog((uint32_t)process->numCpus());
|
||||||
max_cpu.copyOut(tc->getMemPort());
|
max_cpu.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_CPUS_IN_BOX: {
|
case AlphaTru64::GSI_CPUS_IN_BOX: {
|
||||||
TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
|
TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
|
||||||
*cpus_in_box = htog((uint32_t)process->numCpus());
|
*cpus_in_box = htog((uint32_t)process->numCpus());
|
||||||
cpus_in_box.copyOut(tc->getMemPort());
|
cpus_in_box.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_PHYSMEM: {
|
case AlphaTru64::GSI_PHYSMEM: {
|
||||||
TypedBufferArg<uint64_t> physmem(bufPtr);
|
TypedBufferArg<uint64_t> physmem(bufPtr);
|
||||||
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
|
||||||
physmem.copyOut(tc->getMemPort());
|
physmem.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,14 +105,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
infop->cpu_ex_binding = htog(0);
|
infop->cpu_ex_binding = htog(0);
|
||||||
infop->mhz = htog(667);
|
infop->mhz = htog(667);
|
||||||
|
|
||||||
infop.copyOut(tc->getMemPort());
|
infop.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_PROC_TYPE: {
|
case AlphaTru64::GSI_PROC_TYPE: {
|
||||||
TypedBufferArg<uint64_t> proc_type(bufPtr);
|
TypedBufferArg<uint64_t> proc_type(bufPtr);
|
||||||
*proc_type = htog((uint64_t)11);
|
*proc_type = htog((uint64_t)11);
|
||||||
proc_type.copyOut(tc->getMemPort());
|
proc_type.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,14 +121,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strncpy((char *)bufArg.bufferPtr(),
|
strncpy((char *)bufArg.bufferPtr(),
|
||||||
"COMPAQ Professional Workstation XP1000",
|
"COMPAQ Professional Workstation XP1000",
|
||||||
nbytes);
|
nbytes);
|
||||||
bufArg.copyOut(tc->getMemPort());
|
bufArg.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AlphaTru64::GSI_CLK_TCK: {
|
case AlphaTru64::GSI_CLK_TCK: {
|
||||||
TypedBufferArg<uint64_t> clk_hz(bufPtr);
|
TypedBufferArg<uint64_t> clk_hz(bufPtr);
|
||||||
*clk_hz = htog((uint64_t)1024);
|
*clk_hz = htog((uint64_t)1024);
|
||||||
clk_hz.copyOut(tc->getMemPort());
|
clk_hz.copyOut(tc->getMemProxy());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
elp->si_phz = htog(clk_hz);
|
elp->si_phz = htog(clk_hz);
|
||||||
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
|
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
|
||||||
elp->si_max_procs = htog(process->numCpus());
|
elp->si_max_procs = htog(process->numCpus());
|
||||||
elp.copyOut(tc->getMemPort());
|
elp.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,7 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "kern/tru64/tru64_events.hh"
|
#include "kern/tru64/tru64_events.hh"
|
||||||
#include "kern/system_events.hh"
|
#include "kern/system_events.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "mem/port.hh"
|
|
||||||
#include "mem/vport.hh"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -49,7 +47,7 @@ Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p)
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
|
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
|
||||||
virtPort->write(addr, (uint32_t)0);
|
virtProxy->write(addr, (uint32_t)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
#include "arch/alpha/vtophys.hh"
|
#include "arch/alpha/vtophys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace AlphaISA {
|
namespace AlphaISA {
|
||||||
|
@ -50,7 +50,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||||
return tc->readIntReg(16 + number);
|
return tc->readIntReg(16 + number);
|
||||||
} else {
|
} else {
|
||||||
Addr sp = tc->readIntReg(StackPointerReg);
|
Addr sp = tc->readIntReg(StackPointerReg);
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
uint64_t arg = vp->read<uint64_t>(sp +
|
uint64_t arg = vp->read<uint64_t>(sp +
|
||||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||||
return arg;
|
return arg;
|
||||||
|
|
|
@ -38,14 +38,14 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/VtoPhys.hh"
|
#include "debug/VtoPhys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace AlphaISA {
|
namespace AlphaISA {
|
||||||
|
|
||||||
PageTableEntry
|
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();
|
Addr level1_pte = ptbr + vaddr.level1();
|
||||||
PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
|
PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
|
||||||
|
@ -103,7 +103,7 @@ vtophys(ThreadContext *tc, Addr addr)
|
||||||
paddr = vaddr;
|
paddr = vaddr;
|
||||||
} else {
|
} else {
|
||||||
PageTableEntry pte =
|
PageTableEntry pte =
|
||||||
kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
|
kernel_pte_lookup(tc->getPhysProxy(), ptbr, vaddr);
|
||||||
if (pte.valid())
|
if (pte.valid())
|
||||||
paddr = pte.paddr() | vaddr.offset();
|
paddr = pte.paddr() | vaddr.offset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,11 +37,11 @@
|
||||||
#include "arch/alpha/utility.hh"
|
#include "arch/alpha/utility.hh"
|
||||||
|
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
class FunctionalPort;
|
class PortProxy;
|
||||||
|
|
||||||
namespace AlphaISA {
|
namespace AlphaISA {
|
||||||
|
|
||||||
PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr,
|
PageTableEntry kernel_pte_lookup(PortProxy* mem, Addr ptbr,
|
||||||
VAddr vaddr);
|
VAddr vaddr);
|
||||||
|
|
||||||
Addr vtophys(Addr vaddr);
|
Addr vtophys(Addr vaddr);
|
||||||
|
|
|
@ -70,7 +70,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "armv7l");
|
strcpy(name->machine, "armv7l");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
int index = 0;
|
int index = 0;
|
||||||
uint32_t tlsPtr = process->getSyscallArg(tc, index);
|
uint32_t tlsPtr = process->getSyscallArg(tc, index);
|
||||||
|
|
||||||
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
|
tc->getMemProxy()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
|
||||||
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
|
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
|
||||||
tc->setMiscReg(MISCREG_TPIDRURO,tlsPtr);
|
tc->setMiscReg(MISCREG_TPIDRURO,tlsPtr);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -512,7 +512,7 @@ ArmLinuxProcess::initState()
|
||||||
|
|
||||||
// Fill this page with swi -1 so we'll no if we land in it somewhere.
|
// 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)) {
|
for (Addr addr = 0; addr < PageBytes; addr += sizeof(swiNeg1)) {
|
||||||
tc->getMemPort()->writeBlob(commPage + addr,
|
tc->getMemProxy()->writeBlob(commPage + addr,
|
||||||
swiNeg1, sizeof(swiNeg1));
|
swiNeg1, sizeof(swiNeg1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,7 +521,7 @@ ArmLinuxProcess::initState()
|
||||||
0x5f, 0xf0, 0x7f, 0xf5, // dmb
|
0x5f, 0xf0, 0x7f, 0xf5, // dmb
|
||||||
0x0e, 0xf0, 0xa0, 0xe1 // return
|
0x0e, 0xf0, 0xa0, 0xe1 // return
|
||||||
};
|
};
|
||||||
tc->getMemPort()->writeBlob(commPage + 0x0fa0, memory_barrier,
|
tc->getMemProxy()->writeBlob(commPage + 0x0fa0, memory_barrier,
|
||||||
sizeof(memory_barrier));
|
sizeof(memory_barrier));
|
||||||
|
|
||||||
uint8_t cmpxchg[] =
|
uint8_t cmpxchg[] =
|
||||||
|
@ -535,7 +535,7 @@ ArmLinuxProcess::initState()
|
||||||
0x5f, 0xf0, 0x7f, 0xf5, // dmb
|
0x5f, 0xf0, 0x7f, 0xf5, // dmb
|
||||||
0x0e, 0xf0, 0xa0, 0xe1 // return
|
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[] =
|
uint8_t get_tls[] =
|
||||||
{
|
{
|
||||||
|
@ -543,7 +543,7 @@ ArmLinuxProcess::initState()
|
||||||
0x70, 0x0f, 0x1d, 0xee, // mrc p15, 0, r0, c13, c0, 3
|
0x70, 0x0f, 0x1d, 0xee, // mrc p15, 0, r0, c13, c0, 3
|
||||||
0x0e, 0xf0, 0xa0, 0xe1 // return
|
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
|
ArmISA::IntReg
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/Loader.hh"
|
#include "debug/Loader.hh"
|
||||||
#include "kern/linux/events.hh"
|
#include "kern/linux/events.hh"
|
||||||
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/physical.hh"
|
||||||
|
|
||||||
using namespace ArmISA;
|
using namespace ArmISA;
|
||||||
|
@ -57,6 +58,27 @@ using namespace Linux;
|
||||||
LinuxArmSystem::LinuxArmSystem(Params *p)
|
LinuxArmSystem::LinuxArmSystem(Params *p)
|
||||||
: ArmSystem(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
|
// Load symbols at physical address, we might not want
|
||||||
// to do this perminately, for but early bootup work
|
// to do this perminately, for but early bootup work
|
||||||
// it is helpfulp.
|
// it is helpfulp.
|
||||||
|
@ -92,7 +114,7 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
|
||||||
DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
|
DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
|
||||||
DDUMP(Loader, boot_data, size << 2);
|
DDUMP(Loader, boot_data, size << 2);
|
||||||
|
|
||||||
functionalPort->writeBlob(ParamsList, boot_data, size << 2);
|
physProxy->writeBlob(ParamsList, boot_data, size << 2);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
|
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
|
||||||
|
@ -128,22 +150,6 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
|
||||||
secDataPtrAddr &= ~ULL(0x7F);
|
secDataPtrAddr &= ~ULL(0x7F);
|
||||||
secDataAddr &= ~ULL(0x7F);
|
secDataAddr &= ~ULL(0x7F);
|
||||||
penReleaseAddr &= ~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++) {
|
for (int i = 0; i < threadContexts.size(); i++) {
|
||||||
threadContexts[i]->setIntReg(0, 0);
|
threadContexts[i]->setIntReg(0, 0);
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/Stack.hh"
|
#include "debug/Stack.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
#include "sim/process_impl.hh"
|
#include "sim/process_impl.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -48,9 +48,9 @@ namespace ArmISA
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
|
|
||||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
||||||
panic("thread info not compiled into kernel\n");
|
panic("thread info not compiled into kernel\n");
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/physical.hh"
|
||||||
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Linux;
|
using namespace Linux;
|
||||||
|
@ -55,6 +56,18 @@ ArmSystem::ArmSystem(Params *p)
|
||||||
: System(p), bootldr(NULL)
|
: System(p), bootldr(NULL)
|
||||||
{
|
{
|
||||||
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
|
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))
|
if ((p->boot_loader == "") != (p->boot_loader_mem == NULL))
|
||||||
fatal("If boot_loader is specifed, memory to load it must be also.\n");
|
fatal("If boot_loader is specifed, memory to load it must be also.\n");
|
||||||
|
@ -65,29 +78,18 @@ ArmSystem::ArmSystem(Params *p)
|
||||||
if (!bootldr)
|
if (!bootldr)
|
||||||
fatal("Could not read bootloader: %s\n", p->boot_loader);
|
fatal("Could not read bootloader: %s\n", p->boot_loader);
|
||||||
|
|
||||||
Port *mem_port;
|
bootldr->loadSections(physProxy);
|
||||||
FunctionalPort fp(name() + "-fport");
|
|
||||||
mem_port = p->boot_loader_mem->getPort("functional");
|
|
||||||
fp.setPeer(mem_port);
|
|
||||||
mem_port->setPeer(&fp);
|
|
||||||
|
|
||||||
bootldr->loadSections(&fp);
|
|
||||||
bootldr->loadGlobalSymbols(debugSymbolTable);
|
bootldr->loadGlobalSymbols(debugSymbolTable);
|
||||||
|
|
||||||
uint8_t jump_to_bl[] =
|
uint8_t jump_to_bl[] =
|
||||||
{
|
{
|
||||||
0x07, 0xf0, 0xa0, 0xe1 // branch to r7
|
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());
|
inform("Using bootloader at address %#x\n", bootldr->entryPoint());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ArmSystem::initState()
|
|
||||||
{
|
|
||||||
System::initState();
|
|
||||||
if (bootldr) {
|
if (bootldr) {
|
||||||
// Put the address of the boot loader into r7 so we know
|
// Put the address of the boot loader into r7 so we know
|
||||||
// where to branch to after the reset fault
|
// where to branch to after the reset fault
|
||||||
|
@ -98,16 +100,16 @@ ArmSystem::initState()
|
||||||
threadContexts[i]->setIntReg(5, params()->flags_addr);
|
threadContexts[i]->setIntReg(5, params()->flags_addr);
|
||||||
threadContexts[i]->setIntReg(7, bootldr->entryPoint());
|
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");
|
fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
|
||||||
} else {
|
} else {
|
||||||
// Set the initial PC to be at start of the kernel code
|
// Set the initial PC to be at start of the kernel code
|
||||||
threadContexts[0]->pcState(kernelEntry & loadAddrMask);
|
threadContexts[0]->pcState(kernelEntry & loadAddrMask);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < threadContexts.size(); i++) {
|
for (int i = 0; i < threadContexts.size(); i++) {
|
||||||
if (params()->midr_regval) {
|
if (p->midr_regval) {
|
||||||
threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
|
threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
|
||||||
params()->midr_regval);
|
p->midr_regval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,10 @@ class ArmSystem : public System
|
||||||
ArmSystem(Params *p);
|
ArmSystem(Params *p);
|
||||||
~ArmSystem();
|
~ArmSystem();
|
||||||
|
|
||||||
void initState();
|
/**
|
||||||
|
* Initialise the system
|
||||||
|
*/
|
||||||
|
virtual void initState();
|
||||||
|
|
||||||
/** Check if an address should be uncacheable until all caches are enabled.
|
/** Check if an address should be uncacheable until all caches are enabled.
|
||||||
* This exits because coherence on some addresses at boot is maintained via
|
* This exits because coherence on some addresses at boot is maintained via
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
#include "arch/arm/vtophys.hh"
|
#include "arch/arm/vtophys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "arch/arm/tlb.hh"
|
#include "arch/arm/tlb.hh"
|
||||||
|
@ -89,7 +89,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Addr sp = tc->readIntReg(StackPointerReg);
|
Addr sp = tc->readIntReg(StackPointerReg);
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
uint64_t arg;
|
uint64_t arg;
|
||||||
if (size == sizeof(uint64_t)) {
|
if (size == sizeof(uint64_t)) {
|
||||||
// If the argument is even it must be aligned
|
// If the argument is even it must be aligned
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include "base/chunk_generator.hh"
|
#include "base/chunk_generator.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ArmISA;
|
using namespace ArmISA;
|
||||||
|
@ -101,7 +101,7 @@ ArmISA::vtophys(ThreadContext *tc, Addr addr)
|
||||||
N = 0;
|
N = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionalPort *port = tc->getPhysPort();
|
PortProxy* port = tc->getPhysProxy();
|
||||||
Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(addr,31-N,20) << 2);
|
Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(addr,31-N,20) << 2);
|
||||||
|
|
||||||
TableWalker::L1Descriptor l1desc;
|
TableWalker::L1Descriptor l1desc;
|
||||||
|
|
|
@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "mips");
|
strcpy(name->machine, "mips");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// I don't think this exactly matches the HW FPCR
|
||||||
*fpcr = 0;
|
*fpcr = 0;
|
||||||
fpcr.copyOut(tc->getMemPort());
|
fpcr.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -111,7 +111,7 @@ sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
// SSI_IEEE_FP_CONTROL
|
// SSI_IEEE_FP_CONTROL
|
||||||
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
TypedBufferArg<uint64_t> fpcr(bufPtr);
|
||||||
// I don't think this exactly matches the HW FPCR
|
// 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): "
|
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
|
||||||
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -157,9 +157,9 @@ LinuxMipsSystem::setDelayLoop(ThreadContext *tc)
|
||||||
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
|
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
|
||||||
Tick cpuFreq = tc->getCpuPtr()->frequency();
|
Tick cpuFreq = tc->getCpuPtr()->frequency();
|
||||||
Tick intrFreq = platform->intrFrequency();
|
Tick intrFreq = platform->intrFrequency();
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ class ThreadInfo
|
||||||
if (!addr)
|
if (!addr)
|
||||||
addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/);
|
addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/);
|
||||||
|
|
||||||
FunctionalPort *p = tc->getPhysPort();
|
PortProxy* p = tc->getPhysProxy();
|
||||||
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
|
||||||
|
|
||||||
return sp & ~ULL(0x3fff);
|
return sp & ~ULL(0x3fff);
|
||||||
|
|
|
@ -54,9 +54,9 @@ ProcessInfo::task(Addr ksp) const
|
||||||
|
|
||||||
Addr tsk;
|
Addr tsk;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||||
|
|
||||||
return tsk;
|
return tsk;
|
||||||
|
@ -71,9 +71,9 @@ ProcessInfo::pid(Addr ksp) const
|
||||||
|
|
||||||
uint16_t pd;
|
uint16_t pd;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||||
|
|
||||||
return pd;
|
return pd;
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
#include "arch/mips/registers.hh"
|
#include "arch/mips/registers.hh"
|
||||||
#include "arch/mips/vtophys.hh"
|
#include "arch/mips/vtophys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||||
return tc->readIntReg(FirstArgumentReg + number);
|
return tc->readIntReg(FirstArgumentReg + number);
|
||||||
} else {
|
} else {
|
||||||
Addr sp = tc->readIntReg(StackPointerReg);
|
Addr sp = tc->readIntReg(StackPointerReg);
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
uint64_t arg = vp->read<uint64_t>(sp +
|
uint64_t arg = vp->read<uint64_t>(sp +
|
||||||
(number - 4) * sizeof(uint64_t));
|
(number - 4) * sizeof(uint64_t));
|
||||||
return arg;
|
return arg;
|
||||||
|
|
|
@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "power");
|
strcpy(name->machine, "power");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/Stack.hh"
|
#include "debug/Stack.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "sim/process_impl.hh"
|
#include "sim/process_impl.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "sparc");
|
strcpy(name->machine, "sparc");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -69,19 +69,19 @@ getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
if (ruid) {
|
if (ruid) {
|
||||||
BufferArg ruidBuff(ruid, sizeof(IntReg));
|
BufferArg ruidBuff(ruid, sizeof(IntReg));
|
||||||
memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
|
memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||||
ruidBuff.copyOut(tc->getMemPort());
|
ruidBuff.copyOut(tc->getMemProxy());
|
||||||
}
|
}
|
||||||
// Set the euid
|
// Set the euid
|
||||||
if (euid) {
|
if (euid) {
|
||||||
BufferArg euidBuff(euid, sizeof(IntReg));
|
BufferArg euidBuff(euid, sizeof(IntReg));
|
||||||
memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
|
memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||||
euidBuff.copyOut(tc->getMemPort());
|
euidBuff.copyOut(tc->getMemProxy());
|
||||||
}
|
}
|
||||||
// Set the suid
|
// Set the suid
|
||||||
if (suid) {
|
if (suid) {
|
||||||
BufferArg suidBuff(suid, sizeof(IntReg));
|
BufferArg suidBuff(suid, sizeof(IntReg));
|
||||||
memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
|
memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
|
||||||
suidBuff.copyOut(tc->getMemPort());
|
suidBuff.copyOut(tc->getMemProxy());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/Stack.hh"
|
#include "debug/Stack.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "sim/process_impl.hh"
|
#include "sim/process_impl.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
|
@ -448,7 +447,7 @@ void Sparc32LiveProcess::flushWindows(ThreadContext *tc)
|
||||||
for (int index = 16; index < 32; index++) {
|
for (int index = 16; index < 32; index++) {
|
||||||
uint32_t regVal = tc->readIntReg(index);
|
uint32_t regVal = tc->readIntReg(index);
|
||||||
regVal = htog(regVal);
|
regVal = htog(regVal);
|
||||||
if (!tc->getMemPort()->tryWriteBlob(
|
if (!tc->getMemProxy()->tryWriteBlob(
|
||||||
sp + (index - 16) * 4, (uint8_t *)®Val, 4)) {
|
sp + (index - 16) * 4, (uint8_t *)®Val, 4)) {
|
||||||
warn("Failed to save register to the stack when "
|
warn("Failed to save register to the stack when "
|
||||||
"flushing windows.\n");
|
"flushing windows.\n");
|
||||||
|
@ -483,7 +482,7 @@ Sparc64LiveProcess::flushWindows(ThreadContext *tc)
|
||||||
for (int index = 16; index < 32; index++) {
|
for (int index = 16; index < 32; index++) {
|
||||||
IntReg regVal = tc->readIntReg(index);
|
IntReg regVal = tc->readIntReg(index);
|
||||||
regVal = htog(regVal);
|
regVal = htog(regVal);
|
||||||
if (!tc->getMemPort()->tryWriteBlob(
|
if (!tc->getMemProxy()->tryWriteBlob(
|
||||||
sp + 2047 + (index - 16) * 8, (uint8_t *)®Val, 8)) {
|
sp + 2047 + (index - 16) * 8, (uint8_t *)®Val, 8)) {
|
||||||
warn("Failed to save register to the stack when "
|
warn("Failed to save register to the stack when "
|
||||||
"flushing windows.\n");
|
"flushing windows.\n");
|
||||||
|
|
|
@ -55,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "Generic_118558-21");
|
strcpy(name->version, "Generic_118558-21");
|
||||||
strcpy(name->machine, "sun4u");
|
strcpy(name->machine, "sun4u");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,7 @@
|
||||||
using namespace BigEndianGuest;
|
using namespace BigEndianGuest;
|
||||||
|
|
||||||
SparcSystem::SparcSystem(Params *p)
|
SparcSystem::SparcSystem(Params *p)
|
||||||
: System(p), sysTick(0),funcRomPort(p->name + "-fromport"),
|
: System(p), sysTick(0)
|
||||||
funcNvramPort(p->name + "-fnvramport"),
|
|
||||||
funcHypDescPort(p->name + "-fhypdescport"),
|
|
||||||
funcPartDescPort(p->name + "-fpartdescport")
|
|
||||||
{
|
{
|
||||||
resetSymtab = new SymbolTable;
|
resetSymtab = new SymbolTable;
|
||||||
hypervisorSymtab = new SymbolTable;
|
hypervisorSymtab = new SymbolTable;
|
||||||
|
@ -51,23 +48,13 @@ SparcSystem::SparcSystem(Params *p)
|
||||||
nvramSymtab = new SymbolTable;
|
nvramSymtab = new SymbolTable;
|
||||||
hypervisorDescSymtab = new SymbolTable;
|
hypervisorDescSymtab = new SymbolTable;
|
||||||
partitionDescSymtab = new SymbolTable;
|
partitionDescSymtab = new SymbolTable;
|
||||||
|
}
|
||||||
|
|
||||||
Port *rom_port;
|
void
|
||||||
rom_port = params()->rom->getPort("functional");
|
SparcSystem::initState()
|
||||||
funcRomPort.setPeer(rom_port);
|
{
|
||||||
rom_port->setPeer(&funcRomPort);
|
// Call the initialisation of the super class
|
||||||
|
System::initState();
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the boot code, and hypervisor into memory.
|
* Load the boot code, and hypervisor into memory.
|
||||||
|
@ -107,22 +94,22 @@ SparcSystem::SparcSystem(Params *p)
|
||||||
|
|
||||||
// Load reset binary into memory
|
// Load reset binary into memory
|
||||||
reset->setTextBase(params()->reset_addr);
|
reset->setTextBase(params()->reset_addr);
|
||||||
reset->loadSections(&funcRomPort);
|
reset->loadSections(physProxy);
|
||||||
// Load the openboot binary
|
// Load the openboot binary
|
||||||
openboot->setTextBase(params()->openboot_addr);
|
openboot->setTextBase(params()->openboot_addr);
|
||||||
openboot->loadSections(&funcRomPort);
|
openboot->loadSections(physProxy);
|
||||||
// Load the hypervisor binary
|
// Load the hypervisor binary
|
||||||
hypervisor->setTextBase(params()->hypervisor_addr);
|
hypervisor->setTextBase(params()->hypervisor_addr);
|
||||||
hypervisor->loadSections(&funcRomPort);
|
hypervisor->loadSections(physProxy);
|
||||||
// Load the nvram image
|
// Load the nvram image
|
||||||
nvram->setTextBase(params()->nvram_addr);
|
nvram->setTextBase(params()->nvram_addr);
|
||||||
nvram->loadSections(&funcNvramPort);
|
nvram->loadSections(physProxy);
|
||||||
// Load the hypervisor description image
|
// Load the hypervisor description image
|
||||||
hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
|
hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
|
||||||
hypervisor_desc->loadSections(&funcHypDescPort);
|
hypervisor_desc->loadSections(physProxy);
|
||||||
// Load the partition description image
|
// Load the partition description image
|
||||||
partition_desc->setTextBase(params()->partition_desc_addr);
|
partition_desc->setTextBase(params()->partition_desc_addr);
|
||||||
partition_desc->loadSections(&funcPartDescPort);
|
partition_desc->loadSections(physProxy);
|
||||||
|
|
||||||
// load symbols
|
// load symbols
|
||||||
if (!reset->loadGlobalSymbols(resetSymtab))
|
if (!reset->loadGlobalSymbols(resetSymtab))
|
||||||
|
|
|
@ -48,6 +48,8 @@ class SparcSystem : public System
|
||||||
SparcSystem(Params *p);
|
SparcSystem(Params *p);
|
||||||
~SparcSystem();
|
~SparcSystem();
|
||||||
|
|
||||||
|
virtual void initState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialization stuff
|
* Serialization stuff
|
||||||
*/
|
*/
|
||||||
|
@ -94,18 +96,6 @@ class SparcSystem : public System
|
||||||
/** System Tick for syncronized tick across all cpus. */
|
/** System Tick for syncronized tick across all cpus. */
|
||||||
Tick sysTick;
|
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:
|
protected:
|
||||||
const Params *params() const { return (const Params *)_params; }
|
const Params *params() const { return (const Params *)_params; }
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "arch/sparc/utility.hh"
|
#include "arch/sparc/utility.hh"
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
#include "arch/sparc/vtophys.hh"
|
#include "arch/sparc/vtophys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace SparcISA {
|
namespace SparcISA {
|
||||||
|
@ -54,7 +54,7 @@ getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
|
||||||
return tc->readIntReg(8 + number);
|
return tc->readIntReg(8 + number);
|
||||||
} else {
|
} else {
|
||||||
Addr sp = tc->readIntReg(StackPointerReg);
|
Addr sp = tc->readIntReg(StackPointerReg);
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
uint64_t arg = vp->read<uint64_t>(sp + 92 +
|
uint64_t arg = vp->read<uint64_t>(sp + 92 +
|
||||||
(number-NumArgumentRegs) * sizeof(uint64_t));
|
(number-NumArgumentRegs) * sizeof(uint64_t));
|
||||||
return arg;
|
return arg;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/VtoPhys.hh"
|
#include "debug/VtoPhys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ vtophys(ThreadContext *tc, Addr addr)
|
||||||
int pri_context = bits(tlbdata,47,32);
|
int pri_context = bits(tlbdata,47,32);
|
||||||
// int sec_context = bits(tlbdata,63,48);
|
// int sec_context = bits(tlbdata,63,48);
|
||||||
|
|
||||||
FunctionalPort *mem = tc->getPhysPort();
|
PortProxy* mem = tc->getPhysProxy();
|
||||||
TLB* itb = tc->getITBPtr();
|
TLB* itb = tc->getITBPtr();
|
||||||
TLB* dtb = tc->getDTBPtr();
|
TLB* dtb = tc->getDTBPtr();
|
||||||
TlbEntry* tbe;
|
TlbEntry* tbe;
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#include "arch/x86/isa_traits.hh"
|
#include "arch/x86/isa_traits.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port_proxy.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
// Config entry types
|
// Config entry types
|
||||||
|
@ -70,10 +70,10 @@ const char X86ISA::IntelMP::FloatingPointer::signature[] = "_MP_";
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
uint8_t
|
uint8_t
|
||||||
writeOutField(FunctionalPort * port, Addr addr, T val)
|
writeOutField(PortProxy* proxy, Addr addr, T val)
|
||||||
{
|
{
|
||||||
T guestVal = X86ISA::htog(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;
|
uint8_t checkSum = 0;
|
||||||
while(guestVal) {
|
while(guestVal) {
|
||||||
|
@ -84,7 +84,7 @@ writeOutField(FunctionalPort * port, Addr addr, T val)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
writeOutString(FunctionalPort * port, Addr addr, string str, int length)
|
writeOutString(PortProxy* proxy, Addr addr, string str, int length)
|
||||||
{
|
{
|
||||||
char cleanedString[length + 1];
|
char cleanedString[length + 1];
|
||||||
cleanedString[length] = 0;
|
cleanedString[length] = 0;
|
||||||
|
@ -97,7 +97,7 @@ writeOutString(FunctionalPort * port, Addr addr, string str, int length)
|
||||||
memcpy(cleanedString, str.c_str(), str.length());
|
memcpy(cleanedString, str.c_str(), str.length());
|
||||||
memset(cleanedString + str.length(), 0, length - 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;
|
uint8_t checkSum = 0;
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
|
@ -107,7 +107,7 @@ writeOutString(FunctionalPort * port, Addr addr, string str, int length)
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr
|
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
|
// Make sure that either a config table is present or a default
|
||||||
// configuration was found but not both.
|
// configuration was found but not both.
|
||||||
|
@ -120,28 +120,28 @@ X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr)
|
||||||
|
|
||||||
uint8_t checkSum = 0;
|
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++)
|
for (int i = 0; i < 4; i++)
|
||||||
checkSum += signature[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.
|
// The length of the structure in paragraphs, aka 16 byte chunks.
|
||||||
uint8_t length = 1;
|
uint8_t length = 1;
|
||||||
port->writeBlob(addr + 8, &length, 1);
|
proxy->writeBlob(addr + 8, &length, 1);
|
||||||
checkSum += length;
|
checkSum += length;
|
||||||
|
|
||||||
port->writeBlob(addr + 9, &specRev, 1);
|
proxy->writeBlob(addr + 9, &specRev, 1);
|
||||||
checkSum += specRev;
|
checkSum += specRev;
|
||||||
|
|
||||||
port->writeBlob(addr + 11, &defaultConfig, 1);
|
proxy->writeBlob(addr + 11, &defaultConfig, 1);
|
||||||
checkSum += defaultConfig;
|
checkSum += defaultConfig;
|
||||||
|
|
||||||
uint32_t features2_5 = imcrPresent ? (1 << 7) : 0;
|
uint32_t features2_5 = imcrPresent ? (1 << 7) : 0;
|
||||||
checkSum += writeOutField(port, addr + 12, features2_5);
|
checkSum += writeOutField(proxy, addr + 12, features2_5);
|
||||||
|
|
||||||
checkSum = -checkSum;
|
checkSum = -checkSum;
|
||||||
port->writeBlob(addr + 10, &checkSum, 1);
|
proxy->writeBlob(addr + 10, &checkSum, 1);
|
||||||
|
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
@ -158,10 +158,10 @@ X86IntelMPFloatingPointerParams::create()
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::BaseConfigEntry::writeOut(FunctionalPort * port,
|
X86ISA::IntelMP::BaseConfigEntry::writeOut(PortProxy* proxy,
|
||||||
Addr addr, uint8_t &checkSum)
|
Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
port->writeBlob(addr, &type, 1);
|
proxy->writeBlob(addr, &type, 1);
|
||||||
checkSum += type;
|
checkSum += type;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -171,12 +171,12 @@ X86ISA::IntelMP::BaseConfigEntry::BaseConfigEntry(Params * p, uint8_t _type) :
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::ExtConfigEntry::writeOut(FunctionalPort * port,
|
X86ISA::IntelMP::ExtConfigEntry::writeOut(PortProxy* proxy,
|
||||||
Addr addr, uint8_t &checkSum)
|
Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
port->writeBlob(addr, &type, 1);
|
proxy->writeBlob(addr, &type, 1);
|
||||||
checkSum += type;
|
checkSum += type;
|
||||||
port->writeBlob(addr + 1, &length, 1);
|
proxy->writeBlob(addr + 1, &length, 1);
|
||||||
checkSum += length;
|
checkSum += length;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -189,59 +189,59 @@ X86ISA::IntelMP::ExtConfigEntry::ExtConfigEntry(Params * p,
|
||||||
const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP";
|
const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP";
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::ConfigTable::writeOut(FunctionalPort * port, Addr addr)
|
X86ISA::IntelMP::ConfigTable::writeOut(PortProxy* proxy, Addr addr)
|
||||||
{
|
{
|
||||||
uint8_t checkSum = 0;
|
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++)
|
for (int i = 0; i < 4; i++)
|
||||||
checkSum += signature[i];
|
checkSum += signature[i];
|
||||||
|
|
||||||
// Base table length goes here but will be calculated later.
|
// 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;
|
checkSum += specRev;
|
||||||
|
|
||||||
// The checksum goes here but is still being calculated.
|
// The checksum goes here but is still being calculated.
|
||||||
|
|
||||||
checkSum += writeOutString(port, addr + 8, oemID, 8);
|
checkSum += writeOutString(proxy, addr + 8, oemID, 8);
|
||||||
checkSum += writeOutString(port, addr + 16, productID, 12);
|
checkSum += writeOutString(proxy, addr + 16, productID, 12);
|
||||||
|
|
||||||
checkSum += writeOutField(port, addr + 28, oemTableAddr);
|
checkSum += writeOutField(proxy, addr + 28, oemTableAddr);
|
||||||
checkSum += writeOutField(port, addr + 32, oemTableSize);
|
checkSum += writeOutField(proxy, addr + 32, oemTableSize);
|
||||||
checkSum += writeOutField(port, addr + 34, (uint16_t)baseEntries.size());
|
checkSum += writeOutField(proxy, addr + 34, (uint16_t)baseEntries.size());
|
||||||
checkSum += writeOutField(port, addr + 36, localApic);
|
checkSum += writeOutField(proxy, addr + 36, localApic);
|
||||||
|
|
||||||
uint8_t reserved = 0;
|
uint8_t reserved = 0;
|
||||||
port->writeBlob(addr + 43, &reserved, 1);
|
proxy->writeBlob(addr + 43, &reserved, 1);
|
||||||
checkSum += reserved;
|
checkSum += reserved;
|
||||||
|
|
||||||
vector<BaseConfigEntry *>::iterator baseEnt;
|
vector<BaseConfigEntry *>::iterator baseEnt;
|
||||||
uint16_t offset = 44;
|
uint16_t offset = 44;
|
||||||
for (baseEnt = baseEntries.begin();
|
for (baseEnt = baseEntries.begin();
|
||||||
baseEnt != baseEntries.end(); baseEnt++) {
|
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.
|
// 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;
|
vector<ExtConfigEntry *>::iterator extEnt;
|
||||||
uint16_t extOffset = 0;
|
uint16_t extOffset = 0;
|
||||||
uint8_t extCheckSum = 0;
|
uint8_t extCheckSum = 0;
|
||||||
for (extEnt = extEntries.begin();
|
for (extEnt = extEntries.begin();
|
||||||
extEnt != extEntries.end(); extEnt++) {
|
extEnt != extEntries.end(); extEnt++) {
|
||||||
extOffset += (*extEnt)->writeOut(port,
|
extOffset += (*extEnt)->writeOut(proxy,
|
||||||
addr + offset + extOffset, extCheckSum);
|
addr + offset + extOffset, extCheckSum);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkSum += writeOutField(port, addr + 40, extOffset);
|
checkSum += writeOutField(proxy, addr + 40, extOffset);
|
||||||
extCheckSum = -extCheckSum;
|
extCheckSum = -extCheckSum;
|
||||||
checkSum += writeOutField(port, addr + 42, extCheckSum);
|
checkSum += writeOutField(proxy, addr + 42, extCheckSum);
|
||||||
|
|
||||||
// And now, we finally have the whole check sum completed.
|
// And now, we finally have the whole check sum completed.
|
||||||
checkSum = -checkSum;
|
checkSum = -checkSum;
|
||||||
writeOutField(port, addr + 7, checkSum);
|
writeOutField(proxy, addr + 7, checkSum);
|
||||||
|
|
||||||
return offset + extOffset;
|
return offset + extOffset;
|
||||||
};
|
};
|
||||||
|
@ -261,18 +261,18 @@ X86IntelMPConfigTableParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::Processor::writeOut(
|
X86ISA::IntelMP::Processor::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 1, localApicID);
|
checkSum += writeOutField(proxy, addr + 1, localApicID);
|
||||||
checkSum += writeOutField(port, addr + 2, localApicVersion);
|
checkSum += writeOutField(proxy, addr + 2, localApicVersion);
|
||||||
checkSum += writeOutField(port, addr + 3, cpuFlags);
|
checkSum += writeOutField(proxy, addr + 3, cpuFlags);
|
||||||
checkSum += writeOutField(port, addr + 4, cpuSignature);
|
checkSum += writeOutField(proxy, addr + 4, cpuSignature);
|
||||||
checkSum += writeOutField(port, addr + 8, featureFlags);
|
checkSum += writeOutField(proxy, addr + 8, featureFlags);
|
||||||
|
|
||||||
uint32_t reserved = 0;
|
uint32_t reserved = 0;
|
||||||
port->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
|
proxy->writeBlob(addr + 12, (uint8_t *)(&reserved), 4);
|
||||||
port->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
|
proxy->writeBlob(addr + 16, (uint8_t *)(&reserved), 4);
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,11 +298,11 @@ X86IntelMPProcessorParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::Bus::writeOut(
|
X86ISA::IntelMP::Bus::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 1, busID);
|
checkSum += writeOutField(proxy, addr + 1, busID);
|
||||||
checkSum += writeOutString(port, addr + 2, busType, 6);
|
checkSum += writeOutString(proxy, addr + 2, busType, 6);
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,13 +318,13 @@ X86IntelMPBusParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::IOAPIC::writeOut(
|
X86ISA::IntelMP::IOAPIC::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 1, id);
|
checkSum += writeOutField(proxy, addr + 1, id);
|
||||||
checkSum += writeOutField(port, addr + 2, version);
|
checkSum += writeOutField(proxy, addr + 2, version);
|
||||||
checkSum += writeOutField(port, addr + 3, flags);
|
checkSum += writeOutField(proxy, addr + 3, flags);
|
||||||
checkSum += writeOutField(port, addr + 4, address);
|
checkSum += writeOutField(proxy, addr + 4, address);
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,15 +343,15 @@ X86IntelMPIOAPICParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::IntAssignment::writeOut(
|
X86ISA::IntelMP::IntAssignment::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
BaseConfigEntry::writeOut(port, addr, checkSum);
|
BaseConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 1, interruptType);
|
checkSum += writeOutField(proxy, addr + 1, interruptType);
|
||||||
checkSum += writeOutField(port, addr + 2, flags);
|
checkSum += writeOutField(proxy, addr + 2, flags);
|
||||||
checkSum += writeOutField(port, addr + 4, sourceBusID);
|
checkSum += writeOutField(proxy, addr + 4, sourceBusID);
|
||||||
checkSum += writeOutField(port, addr + 5, sourceBusIRQ);
|
checkSum += writeOutField(proxy, addr + 5, sourceBusIRQ);
|
||||||
checkSum += writeOutField(port, addr + 6, destApicID);
|
checkSum += writeOutField(proxy, addr + 6, destApicID);
|
||||||
checkSum += writeOutField(port, addr + 7, destApicIntIn);
|
checkSum += writeOutField(proxy, addr + 7, destApicIntIn);
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,13 +381,13 @@ X86IntelMPLocalIntAssignmentParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::AddrSpaceMapping::writeOut(
|
X86ISA::IntelMP::AddrSpaceMapping::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
ExtConfigEntry::writeOut(port, addr, checkSum);
|
ExtConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 2, busID);
|
checkSum += writeOutField(proxy, addr + 2, busID);
|
||||||
checkSum += writeOutField(port, addr + 3, addrType);
|
checkSum += writeOutField(proxy, addr + 3, addrType);
|
||||||
checkSum += writeOutField(port, addr + 4, addr);
|
checkSum += writeOutField(proxy, addr + 4, addr);
|
||||||
checkSum += writeOutField(port, addr + 12, addrLength);
|
checkSum += writeOutField(proxy, addr + 12, addrLength);
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,15 +405,15 @@ X86IntelMPAddrSpaceMappingParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::BusHierarchy::writeOut(
|
X86ISA::IntelMP::BusHierarchy::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
ExtConfigEntry::writeOut(port, addr, checkSum);
|
ExtConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 2, busID);
|
checkSum += writeOutField(proxy, addr + 2, busID);
|
||||||
checkSum += writeOutField(port, addr + 3, info);
|
checkSum += writeOutField(proxy, addr + 3, info);
|
||||||
checkSum += writeOutField(port, addr + 4, parentBus);
|
checkSum += writeOutField(proxy, addr + 4, parentBus);
|
||||||
|
|
||||||
uint32_t reserved = 0;
|
uint32_t reserved = 0;
|
||||||
port->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
|
proxy->writeBlob(addr + 5, (uint8_t *)(&reserved), 3);
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
@ -434,12 +434,12 @@ X86IntelMPBusHierarchyParams::create()
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
X86ISA::IntelMP::CompatAddrSpaceMod::writeOut(
|
X86ISA::IntelMP::CompatAddrSpaceMod::writeOut(
|
||||||
FunctionalPort * port, Addr addr, uint8_t &checkSum)
|
PortProxy* proxy, Addr addr, uint8_t &checkSum)
|
||||||
{
|
{
|
||||||
ExtConfigEntry::writeOut(port, addr, checkSum);
|
ExtConfigEntry::writeOut(proxy, addr, checkSum);
|
||||||
checkSum += writeOutField(port, addr + 2, busID);
|
checkSum += writeOutField(proxy, addr + 2, busID);
|
||||||
checkSum += writeOutField(port, addr + 3, mod);
|
checkSum += writeOutField(proxy, addr + 3, mod);
|
||||||
checkSum += writeOutField(port, addr + 4, rangeList);
|
checkSum += writeOutField(proxy, addr + 4, rangeList);
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include "enums/X86IntelMPTriggerMode.hh"
|
#include "enums/X86IntelMPTriggerMode.hh"
|
||||||
#include "sim/sim_object.hh"
|
#include "sim/sim_object.hh"
|
||||||
|
|
||||||
class FunctionalPort;
|
class PortProxy;
|
||||||
|
|
||||||
// Config entry types
|
// Config entry types
|
||||||
class X86IntelMPBaseConfigEntryParams;
|
class X86IntelMPBaseConfigEntryParams;
|
||||||
|
@ -93,7 +93,7 @@ class FloatingPointer : public SimObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr);
|
Addr writeOut(PortProxy* proxy, Addr addr);
|
||||||
|
|
||||||
Addr getTableAddr()
|
Addr getTableAddr()
|
||||||
{
|
{
|
||||||
|
@ -117,7 +117,7 @@ class BaseConfigEntry : public SimObject
|
||||||
|
|
||||||
public:
|
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);
|
BaseConfigEntry(Params * p, uint8_t _type);
|
||||||
};
|
};
|
||||||
|
@ -132,7 +132,7 @@ class ExtConfigEntry : public SimObject
|
||||||
|
|
||||||
public:
|
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);
|
ExtConfigEntry(Params * p, uint8_t _type, uint8_t _length);
|
||||||
};
|
};
|
||||||
|
@ -155,7 +155,7 @@ class ConfigTable : public SimObject
|
||||||
std::vector<ExtConfigEntry *> extEntries;
|
std::vector<ExtConfigEntry *> extEntries;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr);
|
Addr writeOut(PortProxy* proxy, Addr addr);
|
||||||
|
|
||||||
ConfigTable(Params * p);
|
ConfigTable(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -172,7 +172,7 @@ class Processor : public BaseConfigEntry
|
||||||
uint32_t featureFlags;
|
uint32_t featureFlags;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
Processor(Params * p);
|
Processor(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -186,7 +186,7 @@ class Bus : public BaseConfigEntry
|
||||||
std::string busType;
|
std::string busType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
Bus(Params * p);
|
Bus(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -202,7 +202,7 @@ class IOAPIC : public BaseConfigEntry
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
IOAPIC(Params * p);
|
IOAPIC(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -221,7 +221,7 @@ class IntAssignment : public BaseConfigEntry
|
||||||
uint8_t destApicIntIn;
|
uint8_t destApicIntIn;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
IntAssignment(X86IntelMPBaseConfigEntryParams * p,
|
IntAssignment(X86IntelMPBaseConfigEntryParams * p,
|
||||||
Enums::X86IntelMPInterruptType _interruptType,
|
Enums::X86IntelMPInterruptType _interruptType,
|
||||||
|
@ -269,7 +269,7 @@ class AddrSpaceMapping : public ExtConfigEntry
|
||||||
uint64_t addrLength;
|
uint64_t addrLength;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
AddrSpaceMapping(Params * p);
|
AddrSpaceMapping(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -284,7 +284,7 @@ class BusHierarchy : public ExtConfigEntry
|
||||||
uint8_t parentBus;
|
uint8_t parentBus;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
BusHierarchy(Params * p);
|
BusHierarchy(Params * p);
|
||||||
};
|
};
|
||||||
|
@ -299,7 +299,7 @@ class CompatAddrSpaceMod : public ExtConfigEntry
|
||||||
uint32_t rangeList;
|
uint32_t rangeList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum);
|
Addr writeOut(PortProxy* proxy, Addr addr, uint8_t &checkSum);
|
||||||
|
|
||||||
CompatAddrSpaceMod(Params * p);
|
CompatAddrSpaceMod(Params * p);
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#include "arch/x86/bios/smbios.hh"
|
#include "arch/x86/bios/smbios.hh"
|
||||||
#include "arch/x86/isa_traits.hh"
|
#include "arch/x86/isa_traits.hh"
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port_proxy.hh"
|
||||||
#include "params/X86SMBiosBiosInformation.hh"
|
#include "params/X86SMBiosBiosInformation.hh"
|
||||||
#include "params/X86SMBiosSMBiosStructure.hh"
|
#include "params/X86SMBiosSMBiosStructure.hh"
|
||||||
#include "params/X86SMBiosSMBiosTable.hh"
|
#include "params/X86SMBiosSMBiosTable.hh"
|
||||||
|
@ -74,15 +74,15 @@ composeBitVector(T vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t
|
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();
|
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);
|
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();
|
return length + getStringLength();
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ X86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) :
|
||||||
|
|
||||||
void
|
void
|
||||||
X86ISA::SMBios::SMBiosStructure::writeOutStrings(
|
X86ISA::SMBios::SMBiosStructure::writeOutStrings(
|
||||||
FunctionalPort * port, Addr addr)
|
PortProxy* proxy, Addr addr)
|
||||||
{
|
{
|
||||||
std::vector<std::string>::iterator it;
|
std::vector<std::string>::iterator it;
|
||||||
Addr offset = 0;
|
Addr offset = 0;
|
||||||
|
@ -103,16 +103,16 @@ X86ISA::SMBios::SMBiosStructure::writeOutStrings(
|
||||||
// If there are string fields but none of them are used, that's a
|
// If there are string fields but none of them are used, that's a
|
||||||
// special case which is handled by this if.
|
// special case which is handled by this if.
|
||||||
if (strings.size() == 0 && stringFields) {
|
if (strings.size() == 0 && stringFields) {
|
||||||
port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
||||||
offset++;
|
offset++;
|
||||||
} else {
|
} else {
|
||||||
for (it = strings.begin(); it != strings.end(); it++) {
|
for (it = strings.begin(); it != strings.end(); it++) {
|
||||||
port->writeBlob(addr + offset,
|
proxy->writeBlob(addr + offset,
|
||||||
(uint8_t *)it->c_str(), it->length() + 1);
|
(uint8_t *)it->c_str(), it->length() + 1);
|
||||||
offset += it->length() + 1;
|
offset += it->length() + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
proxy->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -172,32 +172,32 @@ X86ISA::SMBios::BiosInformation::BiosInformation(Params * p) :
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t
|
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);
|
proxy->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1);
|
||||||
port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
|
proxy->writeBlob(addr + 0x5, (uint8_t *)(&version), 1);
|
||||||
|
|
||||||
uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment);
|
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);
|
proxy->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1);
|
||||||
port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
|
proxy->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1);
|
||||||
|
|
||||||
uint64_t characteristicsGuest = X86ISA::htog(characteristics);
|
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 =
|
uint16_t characteristicExtBytesGuest =
|
||||||
X86ISA::htog(characteristicExtBytes);
|
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);
|
proxy->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1);
|
||||||
port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
|
proxy->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1);
|
||||||
port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
|
proxy->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1);
|
||||||
port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
|
proxy->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1);
|
||||||
|
|
||||||
writeOutStrings(port, addr + getLength());
|
writeOutStrings(proxy, addr + getLength());
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ X86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) :
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
X86ISA::SMBios::SMBiosTable::writeOut(PortProxy* proxy, Addr addr,
|
||||||
Addr &headerSize, Addr &structSize)
|
Addr &headerSize, Addr &structSize)
|
||||||
{
|
{
|
||||||
headerSize = 0x1F;
|
headerSize = 0x1F;
|
||||||
|
@ -224,26 +224,26 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
*/
|
*/
|
||||||
uint8_t mainChecksum = 0;
|
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++)
|
for (int i = 0; i < 4; i++)
|
||||||
mainChecksum += smbiosHeader.anchorString[i];
|
mainChecksum += smbiosHeader.anchorString[i];
|
||||||
|
|
||||||
// The checksum goes here, but we're figuring it out as we go.
|
// 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);
|
(uint8_t *)(&smbiosHeader.entryPointLength), 1);
|
||||||
mainChecksum += smbiosHeader.entryPointLength;
|
mainChecksum += smbiosHeader.entryPointLength;
|
||||||
port->writeBlob(addr + 0x6,
|
proxy->writeBlob(addr + 0x6,
|
||||||
(uint8_t *)(&smbiosHeader.majorVersion), 1);
|
(uint8_t *)(&smbiosHeader.majorVersion), 1);
|
||||||
mainChecksum += smbiosHeader.majorVersion;
|
mainChecksum += smbiosHeader.majorVersion;
|
||||||
port->writeBlob(addr + 0x7,
|
proxy->writeBlob(addr + 0x7,
|
||||||
(uint8_t *)(&smbiosHeader.minorVersion), 1);
|
(uint8_t *)(&smbiosHeader.minorVersion), 1);
|
||||||
mainChecksum += smbiosHeader.minorVersion;
|
mainChecksum += smbiosHeader.minorVersion;
|
||||||
// Maximum structure size goes here, but we'll figure it out later.
|
// 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);
|
(uint8_t *)(&smbiosHeader.entryPointRevision), 1);
|
||||||
mainChecksum += smbiosHeader.entryPointRevision;
|
mainChecksum += smbiosHeader.entryPointRevision;
|
||||||
port->writeBlob(addr + 0xB,
|
proxy->writeBlob(addr + 0xB,
|
||||||
(uint8_t *)(&smbiosHeader.formattedArea), 5);
|
(uint8_t *)(&smbiosHeader.formattedArea), 5);
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
mainChecksum += smbiosHeader.formattedArea[i];
|
mainChecksum += smbiosHeader.formattedArea[i];
|
||||||
|
@ -253,7 +253,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
*/
|
*/
|
||||||
uint8_t intChecksum = 0;
|
uint8_t intChecksum = 0;
|
||||||
|
|
||||||
port->writeBlob(addr + 0x10,
|
proxy->writeBlob(addr + 0x10,
|
||||||
(uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
|
(uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5);
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
|
intChecksum += smbiosHeader.intermediateHeader.anchorString[i];
|
||||||
|
@ -263,20 +263,20 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
|
|
||||||
uint32_t tableAddrGuest =
|
uint32_t tableAddrGuest =
|
||||||
X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr);
|
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++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
intChecksum += tableAddrGuest;
|
intChecksum += tableAddrGuest;
|
||||||
tableAddrGuest >>= 8;
|
tableAddrGuest >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t numStructs = X86ISA::gtoh(structures.size());
|
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++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
intChecksum += numStructs;
|
intChecksum += numStructs;
|
||||||
numStructs >>= 8;
|
numStructs >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
port->writeBlob(addr + 0x1E,
|
proxy->writeBlob(addr + 0x1E,
|
||||||
(uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
|
(uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision),
|
||||||
1);
|
1);
|
||||||
intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
|
intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision;
|
||||||
|
@ -290,7 +290,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
uint16_t maxSize = 0;
|
uint16_t maxSize = 0;
|
||||||
std::vector<SMBiosStructure *>::iterator it;
|
std::vector<SMBiosStructure *>::iterator it;
|
||||||
for (it = structures.begin(); it != structures.end(); 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)
|
if (size > maxSize)
|
||||||
maxSize = size;
|
maxSize = size;
|
||||||
offset += size;
|
offset += size;
|
||||||
|
@ -303,7 +303,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
maxSize = X86ISA::htog(maxSize);
|
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++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
mainChecksum += maxSize;
|
mainChecksum += maxSize;
|
||||||
maxSize >>= 8;
|
maxSize >>= 8;
|
||||||
|
@ -311,7 +311,7 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
|
|
||||||
// Set the checksum
|
// Set the checksum
|
||||||
mainChecksum = -mainChecksum;
|
mainChecksum = -mainChecksum;
|
||||||
port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
|
proxy->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Intermediate header
|
* Intermediate header
|
||||||
|
@ -319,14 +319,14 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr,
|
||||||
|
|
||||||
uint16_t tableSize = offset;
|
uint16_t tableSize = offset;
|
||||||
tableSize = X86ISA::htog(tableSize);
|
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++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
intChecksum += tableSize;
|
intChecksum += tableSize;
|
||||||
tableSize >>= 8;
|
tableSize >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
intChecksum = -intChecksum;
|
intChecksum = -intChecksum;
|
||||||
port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
|
proxy->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
X86ISA::SMBios::BiosInformation *
|
X86ISA::SMBios::BiosInformation *
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include "enums/ExtCharacteristic.hh"
|
#include "enums/ExtCharacteristic.hh"
|
||||||
#include "sim/sim_object.hh"
|
#include "sim/sim_object.hh"
|
||||||
|
|
||||||
class FunctionalPort;
|
class PortProxy;
|
||||||
class X86SMBiosBiosInformationParams;
|
class X86SMBiosBiosInformationParams;
|
||||||
class X86SMBiosSMBiosStructureParams;
|
class X86SMBiosSMBiosStructureParams;
|
||||||
class X86SMBiosSMBiosTableParams;
|
class X86SMBiosSMBiosTableParams;
|
||||||
|
@ -89,7 +89,7 @@ class SMBiosStructure : public SimObject
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint16_t writeOut(FunctionalPort * port, Addr addr);
|
virtual uint16_t writeOut(PortProxy* proxy, Addr addr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool stringFields;
|
bool stringFields;
|
||||||
|
@ -98,7 +98,7 @@ class SMBiosStructure : public SimObject
|
||||||
|
|
||||||
std::vector<std::string> strings;
|
std::vector<std::string> strings;
|
||||||
|
|
||||||
void writeOutStrings(FunctionalPort * port, Addr addr);
|
void writeOutStrings(PortProxy* proxy, Addr addr);
|
||||||
|
|
||||||
int getStringLength();
|
int getStringLength();
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ class BiosInformation : public SMBiosStructure
|
||||||
BiosInformation(Params * p);
|
BiosInformation(Params * p);
|
||||||
|
|
||||||
uint8_t getLength() { return 0x18; }
|
uint8_t getLength() { return 0x18; }
|
||||||
uint16_t writeOut(FunctionalPort * port, Addr addr);
|
uint16_t writeOut(PortProxy* proxy, Addr addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SMBiosTable : public SimObject
|
class SMBiosTable : public SimObject
|
||||||
|
@ -223,7 +223,7 @@ class SMBiosTable : public SimObject
|
||||||
smbiosHeader.intermediateHeader.tableAddr = addr;
|
smbiosHeader.intermediateHeader.tableAddr = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeOut(FunctionalPort * port, Addr addr,
|
void writeOut(PortProxy* proxy, Addr addr,
|
||||||
Addr &headerSize, Addr &structSize);
|
Addr &headerSize, Addr &structSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
|
||||||
strcpy(name->machine, "x86_64");
|
strcpy(name->machine, "x86_64");
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
int code = process->getSyscallArg(tc, index);
|
int code = process->getSyscallArg(tc, index);
|
||||||
uint64_t addr = process->getSyscallArg(tc, index);
|
uint64_t addr = process->getSyscallArg(tc, index);
|
||||||
uint64_t fsBase, gsBase;
|
uint64_t fsBase, gsBase;
|
||||||
TranslatingPort *p = tc->getMemPort();
|
SETranslatingPortProxy* p = tc->getMemProxy();
|
||||||
switch(code)
|
switch(code)
|
||||||
{
|
{
|
||||||
//Each of these valid options should actually check addr.
|
//Each of these valid options should actually check addr.
|
||||||
|
@ -149,10 +149,10 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
|
||||||
gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t),
|
gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t),
|
||||||
numTLSEntries * sizeof(uint64_t));
|
numTLSEntries * sizeof(uint64_t));
|
||||||
|
|
||||||
if (!userDesc.copyIn(tc->getMemPort()))
|
if (!userDesc.copyIn(tc->getMemProxy()))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
if (!gdt.copyIn(tc->getMemPort()))
|
if (!gdt.copyIn(tc->getMemProxy()))
|
||||||
panic("Failed to copy in GDT for %s.\n", desc->name);
|
panic("Failed to copy in GDT for %s.\n", desc->name);
|
||||||
|
|
||||||
if (userDesc->entry_number == (uint32_t)(-1)) {
|
if (userDesc->entry_number == (uint32_t)(-1)) {
|
||||||
|
@ -204,9 +204,9 @@ setThreadArea32Func(SyscallDesc *desc, int callnum,
|
||||||
|
|
||||||
gdt[index] = (uint64_t)segDesc;
|
gdt[index] = (uint64_t)segDesc;
|
||||||
|
|
||||||
if (!userDesc.copyOut(tc->getMemPort()))
|
if (!userDesc.copyOut(tc->getMemProxy()))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (!gdt.copyOut(tc->getMemPort()))
|
if (!gdt.copyOut(tc->getMemProxy()))
|
||||||
panic("Failed to copy out GDT for %s.\n", desc->name);
|
panic("Failed to copy out GDT for %s.\n", desc->name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
#include "arch/vtophys.hh"
|
#include "arch/vtophys.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/port_proxy.hh"
|
||||||
#include "params/LinuxX86System.hh"
|
#include "params/LinuxX86System.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
|
@ -67,8 +67,8 @@ LinuxX86System::initState()
|
||||||
// The location of the real mode data structure.
|
// The location of the real mode data structure.
|
||||||
const Addr realModeData = 0x90200;
|
const Addr realModeData = 0x90200;
|
||||||
|
|
||||||
// A port to write to memory.
|
// A port proxy to write to memory.
|
||||||
FunctionalPort * physPort = threadContexts[0]->getPhysPort();
|
PortProxy* physProxy = threadContexts[0]->getPhysProxy();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deal with the command line stuff.
|
* Deal with the command line stuff.
|
||||||
|
@ -82,14 +82,14 @@ LinuxX86System::initState()
|
||||||
if (commandLine.length() + 1 > realModeData - commandLineBuff)
|
if (commandLine.length() + 1 > realModeData - commandLineBuff)
|
||||||
panic("Command line \"%s\" is longer than %d characters.\n",
|
panic("Command line \"%s\" is longer than %d characters.\n",
|
||||||
commandLine, realModeData - commandLineBuff - 1);
|
commandLine, realModeData - commandLineBuff - 1);
|
||||||
physPort->writeBlob(commandLineBuff,
|
physProxy->writeBlob(commandLineBuff,
|
||||||
(uint8_t *)commandLine.c_str(), commandLine.length() + 1);
|
(uint8_t *)commandLine.c_str(), commandLine.length() + 1);
|
||||||
|
|
||||||
// Generate a pointer of the right size and endianness to put into
|
// Generate a pointer of the right size and endianness to put into
|
||||||
// commandLinePointer.
|
// commandLinePointer.
|
||||||
uint32_t guestCommandLineBuff =
|
uint32_t guestCommandLineBuff =
|
||||||
X86ISA::htog((uint32_t)commandLineBuff);
|
X86ISA::htog((uint32_t)commandLineBuff);
|
||||||
physPort->writeBlob(commandLinePointer,
|
physProxy->writeBlob(commandLinePointer,
|
||||||
(uint8_t *)&guestCommandLineBuff, sizeof(guestCommandLineBuff));
|
(uint8_t *)&guestCommandLineBuff, sizeof(guestCommandLineBuff));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -127,7 +127,7 @@ LinuxX86System::initState()
|
||||||
// A pointer to the buffer for E820 entries.
|
// A pointer to the buffer for E820 entries.
|
||||||
const Addr e820MapPointer = realModeData + 0x2d0;
|
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
|
* Pass the location of the real mode data structure to the kernel
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/Stack.hh"
|
#include "debug/Stack.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "sim/process_impl.hh"
|
#include "sim/process_impl.hh"
|
||||||
#include "sim/syscall_emul.hh"
|
#include "sim/syscall_emul.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -48,9 +48,9 @@ namespace X86ISA
|
||||||
{
|
{
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
|
|
||||||
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
|
||||||
panic("thread info not compiled into kernel\n");
|
panic("thread info not compiled into kernel\n");
|
||||||
|
@ -82,9 +82,9 @@ namespace X86ISA
|
||||||
|
|
||||||
Addr tsk;
|
Addr tsk;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
tsk = vp->readGtoH<Addr>(base + task_off);
|
tsk = vp->readGtoH<Addr>(base + task_off);
|
||||||
|
|
||||||
return tsk;
|
return tsk;
|
||||||
|
@ -99,9 +99,9 @@ namespace X86ISA
|
||||||
|
|
||||||
uint16_t pd;
|
uint16_t pd;
|
||||||
|
|
||||||
VirtualPort *vp;
|
FSTranslatingPortProxy* vp;
|
||||||
|
|
||||||
vp = tc->getVirtPort();
|
vp = tc->getVirtProxy();
|
||||||
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
pd = vp->readGtoH<uint16_t>(task + pid_off);
|
||||||
|
|
||||||
return pd;
|
return pd;
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
#include "base/intmath.hh"
|
#include "base/intmath.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/port_proxy.hh"
|
||||||
#include "params/X86System.hh"
|
#include "params/X86System.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
|
@ -61,8 +61,6 @@ X86System::X86System(Params *p) :
|
||||||
mpConfigTable(p->intel_mp_table),
|
mpConfigTable(p->intel_mp_table),
|
||||||
rsdp(p->acpi_description_table_pointer)
|
rsdp(p->acpi_description_table_pointer)
|
||||||
{
|
{
|
||||||
if (kernel->getArch() == ObjectFile::I386)
|
|
||||||
fatal("Loading a 32 bit x86 kernel is not supported.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -116,6 +114,9 @@ X86System::initState()
|
||||||
{
|
{
|
||||||
System::initState();
|
System::initState();
|
||||||
|
|
||||||
|
if (kernel->getArch() == ObjectFile::I386)
|
||||||
|
fatal("Loading a 32 bit x86 kernel is not supported.\n");
|
||||||
|
|
||||||
ThreadContext *tc = threadContexts[0];
|
ThreadContext *tc = threadContexts[0];
|
||||||
// This is the boot strap processor (BSP). Initialize it to look like
|
// 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
|
// the boot loader has just turned control over to the 64 bit OS. We
|
||||||
|
@ -137,8 +138,8 @@ X86System::initState()
|
||||||
const int PDPTBits = 9;
|
const int PDPTBits = 9;
|
||||||
const int PDTBits = 9;
|
const int PDTBits = 9;
|
||||||
|
|
||||||
// Get a port to write the page tables and descriptor tables.
|
// Get a port proxy to write the page tables and descriptor tables.
|
||||||
FunctionalPort * physPort = tc->getPhysPort();
|
PortProxy* physProxy = tc->getPhysProxy();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the gdt.
|
* Set up the gdt.
|
||||||
|
@ -146,7 +147,7 @@ X86System::initState()
|
||||||
uint8_t numGDTEntries = 0;
|
uint8_t numGDTEntries = 0;
|
||||||
// Place holder at selector 0
|
// Place holder at selector 0
|
||||||
uint64_t nullDescriptor = 0;
|
uint64_t nullDescriptor = 0;
|
||||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||||
(uint8_t *)(&nullDescriptor), 8);
|
(uint8_t *)(&nullDescriptor), 8);
|
||||||
numGDTEntries++;
|
numGDTEntries++;
|
||||||
|
|
||||||
|
@ -168,7 +169,7 @@ X86System::initState()
|
||||||
//it's beginning in memory and it's actual data, we'll use an
|
//it's beginning in memory and it's actual data, we'll use an
|
||||||
//intermediary.
|
//intermediary.
|
||||||
uint64_t csDescVal = csDesc;
|
uint64_t csDescVal = csDesc;
|
||||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||||
(uint8_t *)(&csDescVal), 8);
|
(uint8_t *)(&csDescVal), 8);
|
||||||
|
|
||||||
numGDTEntries++;
|
numGDTEntries++;
|
||||||
|
@ -191,7 +192,7 @@ X86System::initState()
|
||||||
dsDesc.limitHigh = 0xF;
|
dsDesc.limitHigh = 0xF;
|
||||||
dsDesc.limitLow = 0xFF;
|
dsDesc.limitLow = 0xFF;
|
||||||
uint64_t dsDescVal = dsDesc;
|
uint64_t dsDescVal = dsDesc;
|
||||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||||
(uint8_t *)(&dsDescVal), 8);
|
(uint8_t *)(&dsDescVal), 8);
|
||||||
|
|
||||||
numGDTEntries++;
|
numGDTEntries++;
|
||||||
|
@ -219,7 +220,7 @@ X86System::initState()
|
||||||
tssDesc.limitHigh = 0xF;
|
tssDesc.limitHigh = 0xF;
|
||||||
tssDesc.limitLow = 0xFF;
|
tssDesc.limitLow = 0xFF;
|
||||||
uint64_t tssDescVal = tssDesc;
|
uint64_t tssDescVal = tssDesc;
|
||||||
physPort->writeBlob(GDTBase + numGDTEntries * 8,
|
physProxy->writeBlob(GDTBase + numGDTEntries * 8,
|
||||||
(uint8_t *)(&tssDescVal), 8);
|
(uint8_t *)(&tssDescVal), 8);
|
||||||
|
|
||||||
numGDTEntries++;
|
numGDTEntries++;
|
||||||
|
@ -249,24 +250,24 @@ X86System::initState()
|
||||||
// read/write, user, not present
|
// read/write, user, not present
|
||||||
uint64_t pml4e = X86ISA::htog(0x6);
|
uint64_t pml4e = X86ISA::htog(0x6);
|
||||||
for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) {
|
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
|
// Point to the only PDPT
|
||||||
pml4e = X86ISA::htog(0x7 | PageDirPtrTable);
|
pml4e = X86ISA::htog(0x7 | PageDirPtrTable);
|
||||||
physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
|
physProxy->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
|
||||||
|
|
||||||
// Page Directory Pointer Table
|
// Page Directory Pointer Table
|
||||||
|
|
||||||
// read/write, user, not present
|
// read/write, user, not present
|
||||||
uint64_t pdpe = X86ISA::htog(0x6);
|
uint64_t pdpe = X86ISA::htog(0x6);
|
||||||
for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) {
|
for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) {
|
||||||
physPort->writeBlob(PageDirPtrTable + offset,
|
physProxy->writeBlob(PageDirPtrTable + offset,
|
||||||
(uint8_t *)(&pdpe), 8);
|
(uint8_t *)(&pdpe), 8);
|
||||||
}
|
}
|
||||||
// Point to the PDTs
|
// Point to the PDTs
|
||||||
for (int table = 0; table < NumPDTs; table++) {
|
for (int table = 0; table < NumPDTs; table++) {
|
||||||
pdpe = X86ISA::htog(0x7 | PageDirTable[table]);
|
pdpe = X86ISA::htog(0x7 | PageDirTable[table]);
|
||||||
physPort->writeBlob(PageDirPtrTable + table * 8,
|
physProxy->writeBlob(PageDirPtrTable + table * 8,
|
||||||
(uint8_t *)(&pdpe), 8);
|
(uint8_t *)(&pdpe), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +279,7 @@ X86System::initState()
|
||||||
for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) {
|
for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) {
|
||||||
// read/write, user, present, 4MB
|
// read/write, user, present, 4MB
|
||||||
uint64_t pdte = X86ISA::htog(0x87 | base);
|
uint64_t pdte = X86ISA::htog(0x87 | base);
|
||||||
physPort->writeBlob(PageDirTable[table] + offset,
|
physProxy->writeBlob(PageDirTable[table] + offset,
|
||||||
(uint8_t *)(&pdte), 8);
|
(uint8_t *)(&pdte), 8);
|
||||||
base += pageSize;
|
base += pageSize;
|
||||||
}
|
}
|
||||||
|
@ -341,8 +342,8 @@ void
|
||||||
X86System::writeOutSMBiosTable(Addr header,
|
X86System::writeOutSMBiosTable(Addr header,
|
||||||
Addr &headerSize, Addr &structSize, Addr table)
|
Addr &headerSize, Addr &structSize, Addr table)
|
||||||
{
|
{
|
||||||
// Get a port to write the table and header to memory.
|
// Get a port proxy to write the table and header to memory.
|
||||||
FunctionalPort * physPort = threadContexts[0]->getPhysPort();
|
PortProxy* physProxy = threadContexts[0]->getPhysProxy();
|
||||||
|
|
||||||
// If the table location isn't specified, just put it after the header.
|
// 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
|
// The header size as of the 2.5 SMBios specification is 0x1F bytes
|
||||||
|
@ -350,7 +351,7 @@ X86System::writeOutSMBiosTable(Addr header,
|
||||||
table = header + 0x1F;
|
table = header + 0x1F;
|
||||||
smbiosTable->setTableAddr(table);
|
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
|
// Do some bounds checking to make sure we at least didn't step on
|
||||||
// ourselves.
|
// ourselves.
|
||||||
|
@ -362,8 +363,8 @@ void
|
||||||
X86System::writeOutMPTable(Addr fp,
|
X86System::writeOutMPTable(Addr fp,
|
||||||
Addr &fpSize, Addr &tableSize, Addr table)
|
Addr &fpSize, Addr &tableSize, Addr table)
|
||||||
{
|
{
|
||||||
// Get a port to write the table and header to memory.
|
// Get a port proxy to write the table and header to memory.
|
||||||
FunctionalPort * physPort = threadContexts[0]->getPhysPort();
|
PortProxy* physProxy = threadContexts[0]->getPhysProxy();
|
||||||
|
|
||||||
// If the table location isn't specified and it exists, just put
|
// 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
|
// it after the floating pointer. The fp size as of the 1.4 Intel MP
|
||||||
|
@ -374,9 +375,9 @@ X86System::writeOutMPTable(Addr fp,
|
||||||
mpFloatingPointer->setTableAddr(table);
|
mpFloatingPointer->setTableAddr(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
fpSize = mpFloatingPointer->writeOut(physPort, fp);
|
fpSize = mpFloatingPointer->writeOut(physProxy, fp);
|
||||||
if (mpConfigTable)
|
if (mpConfigTable)
|
||||||
tableSize = mpConfigTable->writeOut(physPort, table);
|
tableSize = mpConfigTable->writeOut(physProxy, table);
|
||||||
else
|
else
|
||||||
tableSize = 0;
|
tableSize = 0;
|
||||||
|
|
||||||
|
|
|
@ -414,15 +414,15 @@ ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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;
|
return false;
|
||||||
|
|
||||||
vector<Segment>::iterator extraIt;
|
vector<Segment>::iterator extraIt;
|
||||||
for (extraIt = extraSegments.begin();
|
for (extraIt = extraSegments.begin();
|
||||||
extraIt != extraSegments.end(); extraIt++) {
|
extraIt != extraSegments.end(); extraIt++) {
|
||||||
if (!loadSection(&(*extraIt), memPort, addrMask)) {
|
if (!loadSection(&(*extraIt), memProxy, addrMask)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ class ElfObject : public ObjectFile
|
||||||
public:
|
public:
|
||||||
virtual ~ElfObject() {}
|
virtual ~ElfObject() {}
|
||||||
|
|
||||||
bool loadSections(Port *memPort,
|
bool loadSections(PortProxy *memProxy,
|
||||||
Addr addrMask = std::numeric_limits<Addr>::max());
|
Addr addrMask = std::numeric_limits<Addr>::max());
|
||||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||||
std::numeric_limits<Addr>::max());
|
std::numeric_limits<Addr>::max());
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#include "base/loader/hex_file.hh"
|
#include "base/loader/hex_file.hh"
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "base/cprintf.hh"
|
#include "base/cprintf.hh"
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
/*
|
/*
|
||||||
|
@ -59,7 +59,7 @@ HexFile::~HexFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HexFile::loadSections(Port *memPort)
|
HexFile::loadSections(PortProxy* memProxy)
|
||||||
{
|
{
|
||||||
char Line[64];
|
char Line[64];
|
||||||
Addr MemAddr;
|
Addr MemAddr;
|
||||||
|
@ -71,7 +71,7 @@ HexFile::loadSections(Port *memPort)
|
||||||
parseLine(Line, &MemAddr, &Data);
|
parseLine(Line, &MemAddr, &Data);
|
||||||
if (MemAddr != 0) {
|
if (MemAddr != 0) {
|
||||||
// Now, write to memory
|
// Now, write to memory
|
||||||
memPort->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
|
memProxy->writeBlob(MemAddr << 2, (uint8_t *)&Data, sizeof(Data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
|
|
||||||
class Port;
|
class PortProxy;
|
||||||
|
|
||||||
class HexFile
|
class HexFile
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ class HexFile
|
||||||
virtual ~HexFile();
|
virtual ~HexFile();
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
bool loadSections(Port *memPort);
|
bool loadSections(PortProxy* memProxy);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __BASE_LOADER_HEX_FILE_HH__
|
#endif // __BASE_LOADER_HEX_FILE_HH__
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#include "base/loader/raw_object.hh"
|
#include "base/loader/raw_object.hh"
|
||||||
#include "base/loader/symtab.hh"
|
#include "base/loader/symtab.hh"
|
||||||
#include "base/cprintf.hh"
|
#include "base/cprintf.hh"
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/port_proxy.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -65,16 +65,16 @@ ObjectFile::~ObjectFile()
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
|
ObjectFile::loadSection(Section *sec, PortProxy* memProxy, Addr addrMask)
|
||||||
{
|
{
|
||||||
if (sec->size != 0) {
|
if (sec->size != 0) {
|
||||||
Addr addr = sec->baseAddr & addrMask;
|
Addr addr = sec->baseAddr & addrMask;
|
||||||
if (sec->fileImage) {
|
if (sec->fileImage) {
|
||||||
memPort->writeBlob(addr, sec->fileImage, sec->size);
|
memProxy->writeBlob(addr, sec->fileImage, sec->size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// no image: must be bss
|
// no image: must be bss
|
||||||
memPort->memsetBlob(addr, 0, sec->size);
|
memProxy->memsetBlob(addr, 0, sec->size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -82,11 +82,11 @@ ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ObjectFile::loadSections(Port *memPort, Addr addrMask)
|
ObjectFile::loadSections(PortProxy* memProxy, Addr addrMask)
|
||||||
{
|
{
|
||||||
return (loadSection(&text, memPort, addrMask)
|
return (loadSection(&text, memProxy, addrMask)
|
||||||
&& loadSection(&data, memPort, addrMask)
|
&& loadSection(&data, memProxy, addrMask)
|
||||||
&& loadSection(&bss, memPort, addrMask));
|
&& loadSection(&bss, memProxy, addrMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
|
|
||||||
class Port;
|
class PortProxy;
|
||||||
class SymbolTable;
|
class SymbolTable;
|
||||||
|
|
||||||
class ObjectFile
|
class ObjectFile
|
||||||
|
@ -83,7 +83,7 @@ class ObjectFile
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
virtual bool loadSections(Port *memPort, Addr addrMask =
|
virtual bool loadSections(PortProxy *memProxy, Addr addrMask =
|
||||||
std::numeric_limits<Addr>::max());
|
std::numeric_limits<Addr>::max());
|
||||||
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask =
|
||||||
std::numeric_limits<Addr>::max()) = 0;
|
std::numeric_limits<Addr>::max()) = 0;
|
||||||
|
@ -111,7 +111,7 @@ class ObjectFile
|
||||||
Section data;
|
Section data;
|
||||||
Section bss;
|
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; }
|
void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
#include "arch/vtophys.hh"
|
#include "arch/vtophys.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "base/intmath.hh"
|
#include "base/intmath.hh"
|
||||||
|
@ -138,7 +138,7 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/GDBAll.hh"
|
#include "debug/GDBAll.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port.hh"
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/se_translating_port_proxy.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -465,9 +465,9 @@ BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
|
||||||
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
|
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
VirtualPort *port = context->getVirtPort();
|
FSTranslatingPortProxy *port = context->getVirtProxy();
|
||||||
#else
|
#else
|
||||||
TranslatingPort *port = context->getMemPort();
|
SETranslatingPortProxy *port = context->getMemProxy();
|
||||||
#endif
|
#endif
|
||||||
port->readBlob(vaddr, (uint8_t*)data, size);
|
port->readBlob(vaddr, (uint8_t*)data, size);
|
||||||
|
|
||||||
|
@ -507,9 +507,9 @@ BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
|
||||||
DPRINTFNR("\n");
|
DPRINTFNR("\n");
|
||||||
}
|
}
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
VirtualPort *port = context->getVirtPort();
|
FSTranslatingPortProxy *port = context->getVirtProxy();
|
||||||
#else
|
#else
|
||||||
TranslatingPort *port = context->getMemPort();
|
SETranslatingPortProxy *port = context->getMemProxy();
|
||||||
#endif
|
#endif
|
||||||
port->writeBlob(vaddr, (uint8_t*)data, size);
|
port->writeBlob(vaddr, (uint8_t*)data, size);
|
||||||
#if !FULL_SYSTEM
|
#if !FULL_SYSTEM
|
||||||
|
|
|
@ -97,12 +97,12 @@ class CheckerThreadContext : public ThreadContext
|
||||||
TheISA::Kernel::Statistics *getKernelStats()
|
TheISA::Kernel::Statistics *getKernelStats()
|
||||||
{ return actualTC->getKernelStats(); }
|
{ return actualTC->getKernelStats(); }
|
||||||
|
|
||||||
FunctionalPort *getPhysPort() { return actualTC->getPhysPort(); }
|
PortProxy* getPhysProxy() { return actualTC->getPhysProxy(); }
|
||||||
|
|
||||||
VirtualPort *getVirtPort()
|
FSTranslatingPortProxy* getVirtProxy()
|
||||||
{ return actualTC->getVirtPort(); }
|
{ return actualTC->getVirtProxy(); }
|
||||||
#else
|
#else
|
||||||
TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
|
SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
|
||||||
|
|
||||||
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
|
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
#include "debug/RefCount.hh"
|
#include "debug/RefCount.hh"
|
||||||
#include "debug/SkedCache.hh"
|
#include "debug/SkedCache.hh"
|
||||||
#include "debug/Quiesce.hh"
|
#include "debug/Quiesce.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "params/InOrderCPU.hh"
|
#include "params/InOrderCPU.hh"
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
#include "sim/stat_control.hh"
|
#include "sim/stat_control.hh"
|
||||||
|
@ -766,6 +765,8 @@ InOrderCPU::init()
|
||||||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||||
ThreadContext *src_tc = threadContexts[tid];
|
ThreadContext *src_tc = threadContexts[tid];
|
||||||
TheISA::initCPU(src_tc, src_tc->contextId());
|
TheISA::initCPU(src_tc, src_tc->contextId());
|
||||||
|
// Initialise the ThreadContext's memory proxies
|
||||||
|
thread[tid]->initMemProxies(thread[tid]->getTC());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -888,16 +889,6 @@ InOrderCPU::processInterrupts(Fault interrupt)
|
||||||
trap(interrupt, threadContexts[0]->contextId(), dummyBufferInst);
|
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
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -430,10 +430,6 @@ class InOrderCPU : public BaseCPU
|
||||||
/** Halts the CPU. */
|
/** Halts the CPU. */
|
||||||
void halt() { panic("Halt not implemented!\n"); }
|
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. */
|
/** Check if this address is a valid instruction address. */
|
||||||
bool validInstAddr(Addr addr) { return true; }
|
bool validInstAddr(Addr addr) { return true; }
|
||||||
|
|
||||||
|
|
|
@ -145,21 +145,6 @@ CacheUnit::tlb()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 *
|
Port *
|
||||||
CacheUnit::getPort(const string &if_name, int idx)
|
CacheUnit::getPort(const string &if_name, int idx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,8 +95,6 @@ class CacheUnit : public Resource
|
||||||
|
|
||||||
bool snoopRangeSent;
|
bool snoopRangeSent;
|
||||||
|
|
||||||
void setPeer(Port *port);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Atomic version of receive. Panics. */
|
/** Atomic version of receive. Panics. */
|
||||||
Tick recvAtomic(PacketPtr pkt);
|
Tick recvAtomic(PacketPtr pkt);
|
||||||
|
|
|
@ -39,10 +39,10 @@ using namespace TheISA;
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
|
|
||||||
VirtualPort *
|
FSTranslatingPortProxy*
|
||||||
InOrderThreadContext::getVirtPort()
|
InOrderThreadContext::getVirtProxy()
|
||||||
{
|
{
|
||||||
return thread->getVirtPort();
|
return thread->getVirtProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -118,12 +118,12 @@ class InOrderThreadContext : public ThreadContext
|
||||||
TheISA::Kernel::Statistics *getKernelStats()
|
TheISA::Kernel::Statistics *getKernelStats()
|
||||||
{ return thread->kernelStats; }
|
{ return thread->kernelStats; }
|
||||||
|
|
||||||
FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
|
PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
|
||||||
|
|
||||||
VirtualPort *getVirtPort();
|
FSTranslatingPortProxy* getVirtProxy();
|
||||||
|
|
||||||
void connectMemPorts(ThreadContext *tc)
|
void initMemProxies(ThreadContext *tc)
|
||||||
{ thread->connectMemPorts(tc); }
|
{ thread->initMemProxies(tc); }
|
||||||
|
|
||||||
/** Dumps the function profiling information.
|
/** Dumps the function profiling information.
|
||||||
* @todo: Implement.
|
* @todo: Implement.
|
||||||
|
@ -147,7 +147,7 @@ class InOrderThreadContext : public ThreadContext
|
||||||
return this->thread->quiesceEvent;
|
return this->thread->quiesceEvent;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
TranslatingPort *getMemPort() { return thread->getMemPort(); }
|
SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
|
||||||
|
|
||||||
/** Returns a pointer to this thread's process. */
|
/** Returns a pointer to this thread's process. */
|
||||||
Process *getProcessPtr() { return thread->getProcessPtr(); }
|
Process *getProcessPtr() { return thread->getProcessPtr(); }
|
||||||
|
|
|
@ -610,6 +610,8 @@ FullO3CPU<Impl>::init()
|
||||||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||||
ThreadContext *src_tc = threadContexts[tid];
|
ThreadContext *src_tc = threadContexts[tid];
|
||||||
TheISA::initCPU(src_tc, src_tc->contextId());
|
TheISA::initCPU(src_tc, src_tc->contextId());
|
||||||
|
// Initialise the ThreadContext's memory proxies
|
||||||
|
thread[tid]->initMemProxies(thread[tid]->getTC());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -974,16 +976,6 @@ FullO3CPU<Impl>::processInterrupts(Fault interrupt)
|
||||||
this->trap(interrupt, 0, NULL);
|
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
|
#endif
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
|
|
@ -395,10 +395,6 @@ class FullO3CPU : public BaseO3CPU
|
||||||
/** Halts the CPU. */
|
/** Halts the CPU. */
|
||||||
void halt() { panic("Halt not implemented!\n"); }
|
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. */
|
/** Check if this address is a valid instruction address. */
|
||||||
bool validInstAddr(Addr addr) { return true; }
|
bool validInstAddr(Addr addr) { return true; }
|
||||||
|
|
||||||
|
|
|
@ -305,8 +305,6 @@ class LSQ {
|
||||||
|
|
||||||
bool snoopRangeSent;
|
bool snoopRangeSent;
|
||||||
|
|
||||||
virtual void setPeer(Port *port);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Atomic version of receive. Panics. */
|
/** Atomic version of receive. Panics. */
|
||||||
virtual Tick recvAtomic(PacketPtr pkt);
|
virtual Tick recvAtomic(PacketPtr pkt);
|
||||||
|
@ -334,11 +332,6 @@ class LSQ {
|
||||||
/** D-cache port. */
|
/** D-cache port. */
|
||||||
DcachePort dcachePort;
|
DcachePort dcachePort;
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
|
||||||
/** Tell the CPU to update the Phys and Virt ports. */
|
|
||||||
void updateMemPorts() { cpu->updateMemPorts(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** The LSQ policy for SMT mode. */
|
/** The LSQ policy for SMT mode. */
|
||||||
LSQPolicy lsqPolicy;
|
LSQPolicy lsqPolicy;
|
||||||
|
|
|
@ -40,19 +40,6 @@
|
||||||
|
|
||||||
using namespace std;
|
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>
|
template <class Impl>
|
||||||
Tick
|
Tick
|
||||||
LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
|
LSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt)
|
||||||
|
|
|
@ -97,13 +97,15 @@ class O3ThreadContext : public ThreadContext
|
||||||
virtual TheISA::Kernel::Statistics *getKernelStats()
|
virtual TheISA::Kernel::Statistics *getKernelStats()
|
||||||
{ return thread->kernelStats; }
|
{ 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
|
#else
|
||||||
virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
|
virtual SETranslatingPortProxy* getMemProxy()
|
||||||
|
{ return thread->getMemProxy(); }
|
||||||
|
|
||||||
/** Returns a pointer to this thread's process. */
|
/** Returns a pointer to this thread's process. */
|
||||||
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
|
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
|
||||||
|
|
|
@ -49,10 +49,10 @@
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
VirtualPort *
|
FSTranslatingPortProxy*
|
||||||
O3ThreadContext<Impl>::getVirtPort()
|
O3ThreadContext<Impl>::getVirtProxy()
|
||||||
{
|
{
|
||||||
return thread->getVirtPort();
|
return thread->getVirtProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
|
|
@ -124,12 +124,12 @@ class OzoneCPU : public BaseCPU
|
||||||
TheISA::Kernel::Statistics *getKernelStats()
|
TheISA::Kernel::Statistics *getKernelStats()
|
||||||
{ return thread->getKernelStats(); }
|
{ return thread->getKernelStats(); }
|
||||||
|
|
||||||
FunctionalPort *getPhysPort() { return thread->getPhysPort(); }
|
PortProxy* getPhysProxy() { return thread->getPhysProxy(); }
|
||||||
|
|
||||||
VirtualPort *getVirtPort()
|
FSTranslatingPortProxy* getVirtProxy()
|
||||||
{ return thread->getVirtPort(); }
|
{ return thread->getVirtProxy(); }
|
||||||
#else
|
#else
|
||||||
TranslatingPort *getMemPort() { return thread->getMemPort(); }
|
SETranslatingPortProxy* getMemProxy() { return thread->getMemProxy(); }
|
||||||
|
|
||||||
Process *getProcessPtr() { return thread->getProcessPtr(); }
|
Process *getProcessPtr() { return thread->getProcessPtr(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -195,23 +195,7 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
|
||||||
backEnd->renameTable.copyFrom(thread.renameTable);
|
backEnd->renameTable.copyFrom(thread.renameTable);
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
Port *mem_port;
|
thread.connectMemPorts(tc);
|
||||||
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);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
|
DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
|
||||||
|
|
|
@ -91,6 +91,9 @@ AtomicSimpleCPU::init()
|
||||||
// initialize CPU, including PC
|
// initialize CPU, including PC
|
||||||
TheISA::initCPU(tc, tc->contextId());
|
TheISA::initCPU(tc, tc->contextId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialise the ThreadContext's memory proxies
|
||||||
|
tcBase()->initMemProxies(tcBase());
|
||||||
#endif
|
#endif
|
||||||
if (hasPhysMemPort) {
|
if (hasPhysMemPort) {
|
||||||
bool snoop = false;
|
bool snoop = false;
|
||||||
|
@ -145,18 +148,6 @@ AtomicSimpleCPU::CpuPort::recvRetry()
|
||||||
panic("AtomicSimpleCPU doesn't expect recvRetry callback!");
|
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)
|
AtomicSimpleCPU::AtomicSimpleCPU(AtomicSimpleCPUParams *p)
|
||||||
: BaseSimpleCPU(p), tickEvent(this), width(p->width), locked(false),
|
: BaseSimpleCPU(p), tickEvent(this), width(p->width), locked(false),
|
||||||
simulate_data_stalls(p->simulate_data_stalls),
|
simulate_data_stalls(p->simulate_data_stalls),
|
||||||
|
|
|
@ -95,16 +95,7 @@ class AtomicSimpleCPU : public BaseSimpleCPU
|
||||||
};
|
};
|
||||||
CpuPort icachePort;
|
CpuPort icachePort;
|
||||||
|
|
||||||
class DcachePort : public CpuPort
|
CpuPort dcachePort;
|
||||||
{
|
|
||||||
public:
|
|
||||||
DcachePort(const std::string &_name, AtomicSimpleCPU *_cpu)
|
|
||||||
: CpuPort(_name, _cpu)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual void setPeer(Port *port);
|
|
||||||
};
|
|
||||||
DcachePort dcachePort;
|
|
||||||
|
|
||||||
CpuPort physmemPort;
|
CpuPort physmemPort;
|
||||||
bool hasPhysMemPort;
|
bool hasPhysMemPort;
|
||||||
|
|
|
@ -81,6 +81,9 @@ TimingSimpleCPU::init()
|
||||||
// initialize CPU, including PC
|
// initialize CPU, including PC
|
||||||
TheISA::initCPU(tc, _cpuId);
|
TheISA::initCPU(tc, _cpuId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialise the ThreadContext's memory proxies
|
||||||
|
tcBase()->initMemProxies(tcBase());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -874,18 +877,6 @@ TimingSimpleCPU::completeDrain()
|
||||||
drainEvent->process();
|
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
|
bool
|
||||||
TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
|
TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -212,8 +212,6 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
||||||
: CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu)
|
: CpuPort(_cpu->name() + "-dport", _cpu, _lat), tickEvent(_cpu)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void setPeer(Port *port);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual bool recvTiming(PacketPtr pkt);
|
virtual bool recvTiming(PacketPtr pkt);
|
||||||
|
|
|
@ -50,11 +50,11 @@
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/profile.hh"
|
#include "cpu/profile.hh"
|
||||||
#include "cpu/quiesce_event.hh"
|
#include "cpu/quiesce_event.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#include "sim/serialize.hh"
|
#include "sim/serialize.hh"
|
||||||
#include "sim/sim_exit.hh"
|
#include "sim/sim_exit.hh"
|
||||||
#else
|
#else
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/se_translating_port_proxy.hh"
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
#endif
|
#endif
|
||||||
|
@ -117,10 +117,6 @@ SimpleThread::SimpleThread()
|
||||||
|
|
||||||
SimpleThread::~SimpleThread()
|
SimpleThread::~SimpleThread()
|
||||||
{
|
{
|
||||||
#if FULL_SYSTEM
|
|
||||||
delete physPort;
|
|
||||||
delete virtPort;
|
|
||||||
#endif
|
|
||||||
delete tc;
|
delete tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,13 +208,13 @@ class SimpleThread : public ThreadState
|
||||||
System *getSystemPtr() { return system; }
|
System *getSystemPtr() { return system; }
|
||||||
|
|
||||||
#if FULL_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.
|
/** 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
|
* After a CPU switch it may point to the wrong memory object which could
|
||||||
* mean stale data.
|
* mean stale data.
|
||||||
*/
|
*/
|
||||||
VirtualPort *getVirtPort() { return virtPort; }
|
FSTranslatingPortProxy* getVirtProxy() { return virtProxy; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Status status() const { return _status; }
|
Status status() const { return _status; }
|
||||||
|
|
|
@ -50,9 +50,9 @@ class BaseCPU;
|
||||||
class Checkpoint;
|
class Checkpoint;
|
||||||
class Decoder;
|
class Decoder;
|
||||||
class EndQuiesceEvent;
|
class EndQuiesceEvent;
|
||||||
class TranslatingPort;
|
class SETranslatingPortProxy;
|
||||||
class FunctionalPort;
|
class FSTranslatingPortProxy;
|
||||||
class VirtualPort;
|
class PortProxy;
|
||||||
class Process;
|
class Process;
|
||||||
class System;
|
class System;
|
||||||
namespace TheISA {
|
namespace TheISA {
|
||||||
|
@ -128,13 +128,19 @@ class ThreadContext
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
virtual TheISA::Kernel::Statistics *getKernelStats() = 0;
|
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
|
#else
|
||||||
virtual TranslatingPort *getMemPort() = 0;
|
virtual SETranslatingPortProxy *getMemProxy() = 0;
|
||||||
|
|
||||||
virtual Process *getProcessPtr() = 0;
|
virtual Process *getProcessPtr() = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -298,13 +304,13 @@ class ProxyThreadContext : public ThreadContext
|
||||||
TheISA::Kernel::Statistics *getKernelStats()
|
TheISA::Kernel::Statistics *getKernelStats()
|
||||||
{ return actualTC->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
|
#else
|
||||||
TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
|
SETranslatingPortProxy* getMemProxy() { return actualTC->getMemProxy(); }
|
||||||
|
|
||||||
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
|
Process *getProcessPtr() { return actualTC->getProcessPtr(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,14 +32,15 @@
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/profile.hh"
|
#include "cpu/profile.hh"
|
||||||
#include "cpu/thread_state.hh"
|
#include "cpu/thread_state.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port_proxy.hh"
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/se_translating_port_proxy.hh"
|
||||||
#include "sim/serialize.hh"
|
#include "sim/serialize.hh"
|
||||||
|
#include "sim/system.hh"
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
#include "arch/kernel_stats.hh"
|
#include "arch/kernel_stats.hh"
|
||||||
#include "cpu/quiesce_event.hh"
|
#include "cpu/quiesce_event.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
|
@ -51,9 +52,9 @@ ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid, Process *_process)
|
||||||
baseCpu(cpu), _threadId(_tid), lastActivate(0), lastSuspend(0),
|
baseCpu(cpu), _threadId(_tid), lastActivate(0), lastSuspend(0),
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
|
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
|
||||||
kernelStats(NULL), physPort(NULL), virtPort(NULL),
|
kernelStats(NULL), physProxy(NULL), virtProxy(NULL),
|
||||||
#else
|
#else
|
||||||
port(NULL), process(_process),
|
proxy(NULL), process(_process),
|
||||||
#endif
|
#endif
|
||||||
funcExeInst(0), storeCondFailures(0)
|
funcExeInst(0), storeCondFailures(0)
|
||||||
{
|
{
|
||||||
|
@ -61,10 +62,16 @@ ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid, Process *_process)
|
||||||
|
|
||||||
ThreadState::~ThreadState()
|
ThreadState::~ThreadState()
|
||||||
{
|
{
|
||||||
#if !FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
if (port) {
|
if (physProxy != NULL) {
|
||||||
delete port->getPeer();
|
delete physProxy;
|
||||||
delete port;
|
}
|
||||||
|
if (virtProxy != NULL) {
|
||||||
|
delete virtProxy;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (proxy != NULL) {
|
||||||
|
delete proxy;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -106,38 +113,16 @@ ThreadState::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
void
|
void
|
||||||
ThreadState::connectMemPorts(ThreadContext *tc)
|
ThreadState::initMemProxies(ThreadContext *tc)
|
||||||
{
|
{
|
||||||
connectPhysPort();
|
// Note that this only refers to the port on the CPU side and can
|
||||||
connectVirtPort(tc);
|
// 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.
|
||||||
void
|
if (physProxy == NULL)
|
||||||
ThreadState::connectPhysPort()
|
physProxy = new PortProxy(*baseCpu->getPort("dcache_port"));
|
||||||
{
|
if (virtProxy == NULL)
|
||||||
// @todo: For now this disregards any older port that may have
|
virtProxy = new FSTranslatingPortProxy(tc);
|
||||||
// already existed. Fix this memory leak once the bus port IDs
|
|
||||||
// for functional ports is resolved.
|
|
||||||
if (physPort)
|
|
||||||
physPort->removeConn();
|
|
||||||
else
|
|
||||||
physPort = new FunctionalPort(csprintf("%s-%d-funcport",
|
|
||||||
baseCpu->name(), _threadId));
|
|
||||||
connectToMemFunc(physPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ThreadState::connectVirtPort(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
// @todo: For now this disregards any older port that may have
|
|
||||||
// already existed. Fix this memory leak once the bus port IDs
|
|
||||||
// for functional ports is resolved.
|
|
||||||
if (virtPort)
|
|
||||||
virtPort->removeConn();
|
|
||||||
else
|
|
||||||
virtPort = new VirtualPort(csprintf("%s-%d-vport",
|
|
||||||
baseCpu->name(), _threadId), tc);
|
|
||||||
connectToMemFunc(virtPort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -155,36 +140,17 @@ ThreadState::profileSample()
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
TranslatingPort *
|
SETranslatingPortProxy *
|
||||||
ThreadState::getMemPort()
|
ThreadState::getMemProxy()
|
||||||
{
|
{
|
||||||
if (port != NULL)
|
if (proxy != NULL)
|
||||||
return port;
|
return proxy;
|
||||||
|
|
||||||
/* Use this port to for syscall emulation writes to memory. */
|
/* Use this port proxy to for syscall emulation writes to memory. */
|
||||||
port = new TranslatingPort(csprintf("%s-%d-funcport", baseCpu->name(), _threadId),
|
proxy = new SETranslatingPortProxy(*process->system->getSystemPort(),
|
||||||
process, TranslatingPort::NextPage);
|
process,
|
||||||
|
SETranslatingPortProxy::NextPage);
|
||||||
|
|
||||||
connectToMemFunc(port);
|
return proxy;
|
||||||
|
|
||||||
return port;
|
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -54,8 +54,9 @@ namespace TheISA {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Checkpoint;
|
class Checkpoint;
|
||||||
class Port;
|
class PortProxy;
|
||||||
class TranslatingPort;
|
class SETranslatingPort;
|
||||||
|
class FSTranslatingPort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Struct for holding general thread state that is needed across CPU
|
* Struct for holding general thread state that is needed across CPU
|
||||||
|
@ -93,11 +94,13 @@ struct ThreadState {
|
||||||
Tick readLastSuspend() { return lastSuspend; }
|
Tick readLastSuspend() { return lastSuspend; }
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
void connectMemPorts(ThreadContext *tc);
|
/**
|
||||||
|
* Initialise the physical and virtual port proxies and tie them to
|
||||||
void connectPhysPort();
|
* the data port of the CPU.
|
||||||
|
*
|
||||||
void connectVirtPort(ThreadContext *tc);
|
* tc ThreadContext for the virtual-to-physical translation
|
||||||
|
*/
|
||||||
|
void initMemProxies(ThreadContext *tc);
|
||||||
|
|
||||||
void dumpFuncProfile();
|
void dumpFuncProfile();
|
||||||
|
|
||||||
|
@ -109,17 +112,13 @@ struct ThreadState {
|
||||||
|
|
||||||
TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; }
|
TheISA::Kernel::Statistics *getKernelStats() { return kernelStats; }
|
||||||
|
|
||||||
FunctionalPort *getPhysPort() { return physPort; }
|
PortProxy* getPhysProxy() { return physProxy; }
|
||||||
|
|
||||||
void setPhysPort(FunctionalPort *port) { physPort = port; }
|
FSTranslatingPortProxy* getVirtProxy() { return virtProxy; }
|
||||||
|
|
||||||
VirtualPort *getVirtPort() { return virtPort; }
|
|
||||||
#else
|
#else
|
||||||
Process *getProcessPtr() { return process; }
|
Process *getProcessPtr() { return process; }
|
||||||
|
|
||||||
TranslatingPort *getMemPort();
|
SETranslatingPortProxy* getMemProxy();
|
||||||
|
|
||||||
void setMemPort(TranslatingPort *_port) { port = _port; }
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Reads the number of instructions functionally executed and
|
/** Reads the number of instructions functionally executed and
|
||||||
|
@ -139,9 +138,6 @@ struct ThreadState {
|
||||||
void setStatus(Status new_status) { _status = new_status; }
|
void setStatus(Status new_status) { _status = new_status; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Connects port to the functional port of the memory object
|
|
||||||
* below the CPU. */
|
|
||||||
void connectToMemFunc(Port *port);
|
|
||||||
|
|
||||||
/** Number of instructions committed. */
|
/** Number of instructions committed. */
|
||||||
Counter numInst;
|
Counter numInst;
|
||||||
|
@ -186,15 +182,15 @@ struct ThreadState {
|
||||||
|
|
||||||
TheISA::Kernel::Statistics *kernelStats;
|
TheISA::Kernel::Statistics *kernelStats;
|
||||||
protected:
|
protected:
|
||||||
/** A functional port outgoing only for functional accesses to physical
|
/** A port proxy outgoing only for functional accesses to physical
|
||||||
* addresses.*/
|
* addresses.*/
|
||||||
FunctionalPort *physPort;
|
PortProxy *physProxy;
|
||||||
|
|
||||||
/** A functional port, outgoing only, for functional accesse to virtual
|
/** A translating port proxy, outgoing only, for functional
|
||||||
* addresses. */
|
* accesse to virtual addresses. */
|
||||||
VirtualPort *virtPort;
|
FSTranslatingPortProxy* virtProxy;
|
||||||
#else
|
#else
|
||||||
TranslatingPort *port;
|
SETranslatingPortProxy* proxy;
|
||||||
|
|
||||||
Process *process;
|
Process *process;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
#include "debug/SimpleDiskData.hh"
|
#include "debug/SimpleDiskData.hh"
|
||||||
#include "dev/disk_image.hh"
|
#include "dev/disk_image.hh"
|
||||||
#include "dev/simple_disk.hh"
|
#include "dev/simple_disk.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port_proxy.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -70,7 +70,7 @@ SimpleDisk::read(Addr addr, baddr_t block, int count) const
|
||||||
for (int i = 0, j = 0; i < count; i += SectorSize, j++)
|
for (int i = 0, j = 0; i < count; i += SectorSize, j++)
|
||||||
image->read(data + i, block + 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);
|
DPRINTF(SimpleDisk, "read block=%#x len=%d\n", (uint64_t)block, count);
|
||||||
DDUMP(SimpleDiskData, data, count);
|
DDUMP(SimpleDiskData, data, count);
|
||||||
|
|
|
@ -69,7 +69,7 @@ typedef struct stat global_stat;
|
||||||
typedef struct statfs global_statfs;
|
typedef struct statfs global_statfs;
|
||||||
typedef struct dirent global_dirent;
|
typedef struct dirent global_dirent;
|
||||||
|
|
||||||
class TranslatingPort;
|
class SETranslatingPortProxy;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// This class encapsulates the types, structures, constants,
|
/// This class encapsulates the types, structures, constants,
|
||||||
|
@ -404,7 +404,8 @@ class Tru64 : public OperatingSystem
|
||||||
/// memory space. Used by statfs() and fstatfs().
|
/// memory space. Used by statfs() and fstatfs().
|
||||||
template <class T>
|
template <class T>
|
||||||
static void
|
static void
|
||||||
copyOutStatfsBuf(TranslatingPort *mem, Addr addr, global_statfs *host)
|
copyOutStatfsBuf(SETranslatingPortProxy *mem, Addr addr,
|
||||||
|
global_statfs *host)
|
||||||
{
|
{
|
||||||
using namespace TheISA;
|
using namespace TheISA;
|
||||||
|
|
||||||
|
@ -453,7 +454,7 @@ class Tru64 : public OperatingSystem
|
||||||
|
|
||||||
// just pass basep through uninterpreted.
|
// just pass basep through uninterpreted.
|
||||||
TypedBufferArg<int64_t> basep(tgt_basep);
|
TypedBufferArg<int64_t> basep(tgt_basep);
|
||||||
basep.copyIn(tc->getMemPort());
|
basep.copyIn(tc->getMemProxy());
|
||||||
long host_basep = (off_t)htog((int64_t)*basep);
|
long host_basep = (off_t)htog((int64_t)*basep);
|
||||||
int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep);
|
int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep);
|
||||||
|
|
||||||
|
@ -480,7 +481,7 @@ class Tru64 : public OperatingSystem
|
||||||
tgt_dp->d_reclen = tgt_bufsize;
|
tgt_dp->d_reclen = tgt_bufsize;
|
||||||
tgt_dp->d_namlen = namelen;
|
tgt_dp->d_namlen = namelen;
|
||||||
strcpy(tgt_dp->d_name, host_dp->d_name);
|
strcpy(tgt_dp->d_name, host_dp->d_name);
|
||||||
tgt_dp.copyOut(tc->getMemPort());
|
tgt_dp.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
tgt_buf_ptr += tgt_bufsize;
|
tgt_buf_ptr += tgt_bufsize;
|
||||||
host_buf_ptr += host_dp->d_reclen;
|
host_buf_ptr += host_dp->d_reclen;
|
||||||
|
@ -489,7 +490,7 @@ class Tru64 : public OperatingSystem
|
||||||
delete [] host_buf;
|
delete [] host_buf;
|
||||||
|
|
||||||
*basep = htog((int64_t)host_basep);
|
*basep = htog((int64_t)host_basep);
|
||||||
basep.copyOut(tc->getMemPort());
|
basep.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return tgt_buf_ptr - tgt_buf;
|
return tgt_buf_ptr - tgt_buf;
|
||||||
#endif
|
#endif
|
||||||
|
@ -505,7 +506,7 @@ class Tru64 : public OperatingSystem
|
||||||
int index = 0;
|
int index = 0;
|
||||||
TypedBufferArg<Tru64::sigcontext> sc(process->getSyscallArg(tc, index));
|
TypedBufferArg<Tru64::sigcontext> sc(process->getSyscallArg(tc, index));
|
||||||
|
|
||||||
sc.copyIn(tc->getMemPort());
|
sc.copyIn(tc->getMemProxy());
|
||||||
|
|
||||||
// Restore state from sigcontext structure.
|
// Restore state from sigcontext structure.
|
||||||
// Note that we'll advance PC <- NPC before the end of the cycle,
|
// Note that we'll advance PC <- NPC before the end of the cycle,
|
||||||
|
@ -540,7 +541,7 @@ class Tru64 : public OperatingSystem
|
||||||
int index = 0;
|
int index = 0;
|
||||||
TypedBufferArg<Tru64::vm_stack> argp(process->getSyscallArg(tc, index));
|
TypedBufferArg<Tru64::vm_stack> argp(process->getSyscallArg(tc, index));
|
||||||
|
|
||||||
argp.copyIn(tc->getMemPort());
|
argp.copyIn(tc->getMemProxy());
|
||||||
|
|
||||||
int stack_size =
|
int stack_size =
|
||||||
gtoh(argp->rsize) + gtoh(argp->ysize) + gtoh(argp->gsize);
|
gtoh(argp->rsize) + gtoh(argp->ysize) + gtoh(argp->gsize);
|
||||||
|
@ -567,7 +568,7 @@ class Tru64 : public OperatingSystem
|
||||||
process->allocateMem(rounded_stack_base, rounded_stack_size);
|
process->allocateMem(rounded_stack_base, rounded_stack_size);
|
||||||
|
|
||||||
argp->address = gtoh(rounded_stack_base);
|
argp->address = gtoh(rounded_stack_base);
|
||||||
argp.copyOut(tc->getMemPort());
|
argp.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -591,7 +592,7 @@ class Tru64 : public OperatingSystem
|
||||||
attrp(process->getSyscallArg(tc, index));
|
attrp(process->getSyscallArg(tc, index));
|
||||||
TypedBufferArg<Addr> configptr_ptr(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) {
|
if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) {
|
||||||
cerr << "nxm_task_init: thread library version mismatch! "
|
cerr << "nxm_task_init: thread library version mismatch! "
|
||||||
|
@ -685,10 +686,10 @@ class Tru64 : public OperatingSystem
|
||||||
int size = cur_addr - base_addr;
|
int size = cur_addr - base_addr;
|
||||||
process->allocateMem(base_addr, roundUp(size, VMPageSize));
|
process->allocateMem(base_addr, roundUp(size, VMPageSize));
|
||||||
|
|
||||||
config.copyOut(tc->getMemPort());
|
config.copyOut(tc->getMemProxy());
|
||||||
slot_state.copyOut(tc->getMemPort());
|
slot_state.copyOut(tc->getMemProxy());
|
||||||
rad_state.copyOut(tc->getMemPort());
|
rad_state.copyOut(tc->getMemProxy());
|
||||||
configptr_ptr.copyOut(tc->getMemPort());
|
configptr_ptr.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -727,7 +728,7 @@ class Tru64 : public OperatingSystem
|
||||||
int thread_index = process->getSyscallArg(tc, index);
|
int thread_index = process->getSyscallArg(tc, index);
|
||||||
|
|
||||||
// get attribute args
|
// get attribute args
|
||||||
attrp.copyIn(tc->getMemPort());
|
attrp.copyIn(tc->getMemProxy());
|
||||||
|
|
||||||
if (gtoh(attrp->version) != NXM_LIB_VERSION) {
|
if (gtoh(attrp->version) != NXM_LIB_VERSION) {
|
||||||
cerr << "nxm_thread_create: thread library version mismatch! "
|
cerr << "nxm_thread_create: thread library version mismatch! "
|
||||||
|
@ -752,7 +753,7 @@ class Tru64 : public OperatingSystem
|
||||||
|
|
||||||
TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000,
|
TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000,
|
||||||
rad_state_size);
|
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);
|
uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset);
|
||||||
|
|
||||||
|
@ -763,7 +764,7 @@ class Tru64 : public OperatingSystem
|
||||||
|
|
||||||
// This is supposed to be a port number. Make something up.
|
// This is supposed to be a port number. Make something up.
|
||||||
*kidp = htog(99);
|
*kidp = htog(99);
|
||||||
kidp.copyOut(tc->getMemPort());
|
kidp.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) {
|
} else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) {
|
||||||
|
@ -777,7 +778,7 @@ class Tru64 : public OperatingSystem
|
||||||
ssp->nxm_u.pth_id = attrp->pthid;
|
ssp->nxm_u.pth_id = attrp->pthid;
|
||||||
ssp->nxm_u.nxm_active = htog(uniq_val | 1);
|
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);
|
Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info);
|
||||||
int slot_state_size =
|
int slot_state_size =
|
||||||
|
@ -787,7 +788,7 @@ class Tru64 : public OperatingSystem
|
||||||
slot_state(slot_state_addr,
|
slot_state(slot_state_addr,
|
||||||
slot_state_size);
|
slot_state_size);
|
||||||
|
|
||||||
slot_state.copyIn(tc->getMemPort());
|
slot_state.copyIn(tc->getMemProxy());
|
||||||
|
|
||||||
if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) {
|
if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) {
|
||||||
cerr << "nxm_thread_createFunc: requested VP slot "
|
cerr << "nxm_thread_createFunc: requested VP slot "
|
||||||
|
@ -799,7 +800,7 @@ class Tru64 : public OperatingSystem
|
||||||
// doesn't work anyway
|
// doesn't work anyway
|
||||||
slot_state[thread_index] = Tru64::NXM_SLOT_BOUND;
|
slot_state[thread_index] = Tru64::NXM_SLOT_BOUND;
|
||||||
|
|
||||||
slot_state.copyOut(tc->getMemPort());
|
slot_state.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
// Find a free simulator thread context.
|
// Find a free simulator thread context.
|
||||||
ThreadContext *tc = process->findFreeContext();
|
ThreadContext *tc = process->findFreeContext();
|
||||||
|
@ -811,7 +812,7 @@ class Tru64 : public OperatingSystem
|
||||||
// and get away with just sticking the thread index
|
// and get away with just sticking the thread index
|
||||||
// here.
|
// here.
|
||||||
*kidp = htog(thread_index);
|
*kidp = htog(thread_index);
|
||||||
kidp.copyOut(tc->getMemPort());
|
kidp.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -952,12 +953,12 @@ class Tru64 : public OperatingSystem
|
||||||
|
|
||||||
TypedBufferArg<uint64_t> lockp(uaddr);
|
TypedBufferArg<uint64_t> lockp(uaddr);
|
||||||
|
|
||||||
lockp.copyIn(tc->getMemPort());
|
lockp.copyIn(tc->getMemProxy());
|
||||||
|
|
||||||
if (gtoh(*lockp) == 0) {
|
if (gtoh(*lockp) == 0) {
|
||||||
// lock is free: grab it
|
// lock is free: grab it
|
||||||
*lockp = htog(1);
|
*lockp = htog(1);
|
||||||
lockp.copyOut(tc->getMemPort());
|
lockp.copyOut(tc->getMemProxy());
|
||||||
} else {
|
} else {
|
||||||
// lock is busy: disable until free
|
// lock is busy: disable until free
|
||||||
process->waitList.push_back(Process::WaitRec(uaddr, tc));
|
process->waitList.push_back(Process::WaitRec(uaddr, tc));
|
||||||
|
@ -971,7 +972,7 @@ class Tru64 : public OperatingSystem
|
||||||
{
|
{
|
||||||
TypedBufferArg<uint64_t> lockp(uaddr);
|
TypedBufferArg<uint64_t> lockp(uaddr);
|
||||||
|
|
||||||
lockp.copyIn(tc->getMemPort());
|
lockp.copyIn(tc->getMemProxy());
|
||||||
assert(*lockp != 0);
|
assert(*lockp != 0);
|
||||||
|
|
||||||
// Check for a process waiting on the lock.
|
// Check for a process waiting on the lock.
|
||||||
|
@ -980,7 +981,7 @@ class Tru64 : public OperatingSystem
|
||||||
// clear lock field if no waiting context is taking over the lock
|
// clear lock field if no waiting context is taking over the lock
|
||||||
if (num_waiting == 0) {
|
if (num_waiting == 0) {
|
||||||
*lockp = 0;
|
*lockp = 0;
|
||||||
lockp.copyOut(tc->getMemPort());
|
lockp.copyOut(tc->getMemProxy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1011,12 +1012,12 @@ class Tru64 : public OperatingSystem
|
||||||
Addr uaddr = process->getSyscallArg(tc, index);
|
Addr uaddr = process->getSyscallArg(tc, index);
|
||||||
TypedBufferArg<uint64_t> lockp(uaddr);
|
TypedBufferArg<uint64_t> lockp(uaddr);
|
||||||
|
|
||||||
lockp.copyIn(tc->getMemPort());
|
lockp.copyIn(tc->getMemProxy());
|
||||||
|
|
||||||
if (gtoh(*lockp) == 0) {
|
if (gtoh(*lockp) == 0) {
|
||||||
// lock is free: grab it
|
// lock is free: grab it
|
||||||
*lockp = htog(1);
|
*lockp = htog(1);
|
||||||
lockp.copyOut(tc->getMemPort());
|
lockp.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1077,7 +1078,7 @@ class Tru64 : public OperatingSystem
|
||||||
TypedBufferArg<uint64_t> lockp(lock_addr);
|
TypedBufferArg<uint64_t> lockp(lock_addr);
|
||||||
|
|
||||||
// user is supposed to acquire lock before entering
|
// user is supposed to acquire lock before entering
|
||||||
lockp.copyIn(tc->getMemPort());
|
lockp.copyIn(tc->getMemProxy());
|
||||||
assert(gtoh(*lockp) != 0);
|
assert(gtoh(*lockp) != 0);
|
||||||
|
|
||||||
m5_unlock_mutex(lock_addr, process, tc);
|
m5_unlock_mutex(lock_addr, process, tc);
|
||||||
|
@ -1166,13 +1167,13 @@ class Tru64_F64 : public Tru64
|
||||||
|
|
||||||
typedef F64_stat tgt_stat;
|
typedef F64_stat tgt_stat;
|
||||||
/*
|
/*
|
||||||
static void copyOutStatBuf(TranslatingPort *mem, Addr addr,
|
static void copyOutStatBuf(SETranslatingPortProxy *mem, Addr addr,
|
||||||
global_stat *host)
|
global_stat *host)
|
||||||
{
|
{
|
||||||
Tru64::copyOutStatBuf<Tru64::F64_stat>(mem, addr, 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)
|
global_statfs *host)
|
||||||
{
|
{
|
||||||
Tru64::copyOutStatfsBuf<Tru64::F64_statfs>(mem, addr, host);
|
Tru64::copyOutStatfsBuf<Tru64::F64_statfs>(mem, addr, host);
|
||||||
|
@ -1212,13 +1213,13 @@ class Tru64_PreF64 : public Tru64
|
||||||
|
|
||||||
typedef pre_F64_stat tgt_stat;
|
typedef pre_F64_stat tgt_stat;
|
||||||
/*
|
/*
|
||||||
static void copyOutStatBuf(TranslatingPort *mem, Addr addr,
|
static void copyOutStatBuf(SETranslatingPortProxy *mem, Addr addr,
|
||||||
global_stat *host)
|
global_stat *host)
|
||||||
{
|
{
|
||||||
Tru64::copyOutStatBuf<Tru64::pre_F64_stat>(mem, addr, 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)
|
global_statfs *host)
|
||||||
{
|
{
|
||||||
Tru64::copyOutStatfsBuf<Tru64::pre_F64_statfs>(mem, addr, host);
|
Tru64::copyOutStatfsBuf<Tru64::pre_F64_statfs>(mem, addr, host);
|
||||||
|
|
|
@ -62,7 +62,9 @@ BadAddrEvent::process(ThreadContext *tc)
|
||||||
AddrRangeIter iter;
|
AddrRangeIter iter;
|
||||||
bool found = false;
|
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++) {
|
for (iter = resp.begin(); iter != resp.end(); iter++) {
|
||||||
if (*iter == (K0Seg2Phys(a0) & PAddrImplMask))
|
if (*iter == (K0Seg2Phys(a0) & PAddrImplMask))
|
||||||
found = true;
|
found = true;
|
||||||
|
|
|
@ -48,10 +48,10 @@ if env['TARGET_ISA'] != 'no':
|
||||||
Source('physical.cc')
|
Source('physical.cc')
|
||||||
|
|
||||||
if env['FULL_SYSTEM']:
|
if env['FULL_SYSTEM']:
|
||||||
Source('vport.cc')
|
Source('fs_translating_port_proxy.cc')
|
||||||
elif env['TARGET_ISA'] != 'no':
|
elif env['TARGET_ISA'] != 'no':
|
||||||
Source('page_table.cc')
|
Source('page_table.cc')
|
||||||
Source('translating_port.cc')
|
Source('se_translating_port_proxy.cc')
|
||||||
|
|
||||||
DebugFlag('Bus')
|
DebugFlag('Bus')
|
||||||
DebugFlag('BusAddrRanges')
|
DebugFlag('BusAddrRanges')
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
* Copyright (c) 2006 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -26,6 +38,7 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* Authors: Ali Saidi
|
* Authors: Ali Saidi
|
||||||
|
* Andreas Hansson
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,49 +47,81 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "base/chunk_generator.hh"
|
#include "base/chunk_generator.hh"
|
||||||
#include "config/the_isa.hh"
|
#include "cpu/base.hh"
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
|
|
||||||
|
using namespace TheISA;
|
||||||
|
|
||||||
|
FSTranslatingPortProxy::FSTranslatingPortProxy(ThreadContext *tc)
|
||||||
|
: PortProxy(*(tc->getCpuPtr()->getPort("dcache_port"))), _tc(tc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FSTranslatingPortProxy::FSTranslatingPortProxy(Port &port)
|
||||||
|
: PortProxy(port), _tc(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FSTranslatingPortProxy::~FSTranslatingPortProxy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VirtualPort::readBlob(Addr addr, uint8_t *p, int size)
|
FSTranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size)
|
||||||
{
|
{
|
||||||
Addr paddr;
|
Addr paddr;
|
||||||
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
|
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
|
||||||
gen.next())
|
gen.next())
|
||||||
{
|
{
|
||||||
if (tc)
|
if (_tc)
|
||||||
paddr = TheISA::vtophys(tc,gen.addr());
|
paddr = TheISA::vtophys(_tc,gen.addr());
|
||||||
else
|
else
|
||||||
paddr = TheISA::vtophys(gen.addr());
|
paddr = TheISA::vtophys(gen.addr());
|
||||||
|
|
||||||
FunctionalPort::readBlob(paddr, p, gen.size());
|
PortProxy::readBlob(paddr, p, gen.size());
|
||||||
p += gen.size();
|
p += gen.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VirtualPort::writeBlob(Addr addr, uint8_t *p, int size)
|
FSTranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size)
|
||||||
{
|
{
|
||||||
Addr paddr;
|
Addr paddr;
|
||||||
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
|
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
|
||||||
gen.next())
|
gen.next())
|
||||||
{
|
{
|
||||||
if (tc)
|
if (_tc)
|
||||||
paddr = TheISA::vtophys(tc,gen.addr());
|
paddr = TheISA::vtophys(_tc,gen.addr());
|
||||||
else
|
else
|
||||||
paddr = TheISA::vtophys(gen.addr());
|
paddr = TheISA::vtophys(gen.addr());
|
||||||
|
|
||||||
FunctionalPort::writeBlob(paddr, p, gen.size());
|
PortProxy::writeBlob(paddr, p, gen.size());
|
||||||
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
|
void
|
||||||
CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
|
CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
|
||||||
{
|
{
|
||||||
uint8_t *dst = (uint8_t *)dest;
|
uint8_t *dst = (uint8_t *)dest;
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
|
|
||||||
vp->readBlob(src, dst, cplen);
|
vp->readBlob(src, dst, cplen);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +130,7 @@ void
|
||||||
CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
|
CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
|
||||||
{
|
{
|
||||||
uint8_t *src = (uint8_t *)source;
|
uint8_t *src = (uint8_t *)source;
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
|
|
||||||
vp->writeBlob(dest, src, cplen);
|
vp->writeBlob(dest, src, cplen);
|
||||||
}
|
}
|
||||||
|
@ -95,7 +140,7 @@ CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
char *start = dst;
|
char *start = dst;
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
|
vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
|
||||||
|
@ -107,7 +152,7 @@ CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
|
||||||
void
|
void
|
||||||
CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
|
CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
|
||||||
{
|
{
|
||||||
VirtualPort *vp = tc->getVirtPort();
|
FSTranslatingPortProxy* vp = tc->getVirtProxy();
|
||||||
for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();
|
for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();
|
||||||
gen.next())
|
gen.next())
|
||||||
{
|
{
|
|
@ -1,4 +1,16 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
* Copyright (c) 2006 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -26,45 +38,49 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* Authors: Ali Saidi
|
* Authors: Ali Saidi
|
||||||
|
* Andreas Hansson
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* Virtual Port Object Declaration. These ports incorporate some translation
|
* TranslatingPortProxy Object Declaration for FS.
|
||||||
* into their access methods. Thus you can use one to read and write data
|
*
|
||||||
* to/from virtual addresses.
|
* Port proxies are used when non structural entities need access to
|
||||||
|
* the memory system. Proxy objects replace the previous
|
||||||
|
* FunctionalPort, TranslatingPort and VirtualPort objects, which
|
||||||
|
* provided the same functionality as the proxies, but were instances
|
||||||
|
* of ports not corresponding to real structural ports of the
|
||||||
|
* simulated system. Via the port proxies all the accesses go through
|
||||||
|
* an actual port and thus are transparent to a potentially
|
||||||
|
* distributed memory and automatically adhere to the memory map of
|
||||||
|
* the system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MEM_VPORT_HH__
|
#ifndef __MEM_FS_PORT_PROXY_HH__
|
||||||
#define __MEM_VPORT_HH__
|
#define __MEM_FS_PORT_PROXY_HH__
|
||||||
|
|
||||||
#include "arch/vtophys.hh"
|
#include "arch/vtophys.hh"
|
||||||
#include "config/full_system.hh"
|
#include "mem/port_proxy.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
|
* A TranslatingPortProxy in FS mode translates a virtual address to a
|
||||||
* address can alway be translated, If not it can only be translated if it is a
|
* physical address and then calls the read/write functions of the
|
||||||
* simple address masking operation (such as alpha super page accesses).
|
* 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
|
||||||
|
|
||||||
class VirtualPort : public FunctionalPort
|
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
ThreadContext *tc;
|
ThreadContext* _tc;
|
||||||
|
|
||||||
public:
|
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
|
FSTranslatingPortProxy(ThreadContext* tc);
|
||||||
* prevent someone from accidently deleting the cpus statically
|
|
||||||
* allocated vport.
|
FSTranslatingPortProxy(Port &port);
|
||||||
* @return true if a thread context isn't valid
|
|
||||||
*/
|
virtual ~FSTranslatingPortProxy();
|
||||||
bool nullThreadContext() { return tc != NULL; }
|
|
||||||
|
|
||||||
/** Version of readblob that translates virt->phys and deals
|
/** Version of readblob that translates virt->phys and deals
|
||||||
* with page boundries. */
|
* with page boundries. */
|
||||||
|
@ -73,13 +89,16 @@ class VirtualPort : public FunctionalPort
|
||||||
/** Version of writeBlob that translates virt->phys and deals
|
/** Version of writeBlob that translates virt->phys and deals
|
||||||
* with page boundries. */
|
* with page boundries. */
|
||||||
virtual void writeBlob(Addr addr, uint8_t *p, int size);
|
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 CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen);
|
||||||
void CopyIn(ThreadContext *tc, Addr dest, void *source, 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 CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
|
||||||
void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
|
void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
|
||||||
|
|
||||||
#endif //__MEM_VPORT_HH__
|
#endif //__MEM_FS_PORT_PROXY_HH__
|
||||||
|
|
|
@ -255,48 +255,4 @@ class Port : public EventManager
|
||||||
void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd);
|
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__
|
#endif //__MEM_PORT_HH__
|
||||||
|
|
174
src/mem/port_proxy.hh
Normal file
174
src/mem/port_proxy.hh
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met: redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer;
|
||||||
|
* redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution;
|
||||||
|
* neither the name of the copyright holders nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Andreas Hansson
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* PortProxy Object Declaration.
|
||||||
|
*
|
||||||
|
* Port proxies are used when non structural entities need access to
|
||||||
|
* the memory system. Proxy objects replace the previous
|
||||||
|
* FunctionalPort, TranslatingPort and VirtualPort objects, which
|
||||||
|
* provided the same functionality as the proxies, but were instances
|
||||||
|
* of ports not corresponding to real structural ports of the
|
||||||
|
* simulated system. Via the port proxies all the accesses go through
|
||||||
|
* an actual port and thus are transparent to a potentially
|
||||||
|
* distributed memory and automatically adhere to the memory map of
|
||||||
|
* the system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MEM_PORT_PROXY_HH__
|
||||||
|
#define __MEM_PORT_PROXY_HH__
|
||||||
|
|
||||||
|
#include "config/the_isa.hh"
|
||||||
|
#if THE_ISA != NO_ISA
|
||||||
|
#include "arch/isa_traits.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "base/types.hh"
|
||||||
|
#include "mem/port.hh"
|
||||||
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This object is a proxy for a structural port,
|
||||||
|
* to be used for debug accesses.
|
||||||
|
*
|
||||||
|
* This proxy object is used when non structural entities
|
||||||
|
* (e.g. thread contexts, object file loaders) need access to the
|
||||||
|
* memory system. It calls the corresponding functions on the underlying
|
||||||
|
* structural port, and provides templatized convenience access functions.
|
||||||
|
*
|
||||||
|
* The addresses are interpreted as physical addresses.
|
||||||
|
*
|
||||||
|
* @sa SETranslatingProxy
|
||||||
|
* @sa FSTranslatingProxy
|
||||||
|
*/
|
||||||
|
class PortProxy
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Port &_port;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PortProxy(Port &port) : _port(port) { }
|
||||||
|
virtual ~PortProxy() { }
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Read size bytes memory at address and store in p.
|
||||||
|
*/
|
||||||
|
virtual void readBlob(Addr address, uint8_t* p, int size)
|
||||||
|
{ _port.readBlob(address, p, size); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write size bytes from p to address.
|
||||||
|
*/
|
||||||
|
virtual void writeBlob(Addr address, uint8_t* p, int size)
|
||||||
|
{ _port.writeBlob(address, p, size); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill size bytes starting at addr with byte value val.
|
||||||
|
*/
|
||||||
|
virtual void memsetBlob(Addr address, uint8_t v, int size)
|
||||||
|
{ _port.memsetBlob(address, v, size); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read sizeof(T) bytes from address and return as object T.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
T read(Addr address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write object T to address. Writes sizeof(T) bytes.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
void write(Addr address, T data);
|
||||||
|
|
||||||
|
#if THE_ISA != NO_ISA
|
||||||
|
/**
|
||||||
|
* Read sizeof(T) bytes from address and return as object T.
|
||||||
|
* Performs Guest to Host endianness transform.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
T readGtoH(Addr address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write object T to address. Writes sizeof(T) bytes.
|
||||||
|
* Performs Host to Guest endianness transform.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
void writeHtoG(Addr address, T data);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T
|
||||||
|
PortProxy::read(Addr address)
|
||||||
|
{
|
||||||
|
T data;
|
||||||
|
readBlob(address, (uint8_t*)&data, sizeof(T));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void
|
||||||
|
PortProxy::write(Addr address, T data)
|
||||||
|
{
|
||||||
|
writeBlob(address, (uint8_t*)&data, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if THE_ISA != NO_ISA
|
||||||
|
template <typename T>
|
||||||
|
T
|
||||||
|
PortProxy::readGtoH(Addr address)
|
||||||
|
{
|
||||||
|
T data;
|
||||||
|
readBlob(address, (uint8_t*)&data, sizeof(T));
|
||||||
|
return TheISA::gtoh(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void
|
||||||
|
PortProxy::writeHtoG(Addr address, T data)
|
||||||
|
{
|
||||||
|
data = TheISA::htog(data);
|
||||||
|
writeBlob(address, (uint8_t*)&data, sizeof(T));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __MEM_PORT_PROXY_HH__
|
|
@ -464,8 +464,11 @@ RubyPort::M5Port::recvFunctional(PacketPtr pkt)
|
||||||
// turn packet around to go back to requester if response expected
|
// turn packet around to go back to requester if response expected
|
||||||
if (needsResponse) {
|
if (needsResponse) {
|
||||||
pkt->setFunctionalResponseStatus(accessSucceeded);
|
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",
|
DPRINTF(RubyPort, "Functional access %s!\n",
|
||||||
accessSucceeded ? "successful":"failed");
|
accessSucceeded ? "successful":"failed");
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006 The Regents of The University of Michigan
|
* Copyright (c) 2011 ARM Limited
|
||||||
* All rights reserved.
|
* 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
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -25,29 +34,37 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* Authors: Ali Saidi
|
* Authors: Andreas Hansson
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "arch/isa_traits.hh"
|
#include "mem/ruby/system/RubyPortProxy.hh"
|
||||||
#include "config/the_isa.hh"
|
|
||||||
#include "mem/port.hh"
|
RubyPortProxy::RubyPortProxy(const RubyPortProxyParams* p) :
|
||||||
#include "sim/byteswap.hh"
|
RubyPort(p) {
|
||||||
|
}
|
||||||
|
|
||||||
|
RubyPortProxy::~RubyPortProxy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void
|
void
|
||||||
FunctionalPort::writeHtoG(Addr addr, T d)
|
RubyPortProxy::init()
|
||||||
{
|
{
|
||||||
d = TheISA::htog(d);
|
// Merely override to not care about the m_controller being NULL
|
||||||
writeBlob(addr, (uint8_t*)&d, sizeof(T));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RequestStatus
|
||||||
template <typename T>
|
RubyPortProxy::makeRequest(PacketPtr pkt)
|
||||||
T
|
|
||||||
FunctionalPort::readGtoH(Addr addr)
|
|
||||||
{
|
{
|
||||||
T d;
|
// This sequencer should only be used through the functional
|
||||||
readBlob(addr, (uint8_t*)&d, sizeof(T));
|
// accesses made by the system port and so simply fail if this
|
||||||
return TheISA::gtoh(d);
|
// happens.
|
||||||
|
panic("RubyPortProxy::makeRequest should not be called");
|
||||||
|
return RequestStatus_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RubyPortProxy*
|
||||||
|
RubyPortProxyParams::create()
|
||||||
|
{
|
||||||
|
return new RubyPortProxy(this);
|
||||||
|
}
|
114
src/mem/ruby/system/RubyPortProxy.hh
Normal file
114
src/mem/ruby/system/RubyPortProxy.hh
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met: redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer;
|
||||||
|
* redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution;
|
||||||
|
* neither the name of the copyright holders nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Authors: Andreas Hansson
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* RobyPortProxy for connecting system port to Ruby
|
||||||
|
*
|
||||||
|
* A trivial wrapper that allows the system port to connect to Ruby
|
||||||
|
* and use nothing but functional accesses.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MEM_RUBY_SYSTEM_RUBYPORTPROXY_HH__
|
||||||
|
#define __MEM_RUBY_SYSTEM_RUBYPORTPROXY_HH__
|
||||||
|
|
||||||
|
#include "mem/ruby/system/RubyPort.hh"
|
||||||
|
#include "params/RubyPortProxy.hh"
|
||||||
|
|
||||||
|
class RubyPortProxy : public RubyPort
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new RubyPortProxy.
|
||||||
|
*
|
||||||
|
* @param p Parameters inherited from the RubyPort
|
||||||
|
*/
|
||||||
|
RubyPortProxy(const RubyPortProxyParams* p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destruct a RubyPortProxy.
|
||||||
|
*/
|
||||||
|
virtual ~RubyPortProxy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise a RubyPortProxy by doing nothing and avoid
|
||||||
|
* involving the super class.
|
||||||
|
*/
|
||||||
|
void init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pure virtual member in the super class that we are forced to
|
||||||
|
* implement even if it is never used (since there are only
|
||||||
|
* functional accesses).
|
||||||
|
*
|
||||||
|
* @param pkt The packet to serve to Ruby
|
||||||
|
* @returns always a NULL status
|
||||||
|
*/
|
||||||
|
RequestStatus makeRequest(PacketPtr pkt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pure virtual member in the super class that we are forced to
|
||||||
|
* implement even if it is never used (since there are only
|
||||||
|
* functional accesses).
|
||||||
|
*
|
||||||
|
* @returns always 0
|
||||||
|
*/
|
||||||
|
int outstandingCount() const { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pure virtual member in the super class that we are forced to
|
||||||
|
* implement even if it is never used (since there are only
|
||||||
|
* functional accesses).
|
||||||
|
*
|
||||||
|
* @returns always false
|
||||||
|
*/
|
||||||
|
bool isDeadlockEventScheduled() const { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pure virtual member in the super class that we are forced to
|
||||||
|
* implement even if it is never used (since there are only
|
||||||
|
* functional accesses).
|
||||||
|
*/
|
||||||
|
void descheduleDeadlockEvent() { }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __MEM_RUBY_SYSTEM_RUBYPORTPROXY_HH__
|
|
@ -49,6 +49,7 @@ Source('WireBuffer.cc')
|
||||||
Source('MemoryNode.cc')
|
Source('MemoryNode.cc')
|
||||||
Source('PersistentTable.cc')
|
Source('PersistentTable.cc')
|
||||||
Source('RubyPort.cc')
|
Source('RubyPort.cc')
|
||||||
|
Source('RubyPortProxy.cc')
|
||||||
Source('Sequencer.cc')
|
Source('Sequencer.cc')
|
||||||
Source('System.cc')
|
Source('System.cc')
|
||||||
Source('TimerTable.cc')
|
Source('TimerTable.cc')
|
||||||
|
|
|
@ -44,6 +44,9 @@ class RubyPort(MemObject):
|
||||||
access_phys_mem = Param.Bool(True,
|
access_phys_mem = Param.Bool(True,
|
||||||
"should the rubyport atomically update phys_mem")
|
"should the rubyport atomically update phys_mem")
|
||||||
ruby_system = Param.RubySystem("")
|
ruby_system = Param.RubySystem("")
|
||||||
|
|
||||||
|
class RubyPortProxy(RubyPort):
|
||||||
|
type = 'RubyPortProxy'
|
||||||
|
|
||||||
class RubySequencer(RubyPort):
|
class RubySequencer(RubyPort):
|
||||||
type = 'RubySequencer'
|
type = 'RubySequencer'
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2001-2005 The Regents of The University of Michigan
|
* Copyright (c) 2001-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -27,6 +39,7 @@
|
||||||
*
|
*
|
||||||
* Authors: Ron Dreslinski
|
* Authors: Ron Dreslinski
|
||||||
* Steve Reinhardt
|
* Steve Reinhardt
|
||||||
|
* Andreas Hansson
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -34,23 +47,22 @@
|
||||||
#include "base/chunk_generator.hh"
|
#include "base/chunk_generator.hh"
|
||||||
#include "config/the_isa.hh"
|
#include "config/the_isa.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/se_translating_port_proxy.hh"
|
||||||
#include "mem/translating_port.hh"
|
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
|
|
||||||
using namespace TheISA;
|
using namespace TheISA;
|
||||||
|
|
||||||
TranslatingPort::TranslatingPort(const std::string &_name,
|
SETranslatingPortProxy::SETranslatingPortProxy(Port& port, Process *p,
|
||||||
Process *p, AllocType alloc)
|
AllocType alloc)
|
||||||
: FunctionalPort(_name), pTable(p->pTable), process(p),
|
: PortProxy(port), pTable(p->pTable), process(p),
|
||||||
allocating(alloc)
|
allocating(alloc)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
TranslatingPort::~TranslatingPort()
|
SETranslatingPortProxy::~SETranslatingPortProxy()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
|
SETranslatingPortProxy::tryReadBlob(Addr addr, uint8_t *p, int size)
|
||||||
{
|
{
|
||||||
Addr paddr;
|
Addr paddr;
|
||||||
int prevSize = 0;
|
int prevSize = 0;
|
||||||
|
@ -60,7 +72,7 @@ TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
|
||||||
if (!pTable->translate(gen.addr(),paddr))
|
if (!pTable->translate(gen.addr(),paddr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Port::readBlob(paddr, p + prevSize, gen.size());
|
PortProxy::readBlob(paddr, p + prevSize, gen.size());
|
||||||
prevSize += gen.size();
|
prevSize += gen.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +80,7 @@ TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
|
SETranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size)
|
||||||
{
|
{
|
||||||
if (!tryReadBlob(addr, p, size))
|
if (!tryReadBlob(addr, p, size))
|
||||||
fatal("readBlob(0x%x, ...) failed", addr);
|
fatal("readBlob(0x%x, ...) failed", addr);
|
||||||
|
@ -76,7 +88,7 @@ TranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
|
SETranslatingPortProxy::tryWriteBlob(Addr addr, uint8_t *p, int size)
|
||||||
{
|
{
|
||||||
|
|
||||||
Addr paddr;
|
Addr paddr;
|
||||||
|
@ -99,7 +111,7 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
|
||||||
pTable->translate(gen.addr(), paddr);
|
pTable->translate(gen.addr(), paddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Port::writeBlob(paddr, p + prevSize, gen.size());
|
PortProxy::writeBlob(paddr, p + prevSize, gen.size());
|
||||||
prevSize += gen.size();
|
prevSize += gen.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,14 +120,14 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TranslatingPort::writeBlob(Addr addr, uint8_t *p, int size)
|
SETranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size)
|
||||||
{
|
{
|
||||||
if (!tryWriteBlob(addr, p, size))
|
if (!tryWriteBlob(addr, p, size))
|
||||||
fatal("writeBlob(0x%x, ...) failed", addr);
|
fatal("writeBlob(0x%x, ...) failed", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size)
|
SETranslatingPortProxy::tryMemsetBlob(Addr addr, uint8_t val, int size)
|
||||||
{
|
{
|
||||||
Addr paddr;
|
Addr paddr;
|
||||||
|
|
||||||
|
@ -131,14 +143,14 @@ TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Port::memsetBlob(paddr, val, gen.size());
|
PortProxy::memsetBlob(paddr, val, gen.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size)
|
SETranslatingPortProxy::memsetBlob(Addr addr, uint8_t val, int size)
|
||||||
{
|
{
|
||||||
if (!tryMemsetBlob(addr, val, size))
|
if (!tryMemsetBlob(addr, val, size))
|
||||||
fatal("memsetBlob(0x%x, ...) failed", addr);
|
fatal("memsetBlob(0x%x, ...) failed", addr);
|
||||||
|
@ -146,7 +158,7 @@ TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size)
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TranslatingPort::tryWriteString(Addr addr, const char *str)
|
SETranslatingPortProxy::tryWriteString(Addr addr, const char *str)
|
||||||
{
|
{
|
||||||
Addr paddr,vaddr;
|
Addr paddr,vaddr;
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
@ -158,21 +170,21 @@ TranslatingPort::tryWriteString(Addr addr, const char *str)
|
||||||
if (!pTable->translate(vaddr++,paddr))
|
if (!pTable->translate(vaddr++,paddr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Port::writeBlob(paddr, &c, 1);
|
PortProxy::writeBlob(paddr, &c, 1);
|
||||||
} while (c);
|
} while (c);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TranslatingPort::writeString(Addr addr, const char *str)
|
SETranslatingPortProxy::writeString(Addr addr, const char *str)
|
||||||
{
|
{
|
||||||
if (!tryWriteString(addr, str))
|
if (!tryWriteString(addr, str))
|
||||||
fatal("writeString(0x%x, ...) failed", addr);
|
fatal("writeString(0x%x, ...) failed", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TranslatingPort::tryReadString(std::string &str, Addr addr)
|
SETranslatingPortProxy::tryReadString(std::string &str, Addr addr)
|
||||||
{
|
{
|
||||||
Addr paddr,vaddr;
|
Addr paddr,vaddr;
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
@ -183,7 +195,7 @@ TranslatingPort::tryReadString(std::string &str, Addr addr)
|
||||||
if (!pTable->translate(vaddr++,paddr))
|
if (!pTable->translate(vaddr++,paddr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Port::readBlob(paddr, &c, 1);
|
PortProxy::readBlob(paddr, &c, 1);
|
||||||
str += c;
|
str += c;
|
||||||
} while (c);
|
} while (c);
|
||||||
|
|
||||||
|
@ -191,7 +203,7 @@ TranslatingPort::tryReadString(std::string &str, Addr addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TranslatingPort::readString(std::string &str, Addr addr)
|
SETranslatingPortProxy::readString(std::string &str, Addr addr)
|
||||||
{
|
{
|
||||||
if (!tryReadString(str, addr))
|
if (!tryReadString(str, addr))
|
||||||
fatal("readString(0x%x, ...) failed", addr);
|
fatal("readString(0x%x, ...) failed", addr);
|
|
@ -1,4 +1,16 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2011 ARM Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* The license below extends only to copyright in the software and shall
|
||||||
|
* not be construed as granting a license to any other intellectual
|
||||||
|
* property including but not limited to intellectual property relating
|
||||||
|
* to a hardware implementation of the functionality of the software
|
||||||
|
* licensed hereunder. You may use the software subject to the license
|
||||||
|
* terms below provided that you ensure that this notice is replicated
|
||||||
|
* unmodified and in its entirety in all distributions of the software,
|
||||||
|
* modified or unmodified, in source code or in binary form.
|
||||||
|
*
|
||||||
* Copyright (c) 2001-2005 The Regents of The University of Michigan
|
* Copyright (c) 2001-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -27,18 +39,33 @@
|
||||||
*
|
*
|
||||||
* Authors: Ron Dreslinski
|
* Authors: Ron Dreslinski
|
||||||
* Ali Saidi
|
* Ali Saidi
|
||||||
|
* Andreas Hansson
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MEM_TRANSLATING_PROT_HH__
|
#ifndef __MEM_SE_TRANSLATING_PORT_PROXY_HH__
|
||||||
#define __MEM_TRANSLATING_PROT_HH__
|
#define __MEM_SE_TRANSLATING_PORT_PROXY_HH__
|
||||||
|
|
||||||
#include "mem/port.hh"
|
#include "mem/page_table.hh"
|
||||||
|
#include "mem/port_proxy.hh"
|
||||||
|
#include "sim/process.hh"
|
||||||
|
|
||||||
class PageTable;
|
/**
|
||||||
class Process;
|
* @file
|
||||||
|
* TranslatingPortProxy Object Declaration for SE.
|
||||||
class TranslatingPort : public FunctionalPort
|
*
|
||||||
|
* 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:
|
public:
|
||||||
enum AllocType {
|
enum AllocType {
|
||||||
Always,
|
Always,
|
||||||
|
@ -52,9 +79,8 @@ class TranslatingPort : public FunctionalPort
|
||||||
AllocType allocating;
|
AllocType allocating;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TranslatingPort(const std::string &_name,
|
SETranslatingPortProxy(Port& port, Process* p, AllocType alloc);
|
||||||
Process *p, AllocType alloc);
|
virtual ~SETranslatingPortProxy();
|
||||||
virtual ~TranslatingPort();
|
|
||||||
|
|
||||||
bool tryReadBlob(Addr addr, uint8_t *p, int size);
|
bool tryReadBlob(Addr addr, uint8_t *p, int size);
|
||||||
bool tryWriteBlob(Addr addr, uint8_t *p, int size);
|
bool tryWriteBlob(Addr addr, uint8_t *p, int size);
|
||||||
|
@ -70,4 +96,4 @@ class TranslatingPort : public FunctionalPort
|
||||||
void readString(std::string &str, Addr addr);
|
void readString(std::string &str, Addr addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // __MEM_SE_TRANSLATING_PORT_PROXY_HH__
|
|
@ -36,7 +36,7 @@
|
||||||
#include "arch/vtophys.hh"
|
#include "arch/vtophys.hh"
|
||||||
#include "base/refcnt.hh"
|
#include "base/refcnt.hh"
|
||||||
#include "base/types.hh"
|
#include "base/types.hh"
|
||||||
#include "mem/vport.hh"
|
#include "mem/fs_translating_port_proxy.hh"
|
||||||
|
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/physical.hh"
|
#include "mem/physical.hh"
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/se_translating_port_proxy.hh"
|
||||||
#include "params/LiveProcess.hh"
|
#include "params/LiveProcess.hh"
|
||||||
#include "params/Process.hh"
|
#include "params/Process.hh"
|
||||||
#include "sim/debug.hh"
|
#include "sim/debug.hh"
|
||||||
|
@ -244,12 +244,8 @@ Process::initState()
|
||||||
// mark this context as active so it will start ticking.
|
// mark this context as active so it will start ticking.
|
||||||
tc->activate(0);
|
tc->activate(0);
|
||||||
|
|
||||||
Port *mem_port;
|
initVirtMem = new SETranslatingPortProxy(*system->getSystemPort(), this,
|
||||||
mem_port = system->physmem->getPort("functional");
|
SETranslatingPortProxy::Always);
|
||||||
initVirtMem = new TranslatingPort("process init port", this,
|
|
||||||
TranslatingPort::Always);
|
|
||||||
mem_port->setPeer(initVirtMem);
|
|
||||||
initVirtMem->setPeer(mem_port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// map simulator fd sim_fd to target fd tgt_fd
|
// map simulator fd sim_fd to target fd tgt_fd
|
||||||
|
|
|
@ -57,7 +57,7 @@ class LiveProcessParams;
|
||||||
class SyscallDesc;
|
class SyscallDesc;
|
||||||
class System;
|
class System;
|
||||||
class ThreadContext;
|
class ThreadContext;
|
||||||
class TranslatingPort;
|
class SETranslatingPortProxy;
|
||||||
|
|
||||||
template<class IntType>
|
template<class IntType>
|
||||||
struct AuxVector
|
struct AuxVector
|
||||||
|
@ -132,7 +132,7 @@ class Process : public SimObject
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Memory object for initialization (image loading)
|
/// Memory object for initialization (image loading)
|
||||||
TranslatingPort *initVirtMem;
|
SETranslatingPortProxy *initVirtMem;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageTable *pTable;
|
PageTable *pTable;
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/se_translating_port_proxy.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
|
|
||||||
//This needs to be templated for cases where 32 bit pointers are needed.
|
//This needs to be templated for cases where 32 bit pointers are needed.
|
||||||
|
@ -52,21 +52,21 @@ template<class AddrType>
|
||||||
void
|
void
|
||||||
copyStringArray(std::vector<std::string> &strings,
|
copyStringArray(std::vector<std::string> &strings,
|
||||||
AddrType array_ptr, AddrType data_ptr,
|
AddrType array_ptr, AddrType data_ptr,
|
||||||
TranslatingPort* memPort)
|
SETranslatingPortProxy* memProxy)
|
||||||
{
|
{
|
||||||
AddrType data_ptr_swap;
|
AddrType data_ptr_swap;
|
||||||
for (std::vector<std::string>::size_type i = 0; i < strings.size(); ++i) {
|
for (std::vector<std::string>::size_type i = 0; i < strings.size(); ++i) {
|
||||||
data_ptr_swap = htog(data_ptr);
|
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));
|
sizeof(AddrType));
|
||||||
memPort->writeString(data_ptr, strings[i].c_str());
|
memProxy->writeString(data_ptr, strings[i].c_str());
|
||||||
array_ptr += sizeof(AddrType);
|
array_ptr += sizeof(AddrType);
|
||||||
data_ptr += strings[i].size() + 1;
|
data_ptr += strings[i].size() + 1;
|
||||||
}
|
}
|
||||||
// add NULL terminator
|
// add NULL terminator
|
||||||
data_ptr = 0;
|
data_ptr = 0;
|
||||||
|
|
||||||
memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType));
|
memProxy->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ brkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
// if the address is already there, zero it out
|
// if the address is already there, zero it out
|
||||||
else {
|
else {
|
||||||
uint8_t zero = 0;
|
uint8_t zero = 0;
|
||||||
TranslatingPort *tp = tc->getMemPort();
|
SETranslatingPortProxy *tp = tc->getMemProxy();
|
||||||
|
|
||||||
// split non-page aligned accesses
|
// split non-page aligned accesses
|
||||||
Addr next_page = roundUp(gen.addr(), VMPageSize);
|
Addr next_page = roundUp(gen.addr(), VMPageSize);
|
||||||
|
@ -221,7 +221,7 @@ readFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
|
int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
|
||||||
|
|
||||||
if (bytes_read != -1)
|
if (bytes_read != -1)
|
||||||
bufArg.copyOut(tc->getMemPort());
|
bufArg.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ writeFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
int nbytes = p->getSyscallArg(tc, index);
|
int nbytes = p->getSyscallArg(tc, index);
|
||||||
BufferArg bufArg(bufPtr, nbytes);
|
BufferArg bufArg(bufPtr, nbytes);
|
||||||
|
|
||||||
bufArg.copyIn(tc->getMemPort());
|
bufArg.copyIn(tc->getMemProxy());
|
||||||
|
|
||||||
int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
|
int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ _llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
// target platform
|
// target platform
|
||||||
BufferArg result_buf(result_ptr, sizeof(result));
|
BufferArg result_buf(result_ptr, sizeof(result));
|
||||||
memcpy(result_buf.bufferPtr(), &result, sizeof(result));
|
memcpy(result_buf.bufferPtr(), &result, sizeof(result));
|
||||||
result_buf.copyOut(tc->getMemPort());
|
result_buf.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ gethostnameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
|
|
||||||
strncpy((char *)name.bufferPtr(), hostname, name_len);
|
strncpy((char *)name.bufferPtr(), hostname, name_len);
|
||||||
|
|
||||||
name.copyOut(tc->getMemPort());
|
name.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -346,7 +346,7 @@ getcwdFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.copyOut(tc->getMemPort());
|
buf.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return (result == -1) ? -errno : result;
|
return (result == -1) ? -errno : result;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +358,7 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
string path;
|
string path;
|
||||||
|
|
||||||
int index = 0;
|
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;
|
return (TheISA::IntReg)-EFAULT;
|
||||||
|
|
||||||
// Adjust path for current working directory
|
// Adjust path for current working directory
|
||||||
|
@ -371,7 +371,7 @@ readlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
|
|
||||||
int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
|
int result = readlink(path.c_str(), (char *)buf.bufferPtr(), bufsiz);
|
||||||
|
|
||||||
buf.copyOut(tc->getMemPort());
|
buf.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return (result == -1) ? -errno : result;
|
return (result == -1) ? -errno : result;
|
||||||
}
|
}
|
||||||
|
@ -382,7 +382,7 @@ unlinkFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
string path;
|
string path;
|
||||||
|
|
||||||
int index = 0;
|
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;
|
return (TheISA::IntReg)-EFAULT;
|
||||||
|
|
||||||
// Adjust path for current working directory
|
// Adjust path for current working directory
|
||||||
|
@ -399,7 +399,7 @@ mkdirFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
string path;
|
string path;
|
||||||
|
|
||||||
int index = 0;
|
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;
|
return (TheISA::IntReg)-EFAULT;
|
||||||
|
|
||||||
// Adjust path for current working directory
|
// Adjust path for current working directory
|
||||||
|
@ -417,12 +417,12 @@ renameFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
string old_name;
|
string old_name;
|
||||||
|
|
||||||
int index = 0;
|
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;
|
return -EFAULT;
|
||||||
|
|
||||||
string new_name;
|
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;
|
return -EFAULT;
|
||||||
|
|
||||||
// Adjust path for current working directory
|
// Adjust path for current working directory
|
||||||
|
@ -439,7 +439,7 @@ truncateFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
string path;
|
string path;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
|
if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
off_t length = p->getSyscallArg(tc, index);
|
off_t length = p->getSyscallArg(tc, index);
|
||||||
|
@ -474,7 +474,7 @@ truncate64Func(SyscallDesc *desc, int num,
|
||||||
int index = 0;
|
int index = 0;
|
||||||
string path;
|
string path;
|
||||||
|
|
||||||
if (!tc->getMemPort()->tryReadString(path, process->getSyscallArg(tc, index)))
|
if (!tc->getMemProxy()->tryReadString(path, process->getSyscallArg(tc, index)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
int64_t length = process->getSyscallArg(tc, index, 64);
|
int64_t length = process->getSyscallArg(tc, index, 64);
|
||||||
|
@ -527,7 +527,7 @@ chownFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
|
||||||
string path;
|
string path;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!tc->getMemPort()->tryReadString(path, p->getSyscallArg(tc, index)))
|
if (!tc->getMemProxy()->tryReadString(path, p->getSyscallArg(tc, index)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
/* XXX endianess */
|
/* XXX endianess */
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "debug/SyscallVerbose.hh"
|
#include "debug/SyscallVerbose.hh"
|
||||||
#include "mem/page_table.hh"
|
#include "mem/page_table.hh"
|
||||||
#include "mem/translating_port.hh"
|
#include "mem/se_translating_port_proxy.hh"
|
||||||
#include "sim/byteswap.hh"
|
#include "sim/byteswap.hh"
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
|
@ -120,18 +120,18 @@ class BaseBufferArg {
|
||||||
//
|
//
|
||||||
// copy data into simulator space (read from target memory)
|
// 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
|
return true; // no EFAULT detection for now
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// copy data out of simulator space (write to target memory)
|
// 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
|
return true; // no EFAULT detection for now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,7 +463,7 @@ convertStat64Buf(target_stat &tgt, host_stat64 *host, bool fakeTTY = false)
|
||||||
//Here are a couple convenience functions
|
//Here are a couple convenience functions
|
||||||
template<class OS>
|
template<class OS>
|
||||||
static void
|
static void
|
||||||
copyOutStatBuf(TranslatingPort * mem, Addr addr,
|
copyOutStatBuf(SETranslatingPortProxy* mem, Addr addr,
|
||||||
hst_stat *host, bool fakeTTY = false)
|
hst_stat *host, bool fakeTTY = false)
|
||||||
{
|
{
|
||||||
typedef TypedBufferArg<typename OS::tgt_stat> tgt_stat_buf;
|
typedef TypedBufferArg<typename OS::tgt_stat> tgt_stat_buf;
|
||||||
|
@ -474,7 +474,7 @@ copyOutStatBuf(TranslatingPort * mem, Addr addr,
|
||||||
|
|
||||||
template<class OS>
|
template<class OS>
|
||||||
static void
|
static void
|
||||||
copyOutStat64Buf(TranslatingPort * mem, Addr addr,
|
copyOutStat64Buf(SETranslatingPortProxy* mem, Addr addr,
|
||||||
hst_stat64 *host, bool fakeTTY = false)
|
hst_stat64 *host, bool fakeTTY = false)
|
||||||
{
|
{
|
||||||
typedef TypedBufferArg<typename OS::tgt_stat64> tgt_stat_buf;
|
typedef TypedBufferArg<typename OS::tgt_stat64> tgt_stat_buf;
|
||||||
|
@ -529,7 +529,7 @@ openFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!tc->getMemPort()->tryReadString(path,
|
if (!tc->getMemProxy()->tryReadString(path,
|
||||||
process->getSyscallArg(tc, index)))
|
process->getSyscallArg(tc, index)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ sysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
sysinfo->uptime=seconds_since_epoch;
|
sysinfo->uptime=seconds_since_epoch;
|
||||||
sysinfo->totalram=process->system->memSize();
|
sysinfo->totalram=process->system->memSize();
|
||||||
|
|
||||||
sysinfo.copyOut(tc->getMemPort());
|
sysinfo.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -607,7 +607,7 @@ chmodFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!tc->getMemPort()->tryReadString(path,
|
if (!tc->getMemProxy()->tryReadString(path,
|
||||||
process->getSyscallArg(tc, index))) {
|
process->getSyscallArg(tc, index))) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
@ -713,7 +713,7 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!tc->getMemPort()->tryReadString(path,
|
if (!tc->getMemProxy()->tryReadString(path,
|
||||||
process->getSyscallArg(tc, index))) {
|
process->getSyscallArg(tc, index))) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
@ -728,7 +728,7 @@ statFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
|
copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -743,7 +743,7 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!tc->getMemPort()->tryReadString(path,
|
if (!tc->getMemProxy()->tryReadString(path,
|
||||||
process->getSyscallArg(tc, index)))
|
process->getSyscallArg(tc, index)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
Addr bufPtr = process->getSyscallArg(tc, index);
|
Addr bufPtr = process->getSyscallArg(tc, index);
|
||||||
|
@ -762,7 +762,7 @@ stat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
|
copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -793,7 +793,7 @@ fstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
|
copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (fd == 1));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -808,7 +808,7 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!tc->getMemPort()->tryReadString(path,
|
if (!tc->getMemProxy()->tryReadString(path,
|
||||||
process->getSyscallArg(tc, index))) {
|
process->getSyscallArg(tc, index))) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
@ -823,7 +823,7 @@ lstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
|
copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -837,7 +837,7 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!tc->getMemPort()->tryReadString(path,
|
if (!tc->getMemProxy()->tryReadString(path,
|
||||||
process->getSyscallArg(tc, index))) {
|
process->getSyscallArg(tc, index))) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
@ -857,7 +857,7 @@ lstat64Func(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
copyOutStat64Buf<OS>(tc->getMemPort(), bufPtr, &hostBuf);
|
copyOutStat64Buf<OS>(tc->getMemProxy(), bufPtr, &hostBuf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -883,7 +883,7 @@ fstatFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
copyOutStatBuf<OS>(tc->getMemPort(), bufPtr, &hostBuf, (fd == 1));
|
copyOutStatBuf<OS>(tc->getMemProxy(), bufPtr, &hostBuf, (fd == 1));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -898,7 +898,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!tc->getMemPort()->tryReadString(path,
|
if (!tc->getMemProxy()->tryReadString(path,
|
||||||
process->getSyscallArg(tc, index))) {
|
process->getSyscallArg(tc, index))) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
@ -913,7 +913,7 @@ statfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
|
OS::copyOutStatfsBuf(tc->getMemProxy(), bufPtr, &hostBuf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -938,7 +938,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
OS::copyOutStatfsBuf(tc->getMemPort(), bufPtr, &hostBuf);
|
OS::copyOutStatfsBuf(tc->getMemProxy(), bufPtr, &hostBuf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -957,7 +957,7 @@ writevFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
TranslatingPort *p = tc->getMemPort();
|
SETranslatingPortProxy *p = tc->getMemProxy();
|
||||||
uint64_t tiov_base = process->getSyscallArg(tc, index);
|
uint64_t tiov_base = process->getSyscallArg(tc, index);
|
||||||
size_t count = process->getSyscallArg(tc, index);
|
size_t count = process->getSyscallArg(tc, index);
|
||||||
struct iovec hiov[count];
|
struct iovec hiov[count];
|
||||||
|
@ -1102,7 +1102,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rlp.copyOut(tc->getMemPort());
|
rlp.copyOut(tc->getMemProxy());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,7 +1120,7 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
tp->tv_sec = TheISA::htog(tp->tv_sec);
|
tp->tv_sec = TheISA::htog(tp->tv_sec);
|
||||||
tp->tv_usec = TheISA::htog(tp->tv_usec);
|
tp->tv_usec = TheISA::htog(tp->tv_usec);
|
||||||
|
|
||||||
tp.copyOut(tc->getMemPort());
|
tp.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1135,14 +1135,14 @@ utimesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (!tc->getMemPort()->tryReadString(path,
|
if (!tc->getMemProxy()->tryReadString(path,
|
||||||
process->getSyscallArg(tc, index))) {
|
process->getSyscallArg(tc, index))) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedBufferArg<typename OS::timeval [2]>
|
TypedBufferArg<typename OS::timeval [2]>
|
||||||
tp(process->getSyscallArg(tc, index));
|
tp(process->getSyscallArg(tc, index));
|
||||||
tp.copyIn(tc->getMemPort());
|
tp.copyIn(tc->getMemProxy());
|
||||||
|
|
||||||
struct timeval hostTimeval[2];
|
struct timeval hostTimeval[2];
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
|
@ -1208,7 +1208,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
who);
|
who);
|
||||||
}
|
}
|
||||||
|
|
||||||
rup.copyOut(tc->getMemPort());
|
rup.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1233,7 +1233,7 @@ timesFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
bufp->tms_utime = htog(bufp->tms_utime);
|
bufp->tms_utime = htog(bufp->tms_utime);
|
||||||
|
|
||||||
// Write back
|
// Write back
|
||||||
bufp.copyOut(tc->getMemPort());
|
bufp.copyOut(tc->getMemProxy());
|
||||||
|
|
||||||
// Return clock ticks since system boot
|
// Return clock ticks since system boot
|
||||||
return clocks;
|
return clocks;
|
||||||
|
@ -1254,7 +1254,7 @@ timeFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||||
if(taddr != 0) {
|
if(taddr != 0) {
|
||||||
typename OS::time_t t = sec;
|
typename OS::time_t t = sec;
|
||||||
t = htog(t);
|
t = htog(t);
|
||||||
TranslatingPort *p = tc->getMemPort();
|
SETranslatingPortProxy *p = tc->getMemProxy();
|
||||||
p->writeBlob(taddr, (uint8_t*)&t, (int)sizeof(typename OS::time_t));
|
p->writeBlob(taddr, (uint8_t*)&t, (int)sizeof(typename OS::time_t));
|
||||||
}
|
}
|
||||||
return sec;
|
return sec;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue