diff options
Diffstat (limited to 'sim')
-rw-r--r-- | sim/byteswap.hh | 21 | ||||
-rw-r--r-- | sim/faults.cc | 1 | ||||
-rw-r--r-- | sim/host.hh | 2 | ||||
-rw-r--r-- | sim/main.cc | 4 | ||||
-rw-r--r-- | sim/process.cc | 214 | ||||
-rw-r--r-- | sim/process.hh | 87 | ||||
-rw-r--r-- | sim/pseudo_inst.cc | 2 | ||||
-rw-r--r-- | sim/sim_object.cc | 27 | ||||
-rw-r--r-- | sim/sim_object.hh | 11 | ||||
-rw-r--r-- | sim/syscall_emul.cc | 45 | ||||
-rw-r--r-- | sim/syscall_emul.hh | 101 | ||||
-rw-r--r-- | sim/system.cc | 106 | ||||
-rw-r--r-- | sim/system.hh | 53 | ||||
-rw-r--r-- | sim/vptr.hh | 12 |
14 files changed, 394 insertions, 292 deletions
diff --git a/sim/byteswap.hh b/sim/byteswap.hh index c5d8801ab..a8c5da9d7 100644 --- a/sim/byteswap.hh +++ b/sim/byteswap.hh @@ -38,6 +38,10 @@ // This lets us figure out what the byte order of the host system is #if defined(linux) #include <endian.h> +// If this is a linux system, lets used the optimized definitions if they exist. +// If one doesn't exist, we pretty much get what is listed below, so it all +// works out +#include <byteswap.h> #else #include <machine/endian.h> #endif @@ -47,6 +51,9 @@ static inline uint64_t swap_byte64(uint64_t x) { +#if defined(linux) + return bswap_64(x); +#else return (uint64_t)((((uint64_t)(x) & 0xff) << 56) | ((uint64_t)(x) & 0xff00ULL) << 40 | ((uint64_t)(x) & 0xff0000ULL) << 24 | @@ -55,22 +62,30 @@ swap_byte64(uint64_t x) ((uint64_t)(x) & 0xff0000000000ULL) >> 24 | ((uint64_t)(x) & 0xff000000000000ULL) >> 40 | ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ; +#endif } static inline uint32_t swap_byte32(uint32_t x) { +#if defined(linux) + return bswap_32(x); +#else return (uint32_t)(((uint32_t)(x) & 0xff) << 24 | ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 | ((uint32_t)(x) & 0xff000000) >> 24); - +#endif } static inline uint16_t swap_byte16(uint16_t x) { +#if defined(linux) + return bswap_16(x); +#else return (uint16_t)(((uint16_t)(x) & 0xff) << 8 | ((uint16_t)(x) & 0xff00) >> 8); +#endif } //This lets the compiler figure out how to call the swap_byte functions above @@ -79,7 +94,9 @@ static inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);} static inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);} static inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);} static inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);} -#if defined(__APPLE__) +//This is to prevent the following two functions from compiling on +//64bit machines. It won't detect everything, so it should be changed. +#ifndef __x86_64__ static inline long swap_byte(long x) {return swap_byte32((long)x);} static inline unsigned long swap_byte(unsigned long x) { return swap_byte32((unsigned long)x);} diff --git a/sim/faults.cc b/sim/faults.cc index 701384989..f7e9a0691 100644 --- a/sim/faults.cc +++ b/sim/faults.cc @@ -26,6 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "base/misc.hh" #include "sim/faults.hh" #include "cpu/exec_context.hh" #include "cpu/base.hh" diff --git a/sim/host.hh b/sim/host.hh index f7e64f23c..48c977331 100644 --- a/sim/host.hh +++ b/sim/host.hh @@ -62,4 +62,6 @@ typedef int64_t Tick; */ typedef uint64_t Addr; +const Addr MaxAddr = (Addr)-1; + #endif // __HOST_H__ diff --git a/sim/main.cc b/sim/main.cc index 6f6143506..aecc171ed 100644 --- a/sim/main.cc +++ b/sim/main.cc @@ -355,6 +355,10 @@ main(int argc, char **argv) echoCommandLine(argc, argv, *outputStream); ParamContext::showAllContexts(*configStream); + // Any objects that can't connect themselves until after construction should + // do so now + SimObject::connectAll(); + // Do a second pass to finish initializing the sim objects SimObject::initAll(); diff --git a/sim/process.cc b/sim/process.cc index a84a4f7ba..d88716f1e 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/physical.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,19 @@ 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); + + Port *mem_port; + mem_port = system->physmem->getPort("functional"); + initVirtMem = new TranslatingPort(pTable, true); + mem_port->setPeer(initVirtMem); + initVirtMem->setPeer(mem_port); } void @@ -249,40 +240,33 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process) //////////////////////////////////////////////////////////////////////// -static void +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 +278,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,38 +309,49 @@ 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 + Addr argv_array_base = stack_min + intSize; // room for argc Addr envp_array_base = argv_array_base + argv_array_size; Addr arg_data_base = envp_array_base + envp_array_size; Addr env_data_base = arg_data_base + arg_data_size; // 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 -LiveProcess::syscall(ExecContext *xc) +LiveProcess::syscall(int64_t callnum, ExecContext *xc) { num_syscalls++; - int64_t callnum = xc->readIntReg(SyscallNumReg); - SyscallDesc *desc = getDesc(callnum); if (desc == NULL) fatal("Syscall %d out of range", callnum); @@ -366,81 +359,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); diff --git a/sim/process.hh b/sim/process.hh index 3a48f128c..807bf330f 100644 --- a/sim/process.hh +++ b/sim/process.hh @@ -40,23 +40,28 @@ #include <vector> -#include "arch/isa_traits.hh" -#include "sim/sim_object.hh" -#include "sim/stats.hh" #include "base/statistics.hh" -#include "base/trace.hh" +#include "sim/sim_object.hh" class CPUExecContext; class ExecContext; -class FunctionalMemory; class SyscallDesc; +class PageTable; +class TranslatingPort; +class System; + +void +copyStringArray(std::vector<std::string> &strings, Addr array_ptr, + Addr data_ptr, TranslatingPort* memPort); + class Process : public SimObject { - protected: - typedef TheISA::RegFile RegFile; - typedef TheISA::MachInst MachInst; 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. @@ -76,22 +81,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 - CPUExecContext *cpuXC; // XC to hold the init_regs - - Addr text_base; // text (code) segment base - unsigned text_size; // text (code) size in bytes - - Addr data_base; // initialized data segment base - unsigned data_size; // initialized data + bss size in bytes - Addr brk_point; // top of the data segment Addr stack_base; // stack segment base (highest address) @@ -110,7 +105,6 @@ class Process : public SimObject Addr nxm_end; std::string prog_fname; // file name - Addr prog_entry; // entry point (initial PC) Stats::Scalar<> num_syscalls; // number of syscalls executed @@ -118,6 +112,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); @@ -126,7 +121,11 @@ class Process : public SimObject virtual void startup(); protected: - FunctionalMemory *memory; + /// Memory object for initialization (image loading) + TranslatingPort *initVirtMem; + + public: + PageTable *pTable; private: // file descriptor remapping support @@ -160,29 +159,7 @@ class Process : public SimObject // look up simulator fd for given target fd int sim_fd(int tgt_fd); - // is this a valid instruction fetch address? - bool validInstAddr(Addr addr) - { - return (text_base <= addr && - addr < text_base + text_size && - !(addr & (sizeof(MachInst)-1))); - } - - // is this a valid address? (used to filter data fetches) - // note that we just assume stack size <= 16MB - // this may be alpha-specific - bool validDataAddr(Addr addr) - { - return ((data_base <= addr && addr < brk_point) || - (next_thread_stack_base <= addr && addr < stack_base) || - (text_base <= addr && addr < (text_base + text_size)) || - (mmap_start <= addr && addr < mmap_end) || - (nxm_start <= addr && addr < nxm_end)); - } - - virtual void syscall(ExecContext *xc) = 0; - - virtual FunctionalMemory *getMemory() { return memory; } + virtual void syscall(int64_t callnum, ExecContext *xc) = 0; }; // @@ -192,25 +169,21 @@ 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); - 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, - int stdin_fd, int stdout_fd, int stderr_fd, - std::string executable, - std::vector<std::string> &argv, - std::vector<std::string> &envp); - - virtual void syscall(ExecContext *xc); + virtual void argsInit(int intSize, int pageSize); - virtual SyscallDesc* getDesc(int callnum) { panic("Must be implemented."); } + public: + virtual void syscall(int64_t callnum, ExecContext *xc); + virtual SyscallDesc* getDesc(int callnum) = 0; }; diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc index e475006e7..3cdc05e78 100644 --- a/sim/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@ -175,7 +175,7 @@ namespace AlphaPseudo addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr) { char symb[100]; - CopyString(xc, symb, symbolAddr, 100); + CopyStringOut(xc, symb, symbolAddr, 100); std::string symbol(symb); DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); diff --git a/sim/sim_object.cc b/sim/sim_object.cc index f34e17fe6..17d58ba4f 100644 --- a/sim/sim_object.cc +++ b/sim/sim_object.cc @@ -34,6 +34,7 @@ #include "base/misc.hh" #include "base/trace.hh" #include "base/stats/events.hh" +#include "base/serializer.hh" #include "sim/configfile.hh" #include "sim/host.hh" #include "sim/sim_object.hh" @@ -88,6 +89,11 @@ SimObject::SimObject(const string &_name) } void +SimObject::connect() +{ +} + +void SimObject::init() { } @@ -151,6 +157,21 @@ SimObject::regAllStats() } // +// static function: call connect() on all SimObjects. +// +void +SimObject::connectAll() +{ + SimObjectList::iterator i = simObjectList.begin(); + SimObjectList::iterator end = simObjectList.end(); + + for (; i != end; ++i) { + SimObject *obj = *i; + obj->connect(); + } +} + +// // static function: call init() on all SimObjects. // void @@ -228,4 +249,10 @@ SimObject::recordEvent(const std::string &stat) Stats::recordEvent(stat); } +void +SimObject::drain(Serializer *serializer) +{ + serializer->signalDrained(); +} + DEFINE_SIM_OBJECT_CLASS_NAME("SimObject", SimObject) diff --git a/sim/sim_object.hh b/sim/sim_object.hh index 59d9daf45..76aba7ea1 100644 --- a/sim/sim_object.hh +++ b/sim/sim_object.hh @@ -41,6 +41,8 @@ #include "sim/serialize.hh" #include "sim/startup.hh" +class Serializer; + /* * Abstract superclass for simulation objects. Represents things that * correspond to physical components and can be specified via the @@ -78,7 +80,9 @@ class SimObject : public Serializable, protected StartupCallback // initialization pass of all objects. // Gets invoked after construction, before unserialize. virtual void init(); + virtual void connect(); static void initAll(); + static void connectAll(); // register statistics for this object virtual void regStats(); @@ -94,6 +98,13 @@ class SimObject : public Serializable, protected StartupCallback // static: call nameOut() & serialize() on all SimObjects static void serializeAll(std::ostream &); + // Methods to drain objects in order to take checkpoints + // Or switch from timing -> atomic memory model + virtual void drain(Serializer *serializer); + virtual void resume() { return;} ; + virtual void serializationComplete() + { assert(0 && "Unimplemented"); }; + #ifdef DEBUG public: bool doDebugBreak; diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index 00168b025..ed0da628e 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -33,9 +33,11 @@ #include <iostream> #include "sim/syscall_emul.hh" +#include "base/chunk_generator.hh" #include "base/trace.hh" #include "cpu/exec_context.hh" #include "cpu/base.hh" +#include "mem/page_table.hh" #include "sim/process.hh" #include "sim/sim_events.hh" @@ -46,13 +48,15 @@ using namespace TheISA; void SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc) { - DPRINTFR(SyscallVerbose, "%s: syscall %s called\n", - xc->getCpuPtr()->name(), name); + DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", + curTick,xc->getCpuPtr()->name(), name, + xc->getSyscallArg(0),xc->getSyscallArg(1), + xc->getSyscallArg(2),xc->getSyscallArg(3)); SyscallReturn retval = (*funcPtr)(this, callnum, process, xc); - DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n", - xc->getCpuPtr()->name(), name, retval.value()); + DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n", + curTick,xc->getCpuPtr()->name(), name, retval.value()); if (!(flags & SyscallDesc::SuppressReturnValue)) xc->setSyscallReturn(retval); @@ -64,6 +68,8 @@ unimplementedFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { fatal("syscall %s (#%d) unimplemented.", desc->name, callnum); + + return 1; } @@ -82,7 +88,7 @@ SyscallReturn exitFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - new SimExitEvent("syscall caused exit", xc->getSyscallArg(0) & 0xff); + new SimExitEvent("target called exit()", xc->getSyscallArg(0) & 0xff); return 1; } @@ -98,11 +104,18 @@ getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) SyscallReturn obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { + Addr junk; + // change brk addr to first arg Addr new_brk = xc->getSyscallArg(0); - if (new_brk != 0) - { - p->brk_point = xc->getSyscallArg(0); + if (new_brk != 0) { + for (ChunkGenerator gen(p->brk_point, new_brk - p->brk_point, + VMPageSize); !gen.done(); gen.next()) { + if (!p->pTable->translate(gen.addr(), junk)) + p->pTable->allocate(roundDown(gen.addr(), VMPageSize), + VMPageSize); + } + p->brk_point = new_brk; } DPRINTF(SyscallVerbose, "Break Point changed to: %#X\n", p->brk_point); return p->brk_point; @@ -130,7 +143,7 @@ readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); if (bytes_read != -1) - bufArg.copyOut(xc->getMemPtr()); + bufArg.copyOut(xc->getMemPort()); return bytes_read; } @@ -142,7 +155,7 @@ writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) int nbytes = xc->getSyscallArg(2); BufferArg bufArg(xc->getSyscallArg(1), nbytes); - bufArg.copyIn(xc->getMemPtr()); + bufArg.copyIn(xc->getMemPort()); int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); @@ -183,7 +196,7 @@ gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) strncpy((char *)name.bufferPtr(), hostname, name_len); - name.copyOut(xc->getMemPtr()); + name.copyOut(xc->getMemPort()); return 0; } @@ -193,7 +206,7 @@ unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) + if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) return (TheISA::IntReg)-EFAULT; int result = unlink(path.c_str()); @@ -205,12 +218,12 @@ renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string old_name; - if (xc->getMemPtr()->readString(old_name, xc->getSyscallArg(0)) != NoFault) + if (!xc->getMemPort()->tryReadString(old_name, xc->getSyscallArg(0))) return -EFAULT; string new_name; - if (xc->getMemPtr()->readString(new_name, xc->getSyscallArg(1)) != NoFault) + if (!xc->getMemPort()->tryReadString(new_name, xc->getSyscallArg(1))) return -EFAULT; int64_t result = rename(old_name.c_str(), new_name.c_str()); @@ -222,7 +235,7 @@ truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) + if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) return -EFAULT; off_t length = xc->getSyscallArg(1); @@ -250,7 +263,7 @@ chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) + if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) return -EFAULT; /* XXX endianess */ diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index 35129bcb4..00f016410 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -45,12 +45,15 @@ #endif #include <sys/uio.h> -#include "base/intmath.hh" // for RoundUp -#include "mem/functional/functional.hh" #include "arch/isa_traits.hh" // for Addr - +#include "base/chunk_generator.hh" +#include "base/intmath.hh" // for RoundUp +#include "base/misc.hh" #include "base/trace.hh" +#include "cpu/base.hh" #include "cpu/exec_context.hh" +#include "mem/translating_port.hh" +#include "mem/page_table.hh" #include "sim/process.hh" /// @@ -106,18 +109,18 @@ class BaseBufferArg { // // copy data into simulator space (read from target memory) // - virtual bool copyIn(FunctionalMemory *mem) + virtual bool copyIn(TranslatingPort *memport) { - mem->access(Read, addr, bufPtr, size); + memport->readBlob(addr, bufPtr, size); return true; // no EFAULT detection for now } // // copy data out of simulator space (write to target memory) // - virtual bool copyOut(FunctionalMemory *mem) + virtual bool copyOut(TranslatingPort *memport) { - mem->access(Write, addr, bufPtr, size); + memport->writeBlob(addr, bufPtr, size); return true; // no EFAULT detection for now } @@ -369,7 +372,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) + if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) return -EFAULT; if (path == "/dev/sysdev0") { @@ -416,7 +419,7 @@ chmodFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) + if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) return -EFAULT; uint32_t mode = xc->getSyscallArg(1); @@ -469,8 +472,8 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) - return -EFAULT; + if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) + return -EFAULT; struct stat hostBuf; int result = stat(path.c_str(), &hostBuf); @@ -478,7 +481,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -507,7 +510,7 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStat64Buf(xc->getMemPtr(), fd, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->getMemPort(), fd, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -521,8 +524,8 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) - return -EFAULT; + if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) + return -EFAULT; struct stat hostBuf; int result = lstat(path.c_str(), &hostBuf); @@ -530,7 +533,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -543,8 +546,8 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) - return -EFAULT; + if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) + return -EFAULT; #if BSD_HOST struct stat hostBuf; @@ -557,7 +560,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStat64Buf(xc->getMemPtr(), -1, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->getMemPort(), -1, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -581,7 +584,8 @@ fstatFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); + return 0; } @@ -594,8 +598,8 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) - return -EFAULT; + if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) + return -EFAULT; struct statfs hostBuf; int result = statfs(path.c_str(), &hostBuf); @@ -603,7 +607,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatfsBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -626,7 +630,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatfsBuf(xc->getMemPort(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -644,18 +648,20 @@ writevFunc(SyscallDesc *desc, int callnum, Process *process, return -EBADF; } + TranslatingPort *p = xc->getMemPort(); uint64_t tiov_base = xc->getSyscallArg(1); size_t count = xc->getSyscallArg(2); struct iovec hiov[count]; for (int i = 0; i < count; ++i) { typename OS::tgt_iovec tiov; - xc->getMemPtr()->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), - &tiov, sizeof(typename OS::tgt_iovec)); + + p->readBlob(tiov_base + i*sizeof(typename OS::tgt_iovec), + (uint8_t*)&tiov, sizeof(typename OS::tgt_iovec)); hiov[i].iov_len = gtoh(tiov.iov_len); hiov[i].iov_base = new char [hiov[i].iov_len]; - xc->getMemPtr()->access(Read, gtoh(tiov.iov_base), - hiov[i].iov_base, hiov[i].iov_len); + p->readBlob(gtoh(tiov.iov_base), (uint8_t *)hiov[i].iov_base, + hiov[i].iov_len); } int result = writev(process->sim_fd(fd), hiov, count); @@ -695,16 +701,24 @@ mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) // int fd = p->sim_fd(xc->getSyscallArg(4)); // int offset = xc->getSyscallArg(5); - if (start == 0) { - // user didn't give an address... pick one from our "mmap region" - start = p->mmap_end; - p->mmap_end += roundUp(length, TheISA::VMPageSize); - if (p->nxm_start != 0) { - //If we have an nxm space, make sure we haven't colided - assert(p->mmap_end < p->nxm_start); - } + if ((start % TheISA::VMPageSize) != 0 || + (length % TheISA::VMPageSize) != 0) { + warn("mmap failing: arguments not page-aligned: " + "start 0x%x length 0x%x", + start, length); + return -EINVAL; + } + + if (start != 0) { + warn("mmap: ignoring suggested map address 0x%x, using 0x%x", + start, p->mmap_end); } + // pick next address from our "mmap region" + start = p->mmap_end; + p->pTable->allocate(start, length); + p->mmap_end += length; + if (!(flags & OS::TGT_MAP_ANONYMOUS)) { warn("allowing mmap of file @ fd %d. " "This will break if not /dev/zero.", xc->getSyscallArg(4)); @@ -737,7 +751,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process, break; } - rlp.copyOut(xc->getMemPtr()); + rlp.copyOut(xc->getMemPort()); return 0; } @@ -754,7 +768,7 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, tp->tv_sec = htog(tp->tv_sec); tp->tv_usec = htog(tp->tv_usec); - tp.copyOut(xc->getMemPtr()); + tp.copyOut(xc->getMemPort()); return 0; } @@ -768,11 +782,11 @@ utimesFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) - return -EFAULT; + if (!xc->getMemPort()->tryReadString(path, xc->getSyscallArg(0))) + return -EFAULT; TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1)); - tp.copyIn(xc->getMemPtr()); + tp.copyIn(xc->getMemPort()); struct timeval hostTimeval[2]; for (int i = 0; i < 2; ++i) @@ -824,9 +838,12 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process, rup->ru_nvcsw = 0; rup->ru_nivcsw = 0; - rup.copyOut(xc->getMemPtr()); + rup.copyOut(xc->getMemPort()); return 0; } + + + #endif // __SIM_SYSCALL_EMUL_HH__ diff --git a/sim/system.cc b/sim/system.cc index 8820922c1..ca9d68d77 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -1,16 +1,18 @@ +#include "arch/isa_traits.hh" #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" -#include "base/remote_gdb.hh" +#include "base/trace.hh" #include "cpu/exec_context.hh" -#include "kern/kernel_stats.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" -#include "arch/vtophys.hh" +#include "mem/mem_object.hh" +#include "mem/physical.hh" #include "sim/builder.hh" -#include "arch/isa_traits.hh" #include "sim/byteswap.hh" #include "sim/system.hh" -#include "base/trace.hh" +#if FULL_SYSTEM +#include "arch/vtophys.hh" +#include "base/remote_gdb.hh" +#include "kern/kernel_stats.hh" +#endif using namespace std; using namespace TheISA; @@ -20,15 +22,35 @@ 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 + 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; 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); + + mem_port = physmem->getPort("functional"); + virtPort.setPeer(mem_port); + mem_port->setPeer(&virtPort); + + /** * Load the kernel code into memory */ @@ -38,7 +60,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(); @@ -63,25 +85,33 @@ System::System(Params *p) DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry); DPRINTF(Loader, "Kernel loaded...\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 kernel; delete kernelBinning; +#else + panic("System::fixFuncEventAddr needs to be rewritten " + "to work with syscall emulation"); +#endif // FULL_SYSTEM} } - +#if FULL_SYSTEM int rgdb_wait = -1; +#endif // FULL_SYSTEM + int System::registerExecContext(ExecContext *xc, int id) { @@ -101,6 +131,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(); @@ -116,6 +147,7 @@ System::registerExecContext(ExecContext *xc, int id) } remoteGDB[id] = rgdb; +#endif // FULL_SYSTEM return id; } @@ -137,30 +169,48 @@ 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); +#endif // FULL_SYSTEM } void System::unserialize(Checkpoint *cp, const string §ion) { +#if FULL_SYSTEM kernelBinning->unserialize(cp, section); kernelSymtab->unserialize("kernel_symtab", cp, section); +#endif // FULL_SYSTEM } void @@ -181,5 +231,35 @@ printSystems() System::printSystems(); } +#if FULL_SYSTEM + +// In full system mode, only derived classes (e.g. AlphaLinuxSystem) +// can be created directly. + DEFINE_SIM_OBJECT_CLASS_NAME("System", System) +#else + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(System) + + SimObjectParam<PhysicalMemory *> physmem; + +END_DECLARE_SIM_OBJECT_PARAMS(System) + +BEGIN_INIT_SIM_OBJECT_PARAMS(System) + + INIT_PARAM(physmem, "physical memory") + +END_INIT_SIM_OBJECT_PARAMS(System) + +CREATE_SIM_OBJECT(System) +{ + System::Params *p = new System::Params; + p->name = getInstanceName(); + p->physmem = physmem; + return new System(p); +} + +REGISTER_SIM_OBJECT("System", System) + +#endif diff --git a/sim/system.hh b/sim/system.hh index ea482a102..7e21bd587 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -32,30 +32,34 @@ #include <string> #include <vector> -#include "base/statistics.hh" #include "base/loader/symtab.hh" +#include "base/misc.hh" +#include "base/statistics.hh" #include "cpu/pc_event.hh" -#include "kern/system_events.hh" +#include "mem/port.hh" #include "sim/sim_object.hh" +#if FULL_SYSTEM +#include "kern/system_events.hh" +#include "mem/vport.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 +72,15 @@ class System : public SimObject return numcpus; } +#if FULL_SYSTEM + Platform *platform; + uint64_t init_param; + + /** Port to physical memory used for writing object files into ram at + * boot.*/ + FunctionalPort functionalPort; + VirtualPort virtPort; + /** kernel symbol table */ SymbolTable *kernelSymtab; @@ -85,8 +98,16 @@ class System : public SimObject Kernel::Binning *kernelBinning; +#else + + int page_ptr; + + +#endif // FULL_SYSTEM + protected: +#if FULL_SYSTEM /** * Fix up an address used to match PCs for hooking simulator * events on to target function executions. See comment in @@ -118,18 +139,23 @@ class System : public SimObject return addFuncEvent<T>(kernelSymtab, lbl); } +#endif public: +#if FULL_SYSTEM std::vector<RemoteGDB *> remoteGDB; std::vector<GDBListener *> gdbListen; virtual bool breakpoint() = 0; +#endif // FULL_SYSTEM public: struct Params { std::string name; - Tick boot_cpu_frequency; - MemoryController *memctrl; PhysicalMemory *physmem; + +#if FULL_SYSTEM + Tick boot_cpu_frequency; + std::string boot_osflags; uint64_t init_param; bool bin; std::vector<std::string> binned_fns; @@ -137,6 +163,7 @@ class System : public SimObject std::string kernel_path; std::string readfile; +#endif }; protected: @@ -151,6 +178,8 @@ class System : public SimObject const Params *params() const { return (const Params *)_params; } public: + +#if FULL_SYSTEM /** * Returns the addess the kernel starts at. * @return address the kernel starts at @@ -169,6 +198,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); diff --git a/sim/vptr.hh b/sim/vptr.hh index 0ec452f25..cc57e63f0 100644 --- a/sim/vptr.hh +++ b/sim/vptr.hh @@ -96,20 +96,26 @@ class VPtr operator T *() { - void *addr = vtomem(xc, ptr, sizeof(T)); + panic("Needs to be rewritten\n"); +/* void *addr = vtomem(xc, ptr, sizeof(T)); return (T *)addr; + */ } T *operator->() { - void *addr = vtomem(xc, ptr, sizeof(T)); + panic("Needs to be rewritten\n"); +/* void *addr = vtomem(xc, ptr, sizeof(T)); return (T *)addr; + */ } T &operator*() { - void *addr = vtomem(xc, ptr, sizeof(T)); + panic("Needs to be rewritten\n"); +/* void *addr = vtomem(xc, ptr, sizeof(T)); return *(T *)addr; + */ } }; |