Merge m5.eecs.umich.edu:/bk/newmem

into  ewok.(none):/home/gblack/m5/newmem

--HG--
extra : convert_revision : 08ae5e999d9b313e3e40cb6d58863905b70ca781
This commit is contained in:
Gabe Black 2006-03-31 20:32:18 -05:00
commit adeb458b87
21 changed files with 143 additions and 132 deletions

View file

@ -90,10 +90,8 @@ base_sources = Split('''
mem/connector.cc mem/connector.cc
mem/mem_object.cc mem/mem_object.cc
mem/page_table.cc
mem/physical.cc mem/physical.cc
mem/port.cc mem/port.cc
mem/translating_port.cc
mem/bus.cc mem/bus.cc
python/pyconfig.cc python/pyconfig.cc
@ -255,6 +253,8 @@ turbolaser_sources = Split('''
# Syscall emulation (non-full-system) sources # Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split(''' syscall_emulation_sources = Split('''
kern/linux/linux.cc kern/linux/linux.cc
mem/translating_port.cc
mem/page_table.cc
sim/process.cc sim/process.cc
sim/syscall_emul.cc sim/syscall_emul.cc
''') ''')

View file

@ -60,7 +60,10 @@ AlphaArguments::getArg(bool fp)
} else { } else {
Addr sp = xc->readIntReg(30); Addr sp = xc->readIntReg(30);
Addr paddr = vtophys(xc, sp + (number-6) * sizeof(uint64_t)); Addr paddr = vtophys(xc, sp + (number-6) * sizeof(uint64_t));
return xc->getPhysMemPtr()->phys_read_qword(paddr); // @todo: This read must go through the system or something else.
// return xc->getPhysMemPtr()->phys_read_qword(paddr);
panic("Need to fix alpha arguments\n");
return 0;
} }
} }

View file

@ -36,7 +36,6 @@
#include "cpu/base.hh" #include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh" #include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh" #include "cpu/exec_context.hh"
#include "cpu/fast/cpu.hh"
#include "kern/kernel_stats.hh" #include "kern/kernel_stats.hh"
#include "sim/debug.hh" #include "sim/debug.hh"
#include "sim/sim_events.hh" #include "sim/sim_events.hh"
@ -575,12 +574,4 @@ CPUExecContext::simPalCheck(int palFunc)
return true; return true;
} }
//Forward instantiation for FastCPU object
template
void AlphaISA::processInterrupts(FastCPU *xc);
//Forward instantiation for FastCPU object
template
void AlphaISA::zeroRegisters(FastCPU *xc);
#endif // FULL_SYSTEM #endif // FULL_SYSTEM

View file

@ -63,8 +63,8 @@ AlphaSystem::AlphaSystem(Params *p)
// Load program sections into memory // Load program sections into memory
pal->loadSections(physmem, true); pal->loadSections(&functionalPort, LoadAddrMask);
console->loadSections(physmem, true); console->loadSections(&functionalPort, LoadAddrMask);
// load symbols // load symbols
if (!console->loadGlobalSymbols(consoleSymtab)) if (!console->loadGlobalSymbols(consoleSymtab))

View file

@ -94,7 +94,7 @@ AlphaTLB::lookup(Addr vpn, uint8_t asn) const
void void
AlphaTLB::checkCacheability(MemReqPtr &req) AlphaTLB::checkCacheability(CpuRequestPtr &req)
{ {
// in Alpha, cacheability is controlled by upper-level bits of the // in Alpha, cacheability is controlled by upper-level bits of the
// physical address // physical address
@ -292,7 +292,7 @@ AlphaITB::regStats()
Fault Fault
AlphaITB::translate(MemReqPtr &req) const AlphaITB::translate(CpuRequestPtr &req) const
{ {
ExecContext *xc = req->xc; ExecContext *xc = req->xc;
@ -451,7 +451,7 @@ AlphaDTB::regStats()
} }
Fault Fault
AlphaDTB::translate(MemReqPtr &req, bool write) const AlphaDTB::translate(CpuRequestPtr &req, bool write) const
{ {
ExecContext *xc = req->xc; ExecContext *xc = req->xc;
Addr pc = xc->readPC(); Addr pc = xc->readPC();

View file

@ -35,7 +35,7 @@
#include "arch/alpha/isa_traits.hh" #include "arch/alpha/isa_traits.hh"
#include "arch/alpha/faults.hh" #include "arch/alpha/faults.hh"
#include "base/statistics.hh" #include "base/statistics.hh"
#include "mem/mem_req.hh" #include "mem/request.hh"
#include "sim/sim_object.hh" #include "sim/sim_object.hh"
class ExecContext; class ExecContext;
@ -73,7 +73,7 @@ class AlphaTLB : public SimObject
return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask); return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask);
} }
static void checkCacheability(MemReqPtr &req); static void checkCacheability(CpuRequestPtr &req);
// Checkpointing // Checkpointing
virtual void serialize(std::ostream &os); virtual void serialize(std::ostream &os);
@ -92,7 +92,7 @@ class AlphaITB : public AlphaTLB
AlphaITB(const std::string &name, int size); AlphaITB(const std::string &name, int size);
virtual void regStats(); virtual void regStats();
Fault translate(MemReqPtr &req) const; Fault translate(CpuRequestPtr &req) const;
}; };
class AlphaDTB : public AlphaTLB class AlphaDTB : public AlphaTLB
@ -115,7 +115,7 @@ class AlphaDTB : public AlphaTLB
AlphaDTB(const std::string &name, int size); AlphaDTB(const std::string &name, int size);
virtual void regStats(); virtual void regStats();
Fault translate(MemReqPtr &req, bool write) const; Fault translate(CpuRequestPtr &req, bool write) const;
}; };
#endif // __ALPHA_MEMORY_HH__ #endif // __ALPHA_MEMORY_HH__

View file

@ -63,22 +63,16 @@ ObjectFile::~ObjectFile()
bool bool
ObjectFile::loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys) ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
{ {
if (sec->size != 0) { if (sec->size != 0) {
Addr addr = sec->baseAddr; Addr addr = sec->baseAddr & addrMask;
if (loadPhys) {
// this is Alpha-specific... going to have to fix this
// for other architectures
addr &= (ULL(1) << 40) - 1;
}
if (sec->fileImage) { if (sec->fileImage) {
memPort->writeBlob(addr, sec->fileImage, sec->size, true); memPort->writeBlob(addr, sec->fileImage, sec->size);
} }
else { else {
// no image: must be bss // no image: must be bss
memPort->memsetBlob(addr, 0, sec->size, true); memPort->memsetBlob(addr, 0, sec->size);
} }
} }
return true; return true;
@ -86,11 +80,11 @@ ObjectFile::loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys)
bool bool
ObjectFile::loadSections(TranslatingPort *memPort, bool loadPhys) ObjectFile::loadSections(Port *memPort, Addr addrMask)
{ {
return (loadSection(&text, memPort, loadPhys) return (loadSection(&text, memPort, addrMask)
&& loadSection(&data, memPort, loadPhys) && loadSection(&data, memPort, addrMask)
&& loadSection(&bss, memPort, loadPhys)); && loadSection(&bss, memPort, addrMask));
} }

View file

@ -29,11 +29,12 @@
#ifndef __OBJECT_FILE_HH__ #ifndef __OBJECT_FILE_HH__
#define __OBJECT_FILE_HH__ #define __OBJECT_FILE_HH__
#include <limits>
#include <string> #include <string>
#include "sim/host.hh" // for Addr #include "sim/host.hh" // for Addr
class TranslatingPort; class Port;
class SymbolTable; class SymbolTable;
class ObjectFile class ObjectFile
@ -72,7 +73,8 @@ class ObjectFile
void close(); void close();
virtual bool loadSections(TranslatingPort *memPort, bool loadPhys = false); virtual bool loadSections(Port *memPort, Addr addrMask =
std::numeric_limits<Addr>::max());
virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0; virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0;
virtual bool loadLocalSymbols(SymbolTable *symtab) = 0; virtual bool loadLocalSymbols(SymbolTable *symtab) = 0;
@ -94,7 +96,7 @@ class ObjectFile
Section data; Section data;
Section bss; Section bss;
bool loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys); bool loadSection(Section *sec, Port *memPort, Addr addrMask);
void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; } void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
public: public:

View file

@ -42,10 +42,10 @@
#include "kern/kernel_stats.hh" #include "kern/kernel_stats.hh"
#include "sim/serialize.hh" #include "sim/serialize.hh"
#include "sim/sim_exit.hh" #include "sim/sim_exit.hh"
#include "sim/system.hh"
#include "arch/stacktrace.hh" #include "arch/stacktrace.hh"
#else #else
#include "sim/process.hh" #include "sim/process.hh"
#include "sim/system.hh"
#include "mem/translating_port.hh" #include "mem/translating_port.hh"
#endif #endif
@ -54,12 +54,11 @@ using namespace std;
// constructor // constructor
#if FULL_SYSTEM #if FULL_SYSTEM
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
AlphaITB *_itb, AlphaDTB *_dtb, AlphaITB *_itb, AlphaDTB *_dtb)
Memory *_mem)
: _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
cpu_id(-1), lastActivate(0), lastSuspend(0), mem(_mem), itb(_itb), cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb),
dtb(_dtb), system(_sys), memctrl(_sys->memctrl), physmem(_sys->physmem), dtb(_dtb), memctrl(_sys->memctrl), profile(NULL),
profile(NULL), quiesceEvent(this), func_exe_inst(0), storeCondFailures(0) quiesceEvent(this), func_exe_inst(0), storeCondFailures(0)
{ {
proxy = new ProxyExecContext<CPUExecContext>(this); proxy = new ProxyExecContext<CPUExecContext>(this);
@ -81,13 +80,19 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
} }
#else #else
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
Process *_process, int _asid, Port *mem_port) Process *_process, int _asid, MemObject* memobj)
: _status(ExecContext::Unallocated), : _status(ExecContext::Unallocated),
cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0),
lastSuspend(0), process(_process), asid(_asid), lastSuspend(0), process(_process), asid(_asid),
func_exe_inst(0), storeCondFailures(0) func_exe_inst(0), storeCondFailures(0)
{ {
port = new TranslatingPort(mem_port, process->pTable); /* Use this port to for syscall emulation writes to memory. */
Port *mem_port;
port = new TranslatingPort(process->pTable, false);
mem_port = memobj->getPort("functional");
mem_port->setPeer(port);
port->setPeer(mem_port);
memset(&regs, 0, sizeof(RegFile)); memset(&regs, 0, sizeof(RegFile));
proxy = new ProxyExecContext<CPUExecContext>(this); proxy = new ProxyExecContext<CPUExecContext>(this);
} }

View file

@ -121,9 +121,6 @@ class CPUExecContext
System *system; System *system;
/// Port that syscalls can use to access memory (provides translation step).
TranslatingPort *port;
// Memory *mem;
#if FULL_SYSTEM #if FULL_SYSTEM
AlphaITB *itb; AlphaITB *itb;
@ -167,6 +164,9 @@ class CPUExecContext
void profileSample(); void profileSample();
#else #else
/// Port that syscalls can use to access memory (provides translation step).
TranslatingPort *port;
Process *process; Process *process;
// Address space ID. Note that this is used for TIMING cache // Address space ID. Note that this is used for TIMING cache
@ -203,9 +203,10 @@ class CPUExecContext
// constructor: initialize context from given process structure // constructor: initialize context from given process structure
#if FULL_SYSTEM #if FULL_SYSTEM
CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system, CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem); AlphaITB *_itb, AlphaDTB *_dtb);
#else #else
CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid, Port *mem_port); CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid,
MemObject *memobj);
// Constructor to use XC to pass reg file around. Not used for anything // Constructor to use XC to pass reg file around. Not used for anything
// else. // else.
CPUExecContext(RegFile *regFile); CPUExecContext(RegFile *regFile);
@ -219,8 +220,6 @@ class CPUExecContext
void serialize(std::ostream &os); void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section); void unserialize(Checkpoint *cp, const std::string &section);
TranslatingPort *getMemPort() { return port; }
BaseCPU *getCpuPtr() { return cpu; } BaseCPU *getCpuPtr() { return cpu; }
ExecContext *getProxy() { return proxy; } ExecContext *getProxy() { return proxy; }
@ -230,8 +229,6 @@ class CPUExecContext
#if FULL_SYSTEM #if FULL_SYSTEM
System *getSystemPtr() { return system; } System *getSystemPtr() { return system; }
PhysicalMemory *getPhysMemPtr() { return physmem; }
AlphaITB *getITBPtr() { return itb; } AlphaITB *getITBPtr() { return itb; }
AlphaDTB *getDTBPtr() { return dtb; } AlphaDTB *getDTBPtr() { return dtb; }
@ -255,6 +252,8 @@ class CPUExecContext
} }
#else #else
TranslatingPort *getMemPort() { return port; }
Process *getProcessPtr() { return process; } Process *getProcessPtr() { return process; }
int getInstAsid() { return asid; } int getInstAsid() { return asid; }

View file

@ -36,14 +36,12 @@
#include "sim/serialize.hh" #include "sim/serialize.hh"
#include "sim/byteswap.hh" #include "sim/byteswap.hh"
// forward declaration: see functional_memory.hh
// @todo: Figure out a more architecture independent way to obtain the ITB and // @todo: Figure out a more architecture independent way to obtain the ITB and
// DTB pointers. // DTB pointers.
class AlphaDTB; class AlphaDTB;
class AlphaITB; class AlphaITB;
class BaseCPU; class BaseCPU;
class Event; class Event;
class PhysicalMemory;
class TranslatingPort; class TranslatingPort;
class Process; class Process;
class System; class System;
@ -83,8 +81,6 @@ class ExecContext
virtual ~ExecContext() { }; virtual ~ExecContext() { };
virtual TranslatingPort *getMemPort() = 0;
virtual BaseCPU *getCpuPtr() = 0; virtual BaseCPU *getCpuPtr() = 0;
virtual void setCpuId(int id) = 0; virtual void setCpuId(int id) = 0;
@ -94,12 +90,12 @@ class ExecContext
#if FULL_SYSTEM #if FULL_SYSTEM
virtual System *getSystemPtr() = 0; virtual System *getSystemPtr() = 0;
virtual PhysicalMemory *getPhysMemPtr() = 0;
virtual AlphaITB *getITBPtr() = 0; virtual AlphaITB *getITBPtr() = 0;
virtual AlphaDTB * getDTBPtr() = 0; virtual AlphaDTB * getDTBPtr() = 0;
#else #else
virtual TranslatingPort *getMemPort() = 0;
virtual Process *getProcessPtr() = 0; virtual Process *getProcessPtr() = 0;
#endif #endif
@ -251,8 +247,6 @@ class ProxyExecContext : public ExecContext
public: public:
TranslatingPort *getMemPort() { return actualXC->getMemPort(); }
BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); } BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); }
void setCpuId(int id) { actualXC->setCpuId(id); } void setCpuId(int id) { actualXC->setCpuId(id); }
@ -262,12 +256,12 @@ class ProxyExecContext : public ExecContext
#if FULL_SYSTEM #if FULL_SYSTEM
System *getSystemPtr() { return actualXC->getSystemPtr(); } System *getSystemPtr() { return actualXC->getSystemPtr(); }
PhysicalMemory *getPhysMemPtr() { return actualXC->getPhysMemPtr(); }
AlphaITB *getITBPtr() { return actualXC->getITBPtr(); } AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); } AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
#else #else
TranslatingPort *getMemPort() { return actualXC->getMemPort(); }
Process *getProcessPtr() { return actualXC->getProcessPtr(); } Process *getProcessPtr() { return actualXC->getProcessPtr(); }
#endif #endif

View file

@ -29,11 +29,12 @@
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#include "sim/param.hh"
#include "cpu/exetrace.hh"
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "cpu/base.hh" #include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "cpu/static_inst.hh" #include "cpu/static_inst.hh"
#include "sim/param.hh"
#include "sim/system.hh"
using namespace std; using namespace std;

View file

@ -64,8 +64,8 @@
#if FULL_SYSTEM #if FULL_SYSTEM
#include "base/remote_gdb.hh" #include "base/remote_gdb.hh"
#include "mem/functional/memory_control.hh" //#include "mem/functional/memory_control.hh"
#include "mem/functional/physical.hh" //#include "mem/functional/physical.hh"
#include "sim/system.hh" #include "sim/system.hh"
#include "arch/tlb.hh" #include "arch/tlb.hh"
#include "arch/stacktrace.hh" #include "arch/stacktrace.hh"
@ -155,16 +155,21 @@ SimpleCPU::CpuPort::recvRetry()
} }
SimpleCPU::SimpleCPU(Params *p) SimpleCPU::SimpleCPU(Params *p)
#if !FULL_SYSTEM
: BaseCPU(p), mem(p->mem), icachePort(this), : BaseCPU(p), mem(p->mem), icachePort(this),
dcachePort(this), tickEvent(this, p->width), cpuXC(NULL) dcachePort(this), tickEvent(this, p->width), cpuXC(NULL)
#else
: BaseCPU(p), icachePort(this), dcachePort(this),
tickEvent(this, p->width), cpuXC(NULL)
#endif
{ {
_status = Idle; _status = Idle;
#if FULL_SYSTEM #if FULL_SYSTEM
cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb, p->mem); cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb);
#else #else
cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0, cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process,
&dcachePort); /* asid */ 0, mem);
#endif // !FULL_SYSTEM #endif // !FULL_SYSTEM
xcProxy = cpuXC->getProxy(); xcProxy = cpuXC->getProxy();
@ -899,7 +904,7 @@ SimpleCPU::tick()
#if FULL_SYSTEM #if FULL_SYSTEM
if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode() && if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode() &&
status() != IcacheMissComplete) { status() != IcacheAccessComplete) {
int ipl = 0; int ipl = 0;
int summary = 0; int summary = 0;
checkInterrupts = false; checkInterrupts = false;

View file

@ -26,8 +26,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "encumbered/cpu/full/cpu.hh" #include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "kern/kernel_stats.hh" #include "kern/kernel_stats.hh"
#include "kern/system_events.hh"
#include "sim/system.hh"
using namespace TheISA; using namespace TheISA;
@ -41,11 +44,12 @@ SkipFuncEvent::process(ExecContext *xc)
xc->setPC(newpc); xc->setPC(newpc);
xc->setNextPC(xc->readPC() + sizeof(TheISA::MachInst)); xc->setNextPC(xc->readPC() + sizeof(TheISA::MachInst));
/*
BranchPred *bp = xc->getCpuPtr()->getBranchPred(); BranchPred *bp = xc->getCpuPtr()->getBranchPred();
if (bp != NULL) { if (bp != NULL) {
bp->popRAS(xc->getThreadNum()); bp->popRAS(xc->getThreadNum());
} }
*/
} }

View file

@ -159,6 +159,9 @@ PhysicalMemory::getPort(const std::string &if_name)
panic("PhysicalMemory::getPort: additional port requested to memory!"); panic("PhysicalMemory::getPort: additional port requested to memory!");
port = new MemoryPort(this); port = new MemoryPort(this);
return port; return port;
} else if (if_name == "functional") {
/* special port for functional writes at startup. */
return new MemoryPort(this);
} else { } else {
panic("PhysicalMemory::getPort: unknown port %s requested", if_name); panic("PhysicalMemory::getPort: unknown port %s requested", if_name);
} }
@ -332,9 +335,6 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string &section)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) BEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
Param<string> file; Param<string> file;
#if FULL_SYSTEM
SimObjectParam<MemoryController *> mmu;
#endif
Param<Range<Addr> > range; Param<Range<Addr> > range;
END_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) END_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
@ -342,20 +342,12 @@ END_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
BEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) BEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
INIT_PARAM_DFLT(file, "memory mapped file", ""), INIT_PARAM_DFLT(file, "memory mapped file", ""),
#if FULL_SYSTEM
INIT_PARAM(mmu, "Memory Controller"),
#endif
INIT_PARAM(range, "Device Address Range") INIT_PARAM(range, "Device Address Range")
END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
CREATE_SIM_OBJECT(PhysicalMemory) CREATE_SIM_OBJECT(PhysicalMemory)
{ {
#if FULL_SYSTEM
if (mmu) {
return new PhysicalMemory(getInstanceName(), range, mmu, file);
}
#endif
return new PhysicalMemory(getInstanceName()); return new PhysicalMemory(getInstanceName());
} }

View file

@ -165,8 +165,8 @@ class Port
/** Function called by the associated device to send a functional access, /** Function called by the associated device to send a functional access,
an access in which the data is instantly updated everywhere in the an access in which the data is instantly updated everywhere in the
memory system, without affecting the current state of any block memory system, without affecting the current state of any block or
or moving the block. moving the block.
*/ */
void sendFunctional(Packet &pkt) void sendFunctional(Packet &pkt)
{ return peer->recvFunctional(pkt); } { return peer->recvFunctional(pkt); }
@ -197,21 +197,21 @@ class Port
appropriate chunks. The default implementation can use appropriate chunks. The default implementation can use
getBlockSize() to determine the block size and go from there. getBlockSize() to determine the block size and go from there.
*/ */
void readBlob(Addr addr, uint8_t *p, int size); virtual void readBlob(Addr addr, uint8_t *p, int size);
/** This function is a wrapper around sendFunctional() /** This function is a wrapper around sendFunctional()
that breaks a larger, arbitrarily aligned access into that breaks a larger, arbitrarily aligned access into
appropriate chunks. The default implementation can use appropriate chunks. The default implementation can use
getBlockSize() to determine the block size and go from there. getBlockSize() to determine the block size and go from there.
*/ */
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. This /** Fill size bytes starting at addr with byte value val. This
should not need to be virtual, since it can be implemented in should not need to be virtual, since it can be implemented in
terms of writeBlob(). However, it shouldn't be terms of writeBlob(). However, it shouldn't be
performance-critical either, so it could be if we wanted to. performance-critical either, so it could be if we wanted to.
*/ */
void memsetBlob(Addr addr, uint8_t val, int size); virtual void memsetBlob(Addr addr, uint8_t val, int size);
private: private:
@ -220,4 +220,19 @@ class Port
void blobHelper(Addr addr, uint8_t *p, int size, Command cmd); void blobHelper(Addr addr, uint8_t *p, int size, Command 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:
virtual bool recvTiming(Packet &pkt) { panic("FuncPort is UniDir"); }
virtual Tick recvAtomic(Packet &pkt) { panic("FuncPort is UniDir"); }
virtual void recvFunctional(Packet &pkt) { panic("FuncPort is UniDir"); }
virtual void recvStatusChange(Status status) {panic("FuncPort is UniDir");}
};
#endif //__MEM_PORT_HH__ #endif //__MEM_PORT_HH__

View file

@ -34,8 +34,8 @@
using namespace TheISA; using namespace TheISA;
TranslatingPort::TranslatingPort(Port *_port, PageTable *p_table) TranslatingPort::TranslatingPort(PageTable *p_table, bool alloc)
: port(_port), pTable(p_table) : pTable(p_table), allocating(alloc)
{ } { }
TranslatingPort::~TranslatingPort() TranslatingPort::~TranslatingPort()
@ -52,7 +52,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()); Port::readBlob(paddr, p + prevSize, gen.size());
prevSize += gen.size(); prevSize += gen.size();
} }
@ -68,7 +68,7 @@ TranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
bool bool
TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc) TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
{ {
Addr paddr; Addr paddr;
@ -77,7 +77,7 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc)
for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) { for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
if (!pTable->translate(gen.addr(), paddr)) { if (!pTable->translate(gen.addr(), paddr)) {
if (alloc) { if (allocating) {
pTable->allocate(roundDown(gen.addr(), VMPageSize), pTable->allocate(roundDown(gen.addr(), VMPageSize),
VMPageSize); VMPageSize);
pTable->translate(gen.addr(), paddr); pTable->translate(gen.addr(), paddr);
@ -86,7 +86,7 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc)
} }
} }
port->writeBlob(paddr, p + prevSize, gen.size()); Port::writeBlob(paddr, p + prevSize, gen.size());
prevSize += gen.size(); prevSize += gen.size();
} }
@ -95,21 +95,21 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc)
void void
TranslatingPort::writeBlob(Addr addr, uint8_t *p, int size, bool alloc) TranslatingPort::writeBlob(Addr addr, uint8_t *p, int size)
{ {
if (!tryWriteBlob(addr, p, size, alloc)) 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, bool alloc) TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size)
{ {
Addr paddr; Addr paddr;
for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) { for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
if (!pTable->translate(gen.addr(), paddr)) { if (!pTable->translate(gen.addr(), paddr)) {
if (alloc) { if (allocating) {
pTable->allocate(roundDown(gen.addr(), VMPageSize), pTable->allocate(roundDown(gen.addr(), VMPageSize),
VMPageSize); VMPageSize);
pTable->translate(gen.addr(), paddr); pTable->translate(gen.addr(), paddr);
@ -118,16 +118,16 @@ TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size, bool alloc)
} }
} }
port->memsetBlob(paddr, val, gen.size()); Port::memsetBlob(paddr, val, gen.size());
} }
return true; return true;
} }
void void
TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size, bool alloc) TranslatingPort::memsetBlob(Addr addr, uint8_t val, int size)
{ {
if (!tryMemsetBlob(addr, val, size, alloc)) if (!tryMemsetBlob(addr, val, size))
fatal("memsetBlob(0x%x, ...) failed", addr); fatal("memsetBlob(0x%x, ...) failed", addr);
} }
@ -145,7 +145,7 @@ 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); Port::writeBlob(paddr, &c, 1);
} while (c); } while (c);
return true; return true;
@ -170,7 +170,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); Port::readBlob(paddr, &c, 1);
str += c; str += c;
} while (c); } while (c);

View file

@ -29,34 +29,36 @@
#ifndef __MEM_TRANSLATING_PROT_HH__ #ifndef __MEM_TRANSLATING_PROT_HH__
#define __MEM_TRANSLATING_PROT_HH__ #define __MEM_TRANSLATING_PROT_HH__
class Port; #include "mem/port.hh"
class PageTable; class PageTable;
class TranslatingPort class TranslatingPort : public FunctionalPort
{ {
private: private:
Port *port;
PageTable *pTable; PageTable *pTable;
bool allocating;
TranslatingPort(const TranslatingPort &specmem); TranslatingPort(const TranslatingPort &specmem);
const TranslatingPort &operator=(const TranslatingPort &specmem); const TranslatingPort &operator=(const TranslatingPort &specmem);
public: public:
TranslatingPort(Port *_port, PageTable *p_table); TranslatingPort(PageTable *p_table, bool alloc = false);
virtual ~TranslatingPort(); virtual ~TranslatingPort();
public: public:
bool tryReadBlob(Addr addr, uint8_t *p, int size); bool tryReadBlob(Addr addr, uint8_t *p, int size);
bool tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc = false); bool tryWriteBlob(Addr addr, uint8_t *p, int size);
bool tryMemsetBlob(Addr addr, uint8_t val, int size, bool alloc = false); bool tryMemsetBlob(Addr addr, uint8_t val, int size);
bool tryWriteString(Addr addr, const char *str); bool tryWriteString(Addr addr, const char *str);
bool tryReadString(std::string &str, Addr addr); bool tryReadString(std::string &str, Addr addr);
void readBlob(Addr addr, uint8_t *p, int size); virtual void readBlob(Addr addr, uint8_t *p, int size);
void writeBlob(Addr addr, uint8_t *p, int size, bool alloc = false); virtual void writeBlob(Addr addr, uint8_t *p, int size);
void memsetBlob(Addr addr, uint8_t val, int size, bool alloc = false); virtual void memsetBlob(Addr addr, uint8_t val, int size);
void writeString(Addr addr, const char *str); void writeString(Addr addr, const char *str);
void readString(std::string &str, Addr addr); void readString(std::string &str, Addr addr);
}; };
#endif #endif

View file

@ -153,21 +153,11 @@ Process::startup()
// mark this context as active so it will start ticking. // mark this context as active so it will start ticking.
xc->activate(0); xc->activate(0);
// Here we are grabbing the memory port of the CPU hosting the Port *mem_port;
// initial execution context for initialization. In the long run mem_port = system->physmem->getPort("functional");
// this is not what we want, since it means that all initVirtMem = new TranslatingPort(pTable, true);
// initialization accesses (e.g., loading object file sections) mem_port->setPeer(initVirtMem);
// will be done a cache block at a time through the CPU's cache. initVirtMem->setPeer(mem_port);
// We really want something more like:
//
// memport = system->physmem->getPort();
// myPort.setPeer(memport);
// memport->setPeer(&myPort);
// initVirtMem = new TranslatingPort(myPort, pTable);
//
// but we need our own dummy port "myPort" that doesn't exist.
// In the short term it works just fine though.
initVirtMem = xc->getMemPort();
} }
void void

View file

@ -10,7 +10,6 @@
#if FULL_SYSTEM #if FULL_SYSTEM
#include "base/remote_gdb.hh" #include "base/remote_gdb.hh"
#include "kern/kernel_stats.hh" #include "kern/kernel_stats.hh"
#include "mem/functional/memory_control.hh"
#include "arch/vtophys.hh" #include "arch/vtophys.hh"
#endif #endif
@ -37,6 +36,16 @@ System::System(Params *p)
kernelSymtab = new SymbolTable; kernelSymtab = new SymbolTable;
debugSymbolTable = new SymbolTable; debugSymbolTable = new SymbolTable;
/**
* Get a functional port to memory
*/
Port *mem_port;
mem_port = physmem->getPort("functional");
functionalPort.setPeer(mem_port);
mem_port->setPeer(&functionalPort);
/** /**
* Load the kernel code into memory * Load the kernel code into memory
*/ */
@ -46,7 +55,7 @@ System::System(Params *p)
fatal("Could not load kernel file %s", params()->kernel_path); fatal("Could not load kernel file %s", params()->kernel_path);
// Load program sections into memory // Load program sections into memory
kernel->loadSections(physmem, true); kernel->loadSections(&functionalPort, LoadAddrMask);
// setup entry points // setup entry points
kernelStart = kernel->textBase(); kernelStart = kernel->textBase();

View file

@ -36,6 +36,7 @@
#include "base/misc.hh" #include "base/misc.hh"
#include "base/statistics.hh" #include "base/statistics.hh"
#include "cpu/pc_event.hh" #include "cpu/pc_event.hh"
#include "mem/port.hh"
#include "sim/sim_object.hh" #include "sim/sim_object.hh"
#if FULL_SYSTEM #if FULL_SYSTEM
#include "kern/system_events.hh" #include "kern/system_events.hh"
@ -76,6 +77,10 @@ class System : public SimObject
Platform *platform; Platform *platform;
uint64_t init_param; uint64_t init_param;
/** Port to physical memory used for writing object files into ram at
* boot.*/
FunctionalPort functionalPort;
/** kernel symbol table */ /** kernel symbol table */
SymbolTable *kernelSymtab; SymbolTable *kernelSymtab;