Changes for Process object initialization in merged-memory environment.
System object now exists for both fullsys and syscall emulation, as the latter needs it so that Process objects can find the shared PhysicalMemory for initialization. Changes are incomplete: still need to fix up Process (& EioProcess) memory initialization and syscall emulation code for new mem interface. arch/alpha/alpha_linux_process.cc: arch/alpha/alpha_linux_process.hh: arch/alpha/alpha_tru64_process.cc: arch/alpha/alpha_tru64_process.hh: cpu/base.cc: cpu/base.hh: Take System argument in constructor. cpu/exec_context.cc: Take System argument in constructor. Merge two constructors into a single one. cpu/exec_context.hh: Take System argument in constructor. Merge two constructors into a single one. Replace dummy translation with lookup in Process object's page table. python/m5/objects/Process.py: Add System parameter to Process object (& subobjects). python/m5/objects/System.py: Segregate full-system only Process parameters (most of them!). sim/process.cc: Take System argument in constructor. Move initialization to startup() callback to occur after system & cpus are initialized. Generate ProxyMemory object to pass to loader for transparent virtual page allocation. sim/process.hh: Take System argument in constructor. Move initialization to startup() callback to occur after system & cpus are initialized. sim/system.cc: sim/system.hh: Enable System object for non-full-system too. Basically involved putting most of the existing code inside '#ifdef FULL_SYSTEM'. Key thing needed for syscall emulation at this point is the PhysicalMemory object (for Process initialization). --HG-- extra : convert_revision : f0f34b47bd4f77b502191affd3d03b4d6d9bcdd8
This commit is contained in:
parent
9df80550d4
commit
03a2aca9a9
14 changed files with 239 additions and 137 deletions
|
@ -943,12 +943,13 @@ AlphaLinuxProcess::syscall(ExecContext *xc)
|
|||
|
||||
AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name,
|
||||
ObjectFile *objFile,
|
||||
System *system,
|
||||
int stdin_fd,
|
||||
int stdout_fd,
|
||||
int stderr_fd,
|
||||
std::vector<std::string> &argv,
|
||||
std::vector<std::string> &envp)
|
||||
: LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp)
|
||||
: LiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
|
||||
argv, envp)
|
||||
{
|
||||
init_regs->intRegFile[0] = 0;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ class AlphaLinuxProcess : public LiveProcess
|
|||
/// Constructor.
|
||||
AlphaLinuxProcess(const std::string &name,
|
||||
ObjectFile *objFile,
|
||||
System *system,
|
||||
int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
std::vector<std::string> &argv,
|
||||
std::vector<std::string> &envp);
|
||||
|
|
|
@ -1924,11 +1924,13 @@ AlphaTru64Process::syscall(ExecContext *xc)
|
|||
|
||||
AlphaTru64Process::AlphaTru64Process(const std::string &name,
|
||||
ObjectFile *objFile,
|
||||
System *system,
|
||||
int stdin_fd,
|
||||
int stdout_fd,
|
||||
int stderr_fd,
|
||||
std::vector<std::string> &argv,
|
||||
std::vector<std::string> &envp)
|
||||
: LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp)
|
||||
: LiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
|
||||
argv, envp)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ class AlphaTru64Process : public LiveProcess
|
|||
/// Constructor.
|
||||
AlphaTru64Process(const std::string &name,
|
||||
ObjectFile *objFile,
|
||||
System *system,
|
||||
int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
std::vector<std::string> &argv,
|
||||
std::vector<std::string> &envp);
|
||||
|
|
17
cpu/base.cc
17
cpu/base.cc
|
@ -59,7 +59,7 @@ BaseCPU::BaseCPU(Params *p)
|
|||
#else
|
||||
BaseCPU::BaseCPU(Params *p)
|
||||
: SimObject(p->name), clock(p->clock), params(p),
|
||||
number_of_threads(p->numberOfThreads)
|
||||
number_of_threads(p->numberOfThreads), system(p->system)
|
||||
#endif
|
||||
{
|
||||
DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this);
|
||||
|
@ -211,15 +211,18 @@ BaseCPU::registerExecContexts()
|
|||
{
|
||||
for (int i = 0; i < execContexts.size(); ++i) {
|
||||
ExecContext *xc = execContexts[i];
|
||||
#if FULL_SYSTEM
|
||||
int id = params->cpu_id;
|
||||
if (id != -1)
|
||||
id += i;
|
||||
|
||||
xc->cpu_id = system->registerExecContext(xc, id);
|
||||
if (xc->status() == ExecContext::Suspended) {
|
||||
#if FULL_SYSTEM
|
||||
int id = params->cpu_id;
|
||||
if (id != -1)
|
||||
id += i;
|
||||
|
||||
xc->cpu_id = system->registerExecContext(xc, id);
|
||||
#else
|
||||
xc->cpu_id = xc->process->registerExecContext(xc);
|
||||
xc->cpu_id = xc->process->registerExecContext(xc);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,10 +38,7 @@
|
|||
#include "sim/sim_object.hh"
|
||||
#include "targetarch/isa_traits.hh"
|
||||
|
||||
#if FULL_SYSTEM
|
||||
class System;
|
||||
#endif
|
||||
|
||||
class BranchPred;
|
||||
class ExecContext;
|
||||
|
||||
|
@ -122,8 +119,8 @@ class BaseCPU : public SimObject
|
|||
Tick clock;
|
||||
bool functionTrace;
|
||||
Tick functionTraceStart;
|
||||
#if FULL_SYSTEM
|
||||
System *system;
|
||||
#if FULL_SYSTEM
|
||||
int cpu_id;
|
||||
Tick profile;
|
||||
#endif
|
||||
|
@ -170,9 +167,9 @@ class BaseCPU : public SimObject
|
|||
*/
|
||||
EventQueue **comLoadEventQueue;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
System *system;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
/**
|
||||
* Serialize this object to the given output stream.
|
||||
* @param os The stream to serialize to.
|
||||
|
|
|
@ -76,19 +76,13 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
|
|||
profilePC = 3;
|
||||
}
|
||||
#else
|
||||
ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
|
||||
Process *_process, int _asid)
|
||||
ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
|
||||
FunctionalMemory *_mem, Process *_process, int _asid)
|
||||
: _status(ExecContext::Unallocated),
|
||||
cpu(_cpu), thread_num(_thread_num), cpu_id(-1),
|
||||
process(_process), mem(process->getMemory()), asid(_asid),
|
||||
func_exe_inst(0), storeCondFailures(0)
|
||||
{
|
||||
memset(®s, 0, sizeof(RegFile));
|
||||
}
|
||||
|
||||
ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
|
||||
FunctionalMemory *_mem, int _asid)
|
||||
: cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid),
|
||||
system(_system), mem(_mem),
|
||||
process(_process),
|
||||
asid(_asid),
|
||||
func_exe_inst(0), storeCondFailures(0)
|
||||
{
|
||||
memset(®s, 0, sizeof(RegFile));
|
||||
|
|
|
@ -31,13 +31,12 @@
|
|||
|
||||
#include "config/full_system.hh"
|
||||
#include "mem/functional/functional.hh"
|
||||
#include "mem/mem_interface.hh"
|
||||
#include "mem/mem_req.hh"
|
||||
#include "sim/host.hh"
|
||||
#include "sim/serialize.hh"
|
||||
#include "targetarch/byte_swap.hh"
|
||||
|
||||
// forward declaration: see functional_memory.hh
|
||||
class FunctionalMemory;
|
||||
class PhysicalMemory;
|
||||
class BaseCPU;
|
||||
|
||||
|
@ -123,11 +122,12 @@ class ExecContext
|
|||
// it belongs. For full-system mode, this is the system CPU ID.
|
||||
int cpu_id;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
System *system;
|
||||
FunctionalMemory *mem;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
AlphaITB *itb;
|
||||
AlphaDTB *dtb;
|
||||
System *system;
|
||||
|
||||
// the following two fields are redundant, since we can always
|
||||
// look them up through the system pointer, but we'll leave them
|
||||
|
@ -148,8 +148,6 @@ class ExecContext
|
|||
#else
|
||||
Process *process;
|
||||
|
||||
FunctionalMemory *mem; // functional storage for process address space
|
||||
|
||||
// Address space ID. Note that this is used for TIMING cache
|
||||
// simulation only; all functional memory accesses should use
|
||||
// one of the FunctionalMemory pointers above.
|
||||
|
@ -186,9 +184,8 @@ class ExecContext
|
|||
ExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
|
||||
AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem);
|
||||
#else
|
||||
ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
|
||||
ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
|
||||
int _asid);
|
||||
ExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
|
||||
FunctionalMemory *_mem, Process *_process, int _asid);
|
||||
#endif
|
||||
virtual ~ExecContext();
|
||||
|
||||
|
@ -230,28 +227,19 @@ class ExecContext
|
|||
int getInstAsid() { return asid; }
|
||||
int getDataAsid() { return asid; }
|
||||
|
||||
Fault dummyTranslation(MemReqPtr &req)
|
||||
{
|
||||
#if 0
|
||||
assert((req->vaddr >> 48 & 0xffff) == 0);
|
||||
#endif
|
||||
|
||||
// put the asid in the upper 16 bits of the paddr
|
||||
req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
|
||||
req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
|
||||
return No_Fault;
|
||||
}
|
||||
Fault translateInstReq(MemReqPtr &req)
|
||||
{
|
||||
return dummyTranslation(req);
|
||||
return process->pTable->translate(req);
|
||||
}
|
||||
|
||||
Fault translateDataReadReq(MemReqPtr &req)
|
||||
{
|
||||
return dummyTranslation(req);
|
||||
return process->pTable->translate(req);
|
||||
}
|
||||
|
||||
Fault translateDataWriteReq(MemReqPtr &req)
|
||||
{
|
||||
return dummyTranslation(req);
|
||||
return process->pTable->translate(req);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -334,7 +322,9 @@ class ExecContext
|
|||
|
||||
Fault instRead(MemReqPtr &req)
|
||||
{
|
||||
return mem->read(req, inst);
|
||||
panic("instRead not implemented");
|
||||
// return funcPhysMem->read(req, inst);
|
||||
return No_Fault;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -3,6 +3,7 @@ class Process(SimObject):
|
|||
type = 'Process'
|
||||
abstract = True
|
||||
output = Param.String('cout', 'filename for stdout/stderr')
|
||||
system = Param.System(Parent.any, "system process will run on")
|
||||
|
||||
class LiveProcess(Process):
|
||||
type = 'LiveProcess'
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
from m5 import *
|
||||
class System(SimObject):
|
||||
type = 'System'
|
||||
boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency,
|
||||
"boot processor frequency")
|
||||
memctrl = Param.MemoryController(Parent.any, "memory controller")
|
||||
physmem = Param.PhysicalMemory(Parent.any, "phsyical memory")
|
||||
kernel = Param.String("file that contains the kernel code")
|
||||
console = Param.String("file that contains the console code")
|
||||
pal = Param.String("file that contains palcode")
|
||||
readfile = Param.String("", "file to read startup script from")
|
||||
init_param = Param.UInt64(0, "numerical value to pass into simulator")
|
||||
boot_osflags = Param.String("a", "boot flags to pass to the kernel")
|
||||
system_type = Param.UInt64("Type of system we are emulating")
|
||||
system_rev = Param.UInt64("Revision of system we are emulating")
|
||||
bin = Param.Bool(False, "is this system binned")
|
||||
binned_fns = VectorParam.String([], "functions broken down and binned")
|
||||
|
||||
if build_env['FULL_SYSTEM']:
|
||||
boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency,
|
||||
"boot processor frequency")
|
||||
memctrl = Param.MemoryController(Parent.any, "memory controller")
|
||||
kernel = Param.String("file that contains the kernel code")
|
||||
console = Param.String("file that contains the console code")
|
||||
pal = Param.String("file that contains palcode")
|
||||
readfile = Param.String("", "file to read startup script from")
|
||||
init_param = Param.UInt64(0, "numerical value to pass into simulator")
|
||||
boot_osflags = Param.String("a", "boot flags to pass to the kernel")
|
||||
system_type = Param.UInt64("Type of system we are emulating")
|
||||
system_rev = Param.UInt64("Revision of system we are emulating")
|
||||
bin = Param.Bool(False, "is this system binned")
|
||||
binned_fns = VectorParam.String([], "functions broken down and binned")
|
||||
|
|
102
sim/process.cc
102
sim/process.cc
|
@ -41,11 +41,14 @@
|
|||
#include "cpu/smt.hh"
|
||||
#include "encumbered/cpu/full/thread.hh"
|
||||
#include "encumbered/eio/eio.hh"
|
||||
#include "encumbered/mem/functional/main.hh"
|
||||
#include "mem/page_table.hh"
|
||||
#include "mem/functional/physical.hh"
|
||||
#include "mem/functional/proxy.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/fake_syscall.hh"
|
||||
#include "sim/process.hh"
|
||||
#include "sim/stats.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
#ifdef TARGET_ALPHA
|
||||
#include "arch/alpha/alpha_tru64_process.hh"
|
||||
|
@ -67,18 +70,12 @@ using namespace std;
|
|||
int num_processes = 0;
|
||||
|
||||
Process::Process(const string &nm,
|
||||
System *_system,
|
||||
int stdin_fd, // initial I/O descriptors
|
||||
int stdout_fd,
|
||||
int stderr_fd)
|
||||
: SimObject(nm)
|
||||
: SimObject(nm), system(_system)
|
||||
{
|
||||
// allocate memory space
|
||||
memory = new MainMemory(nm + ".MainMem");
|
||||
|
||||
// allocate initial register file
|
||||
init_regs = new RegFile;
|
||||
memset(init_regs, 0, sizeof(RegFile));
|
||||
|
||||
// initialize first 3 fds (stdin, stdout, stderr)
|
||||
fd_map[STDIN_FILENO] = stdin_fd;
|
||||
fd_map[STDOUT_FILENO] = stdout_fd;
|
||||
|
@ -91,9 +88,11 @@ Process::Process(const string &nm,
|
|||
|
||||
mmap_start = mmap_end = 0;
|
||||
nxm_start = nxm_end = 0;
|
||||
pTable = new PageTable(system);
|
||||
// other parameters will be initialized when the program is loaded
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Process::regStats()
|
||||
{
|
||||
|
@ -145,12 +144,7 @@ Process::registerExecContext(ExecContext *xc)
|
|||
int myIndex = execContexts.size();
|
||||
execContexts.push_back(xc);
|
||||
|
||||
if (myIndex == 0) {
|
||||
// copy process's initial regs struct
|
||||
xc->regs = *init_regs;
|
||||
}
|
||||
|
||||
// return CPU number to caller and increment available CPU count
|
||||
// return CPU number to caller
|
||||
return myIndex;
|
||||
}
|
||||
|
||||
|
@ -158,7 +152,9 @@ void
|
|||
Process::startup()
|
||||
{
|
||||
if (execContexts.empty())
|
||||
return;
|
||||
fatal("Process %s is not associated with any CPUs!\n", name());
|
||||
|
||||
initVirtMem = new ProxyMemory<FunctionalMemory>(system->physmem, pTable);
|
||||
|
||||
// first exec context for this process... initialize & enable
|
||||
ExecContext *xc = execContexts[0];
|
||||
|
@ -249,23 +245,26 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process)
|
|||
|
||||
static void
|
||||
copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr,
|
||||
FunctionalMemory *memory)
|
||||
FunctionalMemory *func)
|
||||
{
|
||||
for (int i = 0; i < strings.size(); ++i) {
|
||||
memory->access(Write, array_ptr, &data_ptr, sizeof(Addr));
|
||||
memory->writeString(data_ptr, strings[i].c_str());
|
||||
func->prot_write(array_ptr, (uint8_t*)&data_ptr, sizeof(Addr));
|
||||
func->writeString(data_ptr, strings[i].c_str());
|
||||
array_ptr += sizeof(Addr);
|
||||
data_ptr += strings[i].size() + 1;
|
||||
}
|
||||
// add NULL terminator
|
||||
data_ptr = 0;
|
||||
memory->access(Write, array_ptr, &data_ptr, sizeof(Addr));
|
||||
|
||||
func->prot_write(array_ptr, (uint8_t*)&data_ptr, sizeof(Addr));
|
||||
}
|
||||
|
||||
LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
|
||||
LiveProcess::LiveProcess(const string &nm, ObjectFile *_objFile,
|
||||
System *_system,
|
||||
int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
vector<string> &argv, vector<string> &envp)
|
||||
: Process(nm, stdin_fd, stdout_fd, stderr_fd)
|
||||
vector<string> &_argv, vector<string> &_envp)
|
||||
: Process(nm, _system, stdin_fd, stdout_fd, stderr_fd),
|
||||
objFile(_objFile), argv(_argv), envp(_envp)
|
||||
{
|
||||
prog_fname = argv[0];
|
||||
|
||||
|
@ -274,10 +273,18 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
|
|||
text_size = objFile->textSize();
|
||||
data_base = objFile->dataBase();
|
||||
data_size = objFile->dataSize() + objFile->bssSize();
|
||||
brk_point = roundUp(data_base + data_size, VMPageSize);
|
||||
brk_point = = roundUp(data_base + data_size, VMPageSize);
|
||||
|
||||
// load object file into target memory
|
||||
objFile->loadSections(memory);
|
||||
// Set up stack. On Alpha, stack goes below text section. This
|
||||
// code should get moved to some architecture-specific spot.
|
||||
stack_base = text_base - (409600+4096);
|
||||
|
||||
// Set up region for mmaps. Tru64 seems to start just above 0 and
|
||||
// grow up from there.
|
||||
mmap_start = mmap_end = 0x10000;
|
||||
|
||||
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
||||
|
||||
// load up symbols, if any... these may be used for debugging or
|
||||
// profiling.
|
||||
|
@ -290,17 +297,15 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
|
|||
debugSymbolTable = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set up stack. On Alpha, stack goes below text section. This
|
||||
// code should get moved to some architecture-specific spot.
|
||||
stack_base = text_base - (409600+4096);
|
||||
void
|
||||
LiveProcess::startup()
|
||||
{
|
||||
Process::startup();
|
||||
|
||||
// Set up region for mmaps. Tru64 seems to start just above 0 and
|
||||
// grow up from there.
|
||||
mmap_start = mmap_end = 0x10000;
|
||||
|
||||
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
||||
// load object file into target memory
|
||||
objFile->loadSections(initVirtMem);
|
||||
|
||||
// Calculate how much space we need for arg & env arrays.
|
||||
int argv_array_size = sizeof(Addr) * (argv.size() + 1);
|
||||
|
@ -325,6 +330,8 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
|
|||
// align it
|
||||
stack_min &= ~7;
|
||||
stack_size = stack_base - stack_min;
|
||||
// map memory
|
||||
pTable->allocate(stack_min, stack_size);
|
||||
|
||||
// map out initial stack contents
|
||||
Addr argv_array_base = stack_min + sizeof(uint64_t); // room for argc
|
||||
|
@ -334,10 +341,12 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
|
|||
|
||||
// write contents to stack
|
||||
uint64_t argc = argv.size();
|
||||
memory->access(Write, stack_min, &argc, sizeof(uint64_t));
|
||||
initVirtMem->prot_write(stack_min, (uint8_t*)&argc, sizeof(uint64_t));
|
||||
|
||||
copyStringArray(argv, argv_array_base, arg_data_base, memory);
|
||||
copyStringArray(envp, envp_array_base, env_data_base, memory);
|
||||
copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
|
||||
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
|
||||
|
||||
RegFile *init_regs = &(execContexts[0]->regs);
|
||||
|
||||
init_regs->intRegFile[ArgumentReg0] = argc;
|
||||
init_regs->intRegFile[ArgumentReg1] = argv_array_base;
|
||||
|
@ -345,11 +354,13 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
|
|||
init_regs->intRegFile[GlobalPointerReg] = objFile->globalPointer();
|
||||
init_regs->pc = prog_entry;
|
||||
init_regs->npc = prog_entry + sizeof(MachInst);
|
||||
|
||||
num_processes++;
|
||||
}
|
||||
|
||||
|
||||
LiveProcess *
|
||||
LiveProcess::create(const string &nm,
|
||||
LiveProcess::create(const string &nm, System *system,
|
||||
int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
string executable,
|
||||
vector<string> &argv, vector<string> &envp)
|
||||
|
@ -362,17 +373,20 @@ LiveProcess::create(const string &nm,
|
|||
|
||||
// check object type & set up syscall emulation pointer
|
||||
if (objFile->getArch() == ObjectFile::Alpha) {
|
||||
|
||||
switch (objFile->getOpSys()) {
|
||||
case ObjectFile::Tru64:
|
||||
process = new AlphaTru64Process(nm, objFile,
|
||||
process = new AlphaTru64Process(nm, objFile, system,
|
||||
stdin_fd, stdout_fd, stderr_fd,
|
||||
argv, envp);
|
||||
|
||||
break;
|
||||
|
||||
case ObjectFile::Linux:
|
||||
process = new AlphaLinuxProcess(nm, objFile,
|
||||
process = new AlphaLinuxProcess(nm, objFile, system,
|
||||
stdin_fd, stdout_fd, stderr_fd,
|
||||
argv, envp);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -398,6 +412,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
|
|||
Param<string> input;
|
||||
Param<string> output;
|
||||
VectorParam<string> env;
|
||||
SimObjectParam<System *> system;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
|
||||
|
||||
|
@ -408,7 +423,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess)
|
|||
INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
|
||||
INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
|
||||
INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
|
||||
INIT_PARAM(env, "environment settings")
|
||||
INIT_PARAM(env, "environment settings"),
|
||||
INIT_PARAM(system, "system")
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(LiveProcess)
|
||||
|
||||
|
@ -435,7 +451,7 @@ CREATE_SIM_OBJECT(LiveProcess)
|
|||
|
||||
stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
|
||||
|
||||
return LiveProcess::create(getInstanceName(),
|
||||
return LiveProcess::create(getInstanceName(), system,
|
||||
stdin_fd, stdout_fd, stderr_fd,
|
||||
(string)executable == "" ? cmd[0] : executable,
|
||||
cmd, env);
|
||||
|
|
|
@ -40,18 +40,27 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "targetarch/isa_traits.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
#include "sim/stats.hh"
|
||||
#include "base/statistics.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "mem/base_mem.hh"
|
||||
#include "mem/mem_interface.hh"
|
||||
#include "mem/page_table.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
#include "sim/stats.hh"
|
||||
#include "targetarch/isa_traits.hh"
|
||||
|
||||
class ExecContext;
|
||||
class FunctionalMemory;
|
||||
class System;
|
||||
|
||||
class Process : public SimObject
|
||||
{
|
||||
public:
|
||||
|
||||
/// Pointer to object representing the system this process is
|
||||
/// running on.
|
||||
System *system;
|
||||
|
||||
// have we initialized an execution context from this process? If
|
||||
// yes, subsequent contexts are assumed to be for dynamically
|
||||
// created threads and are not initialized.
|
||||
|
@ -71,15 +80,12 @@ class Process : public SimObject
|
|||
|
||||
WaitRec(Addr chan, ExecContext *ctx)
|
||||
: waitChan(chan), waitingContext(ctx)
|
||||
{
|
||||
}
|
||||
{ }
|
||||
};
|
||||
|
||||
// list of all blocked contexts
|
||||
std::list<WaitRec> waitList;
|
||||
|
||||
RegFile *init_regs; // initial register contents
|
||||
|
||||
Addr text_base; // text (code) segment base
|
||||
unsigned text_size; // text (code) size in bytes
|
||||
|
||||
|
@ -112,6 +118,7 @@ class Process : public SimObject
|
|||
protected:
|
||||
// constructor
|
||||
Process(const std::string &nm,
|
||||
System *_system,
|
||||
int stdin_fd, // initial I/O descriptors
|
||||
int stdout_fd,
|
||||
int stderr_fd);
|
||||
|
@ -120,7 +127,11 @@ class Process : public SimObject
|
|||
virtual void startup();
|
||||
|
||||
protected:
|
||||
FunctionalMemory *memory;
|
||||
/// Memory object for initialization (image loading)
|
||||
FunctionalMemory *initVirtMem;
|
||||
|
||||
public:
|
||||
PageTable *pTable;
|
||||
|
||||
private:
|
||||
// file descriptor remapping support
|
||||
|
@ -175,8 +186,6 @@ class Process : public SimObject
|
|||
}
|
||||
|
||||
virtual void syscall(ExecContext *xc) = 0;
|
||||
|
||||
virtual FunctionalMemory *getMemory() { return memory; }
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -186,16 +195,23 @@ class ObjectFile;
|
|||
class LiveProcess : public Process
|
||||
{
|
||||
protected:
|
||||
ObjectFile *objFile;
|
||||
std::vector<std::string> argv;
|
||||
std::vector<std::string> envp;
|
||||
|
||||
LiveProcess(const std::string &nm, ObjectFile *objFile,
|
||||
int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
std::vector<std::string> &argv,
|
||||
std::vector<std::string> &envp);
|
||||
|
||||
void startup();
|
||||
|
||||
public:
|
||||
// this function is used to create the LiveProcess object, since
|
||||
// we can't tell which subclass of LiveProcess to use until we
|
||||
// open and look at the object file.
|
||||
static LiveProcess *create(const std::string &nm,
|
||||
System *_system,
|
||||
int stdin_fd, int stdout_fd, int stderr_fd,
|
||||
std::string executable,
|
||||
std::vector<std::string> &argv,
|
||||
|
|
|
@ -28,15 +28,17 @@
|
|||
|
||||
#include "base/loader/object_file.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/remote_gdb.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#include "mem/functional/memory_control.hh"
|
||||
#include "mem/functional/physical.hh"
|
||||
#include "targetarch/vtophys.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/system.hh"
|
||||
#include "base/trace.hh"
|
||||
#if FULL_SYSTEM
|
||||
#include "base/remote_gdb.hh"
|
||||
#include "kern/kernel_stats.hh"
|
||||
#include "mem/functional/memory_control.hh"
|
||||
#include "targetarch/vtophys.hh"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -45,12 +47,18 @@ vector<System *> System::systemList;
|
|||
int System::numSystemsRunning = 0;
|
||||
|
||||
System::System(Params *p)
|
||||
: SimObject(p->name), memctrl(p->memctrl), physmem(p->physmem),
|
||||
init_param(p->init_param), numcpus(0), params(p)
|
||||
: SimObject(p->name), physmem(p->physmem), numcpus(0),
|
||||
#if FULL_SYSTEM
|
||||
memctrl(p->memctrl), init_param(p->init_param),
|
||||
#else
|
||||
page_ptr(0),
|
||||
#endif
|
||||
params(p)
|
||||
{
|
||||
// add self to global system list
|
||||
systemList.push_back(this);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
kernelSymtab = new SymbolTable;
|
||||
consoleSymtab = new SymbolTable;
|
||||
palSymtab = new SymbolTable;
|
||||
|
@ -123,7 +131,7 @@ System::System(Params *p)
|
|||
DPRINTF(Loader, "Kernel loaded...\n");
|
||||
|
||||
Addr addr = 0;
|
||||
#ifndef NDEBUG
|
||||
#ifdef DEBUG
|
||||
consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
|
||||
#endif
|
||||
|
||||
|
@ -157,14 +165,17 @@ System::System(Params *p)
|
|||
} else
|
||||
panic("could not find hwrpb\n");
|
||||
|
||||
kernelBinning = new Kernel::Binning(this);
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
// increment the number of running systms
|
||||
numSystemsRunning++;
|
||||
|
||||
kernelBinning = new Kernel::Binning(this);
|
||||
}
|
||||
|
||||
System::~System()
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
delete kernelSymtab;
|
||||
delete consoleSymtab;
|
||||
delete kernel;
|
||||
|
@ -176,6 +187,8 @@ System::~System()
|
|||
#ifdef DEBUG
|
||||
delete consolePanicEvent;
|
||||
#endif
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
}
|
||||
|
||||
|
||||
|
@ -213,6 +226,7 @@ System::~System()
|
|||
Addr
|
||||
System::fixFuncEventAddr(Addr addr)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
// mask for just the opcode, Ra, and Rb fields (not the offset)
|
||||
const uint32_t inst_mask = 0xffff0000;
|
||||
// ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27
|
||||
|
@ -234,9 +248,13 @@ System::fixFuncEventAddr(Addr addr)
|
|||
} else {
|
||||
return addr;
|
||||
}
|
||||
#else
|
||||
panic("System::fixFuncEventAddr needs to be rewritten "
|
||||
"to work with syscall emulation");
|
||||
#endif // FULL_SYSTEM}
|
||||
}
|
||||
|
||||
|
||||
#if FULL_SYSTEM
|
||||
void
|
||||
System::setAlphaAccess(Addr access)
|
||||
{
|
||||
|
@ -263,6 +281,8 @@ System::breakpoint()
|
|||
|
||||
int rgdb_wait = -1;
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
int
|
||||
System::registerExecContext(ExecContext *xc, int id)
|
||||
{
|
||||
|
@ -282,6 +302,7 @@ System::registerExecContext(ExecContext *xc, int id)
|
|||
execContexts[id] = xc;
|
||||
numcpus++;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
RemoteGDB *rgdb = new RemoteGDB(this, xc);
|
||||
GDBListener *gdbl = new GDBListener(rgdb, 7000 + id);
|
||||
gdbl->listen();
|
||||
|
@ -297,6 +318,7 @@ System::registerExecContext(ExecContext *xc, int id)
|
|||
}
|
||||
|
||||
remoteGDB[id] = rgdb;
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
return id;
|
||||
}
|
||||
|
@ -320,34 +342,52 @@ System::replaceExecContext(ExecContext *xc, int id)
|
|||
}
|
||||
|
||||
execContexts[id] = xc;
|
||||
#if FULL_SYSTEM
|
||||
remoteGDB[id]->replaceExecContext(xc);
|
||||
#endif // FULL_SYSTEM
|
||||
}
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
Addr
|
||||
System::new_page()
|
||||
{
|
||||
Addr return_addr = page_ptr << LogVMPageSize;
|
||||
++page_ptr;
|
||||
return return_addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
System::regStats()
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
kernelBinning->regStats(name() + ".kern");
|
||||
#endif // FULL_SYSTEM
|
||||
}
|
||||
|
||||
void
|
||||
System::serialize(ostream &os)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
kernelBinning->serialize(os);
|
||||
|
||||
kernelSymtab->serialize("kernel_symtab", os);
|
||||
consoleSymtab->serialize("console_symtab", os);
|
||||
palSymtab->serialize("pal_symtab", os);
|
||||
#endif // FULL_SYSTEM
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
System::unserialize(Checkpoint *cp, const string §ion)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
kernelBinning->unserialize(cp, section);
|
||||
|
||||
kernelSymtab->unserialize("kernel_symtab", cp, section);
|
||||
consoleSymtab->unserialize("console_symtab", cp, section);
|
||||
palSymtab->unserialize("pal_symtab", cp, section);
|
||||
#endif // FULL_SYSTEM
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -370,9 +410,11 @@ printSystems()
|
|||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
|
||||
|
||||
SimObjectParam<PhysicalMemory *> physmem;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
Param<Tick> boot_cpu_frequency;
|
||||
SimObjectParam<MemoryController *> memctrl;
|
||||
SimObjectParam<PhysicalMemory *> physmem;
|
||||
|
||||
Param<string> kernel;
|
||||
Param<string> console;
|
||||
|
@ -388,14 +430,18 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
|
|||
Param<bool> bin;
|
||||
VectorParam<string> binned_fns;
|
||||
Param<bool> bin_int;
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(System)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(System)
|
||||
|
||||
INIT_PARAM(physmem, "physical memory")
|
||||
|
||||
#if FULL_SYSTEM
|
||||
,
|
||||
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
|
||||
INIT_PARAM(memctrl, "memory controller"),
|
||||
INIT_PARAM(physmem, "phsyical memory"),
|
||||
INIT_PARAM(kernel, "file that contains the kernel code"),
|
||||
INIT_PARAM(console, "file that contains the console code"),
|
||||
INIT_PARAM(pal, "file that contains palcode"),
|
||||
|
@ -408,6 +454,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(System)
|
|||
INIT_PARAM_DFLT(bin, "is this system to be binned", false),
|
||||
INIT_PARAM(binned_fns, "functions to be broken down and binned"),
|
||||
INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(System)
|
||||
|
||||
|
@ -415,9 +462,10 @@ CREATE_SIM_OBJECT(System)
|
|||
{
|
||||
System::Params *p = new System::Params;
|
||||
p->name = getInstanceName();
|
||||
p->physmem = physmem;
|
||||
#if FULL_SYSTEM
|
||||
p->boot_cpu_frequency = boot_cpu_frequency;
|
||||
p->memctrl = memctrl;
|
||||
p->physmem = physmem;
|
||||
p->kernel_path = kernel;
|
||||
p->console_path = console;
|
||||
p->palcode = pal;
|
||||
|
@ -429,6 +477,7 @@ CREATE_SIM_OBJECT(System)
|
|||
p->bin = bin;
|
||||
p->binned_fns = binned_fns;
|
||||
p->bin_int = bin_int;
|
||||
#endif // FULL_SYSTEM
|
||||
return new System(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,27 +35,29 @@
|
|||
#include "base/statistics.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "cpu/pc_event.hh"
|
||||
#include "kern/system_events.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
#if FULL_SYSTEM
|
||||
#include "kern/system_events.hh"
|
||||
#endif
|
||||
|
||||
class BaseCPU;
|
||||
class ExecContext;
|
||||
class GDBListener;
|
||||
class MemoryController;
|
||||
class ObjectFile;
|
||||
class PhysicalMemory;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
class Platform;
|
||||
class GDBListener;
|
||||
class RemoteGDB;
|
||||
namespace Kernel { class Binning; }
|
||||
#endif
|
||||
|
||||
class System : public SimObject
|
||||
{
|
||||
public:
|
||||
MemoryController *memctrl;
|
||||
PhysicalMemory *physmem;
|
||||
Platform *platform;
|
||||
PCEventQueue pcEventQueue;
|
||||
uint64_t init_param;
|
||||
|
||||
std::vector<ExecContext *> execContexts;
|
||||
int numcpus;
|
||||
|
@ -68,6 +70,11 @@ class System : public SimObject
|
|||
return numcpus;
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
MemoryController *memctrl;
|
||||
Platform *platform;
|
||||
uint64_t init_param;
|
||||
|
||||
/** kernel symbol table */
|
||||
SymbolTable *kernelSymtab;
|
||||
|
||||
|
@ -97,11 +104,18 @@ class System : public SimObject
|
|||
|
||||
Kernel::Binning *kernelBinning;
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef DEBUG
|
||||
/** Event to halt the simulator if the console calls panic() */
|
||||
BreakPCEvent *consolePanicEvent;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
int page_ptr;
|
||||
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
@ -128,6 +142,7 @@ class System : public SimObject
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
/** Add a function-based event to kernel code. */
|
||||
template <class T>
|
||||
T *System::addKernelFuncEvent(const char *lbl)
|
||||
|
@ -148,19 +163,24 @@ class System : public SimObject
|
|||
{
|
||||
return addFuncEvent<T>(consoleSymtab, lbl);
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
#if FULL_SYSTEM
|
||||
std::vector<RemoteGDB *> remoteGDB;
|
||||
std::vector<GDBListener *> gdbListen;
|
||||
bool breakpoint();
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
public:
|
||||
struct Params
|
||||
{
|
||||
std::string name;
|
||||
PhysicalMemory *physmem;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
Tick boot_cpu_frequency;
|
||||
MemoryController *memctrl;
|
||||
PhysicalMemory *physmem;
|
||||
uint64_t init_param;
|
||||
bool bin;
|
||||
std::vector<std::string> binned_fns;
|
||||
|
@ -174,6 +194,7 @@ class System : public SimObject
|
|||
std::string readfile;
|
||||
uint64_t system_type;
|
||||
uint64_t system_rev;
|
||||
#endif
|
||||
};
|
||||
Params *params;
|
||||
|
||||
|
@ -183,6 +204,8 @@ class System : public SimObject
|
|||
void startup();
|
||||
|
||||
public:
|
||||
|
||||
#if FULL_SYSTEM
|
||||
/**
|
||||
* Set the m5AlphaAccess pointer in the console
|
||||
*/
|
||||
|
@ -206,6 +229,12 @@ class System : public SimObject
|
|||
*/
|
||||
Addr getKernelEntry() const { return kernelEntry; }
|
||||
|
||||
#else
|
||||
|
||||
Addr new_page();
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
int registerExecContext(ExecContext *xc, int xcIndex);
|
||||
void replaceExecContext(ExecContext *xc, int xcIndex);
|
||||
|
||||
|
|
Loading…
Reference in a new issue