Merge m5.eecs.umich.edu:/bk/newmem
into ewok.(none):/home/gblack/m5/newmem --HG-- extra : convert_revision : 08ae5e999d9b313e3e40cb6d58863905b70ca781
This commit is contained in:
commit
adeb458b87
21 changed files with 143 additions and 132 deletions
|
@ -90,10 +90,8 @@ base_sources = Split('''
|
|||
|
||||
mem/connector.cc
|
||||
mem/mem_object.cc
|
||||
mem/page_table.cc
|
||||
mem/physical.cc
|
||||
mem/port.cc
|
||||
mem/translating_port.cc
|
||||
mem/bus.cc
|
||||
|
||||
python/pyconfig.cc
|
||||
|
@ -255,6 +253,8 @@ turbolaser_sources = Split('''
|
|||
# Syscall emulation (non-full-system) sources
|
||||
syscall_emulation_sources = Split('''
|
||||
kern/linux/linux.cc
|
||||
mem/translating_port.cc
|
||||
mem/page_table.cc
|
||||
sim/process.cc
|
||||
sim/syscall_emul.cc
|
||||
''')
|
||||
|
|
|
@ -60,7 +60,10 @@ AlphaArguments::getArg(bool fp)
|
|||
} else {
|
||||
Addr sp = xc->readIntReg(30);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "cpu/base.hh"
|
||||
#include "cpu/cpu_exec_context.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "cpu/fast/cpu.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#include "sim/debug.hh"
|
||||
#include "sim/sim_events.hh"
|
||||
|
@ -575,12 +574,4 @@ CPUExecContext::simPalCheck(int palFunc)
|
|||
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
|
||||
|
|
|
@ -63,8 +63,8 @@ AlphaSystem::AlphaSystem(Params *p)
|
|||
|
||||
|
||||
// Load program sections into memory
|
||||
pal->loadSections(physmem, true);
|
||||
console->loadSections(physmem, true);
|
||||
pal->loadSections(&functionalPort, LoadAddrMask);
|
||||
console->loadSections(&functionalPort, LoadAddrMask);
|
||||
|
||||
// load symbols
|
||||
if (!console->loadGlobalSymbols(consoleSymtab))
|
||||
|
|
|
@ -94,7 +94,7 @@ AlphaTLB::lookup(Addr vpn, uint8_t asn) const
|
|||
|
||||
|
||||
void
|
||||
AlphaTLB::checkCacheability(MemReqPtr &req)
|
||||
AlphaTLB::checkCacheability(CpuRequestPtr &req)
|
||||
{
|
||||
// in Alpha, cacheability is controlled by upper-level bits of the
|
||||
// physical address
|
||||
|
@ -292,7 +292,7 @@ AlphaITB::regStats()
|
|||
|
||||
|
||||
Fault
|
||||
AlphaITB::translate(MemReqPtr &req) const
|
||||
AlphaITB::translate(CpuRequestPtr &req) const
|
||||
{
|
||||
ExecContext *xc = req->xc;
|
||||
|
||||
|
@ -451,7 +451,7 @@ AlphaDTB::regStats()
|
|||
}
|
||||
|
||||
Fault
|
||||
AlphaDTB::translate(MemReqPtr &req, bool write) const
|
||||
AlphaDTB::translate(CpuRequestPtr &req, bool write) const
|
||||
{
|
||||
ExecContext *xc = req->xc;
|
||||
Addr pc = xc->readPC();
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "arch/alpha/isa_traits.hh"
|
||||
#include "arch/alpha/faults.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "mem/mem_req.hh"
|
||||
#include "mem/request.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
class ExecContext;
|
||||
|
@ -73,7 +73,7 @@ class AlphaTLB : public SimObject
|
|||
return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask);
|
||||
}
|
||||
|
||||
static void checkCacheability(MemReqPtr &req);
|
||||
static void checkCacheability(CpuRequestPtr &req);
|
||||
|
||||
// Checkpointing
|
||||
virtual void serialize(std::ostream &os);
|
||||
|
@ -92,7 +92,7 @@ class AlphaITB : public AlphaTLB
|
|||
AlphaITB(const std::string &name, int size);
|
||||
virtual void regStats();
|
||||
|
||||
Fault translate(MemReqPtr &req) const;
|
||||
Fault translate(CpuRequestPtr &req) const;
|
||||
};
|
||||
|
||||
class AlphaDTB : public AlphaTLB
|
||||
|
@ -115,7 +115,7 @@ class AlphaDTB : public AlphaTLB
|
|||
AlphaDTB(const std::string &name, int size);
|
||||
virtual void regStats();
|
||||
|
||||
Fault translate(MemReqPtr &req, bool write) const;
|
||||
Fault translate(CpuRequestPtr &req, bool write) const;
|
||||
};
|
||||
|
||||
#endif // __ALPHA_MEMORY_HH__
|
||||
|
|
|
@ -63,22 +63,16 @@ ObjectFile::~ObjectFile()
|
|||
|
||||
|
||||
bool
|
||||
ObjectFile::loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys)
|
||||
ObjectFile::loadSection(Section *sec, Port *memPort, Addr addrMask)
|
||||
{
|
||||
if (sec->size != 0) {
|
||||
Addr addr = sec->baseAddr;
|
||||
if (loadPhys) {
|
||||
// this is Alpha-specific... going to have to fix this
|
||||
// for other architectures
|
||||
addr &= (ULL(1) << 40) - 1;
|
||||
}
|
||||
|
||||
Addr addr = sec->baseAddr & addrMask;
|
||||
if (sec->fileImage) {
|
||||
memPort->writeBlob(addr, sec->fileImage, sec->size, true);
|
||||
memPort->writeBlob(addr, sec->fileImage, sec->size);
|
||||
}
|
||||
else {
|
||||
// no image: must be bss
|
||||
memPort->memsetBlob(addr, 0, sec->size, true);
|
||||
memPort->memsetBlob(addr, 0, sec->size);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -86,11 +80,11 @@ ObjectFile::loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys)
|
|||
|
||||
|
||||
bool
|
||||
ObjectFile::loadSections(TranslatingPort *memPort, bool loadPhys)
|
||||
ObjectFile::loadSections(Port *memPort, Addr addrMask)
|
||||
{
|
||||
return (loadSection(&text, memPort, loadPhys)
|
||||
&& loadSection(&data, memPort, loadPhys)
|
||||
&& loadSection(&bss, memPort, loadPhys));
|
||||
return (loadSection(&text, memPort, addrMask)
|
||||
&& loadSection(&data, memPort, addrMask)
|
||||
&& loadSection(&bss, memPort, addrMask));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,11 +29,12 @@
|
|||
#ifndef __OBJECT_FILE_HH__
|
||||
#define __OBJECT_FILE_HH__
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "sim/host.hh" // for Addr
|
||||
|
||||
class TranslatingPort;
|
||||
class Port;
|
||||
class SymbolTable;
|
||||
|
||||
class ObjectFile
|
||||
|
@ -72,7 +73,8 @@ class ObjectFile
|
|||
|
||||
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 loadLocalSymbols(SymbolTable *symtab) = 0;
|
||||
|
||||
|
@ -94,7 +96,7 @@ class ObjectFile
|
|||
Section data;
|
||||
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; }
|
||||
|
||||
public:
|
||||
|
|
|
@ -42,10 +42,10 @@
|
|||
#include "kern/kernel_stats.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
#include "sim/system.hh"
|
||||
#include "arch/stacktrace.hh"
|
||||
#else
|
||||
#include "sim/process.hh"
|
||||
#include "sim/system.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#endif
|
||||
|
||||
|
@ -54,12 +54,11 @@ using namespace std;
|
|||
// constructor
|
||||
#if FULL_SYSTEM
|
||||
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
|
||||
AlphaITB *_itb, AlphaDTB *_dtb,
|
||||
Memory *_mem)
|
||||
AlphaITB *_itb, AlphaDTB *_dtb)
|
||||
: _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
|
||||
cpu_id(-1), lastActivate(0), lastSuspend(0), mem(_mem), itb(_itb),
|
||||
dtb(_dtb), system(_sys), memctrl(_sys->memctrl), physmem(_sys->physmem),
|
||||
profile(NULL), quiesceEvent(this), func_exe_inst(0), storeCondFailures(0)
|
||||
cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb),
|
||||
dtb(_dtb), memctrl(_sys->memctrl), profile(NULL),
|
||||
quiesceEvent(this), func_exe_inst(0), storeCondFailures(0)
|
||||
{
|
||||
proxy = new ProxyExecContext<CPUExecContext>(this);
|
||||
|
||||
|
@ -81,13 +80,19 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
|
|||
}
|
||||
#else
|
||||
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
|
||||
Process *_process, int _asid, Port *mem_port)
|
||||
Process *_process, int _asid, MemObject* memobj)
|
||||
: _status(ExecContext::Unallocated),
|
||||
cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0),
|
||||
lastSuspend(0), process(_process), asid(_asid),
|
||||
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(®s, 0, sizeof(RegFile));
|
||||
proxy = new ProxyExecContext<CPUExecContext>(this);
|
||||
}
|
||||
|
|
|
@ -121,9 +121,6 @@ class CPUExecContext
|
|||
|
||||
System *system;
|
||||
|
||||
/// Port that syscalls can use to access memory (provides translation step).
|
||||
TranslatingPort *port;
|
||||
// Memory *mem;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
AlphaITB *itb;
|
||||
|
@ -167,6 +164,9 @@ class CPUExecContext
|
|||
void profileSample();
|
||||
|
||||
#else
|
||||
/// Port that syscalls can use to access memory (provides translation step).
|
||||
TranslatingPort *port;
|
||||
|
||||
Process *process;
|
||||
|
||||
// Address space ID. Note that this is used for TIMING cache
|
||||
|
@ -203,9 +203,10 @@ class CPUExecContext
|
|||
// constructor: initialize context from given process structure
|
||||
#if FULL_SYSTEM
|
||||
CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
|
||||
AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem);
|
||||
AlphaITB *_itb, AlphaDTB *_dtb);
|
||||
#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
|
||||
// else.
|
||||
CPUExecContext(RegFile *regFile);
|
||||
|
@ -219,8 +220,6 @@ class CPUExecContext
|
|||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
TranslatingPort *getMemPort() { return port; }
|
||||
|
||||
BaseCPU *getCpuPtr() { return cpu; }
|
||||
|
||||
ExecContext *getProxy() { return proxy; }
|
||||
|
@ -230,8 +229,6 @@ class CPUExecContext
|
|||
#if FULL_SYSTEM
|
||||
System *getSystemPtr() { return system; }
|
||||
|
||||
PhysicalMemory *getPhysMemPtr() { return physmem; }
|
||||
|
||||
AlphaITB *getITBPtr() { return itb; }
|
||||
|
||||
AlphaDTB *getDTBPtr() { return dtb; }
|
||||
|
@ -255,6 +252,8 @@ class CPUExecContext
|
|||
}
|
||||
|
||||
#else
|
||||
TranslatingPort *getMemPort() { return port; }
|
||||
|
||||
Process *getProcessPtr() { return process; }
|
||||
|
||||
int getInstAsid() { return asid; }
|
||||
|
|
|
@ -36,14 +36,12 @@
|
|||
#include "sim/serialize.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
// forward declaration: see functional_memory.hh
|
||||
// @todo: Figure out a more architecture independent way to obtain the ITB and
|
||||
// DTB pointers.
|
||||
class AlphaDTB;
|
||||
class AlphaITB;
|
||||
class BaseCPU;
|
||||
class Event;
|
||||
class PhysicalMemory;
|
||||
class TranslatingPort;
|
||||
class Process;
|
||||
class System;
|
||||
|
@ -83,8 +81,6 @@ class ExecContext
|
|||
|
||||
virtual ~ExecContext() { };
|
||||
|
||||
virtual TranslatingPort *getMemPort() = 0;
|
||||
|
||||
virtual BaseCPU *getCpuPtr() = 0;
|
||||
|
||||
virtual void setCpuId(int id) = 0;
|
||||
|
@ -94,12 +90,12 @@ class ExecContext
|
|||
#if FULL_SYSTEM
|
||||
virtual System *getSystemPtr() = 0;
|
||||
|
||||
virtual PhysicalMemory *getPhysMemPtr() = 0;
|
||||
|
||||
virtual AlphaITB *getITBPtr() = 0;
|
||||
|
||||
virtual AlphaDTB * getDTBPtr() = 0;
|
||||
#else
|
||||
virtual TranslatingPort *getMemPort() = 0;
|
||||
|
||||
virtual Process *getProcessPtr() = 0;
|
||||
#endif
|
||||
|
||||
|
@ -251,8 +247,6 @@ class ProxyExecContext : public ExecContext
|
|||
|
||||
public:
|
||||
|
||||
TranslatingPort *getMemPort() { return actualXC->getMemPort(); }
|
||||
|
||||
BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); }
|
||||
|
||||
void setCpuId(int id) { actualXC->setCpuId(id); }
|
||||
|
@ -262,12 +256,12 @@ class ProxyExecContext : public ExecContext
|
|||
#if FULL_SYSTEM
|
||||
System *getSystemPtr() { return actualXC->getSystemPtr(); }
|
||||
|
||||
PhysicalMemory *getPhysMemPtr() { return actualXC->getPhysMemPtr(); }
|
||||
|
||||
AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
|
||||
|
||||
AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
|
||||
#else
|
||||
TranslatingPort *getMemPort() { return actualXC->getMemPort(); }
|
||||
|
||||
Process *getProcessPtr() { return actualXC->getProcessPtr(); }
|
||||
#endif
|
||||
|
||||
|
|
|
@ -29,11 +29,12 @@
|
|||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "sim/param.hh"
|
||||
#include "cpu/exetrace.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/exetrace.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "sim/param.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
|
||||
#if FULL_SYSTEM
|
||||
#include "base/remote_gdb.hh"
|
||||
#include "mem/functional/memory_control.hh"
|
||||
#include "mem/functional/physical.hh"
|
||||
//#include "mem/functional/memory_control.hh"
|
||||
//#include "mem/functional/physical.hh"
|
||||
#include "sim/system.hh"
|
||||
#include "arch/tlb.hh"
|
||||
#include "arch/stacktrace.hh"
|
||||
|
@ -155,16 +155,21 @@ SimpleCPU::CpuPort::recvRetry()
|
|||
}
|
||||
|
||||
SimpleCPU::SimpleCPU(Params *p)
|
||||
#if !FULL_SYSTEM
|
||||
: BaseCPU(p), mem(p->mem), icachePort(this),
|
||||
dcachePort(this), tickEvent(this, p->width), cpuXC(NULL)
|
||||
#else
|
||||
: BaseCPU(p), icachePort(this), dcachePort(this),
|
||||
tickEvent(this, p->width), cpuXC(NULL)
|
||||
#endif
|
||||
{
|
||||
_status = Idle;
|
||||
|
||||
#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
|
||||
cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0,
|
||||
&dcachePort);
|
||||
cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process,
|
||||
/* asid */ 0, mem);
|
||||
#endif // !FULL_SYSTEM
|
||||
|
||||
xcProxy = cpuXC->getProxy();
|
||||
|
@ -899,7 +904,7 @@ SimpleCPU::tick()
|
|||
|
||||
#if FULL_SYSTEM
|
||||
if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode() &&
|
||||
status() != IcacheMissComplete) {
|
||||
status() != IcacheAccessComplete) {
|
||||
int ipl = 0;
|
||||
int summary = 0;
|
||||
checkInterrupts = false;
|
||||
|
|
|
@ -26,8 +26,11 @@
|
|||
* 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/system_events.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace TheISA;
|
||||
|
||||
|
@ -41,11 +44,12 @@ SkipFuncEvent::process(ExecContext *xc)
|
|||
|
||||
xc->setPC(newpc);
|
||||
xc->setNextPC(xc->readPC() + sizeof(TheISA::MachInst));
|
||||
|
||||
/*
|
||||
BranchPred *bp = xc->getCpuPtr()->getBranchPred();
|
||||
if (bp != NULL) {
|
||||
bp->popRAS(xc->getThreadNum());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -159,6 +159,9 @@ PhysicalMemory::getPort(const std::string &if_name)
|
|||
panic("PhysicalMemory::getPort: additional port requested to memory!");
|
||||
port = new MemoryPort(this);
|
||||
return port;
|
||||
} else if (if_name == "functional") {
|
||||
/* special port for functional writes at startup. */
|
||||
return new MemoryPort(this);
|
||||
} else {
|
||||
panic("PhysicalMemory::getPort: unknown port %s requested", if_name);
|
||||
}
|
||||
|
@ -332,9 +335,6 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string §ion)
|
|||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
|
||||
|
||||
Param<string> file;
|
||||
#if FULL_SYSTEM
|
||||
SimObjectParam<MemoryController *> mmu;
|
||||
#endif
|
||||
Param<Range<Addr> > range;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
|
||||
|
@ -342,20 +342,12 @@ END_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory)
|
|||
BEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
|
||||
|
||||
INIT_PARAM_DFLT(file, "memory mapped file", ""),
|
||||
#if FULL_SYSTEM
|
||||
INIT_PARAM(mmu, "Memory Controller"),
|
||||
#endif
|
||||
INIT_PARAM(range, "Device Address Range")
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
|
||||
|
||||
CREATE_SIM_OBJECT(PhysicalMemory)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if (mmu) {
|
||||
return new PhysicalMemory(getInstanceName(), range, mmu, file);
|
||||
}
|
||||
#endif
|
||||
|
||||
return new PhysicalMemory(getInstanceName());
|
||||
}
|
||||
|
|
25
mem/port.hh
25
mem/port.hh
|
@ -165,8 +165,8 @@ class Port
|
|||
|
||||
/** Function called by the associated device to send a functional access,
|
||||
an access in which the data is instantly updated everywhere in the
|
||||
memory system, without affecting the current state of any block
|
||||
or moving the block.
|
||||
memory system, without affecting the current state of any block or
|
||||
moving the block.
|
||||
*/
|
||||
void sendFunctional(Packet &pkt)
|
||||
{ return peer->recvFunctional(pkt); }
|
||||
|
@ -197,21 +197,21 @@ class Port
|
|||
appropriate chunks. The default implementation can use
|
||||
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()
|
||||
that breaks a larger, arbitrarily aligned access into
|
||||
appropriate chunks. The default implementation can use
|
||||
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
|
||||
should not need to be virtual, since it can be implemented in
|
||||
terms of writeBlob(). However, it shouldn't be
|
||||
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:
|
||||
|
||||
|
@ -220,4 +220,19 @@ class Port
|
|||
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__
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
|
||||
using namespace TheISA;
|
||||
|
||||
TranslatingPort::TranslatingPort(Port *_port, PageTable *p_table)
|
||||
: port(_port), pTable(p_table)
|
||||
TranslatingPort::TranslatingPort(PageTable *p_table, bool alloc)
|
||||
: pTable(p_table), allocating(alloc)
|
||||
{ }
|
||||
|
||||
TranslatingPort::~TranslatingPort()
|
||||
|
@ -52,7 +52,7 @@ TranslatingPort::tryReadBlob(Addr addr, uint8_t *p, int size)
|
|||
if (!pTable->translate(gen.addr(),paddr))
|
||||
return false;
|
||||
|
||||
port->readBlob(paddr, p + prevSize, gen.size());
|
||||
Port::readBlob(paddr, p + prevSize, gen.size());
|
||||
prevSize += gen.size();
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ TranslatingPort::readBlob(Addr addr, uint8_t *p, int size)
|
|||
|
||||
|
||||
bool
|
||||
TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc)
|
||||
TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size)
|
||||
{
|
||||
|
||||
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()) {
|
||||
|
||||
if (!pTable->translate(gen.addr(), paddr)) {
|
||||
if (alloc) {
|
||||
if (allocating) {
|
||||
pTable->allocate(roundDown(gen.addr(), VMPageSize),
|
||||
VMPageSize);
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -95,21 +95,21 @@ TranslatingPort::tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc)
|
|||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
bool
|
||||
TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size, bool alloc)
|
||||
TranslatingPort::tryMemsetBlob(Addr addr, uint8_t val, int size)
|
||||
{
|
||||
Addr paddr;
|
||||
|
||||
for (ChunkGenerator gen(addr, size, VMPageSize); !gen.done(); gen.next()) {
|
||||
|
||||
if (!pTable->translate(gen.addr(), paddr)) {
|
||||
if (alloc) {
|
||||
if (allocating) {
|
||||
pTable->allocate(roundDown(gen.addr(), VMPageSize),
|
||||
VMPageSize);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ TranslatingPort::tryWriteString(Addr addr, const char *str)
|
|||
if (!pTable->translate(vaddr++,paddr))
|
||||
return false;
|
||||
|
||||
port->writeBlob(paddr, &c, 1);
|
||||
Port::writeBlob(paddr, &c, 1);
|
||||
} while (c);
|
||||
|
||||
return true;
|
||||
|
@ -170,7 +170,7 @@ TranslatingPort::tryReadString(std::string &str, Addr addr)
|
|||
if (!pTable->translate(vaddr++,paddr))
|
||||
return false;
|
||||
|
||||
port->readBlob(paddr, &c, 1);
|
||||
Port::readBlob(paddr, &c, 1);
|
||||
str += c;
|
||||
} while (c);
|
||||
|
||||
|
|
|
@ -29,34 +29,36 @@
|
|||
#ifndef __MEM_TRANSLATING_PROT_HH__
|
||||
#define __MEM_TRANSLATING_PROT_HH__
|
||||
|
||||
class Port;
|
||||
#include "mem/port.hh"
|
||||
|
||||
class PageTable;
|
||||
|
||||
class TranslatingPort
|
||||
class TranslatingPort : public FunctionalPort
|
||||
{
|
||||
private:
|
||||
Port *port;
|
||||
PageTable *pTable;
|
||||
bool allocating;
|
||||
|
||||
TranslatingPort(const TranslatingPort &specmem);
|
||||
const TranslatingPort &operator=(const TranslatingPort &specmem);
|
||||
|
||||
public:
|
||||
TranslatingPort(Port *_port, PageTable *p_table);
|
||||
TranslatingPort(PageTable *p_table, bool alloc = false);
|
||||
virtual ~TranslatingPort();
|
||||
|
||||
public:
|
||||
bool tryReadBlob(Addr addr, uint8_t *p, int size);
|
||||
bool tryWriteBlob(Addr addr, uint8_t *p, int size, bool alloc = false);
|
||||
bool tryMemsetBlob(Addr addr, uint8_t val, int size, bool alloc = false);
|
||||
bool tryWriteBlob(Addr addr, uint8_t *p, int size);
|
||||
bool tryMemsetBlob(Addr addr, uint8_t val, int size);
|
||||
bool tryWriteString(Addr addr, const char *str);
|
||||
bool tryReadString(std::string &str, Addr addr);
|
||||
|
||||
void readBlob(Addr addr, uint8_t *p, int size);
|
||||
void writeBlob(Addr addr, uint8_t *p, int size, bool alloc = false);
|
||||
void memsetBlob(Addr addr, uint8_t val, int size, bool alloc = false);
|
||||
virtual void readBlob(Addr addr, uint8_t *p, int size);
|
||||
virtual void writeBlob(Addr addr, uint8_t *p, int size);
|
||||
virtual void memsetBlob(Addr addr, uint8_t val, int size);
|
||||
void writeString(Addr addr, const char *str);
|
||||
void readString(std::string &str, Addr addr);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -153,21 +153,11 @@ Process::startup()
|
|||
// mark this context as active so it will start ticking.
|
||||
xc->activate(0);
|
||||
|
||||
// Here we are grabbing the memory port of the CPU hosting the
|
||||
// initial execution context for initialization. In the long run
|
||||
// this is not what we want, since it means that all
|
||||
// initialization accesses (e.g., loading object file sections)
|
||||
// will be done a cache block at a time through the CPU's cache.
|
||||
// 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();
|
||||
Port *mem_port;
|
||||
mem_port = system->physmem->getPort("functional");
|
||||
initVirtMem = new TranslatingPort(pTable, true);
|
||||
mem_port->setPeer(initVirtMem);
|
||||
initVirtMem->setPeer(mem_port);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#if FULL_SYSTEM
|
||||
#include "base/remote_gdb.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#include "mem/functional/memory_control.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#endif
|
||||
|
||||
|
@ -37,6 +36,16 @@ System::System(Params *p)
|
|||
kernelSymtab = 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
|
||||
*/
|
||||
|
@ -46,7 +55,7 @@ System::System(Params *p)
|
|||
fatal("Could not load kernel file %s", params()->kernel_path);
|
||||
|
||||
// Load program sections into memory
|
||||
kernel->loadSections(physmem, true);
|
||||
kernel->loadSections(&functionalPort, LoadAddrMask);
|
||||
|
||||
// setup entry points
|
||||
kernelStart = kernel->textBase();
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "base/misc.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "cpu/pc_event.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
#if FULL_SYSTEM
|
||||
#include "kern/system_events.hh"
|
||||
|
@ -76,6 +77,10 @@ class System : public SimObject
|
|||
Platform *platform;
|
||||
uint64_t init_param;
|
||||
|
||||
/** Port to physical memory used for writing object files into ram at
|
||||
* boot.*/
|
||||
FunctionalPort functionalPort;
|
||||
|
||||
/** kernel symbol table */
|
||||
SymbolTable *kernelSymtab;
|
||||
|
||||
|
|
Loading…
Reference in a new issue