/*
 * 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/core.hh"
#include "sim/guest_abi.hh"
#include "sim/sim_object.hh"

namespace gem5
{

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_v<Arg>>>
{
    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_v<Arg>>>
{
    static Arg
    get(ThreadContext *tc, ArmSemihosting::Abi32::State &state)
    {
        if (std::is_signed_v<Arg>)
            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_v<ArmSemihosting::AbiBase, Abi>>>
{
    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
} // namespace gem5

#endif // __ARCH_ARM_SEMIHOSTING_HH__
