/*
 * Copyright (c) 2014 Advanced Micro Devices, Inc.
 * Copyright (c) 2001-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 */

#ifndef __PROCESS_HH__
#define __PROCESS_HH__

#include <string>
#include <vector>

#include "arch/registers.hh"
#include "base/statistics.hh"
#include "base/types.hh"
#include "config/the_isa.hh"
#include "mem/se_translating_port_proxy.hh"
#include "sim/sim_object.hh"
#include "sim/syscallreturn.hh"

class PageTable;
struct ProcessParams;
struct LiveProcessParams;
class SyscallDesc;
class System;
class ThreadContext;
class EmulatedDriver;

template<class IntType>
struct AuxVector
{
    IntType a_type;
    IntType a_val;

    AuxVector()
    {}

    AuxVector(IntType type, IntType val);
};

class Process : public SimObject
{
  public:

    /// Pointer to object representing the system this process is
    /// running on.
    System *system;

    // thread contexts associated with this process
    std::vector<int> contextIds;

    // number of CPUs (esxec contexts, really) assigned to this process.
    unsigned int numCpus() { return contextIds.size(); }

    // record of blocked context
    struct WaitRec
    {
        Addr waitChan;
        ThreadContext *waitingContext;

        WaitRec(Addr chan, ThreadContext *ctx)
            : waitChan(chan), waitingContext(ctx)
        {       }
    };

    // list of all blocked contexts
    std::list<WaitRec> waitList;

    Addr brk_point;             // top of the data segment

    Addr stack_base;            // stack segment base (highest address)
    unsigned stack_size;        // initial stack size
    Addr stack_min;             // lowest address accessed on the stack

    // The maximum size allowed for the stack.
    Addr max_stack_size;

    // addr to use for next stack region (for multithreaded apps)
    Addr next_thread_stack_base;

    // Base of region for mmaps (when user doesn't specify an address).
    Addr mmap_start;
    Addr mmap_end;

    // Base of region for nxm data
    Addr nxm_start;
    Addr nxm_end;

    Stats::Scalar num_syscalls;       // number of syscalls executed

  protected:
    // constructor
    Process(ProcessParams *params);

    virtual void initState();

    DrainState drain() M5_ATTR_OVERRIDE;

  public:

    //This id is assigned by m5 and is used to keep process' tlb entries
    //separated.
    uint64_t M5_pid;

    // flag for using architecture specific page table
    bool useArchPT;
    // running KvmCPU in SE mode requires special initialization
    bool kvmInSE;

    PageTableBase* pTable;

    class FdMap : public Serializable
    {
      public:
        int fd;
        std::string filename;
        int mode;
        int flags;
        bool isPipe;
        int readPipeSource;
        uint64_t fileOffset;
        EmulatedDriver *driver;

        FdMap()
            : fd(-1), filename("NULL"), mode(0), flags(0),
              isPipe(false), readPipeSource(0), fileOffset(0), driver(NULL)
        { }

        void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
        void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
    };

  protected:
    /// Memory proxy for initialization (image loading)
    SETranslatingPortProxy initVirtMem;

  private:
    // file descriptor remapping support
    static const int MAX_FD = 256;    // max legal fd value
    FdMap fd_map[MAX_FD+1];


  public:
    // static helper functions to generate file descriptors for constructor
    static int openInputFile(const std::string &filename);
    static int openOutputFile(const std::string &filename);

    // override of virtual SimObject method: register statistics
    virtual void regStats();

    // After getting registered with system object, tell process which
    // system-wide context id it is assigned.
    void assignThreadContext(int context_id)
    {
        contextIds.push_back(context_id);
    }

    // Find a free context to use
    ThreadContext *findFreeContext();

    // provide program name for debug messages
    virtual const char *progName() const { return "<unknown>"; }

    // map simulator fd sim_fd to target fd tgt_fd
    void dup_fd(int sim_fd, int tgt_fd);

    // generate new target fd for sim_fd
    int alloc_fd(int sim_fd, const std::string& filename, int flags, int mode,
                 bool pipe);

    // free target fd (e.g., after close)
    void free_fd(int tgt_fd);

    // look up simulator fd for given target fd
    int sim_fd(int tgt_fd);

    // look up simulator fd_map object for a given target fd
    FdMap *sim_fd_obj(int tgt_fd);

    // fix all offsets for currently open files and save them
    void fix_file_offsets();

    // find all offsets for currently open files and save them
    void find_file_offsets();

    // set the source of this read pipe for a checkpoint resume
    void setReadPipeSource(int read_pipe_fd, int source_fd);

    virtual void syscall(int64_t callnum, ThreadContext *tc) = 0;

    void allocateMem(Addr vaddr, int64_t size, bool clobber = false);

    /// Attempt to fix up a fault at vaddr by allocating a page on the stack.
    /// @return Whether the fault has been fixed.
    bool fixupStackFault(Addr vaddr);

    /**
     * Maps a contiguous range of virtual addresses in this process's
     * address space to a contiguous range of physical addresses.
     * This function exists primarily to expose the map operation to
     * python, so that configuration scripts can set up mappings in SE mode.
     *
     * @param vaddr The starting virtual address of the range.
     * @param paddr The starting physical address of the range.
     * @param size The length of the range in bytes.
     * @param cacheable Specifies whether accesses are cacheable.
     * @return True if the map operation was successful.  (At this
     *           point in time, the map operation always succeeds.)
     */
    bool map(Addr vaddr, Addr paddr, int size, bool cacheable = true);

    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
};

//
// "Live" process with system calls redirected to host system
//
class ObjectFile;
class LiveProcess : public Process
{
  protected:
    ObjectFile *objFile;
    std::vector<std::string> argv;
    std::vector<std::string> envp;
    std::string cwd;

    LiveProcess(LiveProcessParams *params, ObjectFile *objFile);

    // Id of the owner of the process
    uint64_t __uid;
    uint64_t __euid;
    uint64_t __gid;
    uint64_t __egid;

    // pid of the process and it's parent
    uint64_t __pid;
    uint64_t __ppid;

    // Emulated drivers available to this process
    std::vector<EmulatedDriver *> drivers;

  public:

    enum AuxiliaryVectorType {
        M5_AT_NULL = 0,
        M5_AT_IGNORE = 1,
        M5_AT_EXECFD = 2,
        M5_AT_PHDR = 3,
        M5_AT_PHENT = 4,
        M5_AT_PHNUM = 5,
        M5_AT_PAGESZ = 6,
        M5_AT_BASE = 7,
        M5_AT_FLAGS = 8,
        M5_AT_ENTRY = 9,
        M5_AT_NOTELF = 10,
        M5_AT_UID = 11,
        M5_AT_EUID = 12,
        M5_AT_GID = 13,
        M5_AT_EGID = 14,
        // The following may be specific to Linux
        M5_AT_PLATFORM = 15,
        M5_AT_HWCAP = 16,
        M5_AT_CLKTCK = 17,

        M5_AT_SECURE = 23,
        M5_BASE_PLATFORM = 24,
        M5_AT_RANDOM = 25,

        M5_AT_EXECFN = 31,

        M5_AT_VECTOR_SIZE = 44
    };

    inline uint64_t uid() {return __uid;}
    inline uint64_t euid() {return __euid;}
    inline uint64_t gid() {return __gid;}
    inline uint64_t egid() {return __egid;}
    inline uint64_t pid() {return __pid;}
    inline uint64_t ppid() {return __ppid;}

    // provide program name for debug messages
    virtual const char *progName() const { return argv[0].c_str(); }

    std::string
    fullPath(const std::string &filename)
    {
        if (filename[0] == '/' || cwd.empty())
            return filename;

        std::string full = cwd;

        if (cwd[cwd.size() - 1] != '/')
            full += '/';

        return full + filename;
    }

    std::string getcwd() const { return cwd; }

    virtual void syscall(int64_t callnum, ThreadContext *tc);

    virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i) = 0;
    virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width);
    virtual void setSyscallArg(ThreadContext *tc,
            int i, TheISA::IntReg val) = 0;
    virtual void setSyscallReturn(ThreadContext *tc,
            SyscallReturn return_value) = 0;

    virtual SyscallDesc *getDesc(int callnum) = 0;

    /**
     * Find an emulated device driver.
     *
     * @param filename Name of the device (under /dev)
     * @return Pointer to driver object if found, else NULL
     */
    EmulatedDriver *findDriver(std::string filename);

    // 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(LiveProcessParams *params);
};


#endif // __PROCESS_HH__
