/*
 * Copyright (c) 2018, 2019 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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.
 */

#ifndef __ARCH_ARM_SEMIHOSTING_HH__
#define __ARCH_ARM_SEMIHOSTING_HH__

#include <cstdio>
#include <functional>
#include <map>
#include <memory>
#include <utility>
#include <vector>

#include "arch/arm/regs/int.hh"
#include "arch/arm/utility.hh"
#include "cpu/thread_context.hh"
#include "mem/port_proxy.hh"
#include "sim/guest_abi.hh"
#include "sim/sim_object.hh"

struct ArmSemihostingParams;
class SerialDevice;

/**
 * Semihosting for AArch32 and AArch64
 *
 * This class implements the Arm semihosting interface. This interface
 * allows baremetal code access service, such as IO, from the
 * simulator. It is conceptually a simplified version of gem5's more
 * general syscall emulation mode.
 *
 * Exits calls (SYS_EXIT, SYS_EXIT_EXTENDED) from the guest get
 * translated into simualtion exits. Well-known exit codes are
 * translated to messages on the form 'semi:ADP_.*' while unknown
 * codes are returned in hex ('semi:0x..'). The subcode is reported in
 * the gem5 exit event.
 */
class ArmSemihosting : public SimObject
{
  public:
    enum
    {
        // Standard ARM immediate values which trigger semihosting.
        T32Imm = 0xAB,
        A32Imm = 0x123456,
        A64Imm = 0xF000,

        // The immediate value which enables gem5 semihosting calls. Use the
        // standard value for thumb.
        Gem5Imm = 0x5D57
    };

    static PortProxy &portProxy(ThreadContext *tc);

    struct AbiBase
    {
        template <typename Arg>
        class StateBase
        {
          private:
            Addr argPointer;
            ByteOrder endian;

          public:
            StateBase(const ThreadContext *tc, Addr arg_pointer) :
                argPointer(arg_pointer), endian(ArmISA::byteOrder(tc))
            {}

            /*
             * These two methods are used to both read an argument or its
             * address, and to move position on to the next location. Normally
             * State would be more passive, but since it behaves almost the
             * same no matter what the argument type is we can simplify and
             * consolidate a little bit by centralizing these methods.
             */

            // Return the address of an argument slot and move past it.
            Addr
            getAddr()
            {
                Addr addr = argPointer;
                argPointer += sizeof(Arg);
                return addr;
            }

            // Read the value in an argument slot and move past it.
            Arg
            get(ThreadContext *tc)
            {
                Arg arg = ArmSemihosting::portProxy(tc).read<Arg>(
                        argPointer, endian);
                argPointer += sizeof(Arg);
                return arg;
            }

            using ArgType = Arg;
        };
    };

    struct Abi64 : public AbiBase
    {
        using UintPtr = uint64_t;

        class State : public StateBase<uint64_t>
        {
          public:
            // For 64 bit semihosting, the params are pointer to by X1.
            explicit State(const ThreadContext *tc) :
                StateBase<uint64_t>(tc, tc->readIntReg(ArmISA::INTREG_X1))
            {}
        };
    };

    struct Abi32 : public AbiBase
    {
        using UintPtr = uint32_t;

        class State : public StateBase<uint64_t>
        {
          public:
            // For 32 bit semihosting, the params are pointer to by R1.
            explicit State(const ThreadContext *tc) :
                StateBase<uint64_t>(tc, tc->readIntReg(ArmISA::INTREG_R1))
            {}
        };
    };

    // Use this argument type when you need to modify an argument in place.
    // This will give you the address of the argument itself and the size of
    // each argument slot, rather than the actual value of the argument.
    struct InPlaceArg
    {
        Addr addr;
        size_t size;

        InPlaceArg(Addr _addr, size_t _size) : addr(_addr), size(_size) {}

        // A helper function to read the argument since the guest ABI mechanism
        // didn't do that for us.
        uint64_t
        read(ThreadContext *tc, ByteOrder endian)
        {
            auto &proxy = ArmSemihosting::portProxy(tc);
            if (size == 8)
                return proxy.read<uint64_t>(addr, endian);
            else if (size == 4)
                return proxy.read<uint32_t>(addr, endian);
            else
                panic("Unexpected semihosting argument size %d.", size);
        }

        // A helper function to write to the argument's slot in the params.
        void
        write(ThreadContext *tc, uint64_t val, ByteOrder endian)
        {
            auto &proxy = ArmSemihosting::portProxy(tc);
            if (size == 8)
                proxy.write<uint64_t>(addr, val, endian);
            else if (size == 4)
                proxy.write<uint32_t>(addr, val, endian);
            else
                panic("Unexpected semihosting argument size %d.", size);
        }
    };

    enum Operation
    {
        SYS_OPEN = 0x01,
        SYS_CLOSE = 0x02,
        SYS_WRITEC = 0x03,
        SYS_WRITE0 = 0x04,
        SYS_WRITE = 0x05,
        SYS_READ = 0x06,
        SYS_READC = 0x07,
        SYS_ISERROR = 0x08,
        SYS_ISTTY = 0x09,
        SYS_SEEK = 0x0A,
        SYS_FLEN = 0x0C,
        SYS_TMPNAM = 0x0D,
        SYS_REMOVE = 0x0E,
        SYS_RENAME = 0x0F,
        SYS_CLOCK = 0x10,
        SYS_TIME = 0x11,
        SYS_SYSTEM = 0x12,
        SYS_ERRNO = 0x13,
        SYS_GET_CMDLINE = 0x15,
        SYS_HEAPINFO = 0x16,
        SYS_EXIT = 0x18,
        SYS_EXIT_EXTENDED = 0x20,
        SYS_ELAPSED = 0x30,
        SYS_TICKFREQ = 0x31,

        MaxStandardOp = 0xFF,

        SYS_GEM5_PSEUDO_OP = 0x100
    };

    ArmSemihosting(const ArmSemihostingParams &p);

    /** Perform an Arm Semihosting call from aarch64 code. */
    bool call64(ThreadContext *tc, bool gem5_ops);
    /** Perform an Arm Semihosting call from aarch32 code. */
    bool call32(ThreadContext *tc, bool gem5_ops);

  public: // SimObject and related interfaces
    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

  protected: // Configuration
    const std::string cmdLine;
    const Addr memReserve;
    const Addr stackSize;

    /**
     * Base time when the simulation started. This is used to
     * calculate the time of date when the guest call SYS_TIME.
     */
    const time_t timeBase;

    /** Number of bits to right shift gem5 ticks to fit in a uint32_t */
    const unsigned tickShift;

  protected: // Internal state
    typedef uint64_t SemiErrno;
    SemiErrno semiErrno;

  protected: // File IO
    /**
     * Internal state for open files
     *
     * This class describes the internal state of a file opened
     * through the semihosting interface.
     *
     * A file instance is normally created using one of the
     * ArmSemihosting::FileBase::create() factory methods. These
     * methods handle some the magic file names in the Arm Semihosting
     * specification and instantiate the right implementation. For the
     * same, when unserializing a checkpoint, the create method must
     * be used to unserialize a new instance of a file descriptor.
     */
    class FileBase : public Serializable
    {
      public:
        FileBase(ArmSemihosting &_parent, const char *name, const char *_mode)
            : parent(_parent), _name(name), mode(_mode) {}
        virtual ~FileBase() {};

        FileBase() = delete;
        FileBase(FileBase &) = delete;

        static std::unique_ptr<FileBase> create(
            ArmSemihosting &parent, const std::string &fname,
            const char *mode);
        static std::unique_ptr<FileBase> create(
            ArmSemihosting &parent, CheckpointIn &cp, const std::string &sec);

        void serialize(CheckpointOut &cp) const override;
        void unserialize(CheckpointIn &cp) override;

        const std::string &fileName() { return _name; }

      public:
        /** @{
         * Semihosting file IO interfaces
         *
         * These interfaces implement common IO functionality in the
         * Semihosting interface.
         *
         * All functions return a negative value that corresponds to a
         * UNIX errno value when they fail and >=0 on success.
         */

        /**
         * Open the the file.
         *
         * @return <0 on error (-errno), 0 on success.
         */
        virtual int64_t open() { return 0; }

        /**
         * Close the file.
         *
         * @return <0 on error (-errno), 0 on success.
         */
        virtual int64_t close() { return 0; }

        /**
         * Check if a file corresponds to a TTY device.
         *
         * @return True if the file is a TTY, false otherwise.
         */
        virtual bool isTTY() const { return false; }

        /**
         * Read data from file.
         *
         * @return <0 on error (-errno), bytes read on success (0 for EOF).
         */
        virtual int64_t read(uint8_t *buffer, uint64_t size);

        /**
         * Write data to file.
         *
         * @return <0 on error (-errno), bytes written on success.
         */
        virtual int64_t write(const uint8_t *buffer, uint64_t size);

        /**
         * Seek to an absolute position in the file.
         *
         * @param pos Byte offset from start of file.
         * @return <0 on error (-errno), 0 on success.
         */
        virtual int64_t seek(uint64_t pos);

        /**
         * Get the length of a file in bytes.
         *
         * @return <0 on error (-errno), length on success
         */
        virtual int64_t flen();

        /** @} */

      protected:
        ArmSemihosting &parent;
        std::string _name;
        std::string mode;
    };

    /** Implementation of the ':semihosting-features' magic file. */
    class FileFeatures : public FileBase
    {
      public:
        FileFeatures(ArmSemihosting &_parent,
                     const char *name, const char *mode);

        void serialize(CheckpointOut &cp) const override;
        void unserialize(CheckpointIn &cp) override;

        int64_t read(uint8_t *buffer, uint64_t size) override;
        int64_t seek(uint64_t pos) override;

      protected:
        size_t pos;
    };

    class File : public FileBase
    {
      public:
        File(ArmSemihosting &_parent, const char *name, const char *mode);
        ~File();

        void serialize(CheckpointOut &cp) const override;
        void unserialize(CheckpointIn &cp) override;

        int64_t open() override { return openImpl(false); }
        int64_t close() override;
        bool isTTY() const override;
        int64_t read(uint8_t *buffer, uint64_t size) override;
        int64_t write(const uint8_t *buffer, uint64_t size) override;
        int64_t seek(uint64_t pos) override;
        int64_t flen() override;

      protected:
        int64_t openImpl(bool unserialize);
        bool needClose() const { return !isTTY(); }

        FILE *file;
    };

    std::string filesRootDir;
    std::vector<std::unique_ptr<FileBase>> files;
    using Handle = size_t;
    FILE *stdin;
    FILE *stdout;
    FILE *stderr;

  protected: // Helper functions
    unsigned
    calcTickShift() const
    {
        int msb = findMsbSet(sim_clock::Frequency);
        return msb > 31 ? msb - 31 : 0;
    }
    uint64_t
    semiTick(Tick tick) const
    {
        return tick >> tickShift;
    }
    void semiExit(uint64_t code, uint64_t subcode);
    std::string readString(ThreadContext *tc, Addr ptr, size_t len);

  public:
    typedef std::pair<uint64_t, SemiErrno> RetErrno;

  private:
    static RetErrno
    retError(SemiErrno e)
    {
        return RetErrno((uint64_t)-1, e);
    }

    static RetErrno
    retOK(uint64_t r)
    {
        return RetErrno(r, 0);
    }

    /**
     * Semihosting call information structure.
     *
     * This structure describes how a semi-hosting call is
     * implemented. It contains debug information (e.g., the name of
     * the call), and a way to invoke it in a particular context.
     */
    struct SemiCall
    {
        /** Call name */
        const char *name;

        // A type for member functions implementing semihosting calls.
        template <typename ...Args>
        using Implementation =
            RetErrno (ArmSemihosting::*)(ThreadContext *tc, Args... args);

        // Since guest ABI doesn't know how to call member function pointers,
        // this template builds a wrapper that takes care of that.
        template <typename ...Args>
        static inline std::function<RetErrno(ThreadContext *tc, Args... args)>
        wrapImpl(ArmSemihosting *sh, Implementation<Args...> impl)
        {
            return [sh, impl](ThreadContext *tc, Args... args) {
                return (sh->*impl)(tc, args...);
            };
        }

        // A type for functions which dispatch semihosting calls through the
        // guest ABI mechanism.
        using Dispatcher =
            std::function<RetErrno(ArmSemihosting *sh, ThreadContext *tc)>;
        using Dumper = std::function<std::string(ThreadContext *tc)>;

        // Dispatchers for 32 and 64 bits.
        Dispatcher call32;
        Dispatcher call64;

        // Dumpers which print semihosting calls and their arguments.
        Dumper dump32;
        Dumper dump64;

        // A function which builds a dispatcher for a semihosting call.
        template <typename Abi, typename ...Args>
        static inline Dispatcher
        buildDispatcher(Implementation<Args...> impl)
        {
            // This lambda is the dispatcher we're building.
            return [impl](ArmSemihosting *sh, ThreadContext *tc) {
                auto wrapper = wrapImpl(sh, impl);
                return invokeSimcall<Abi>(tc, wrapper);
            };
        }

        // A function which builds a dumper for a semihosting call.
        template <typename Abi, typename ...Args>
        static inline Dumper
        buildDumper(const char *name, Implementation<Args...> impl)
        {
            // This lambda is the dumper we're building.
            return [name](ThreadContext *tc) -> std::string {
                return dumpSimcall<Abi, RetErrno, Args...>(name, tc);
            };
        }

        // When there's one implementation, use it for both 32 and 64 bits.
        template <typename ...Args>
        SemiCall(const char *_name, Implementation<Args...> common) :
            name(_name), call32(buildDispatcher<Abi32>(common)),
            call64(buildDispatcher<Abi64>(common)),
            dump32(buildDumper<Abi32>(_name, common)),
            dump64(buildDumper<Abi64>(_name, common))
        {}

        // When there are two, use one for 32 bits and one for 64 bits.
        template <typename ...Args32, typename ...Args64>
        SemiCall(const char *_name, Implementation<Args32...> impl32,
                 Implementation<Args64...> impl64) :
            name(_name), call32(buildDispatcher<Abi32>(impl32)),
            call64(buildDispatcher<Abi64>(impl64)),
            dump32(buildDumper<Abi32>(_name, impl32)),
            dump64(buildDumper<Abi64>(_name, impl64))
        {}
    };

    RetErrno callOpen(ThreadContext *tc, const Addr name_base,
                      int fmode, size_t name_size);
    RetErrno callClose(ThreadContext *tc, Handle handle);
    RetErrno callWriteC(ThreadContext *tc, InPlaceArg c);
    RetErrno callWrite0(ThreadContext *tc, InPlaceArg str);
    RetErrno callWrite(ThreadContext *tc, Handle handle,
                       Addr buffer, size_t size);
    RetErrno callRead(ThreadContext *tc, Handle handle,
                      Addr buffer, size_t size);
    RetErrno callReadC(ThreadContext *tc);
    RetErrno callIsError(ThreadContext *tc, int64_t status);
    RetErrno callIsTTY(ThreadContext *tc, Handle handle);
    RetErrno callSeek(ThreadContext *tc, Handle handle, uint64_t pos);
    RetErrno callFLen(ThreadContext *tc, Handle handle);
    RetErrno callTmpNam(ThreadContext *tc, Addr buffer,
                        uint64_t id, size_t size);
    RetErrno callRemove(ThreadContext *tc, Addr name_base, size_t name_size);
    RetErrno callRename(ThreadContext *tc, Addr from_addr, size_t from_size,
                        Addr to_addr, size_t to_size);
    RetErrno callClock(ThreadContext *tc);
    RetErrno callTime(ThreadContext *tc);
    RetErrno callSystem(ThreadContext *tc, Addr cmd_addr, size_t cmd_size);
    RetErrno callErrno(ThreadContext *tc);
    RetErrno callGetCmdLine(ThreadContext *tc, Addr addr, InPlaceArg size_arg);

    void gatherHeapInfo(ThreadContext *tc, bool aarch64,
                        Addr &heap_base, Addr &heap_limit,
                        Addr &stack_base, Addr &stack_limit);
    RetErrno callHeapInfo32(ThreadContext *tc, Addr block_addr);
    RetErrno callHeapInfo64(ThreadContext *tc, Addr block_addr);
    RetErrno callExit32(ThreadContext *tc, InPlaceArg code);
    RetErrno callExit64(ThreadContext *tc, uint64_t code, uint64_t subcode);
    RetErrno callExitExtended(ThreadContext *tc, uint64_t code,
                              uint64_t subcode);

    RetErrno callElapsed32(ThreadContext *tc, InPlaceArg low, InPlaceArg high);
    RetErrno callElapsed64(ThreadContext *tc, InPlaceArg ticks);
    RetErrno callTickFreq(ThreadContext *tc);

    RetErrno callGem5PseudoOp32(ThreadContext *tc, uint32_t encoded_func);
    RetErrno callGem5PseudoOp64(ThreadContext *tc, uint64_t encoded_func);

    template <typename Abi>
    void
    unrecognizedCall(ThreadContext *tc, const char *format, uint64_t op)
    {
        warn(format, op);
        std::function<RetErrno(ThreadContext *tc)> retErr =
            [](ThreadContext *tc) { return retError(EINVAL); };
        invokeSimcall<Abi>(tc, retErr);
    }

    static FILE *getSTDIO(const char *stream_name,
                          const std::string &name, const char *mode);

    static const std::map<uint32_t, SemiCall> calls;
    static const std::vector<const char *> fmodes;
    static const std::map<uint64_t, const char *> exitCodes;
    static const std::vector<uint8_t> features;
    static const std::map<const std::string, FILE *> stdioMap;

    // used in callTmpNam() to deterministically generate a temp filename
    uint16_t tmpNameIndex = 0;

};

std::ostream &operator << (
        std::ostream &os, const ArmSemihosting::InPlaceArg &ipa);

GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi);
namespace guest_abi
{

template <typename Arg>
struct Argument<ArmSemihosting::Abi64, Arg,
    typename std::enable_if_t<std::is_integral<Arg>::value>>
{
    static Arg
    get(ThreadContext *tc, ArmSemihosting::Abi64::State &state)
    {
        return state.get(tc);
    }
};

template <typename Arg>
struct Argument<ArmSemihosting::Abi32, Arg,
    typename std::enable_if_t<std::is_integral<Arg>::value>>
{
    static Arg
    get(ThreadContext *tc, ArmSemihosting::Abi32::State &state)
    {
        if (std::is_signed<Arg>::value)
            return sext<32>(state.get(tc));
        else
            return state.get(tc);
    }
};

template <typename Abi>
struct Argument<Abi, ArmSemihosting::InPlaceArg, typename std::enable_if_t<
    std::is_base_of<ArmSemihosting::AbiBase, Abi>::value>>
{
    static ArmSemihosting::InPlaceArg
    get(ThreadContext *tc, typename Abi::State &state)
    {
        return ArmSemihosting::InPlaceArg(
                state.getAddr(), sizeof(typename Abi::State::ArgType));
    }
};

template <>
struct Result<ArmSemihosting::Abi32, ArmSemihosting::RetErrno>
{
    static void
    store(ThreadContext *tc, const ArmSemihosting::RetErrno &err)
    {
        tc->setIntReg(ArmISA::INTREG_R0, err.first);
    }
};

template <>
struct Result<ArmSemihosting::Abi64, ArmSemihosting::RetErrno>
{
    static void
    store(ThreadContext *tc, const ArmSemihosting::RetErrno &err)
    {
        tc->setIntReg(ArmISA::INTREG_X0, err.first);
    }
};

} // namespace guest_abi

#endif // __ARCH_ARM_SEMIHOSTING_HH__
