Add a functional port that is used to load the original binaries in FS
SE mode now has a port that goes to whatever toplevel mem object the CPU sees that does the appropriate translation for syscall emulation SConscript: translating port is a syscall emu only source arch/alpha/system.cc: base/loader/object_file.cc: base/loader/object_file.hh: Use the new functional port to write the binaries into memory cpu/cpu_exec_context.cc: cpu/cpu_exec_context.hh: cpu/simple/cpu.cc: We aren't always going to be writing straight to memory with syscalls support writing to a cache mem/port.hh: Add a simple unidirectional functional port that panics on any incoming requests mem/translating_port.hh: make translating port inherit from the simple port sim/system.cc: sim/system.hh: Add a functional port that is used to load the original binaries --HG-- extra : convert_revision : 9096866d0b23e3aceea68394abb76e63c0f8fd8d
This commit is contained in:
parent
e196d20d9d
commit
5936c79ba0
11 changed files with 52 additions and 31 deletions
|
@ -92,7 +92,6 @@ base_sources = Split('''
|
|||
mem/mem_object.cc
|
||||
mem/physical.cc
|
||||
mem/port.cc
|
||||
mem/translating_port.cc
|
||||
mem/bus.cc
|
||||
|
||||
python/pyconfig.cc
|
||||
|
@ -254,6 +253,7 @@ 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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -63,16 +63,10 @@ ObjectFile::~ObjectFile()
|
|||
|
||||
|
||||
bool
|
||||
ObjectFile::loadSection(Section *sec, Port *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);
|
||||
}
|
||||
|
@ -86,11 +80,11 @@ ObjectFile::loadSection(Section *sec, Port *memPort, bool loadPhys)
|
|||
|
||||
|
||||
bool
|
||||
ObjectFile::loadSections(Port *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,6 +29,7 @@
|
|||
#ifndef __OBJECT_FILE_HH__
|
||||
#define __OBJECT_FILE_HH__
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "sim/host.hh" // for Addr
|
||||
|
@ -72,7 +73,8 @@ class ObjectFile
|
|||
|
||||
void close();
|
||||
|
||||
virtual bool loadSections(Port *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, Port *memPort, bool loadPhys);
|
||||
bool loadSection(Section *sec, Port *memPort, Addr addrMask);
|
||||
void setGlobalPointer(Addr global_ptr) { globalPtr = global_ptr; }
|
||||
|
||||
public:
|
||||
|
|
|
@ -80,7 +80,7 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
|
|||
}
|
||||
#else
|
||||
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
|
||||
Process *_process, int _asid)
|
||||
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),
|
||||
|
@ -89,7 +89,7 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
|
|||
/* 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 = memobj->getPort("functional");
|
||||
mem_port->setPeer(port);
|
||||
port->setPeer(mem_port);
|
||||
|
||||
|
|
|
@ -205,8 +205,8 @@ class CPUExecContext
|
|||
CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
|
||||
AlphaITB *_itb, AlphaDTB *_dtb);
|
||||
#else
|
||||
CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process,
|
||||
int _asid);
|
||||
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);
|
||||
|
|
|
@ -169,7 +169,7 @@ SimpleCPU::SimpleCPU(Params *p)
|
|||
cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb);
|
||||
#else
|
||||
cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process,
|
||||
/* asid */ 0);
|
||||
/* asid */ 0, mem);
|
||||
#endif // !FULL_SYSTEM
|
||||
|
||||
xcProxy = cpuXC->getProxy();
|
||||
|
|
19
mem/port.hh
19
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); }
|
||||
|
@ -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__
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
class PageTable;
|
||||
|
||||
class TranslatingPort : public Port
|
||||
class TranslatingPort : public FunctionalPort
|
||||
{
|
||||
private:
|
||||
PageTable *pTable;
|
||||
|
@ -59,11 +59,6 @@ class TranslatingPort : public Port
|
|||
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
|
||||
|
|
|
@ -36,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
|
||||
*/
|
||||
|
@ -45,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