Make TranslatingPort be a type of Port rather than something special
arch/alpha/arguments.cc:
rather than returning 0, put a panic in... it will actually make us fix
this rather than scratching our respective heads
base/loader/object_file.cc:
base/loader/object_file.hh:
Object loader now takes a port rather than a translating port
cpu/cpu_exec_context.cc:
cpu/cpu_exec_context.hh:
sim/process.cc:
Make translating port a type of port rather than anything special
cpu/simple/cpu.cc:
no need to grab a port from the cpu anymore
mem/physical.cc:
add an additional type of port to physicalmemory called "functional"
Only used for functional accesses (loading binaries/syscall emu)
mem/port.hh:
make readBlok/writeBlob virtual so translating port can do the
translation first
mem/translating_port.cc:
mem/translating_port.hh:
Make TranslatingPort inherit from Port
sim/system.cc:
header file that doesn't exit removed
--HG--
extra : convert_revision : 89b08f6146bba61f5605678d736055feab2fe6f7
This commit is contained in:
@@ -62,6 +62,7 @@ AlphaArguments::getArg(bool fp)
|
||||
Addr paddr = vtophys(xc, sp + (number-6) * sizeof(uint64_t));
|
||||
// @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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ ObjectFile::~ObjectFile()
|
||||
|
||||
|
||||
bool
|
||||
ObjectFile::loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys)
|
||||
ObjectFile::loadSection(Section *sec, Port *memPort, bool loadPhys)
|
||||
{
|
||||
if (sec->size != 0) {
|
||||
Addr addr = sec->baseAddr;
|
||||
@@ -74,11 +74,11 @@ ObjectFile::loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys)
|
||||
}
|
||||
|
||||
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,7 +86,7 @@ ObjectFile::loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys)
|
||||
|
||||
|
||||
bool
|
||||
ObjectFile::loadSections(TranslatingPort *memPort, bool loadPhys)
|
||||
ObjectFile::loadSections(Port *memPort, bool loadPhys)
|
||||
{
|
||||
return (loadSection(&text, memPort, loadPhys)
|
||||
&& loadSection(&data, memPort, loadPhys)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#include "sim/host.hh" // for Addr
|
||||
|
||||
class TranslatingPort;
|
||||
class Port;
|
||||
class SymbolTable;
|
||||
|
||||
class ObjectFile
|
||||
@@ -72,7 +72,7 @@ class ObjectFile
|
||||
|
||||
void close();
|
||||
|
||||
virtual bool loadSections(TranslatingPort *memPort, bool loadPhys = false);
|
||||
virtual bool loadSections(Port *memPort, bool loadPhys = false);
|
||||
virtual bool loadGlobalSymbols(SymbolTable *symtab) = 0;
|
||||
virtual bool loadLocalSymbols(SymbolTable *symtab) = 0;
|
||||
|
||||
@@ -94,7 +94,7 @@ class ObjectFile
|
||||
Section data;
|
||||
Section bss;
|
||||
|
||||
bool loadSection(Section *sec, TranslatingPort *memPort, bool loadPhys);
|
||||
bool loadSection(Section *sec, Port *memPort, bool loadPhys);
|
||||
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
|
||||
|
||||
@@ -80,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)
|
||||
: _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 = process->system->physmem->getPort("functional");
|
||||
mem_port->setPeer(port);
|
||||
port->setPeer(mem_port);
|
||||
|
||||
memset(®s, 0, sizeof(RegFile));
|
||||
proxy = new ProxyExecContext<CPUExecContext>(this);
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ class CPUExecContext
|
||||
AlphaITB *_itb, AlphaDTB *_dtb);
|
||||
#else
|
||||
CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process,
|
||||
int _asid, Port *mem_port);
|
||||
int _asid);
|
||||
// Constructor to use XC to pass reg file around. Not used for anything
|
||||
// else.
|
||||
CPUExecContext(RegFile *regFile);
|
||||
|
||||
@@ -168,8 +168,8 @@ SimpleCPU::SimpleCPU(Params *p)
|
||||
#if FULL_SYSTEM
|
||||
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);
|
||||
#endif // !FULL_SYSTEM
|
||||
|
||||
xcProxy = cpuXC->getProxy();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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,41 @@
|
||||
#ifndef __MEM_TRANSLATING_PROT_HH__
|
||||
#define __MEM_TRANSLATING_PROT_HH__
|
||||
|
||||
class Port;
|
||||
#include "mem/port.hh"
|
||||
|
||||
class PageTable;
|
||||
|
||||
class TranslatingPort
|
||||
class TranslatingPort : public Port
|
||||
{
|
||||
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);
|
||||
|
||||
virtual bool recvTiming(Packet &pkt) { panic("TransPort is UniDir"); }
|
||||
virtual Tick recvAtomic(Packet &pkt) { panic("TransPort is UniDir"); }
|
||||
virtual void recvFunctional(Packet &pkt) { panic("TransPort is UniDir"); }
|
||||
virtual void recvStatusChange(Status status) {panic("TransPort is UniDir");}
|
||||
|
||||
};
|
||||
|
||||
#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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user