diff options
Diffstat (limited to 'sim/process.cc')
-rw-r--r-- | sim/process.cc | 216 |
1 files changed, 72 insertions, 144 deletions
diff --git a/sim/process.cc b/sim/process.cc index a84a4f7ba..7b27c4274 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -37,18 +37,15 @@ #include "base/loader/symtab.hh" #include "base/statistics.hh" #include "config/full_system.hh" -#include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" -#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/mem_object.hh" +#include "mem/translating_port.hh" #include "sim/builder.hh" #include "sim/process.hh" #include "sim/stats.hh" #include "sim/syscall_emul.hh" - -#include "arch/process.hh" +#include "sim/system.hh" using namespace std; using namespace TheISA; @@ -66,20 +63,12 @@ using namespace TheISA; 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)); - - cpuXC = new CPUExecContext(init_regs); - // initialize first 3 fds (stdin, stdout, stderr) fd_map[STDIN_FILENO] = stdin_fd; fd_map[STDOUT_FILENO] = stdout_fd; @@ -92,9 +81,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() { @@ -146,13 +137,7 @@ Process::registerExecContext(ExecContext *xc) int myIndex = execContexts.size(); execContexts.push_back(xc); - if (myIndex == 0) { - // copy process's initial regs struct - // Hack for now to copy init regs - xc->copyArchRegs(cpuXC->getProxy()); - } - - // return CPU number to caller and increment available CPU count + // return CPU number to caller return myIndex; } @@ -160,13 +145,29 @@ void Process::startup() { if (execContexts.empty()) - return; + fatal("Process %s is not associated with any CPUs!\n", name()); // first exec context for this process... initialize & enable ExecContext *xc = execContexts[0]; // 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(); } void @@ -251,38 +252,31 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process) static void copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr, - FunctionalMemory *memory) + TranslatingPort* memPort) { Addr data_ptr_swap; for (int i = 0; i < strings.size(); ++i) { data_ptr_swap = htog(data_ptr); - memory->access(Write, array_ptr, &data_ptr_swap, sizeof(Addr)); - memory->writeString(data_ptr, strings[i].c_str()); + memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap, sizeof(Addr)); + memPort->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)); + + memPort->writeBlob(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]; - prog_entry = objFile->entryPoint(); - text_base = objFile->textBase(); - text_size = objFile->textSize(); - data_base = objFile->dataBase(); - data_size = objFile->dataSize() + objFile->bssSize(); - brk_point = roundUp(data_base + data_size, VMPageSize); - - // load object file into target memory - objFile->loadSections(memory); - // load up symbols, if any... these may be used for debugging or // profiling. if (!debugSymbolTable) { @@ -294,21 +288,19 @@ 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); - - // Set up region for mmaps. Tru64 seems to start just above 0 and - // grow up from there. - mmap_start = mmap_end = 0x10000; +void +LiveProcess::argsInit(int intSize, int pageSize) +{ + Process::startup(); - // 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); - int envp_array_size = sizeof(Addr) * (envp.size() + 1); + int argv_array_size = intSize * (argv.size() + 1); + int envp_array_size = intSize * (envp.size() + 1); int arg_data_size = 0; for (int i = 0; i < argv.size(); ++i) { arg_data_size += argv[i].size() + 1; @@ -327,8 +319,11 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile, // set bottom of stack stack_min = stack_base - space_needed; // align it - stack_min &= ~7; + stack_min &= ~(intSize-1); stack_size = stack_base - stack_min; + // map memory + pTable->allocate(roundDown(stack_min, pageSize), + roundUp(stack_size, pageSize)); // map out initial stack contents Addr argv_array_base = stack_min + sizeof(uint64_t); // room for argc @@ -338,18 +333,28 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile, // write contents to stack uint64_t argc = argv.size(); - argc = htog(argc); - memory->access(Write, stack_min, &argc, sizeof(uint64_t)); - - copyStringArray(argv, argv_array_base, arg_data_base, memory); - copyStringArray(envp, envp_array_base, env_data_base, memory); - - cpuXC->setIntReg(ArgumentReg0, argc); - cpuXC->setIntReg(ArgumentReg1, argv_array_base); - cpuXC->setIntReg(StackPointerReg, stack_min); - cpuXC->setIntReg(GlobalPointerReg, objFile->globalPointer()); - cpuXC->setPC(prog_entry); - cpuXC->setNextPC(prog_entry + sizeof(MachInst)); + if (intSize == 8) + argc = htog((uint64_t)argc); + else if (intSize == 4) + argc = htog((uint32_t)argc); + else + panic("Unknown int size"); + + initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); + + copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); + copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); + + execContexts[0]->setIntReg(ArgumentReg0, argc); + execContexts[0]->setIntReg(ArgumentReg1, argv_array_base); + execContexts[0]->setIntReg(StackPointerReg, stack_min); + + Addr prog_entry = objFile->entryPoint(); + execContexts[0]->setPC(prog_entry); + execContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); + execContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst))); + + num_processes++; } void @@ -366,81 +371,4 @@ LiveProcess::syscall(ExecContext *xc) desc->doSyscall(callnum, this, xc); } -LiveProcess * -LiveProcess::create(const string &nm, - int stdin_fd, int stdout_fd, int stderr_fd, - string executable, - vector<string> &argv, vector<string> &envp) -{ - LiveProcess *process = NULL; - ObjectFile *objFile = createObjectFile(executable); - if (objFile == NULL) { - fatal("Can't load object file %s", executable); - } - - // set up syscall emulation pointer for the current ISA - process = createProcess(nm, objFile, - stdin_fd, stdout_fd, stderr_fd, - argv, envp); - - delete objFile; - - if (process == NULL) - fatal("Unknown error creating process object."); - - return process; -} - - - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) - - VectorParam<string> cmd; - Param<string> executable; - Param<string> input; - Param<string> output; - VectorParam<string> env; - -END_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) - - -BEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess) - - INIT_PARAM(cmd, "command line (executable plus arguments)"), - 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") - -END_INIT_SIM_OBJECT_PARAMS(LiveProcess) - - -CREATE_SIM_OBJECT(LiveProcess) -{ - string in = input; - string out = output; - - // initialize file descriptors to default: same as simulator - int stdin_fd, stdout_fd, stderr_fd; - - if (in == "stdin" || in == "cin") - stdin_fd = STDIN_FILENO; - else - stdin_fd = Process::openInputFile(input); - - if (out == "stdout" || out == "cout") - stdout_fd = STDOUT_FILENO; - else if (out == "stderr" || out == "cerr") - stdout_fd = STDERR_FILENO; - else - stdout_fd = Process::openOutputFile(out); - - stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO; - - return LiveProcess::create(getInstanceName(), - stdin_fd, stdout_fd, stderr_fd, - (string)executable == "" ? cmd[0] : executable, - cmd, env); -} - -REGISTER_SIM_OBJECT("LiveProcess", LiveProcess) +DEFINE_SIM_OBJECT_CLASS_NAME("LiveProcess", LiveProcess); |