/*
 * 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.
 */

#include "arch/arm/semihosting.hh"

#include <cstdio>

#include "arch/arm/utility.hh"
#include "base/logging.hh"
#include "base/time.hh"
#include "debug/Semihosting.hh"
#include "dev/serial/serial.hh"
#include "mem/physical.hh"
#include "mem/se_translating_port_proxy.hh"
#include "mem/translating_port_proxy.hh"
#include "params/ArmSemihosting.hh"
#include "sim/byteswap.hh"
#include "sim/full_system.hh"
#include "sim/pseudo_inst.hh"
#include "sim/sim_exit.hh"
#include "sim/system.hh"

const std::map<uint32_t, ArmSemihosting::SemiCall> ArmSemihosting::calls{
    { SYS_OPEN,     { "SYS_OPEN", &ArmSemihosting::callOpen } },
    { SYS_CLOSE,    { "SYS_CLOSE", &ArmSemihosting::callClose } },
    { SYS_WRITEC,   { "SYS_WRITEC", &ArmSemihosting::callWriteC } },
    { SYS_WRITE0,   { "SYS_WRITE0", &ArmSemihosting::callWrite0 } },
    { SYS_WRITE,    { "SYS_WRITE", &ArmSemihosting::callWrite } },
    { SYS_READ,     { "SYS_READ", &ArmSemihosting::callRead } },
    { SYS_READC,    { "SYS_READC", &ArmSemihosting::callReadC } },
    { SYS_ISERROR,  { "SYS_ISERROR", &ArmSemihosting::callIsError } },
    { SYS_ISTTY,    { "SYS_ISTTY", &ArmSemihosting::callIsTTY } },
    { SYS_SEEK,     { "SYS_SEEK", &ArmSemihosting::callSeek } },
    { SYS_FLEN,     { "SYS_FLEN", &ArmSemihosting::callFLen } },
    { SYS_TMPNAM,   { "SYS_TMPNAM", &ArmSemihosting::callTmpNam } },
    { SYS_REMOVE,   { "SYS_REMOVE", &ArmSemihosting::callRemove } },
    { SYS_RENAME,   { "SYS_RENAME", &ArmSemihosting::callRename } },
    { SYS_CLOCK,    { "SYS_CLOCK", &ArmSemihosting::callClock } },
    { SYS_TIME,     { "SYS_TIME", &ArmSemihosting::callTime } },
    { SYS_SYSTEM,   { "SYS_SYSTEM", &ArmSemihosting::callSystem } },
    { SYS_ERRNO,    { "SYS_ERRNO", &ArmSemihosting::callErrno } },
    { SYS_GET_CMDLINE,
        { "SYS_GET_CMDLINE", &ArmSemihosting::callGetCmdLine } },
    { SYS_HEAPINFO, { "SYS_HEAPINFO", &ArmSemihosting::callHeapInfo32,
                                      &ArmSemihosting::callHeapInfo64 } },

    { SYS_EXIT,     { "SYS_EXIT", &ArmSemihosting::callExit32,
                                  &ArmSemihosting::callExit64} },
    { SYS_EXIT_EXTENDED,
        { "SYS_EXIT_EXTENDED", &ArmSemihosting::callExitExtended } },

    { SYS_ELAPSED,  { "SYS_ELAPSED", &ArmSemihosting::callElapsed32,
                                     &ArmSemihosting::callElapsed64 } },
    { SYS_TICKFREQ, { "SYS_TICKFREQ", &ArmSemihosting::callTickFreq } },
    { SYS_GEM5_PSEUDO_OP,
        { "SYS_GEM5_PSEUDO_OP", &ArmSemihosting::callGem5PseudoOp32,
                                &ArmSemihosting::callGem5PseudoOp64 } },
};

const std::vector<const char *> ArmSemihosting::fmodes{
    "r", "rb", "r+", "r+b",
    "w", "wb", "w+", "w+b",
    "a", "ab", "a+", "a+b",
};

const std::map<uint64_t, const char *> ArmSemihosting::exitCodes{
    { 0x20000, "semi:ADP_Stopped_BranchThroughZero" },
    { 0x20001, "semi:ADP_Stopped_UndefinedInstr" },
    { 0x20002, "semi:ADP_Stopped_SoftwareInterrupt" },
    { 0x20003, "semi:ADP_Stopped_PrefetchAbort" },
    { 0x20004, "semi:ADP_Stopped_DataAbort" },
    { 0x20005, "semi:ADP_Stopped_AddressException" },
    { 0x20006, "semi:ADP_Stopped_IRQ" },
    { 0x20007, "semi:ADP_Stopped_FIQ" },

    { 0x20020, "semi:ADP_Stopped_BreakPoint" },
    { 0x20021, "semi:ADP_Stopped_WatchPoint" },
    { 0x20022, "semi:ADP_Stopped_StepComplete" },
    { 0x20023, "semi:ADP_Stopped_RunTimeErrorUnknown" },
    { 0x20024, "semi:ADP_Stopped_InternalError" },
    { 0x20025, "semi:ADP_Stopped_UserInterruption" },
    { 0x20026, "semi:ADP_Stopped_ApplicationExit" },
    { 0x20027, "semi:ADP_Stopped_StackOverflow" },
    { 0x20028, "semi:ADP_Stopped_DivisionByZero" },
    { 0x20029, "semi:ADP_Stopped_DivisionByZero" },
};


const std::vector<uint8_t> ArmSemihosting::features{
    0x53, 0x48, 0x46, 0x42, // Magic
    0x3,                    // EXT_EXIT_EXTENDED, EXT_STDOUT_STDERR
};

const std::map<const std::string, FILE *> ArmSemihosting::stdioMap{
    {"cin",    ::stdin},
    {"stdin",  ::stdin},
    {"cout",   ::stdout},
    {"stdout", ::stdout},
    {"cerr",   ::stderr},
    {"stderr", ::stderr},
};

ArmSemihosting::ArmSemihosting(const ArmSemihostingParams *p)
    : SimObject(p),
      cmdLine(p->cmd_line),
      memReserve(p->mem_reserve),
      stackSize(p->stack_size),
      timeBase([p]{ struct tm t = p->time; return mkutctime(&t); }()),
      tickShift(calcTickShift()),
      semiErrno(0),
      filesRootDir(!p->files_root_dir.empty() &&
                   p->files_root_dir.back() != '/' ?
                   p->files_root_dir + '/' : p->files_root_dir),
      stdin(getSTDIO("stdin", p->stdin, "r")),
      stdout(getSTDIO("stdout", p->stdout, "w")),
      stderr(p->stderr == p->stdout ?
             stdout : getSTDIO("stderr", p->stderr, "w"))
{
    // Create an empty place-holder file for position 0 as semi-hosting
    // calls typically expect non-zero file handles.
    files.push_back(nullptr);

    if (tickShift > 0)
        inform("Semihosting: Shifting elapsed ticks by %i bits.",
               tickShift);
}

bool
ArmSemihosting::call64(ThreadContext *tc, bool gem5_ops)
{
    RegVal op = tc->readIntReg(ArmISA::INTREG_X0 & mask(32));
    if (op > MaxStandardOp && !gem5_ops) {
        unrecognizedCall<Abi64>(
                tc, "Gem5 semihosting op (0x%x) disabled from here.", op);
        return false;
    }

    auto it = calls.find(op);
    if (it == calls.end()) {
        unrecognizedCall<Abi64>(
                tc, "Unknown aarch64 semihosting call: op = 0x%x", op);
        return false;
    }
    const SemiCall &call = it->second;

    DPRINTF(Semihosting, "Semihosting call64: %s\n", call.dump64(tc));
    auto err = call.call64(this, tc);
    semiErrno = err.second;
    DPRINTF(Semihosting, "\t ->: 0x%x, %i\n", err.first, err.second);

    return true;
}

bool
ArmSemihosting::call32(ThreadContext *tc, bool gem5_ops)
{
    RegVal op = tc->readIntReg(ArmISA::INTREG_R0);
    if (op > MaxStandardOp && !gem5_ops) {
        unrecognizedCall<Abi32>(
                tc, "Gem5 semihosting op (0x%x) disabled from here.", op);
        return false;
    }

    auto it = calls.find(op);
    if (it == calls.end()) {
        unrecognizedCall<Abi32>(
                tc, "Unknown aarch32 semihosting call: op = 0x%x", op);
        return false;
    }
    const SemiCall &call = it->second;

    DPRINTF(Semihosting, "Semihosting call32: %s\n", call.dump32(tc));
    auto err = call.call32(this, tc);
    semiErrno = err.second;
    DPRINTF(Semihosting, "\t ->: 0x%x, %i\n", err.first, err.second);

    return true;
}

void
ArmSemihosting::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(semiErrno);

    paramOut(cp, "num_files", files.size());
    for (int i = 0; i < files.size(); i++) {
        // File closed?
        if (!files[i])
            continue;

        files[i]->serializeSection(cp, csprintf("file%i", i));
    }
}

void
ArmSemihosting::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(semiErrno);

    size_t num_files;
    paramIn(cp, "num_files", num_files);
    files.resize(num_files);
    for (int i = 0; i < num_files; i++)
        files[i] = FileBase::create(*this, cp, csprintf("file%i", i));
}

PortProxy &
ArmSemihosting::portProxy(ThreadContext *tc)
{
    static std::unique_ptr<PortProxy> port_proxy_s;
    static System *secure_sys = nullptr;

    if (ArmISA::inSecureState(tc)) {
        System *sys = tc->getSystemPtr();
        if (sys != secure_sys) {
            if (FullSystem) {
                port_proxy_s.reset(
                        new TranslatingPortProxy(tc, Request::SECURE));
            } else {
                port_proxy_s.reset(
                        new SETranslatingPortProxy(
                            tc, SETranslatingPortProxy::NextPage,
                            Request::SECURE));
            }
        }
        secure_sys = sys;
        return *port_proxy_s;
    } else {
        return tc->getVirtProxy();
    }
}


std::string
ArmSemihosting::readString(ThreadContext *tc, Addr ptr, size_t len)
{
    std::vector<char> buf(len + 1);

    buf[len] = '\0';
    portProxy(tc).readBlob(ptr, buf.data(), len);

    return std::string(buf.data());
}

ArmSemihosting::RetErrno
ArmSemihosting::callOpen(ThreadContext *tc, const Addr name_base,
                         int fmode, size_t name_size)
{
    const char *mode = fmode < fmodes.size() ? fmodes[fmode] : nullptr;

    DPRINTF(Semihosting, "Semihosting SYS_OPEN(0x%x, %i[%s], %i)\n",
            name_base, fmode, mode ? mode : "-", name_size);
    if (!mode || !name_base)
        return retError(EINVAL);

    std::string fname = readString(tc, name_base, name_size);
    if (!fname.empty() && fname.front() != '/')
        fname = filesRootDir + fname;

    std::unique_ptr<ArmSemihosting::FileBase> file =
        FileBase::create(*this, fname, mode);
    int64_t ret = file->open();
    DPRINTF(Semihosting, "Semihosting SYS_OPEN(\"%s\", %i[%s]): %i\n",
            fname, fmode, mode, ret);
    if (ret < 0) {
        return retError(-ret);
    } else {
        files.push_back(std::move(file));
        return retOK(files.size() - 1);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callClose(ThreadContext *tc, Handle handle)
{
    if (handle > files.size()) {
        DPRINTF(Semihosting, "Semihosting SYS_CLOSE(%i): Illegal file\n");
        return retError(EBADF);
    }

    std::unique_ptr<FileBase> &file = files[handle];
    int64_t error = file->close();
    DPRINTF(Semihosting, "Semihosting SYS_CLOSE(%i[%s]): %i\n",
            handle, file->fileName(), error);
    if (error < 0) {
        return retError(-error);
    } else {
        // Zap the pointer and free the entry in the file table as
        // well.
        files[handle].reset();
        return retOK(0);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callWriteC(ThreadContext *tc, InPlaceArg arg)
{
    const char c = portProxy(tc).read<char>(arg.addr);

    DPRINTF(Semihosting, "Semihosting SYS_WRITEC('%c')\n", c);
    std::cout.put(c);

    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callWrite0(ThreadContext *tc, InPlaceArg arg)
{
    DPRINTF(Semihosting, "Semihosting SYS_WRITE0(...)\n");
    PortProxy &proxy = portProxy(tc);
    std::string str;
    proxy.readString(str, arg.addr);
    std::cout.write(str.c_str(), str.size());

    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callWrite(ThreadContext *tc, Handle handle, Addr addr,
                          size_t size)
{
    if (handle > files.size() || !files[handle])
        return RetErrno(size, EBADF);

    std::vector<uint8_t> buffer(size);
    portProxy(tc).readBlob(addr, buffer.data(), buffer.size());

    int64_t ret = files[handle]->write(buffer.data(), buffer.size());
    if (ret < 0) {
        // No bytes written (we're returning the number of bytes not
        // written)
        return RetErrno(size, -ret);
    } else {
        // Return the number of bytes not written
        return RetErrno(size - ret, 0);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callRead(ThreadContext *tc, Handle handle, Addr addr,
                         size_t size)
{
    if (handle > files.size() || !files[handle])
        return RetErrno(size, EBADF);

    std::vector<uint8_t> buffer(size);
    int64_t ret = files[handle]->read(buffer.data(), buffer.size());
    if (ret < 0) {
        return RetErrno(size, -ret);
    } else {
        panic_if(ret > buffer.size(), "Read longer than buffer size.");

        portProxy(tc).writeBlob(addr, buffer.data(), ret);

        // Return the number of bytes not written
        return retOK(size - ret);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callReadC(ThreadContext *tc)
{
    return retOK((char)std::cin.get());
}

ArmSemihosting::RetErrno
ArmSemihosting::callIsError(ThreadContext *tc, int64_t status)
{
    return retOK(status < 0 ? 1 : 0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callIsTTY(ThreadContext *tc, Handle handle)
{
    if (handle > files.size() || !files[handle])
        return retError(EBADF);

    int64_t ret = files[handle]->isTTY();
    if (ret < 0) {
        return retError(-ret);
    } else {
        return retOK(ret ? 1 : 0);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callSeek(ThreadContext *tc, Handle handle, uint64_t pos)
{
    if (handle > files.size() || !files[handle])
        return retError(EBADF);

    int64_t ret = files[handle]->seek(pos);
    if (ret < 0) {
        return retError(-ret);
    } else {
        return retOK(0);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callFLen(ThreadContext *tc, Handle handle)
{
    if (handle > files.size() || !files[handle])
        return retError(EBADF);

    int64_t ret = files[handle]->flen();
    if (ret < 0) {
        return retError(-ret);
    } else {
        return retOK(ret);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callTmpNam(ThreadContext *tc, Addr addr, uint64_t id,
                           size_t size)
{
    std::vector<char> buf(L_tmpnam);
    char *path = tmpnam(buf.data());
    if (!path)
        return retError(EINVAL);

    const size_t path_len = strlen(path);
    if (path_len >= size)
        return retError(ENOSPC);

    portProxy(tc).writeBlob(addr, path, path_len + 1);
    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callRemove(ThreadContext *tc, Addr name_base, size_t name_size)
{
    std::string fname = readString(tc, name_base, name_size);

    if (remove(fname.c_str()) != 0) {
        return retError(errno);
    } else {
        return retOK(0);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callRename(ThreadContext *tc, Addr from_addr, size_t from_size,
                           Addr to_addr, size_t to_size)
{
    std::string from = readString(tc, from_addr, from_size);
    std::string to = readString(tc, to_addr, to_size);

    if (rename(from.c_str(), to.c_str()) != 0) {
        return retError(errno);
    } else {
        return retOK(0);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callClock(ThreadContext *tc)
{
    return retOK(curTick() / (SimClock::Int::s / 100));
}

ArmSemihosting::RetErrno
ArmSemihosting::callTime(ThreadContext *tc)
{
    return retOK(timeBase + round(curTick() / SimClock::Float::s));
}

ArmSemihosting::RetErrno
ArmSemihosting::callSystem(ThreadContext *tc, Addr cmd_addr, size_t cmd_size)
{
    const std::string cmd = readString(tc, cmd_addr, cmd_size);
    warn("Semihosting: SYS_SYSTEM not implemented. Guest tried to run: %s\n",
         cmd);
    return retError(EINVAL);

}

ArmSemihosting::RetErrno
ArmSemihosting::callErrno(ThreadContext *tc)
{
    // Preserve errno by returning it in errno as well.
    return RetErrno(semiErrno, semiErrno);
}

ArmSemihosting::RetErrno
ArmSemihosting::callGetCmdLine(ThreadContext *tc, Addr addr,
                               InPlaceArg size_arg)
{
    PortProxy &proxy = portProxy(tc);
    ByteOrder endian = ArmISA::byteOrder(tc);
    size_t size = size_arg.read(tc, endian);

    if (cmdLine.size() + 1 < size) {
        proxy.writeBlob(addr, cmdLine.c_str(), cmdLine.size() + 1);
        size_arg.write(tc, cmdLine.size(), endian);
        return retOK(0);
    } else {
        return retError(0);
    }
}

void
ArmSemihosting::gatherHeapInfo(ThreadContext *tc, bool aarch64,
                               Addr &heap_base, Addr &heap_limit,
                               Addr &stack_base, Addr &stack_limit)
{
    const PhysicalMemory &phys = tc->getSystemPtr()->getPhysMem();
    const AddrRangeList memories = phys.getConfAddrRanges();
    fatal_if(memories.size() < 1, "No memories reported from System");
    warn_if(memories.size() > 1, "Multiple physical memory ranges available. "
            "Using first range heap/stack.");
    const AddrRange memory = *memories.begin();
    const Addr mem_start = memory.start() + memReserve;
    Addr mem_end = memory.end();

    // Make sure that 32-bit guests can access their memory.
    if (!aarch64) {
        const Addr phys_max = (1ULL << 32) - 1;
        panic_if(mem_start > phys_max,
                 "Physical memory out of range for a 32-bit guest.");
        if (mem_end > phys_max) {
            warn("Some physical memory out of range for a 32-bit guest.");
            mem_end = phys_max;
        }
    }

    fatal_if(mem_start + stackSize >= mem_end,
             "Physical memory too small to fit desired stack and a heap.");

    heap_base = mem_start;
    heap_limit = mem_end - stackSize + 1;
    stack_base = (mem_end + 1) & ~0x7ULL; // 8 byte stack alignment
    stack_limit = heap_limit;

    inform("Reporting heap/stack info to guest:\n"
           "\tHeap base: 0x%x\n"
           "\tHeap limit: 0x%x\n"
           "\tStack base: 0x%x\n"
           "\tStack limit: 0x%x\n",
           heap_base, heap_limit, stack_base, stack_limit);
}

ArmSemihosting::RetErrno
ArmSemihosting::callHeapInfo32(ThreadContext *tc, Addr block_addr)
{
    uint64_t heap_base, heap_limit, stack_base, stack_limit;
    gatherHeapInfo(tc, false, heap_base, heap_limit, stack_base, stack_limit);

    std::array<uint32_t, 4> block = {{
        (uint32_t)heap_base, (uint32_t)heap_limit,
        (uint32_t)stack_base, (uint32_t)stack_limit
    }};
    portProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc));

    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callHeapInfo64(ThreadContext *tc, Addr block_addr)
{
    uint64_t heap_base, heap_limit, stack_base, stack_limit;
    gatherHeapInfo(tc, true, heap_base, heap_limit, stack_base, stack_limit);

    std::array<uint64_t, 4> block = {{
        heap_base, heap_limit, stack_base, stack_limit
    }};
    portProxy(tc).write(block_addr, block, ArmISA::byteOrder(tc));

    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callExit32(ThreadContext *tc, InPlaceArg code)
{
    semiExit(code.addr, 0);
    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callExit64(ThreadContext *tc, uint64_t code, uint64_t subcode)
{
    semiExit(code, subcode);
    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callExitExtended(ThreadContext *tc,
                                 uint64_t code, uint64_t subcode)
{
    semiExit(code, subcode);
    return retOK(0);
}

void
ArmSemihosting::semiExit(uint64_t code, uint64_t subcode)
{
    auto it = exitCodes.find(code);
    if (it != exitCodes.end()) {
        exitSimLoop(it->second, subcode);
    } else {
        exitSimLoop(csprintf("semi:0x%x", code), subcode);
    }
}


ArmSemihosting::RetErrno
ArmSemihosting::callElapsed32(ThreadContext *tc, InPlaceArg low,
                              InPlaceArg high)
{
    ByteOrder endian = ArmISA::byteOrder(tc);
    uint64_t tick = semiTick(curTick());

    low.write(tc, tick, endian);
    high.write(tc, tick >> 32, endian);

    return retOK(0);
}


ArmSemihosting::RetErrno
ArmSemihosting::callElapsed64(ThreadContext *tc, InPlaceArg ticks)
{
    ticks.write(tc, semiTick(curTick()), ArmISA::byteOrder(tc));
    return retOK(0);
}


ArmSemihosting::RetErrno
ArmSemihosting::callTickFreq(ThreadContext *tc)
{
    return retOK(semiTick(SimClock::Frequency));
}


struct SemiPseudoAbi32 : public ArmSemihosting::Abi32
{
    class State : public ArmSemihosting::Abi32::State
    {
      public:
        State(const ThreadContext *tc) : ArmSemihosting::Abi32::State(tc)
        {
            // Use getAddr() to skip the func number in the first slot.
            getAddr();
        }
    };
};

struct SemiPseudoAbi64 : public ArmSemihosting::Abi64
{
    class State : public ArmSemihosting::Abi64::State
    {
      public:
        State(const ThreadContext *tc) : ArmSemihosting::Abi64::State(tc)
        {
            // Use getAddr() to skip the func number in the first slot.
            getAddr();
        }
    };
};

namespace GuestABI
{

// Ignore return values since those will be handled by semihosting.
template <typename T>
struct Result<SemiPseudoAbi32, T>
{
    static void store(ThreadContext *tc, const T &ret) {}
};
template <typename T>
struct Result<SemiPseudoAbi64, T>
{
    static void store(ThreadContext *tc, const T &ret) {}
};

// Handle arguments the same as for semihosting operations. Skipping the first
// slot is handled internally by the State type.
template <typename T>
struct Argument<SemiPseudoAbi32, T> :
    public Argument<ArmSemihosting::Abi32, T>
{};
template <typename T>
struct Argument<SemiPseudoAbi64, T> :
    public Argument<ArmSemihosting::Abi64, T>
{};

} // namespace GuestABI

ArmSemihosting::RetErrno
ArmSemihosting::callGem5PseudoOp32(ThreadContext *tc, uint32_t encoded_func)
{
    uint8_t func;
    PseudoInst::decodeAddrOffset(encoded_func, func);

    uint64_t ret;
    if (PseudoInst::pseudoInst<SemiPseudoAbi32>(tc, func, ret))
        return retOK(ret);
    else
        return retError(EINVAL);
}

ArmSemihosting::RetErrno
ArmSemihosting::callGem5PseudoOp64(ThreadContext *tc, uint64_t encoded_func)
{
    uint8_t func;
    PseudoInst::decodeAddrOffset(encoded_func, func);

    uint64_t ret;
    if (PseudoInst::pseudoInst<SemiPseudoAbi64>(tc, func, ret))
        return retOK(ret);
    else
        return retError(EINVAL);
}

FILE *
ArmSemihosting::getSTDIO(const char *stream_name,
                         const std::string &name, const char *mode)
{
    auto it = stdioMap.find(name);
    if (it == stdioMap.end()) {
        FILE *f = fopen(name.c_str(), mode);
        if (!f) {
            fatal("Failed to open %s (%s): %s\n",
                  stream_name, name, strerror(errno));
        }
        return f;
    } else {
        return it->second;
    }
}

std::unique_ptr<ArmSemihosting::FileBase>
ArmSemihosting::FileBase::create(
    ArmSemihosting &parent, const std::string &fname, const char *mode)
{
    std::unique_ptr<FileBase> file;
    if (fname == ":semihosting-features") {
        file.reset(new FileFeatures(parent, fname.c_str(), mode));
    } else {
        file.reset(new File(parent, fname.c_str(), mode));
    }

    return file;
}

std::unique_ptr<ArmSemihosting::FileBase>
ArmSemihosting::FileBase::create(ArmSemihosting &parent,
                                 CheckpointIn &cp, const std::string &sec)
{
    std::unique_ptr<FileBase> file;
    ScopedCheckpointSection _sec(cp, sec);

    // Was the file open when the checkpoint was created?
    if (!cp.sectionExists(Serializable::currentSection()))
        return file;

    std::string fname, mode;
    paramIn(cp, "name", fname);
    paramIn(cp, "mode", mode);
    file = create(parent, fname, mode.c_str());
    assert(file);
    file->unserialize(cp);

    return file;
}

void
ArmSemihosting::FileBase::serialize(CheckpointOut &cp) const
{
    paramOut(cp, "name", _name);
    SERIALIZE_SCALAR(mode);
}

void
ArmSemihosting::FileBase::unserialize(CheckpointIn &cp)
{
    /* Unserialization of name and mode happens in
     * ArmSemihosting::FileBase::create() */
}

int64_t
ArmSemihosting::FileBase::read(uint8_t *buffer, uint64_t size)
{
    return -EINVAL;
}

int64_t
ArmSemihosting::FileBase::write(const uint8_t *buffer, uint64_t size)
{
    return -EINVAL;
}

int64_t
ArmSemihosting::FileBase::seek(uint64_t pos)
{
    return -EINVAL;
}

int64_t
ArmSemihosting::FileBase::flen()
{
    return -EINVAL;
}


ArmSemihosting::FileFeatures::FileFeatures(
    ArmSemihosting &_parent, const char *_name, const char *_mode)
    : FileBase(_parent, _name, _mode)
{
}

int64_t
ArmSemihosting::FileFeatures::read(uint8_t *buffer, uint64_t size)
{
    int64_t len = 0;

    for (; pos < size && pos < ArmSemihosting::features.size(); pos++)
        buffer[len++] = ArmSemihosting::features[pos];

    return len;
}

int64_t
ArmSemihosting::FileFeatures::seek(uint64_t _pos)
{
    if (_pos < ArmSemihosting::features.size()) {
        pos = _pos;
        return 0;
    } else {
        return -ENXIO;
    }
}

void
ArmSemihosting::FileFeatures::serialize(CheckpointOut &cp) const
{
    FileBase::serialize(cp);
    SERIALIZE_SCALAR(pos);
}

void
ArmSemihosting::FileFeatures::unserialize(CheckpointIn &cp)
{
    FileBase::unserialize(cp);
    UNSERIALIZE_SCALAR(pos);
}



ArmSemihosting::File::File(ArmSemihosting &_parent,
                           const char *_name, const char *_perms)
    : FileBase(_parent, _name, _perms),
      file(nullptr)
{
}

ArmSemihosting::File::~File()
{
    if (file)
        close();
}

int64_t
ArmSemihosting::File::openImpl(bool in_cpt)
{
    panic_if(file, "Trying to open an already open file.\n");

    if (_name == ":tt") {
        if (mode[0] == 'r') {
            file = parent.stdin;
        } else if (mode[0] == 'w') {
            file = parent.stdout;
        } else if (mode[0] == 'a') {
            file = parent.stderr;
        } else {
            warn("Unknown file mode for the ':tt' special file");
            return -EINVAL;
        }
    } else {
        std::string real_mode(this->mode);
        // Avoid truncating the file if we are restoring from a
        // checkpoint.
        if (in_cpt && real_mode[0] == 'w')
            real_mode[0] = 'a';

        file = fopen(_name.c_str(), real_mode.c_str());
    }

    return file ? 0 : -errno;
}

int64_t
ArmSemihosting::File::close()
{
    panic_if(!file, "Trying to close an already closed file.\n");

    if (needClose()) {
        fclose(file);
    }
    file = nullptr;

    return 0;
}

bool
ArmSemihosting::File::isTTY() const
{
    return file == parent.stdout ||
        file == parent.stderr ||
        file == parent.stdin;
}

int64_t
ArmSemihosting::File::read(uint8_t *buffer, uint64_t size)
{
    panic_if(!file, "Trying to read from a closed file");

    size_t ret = fread(buffer, 1, size, file);
    if (ret == 0) {
        // Error or EOF. Assume errors are due to invalid file
        // operations (e.g., reading a write-only stream).
        return ferror(file) ? -EINVAL : 0;
    } else {
        return ret;
    }
}

int64_t
ArmSemihosting::File::write(const uint8_t *buffer, uint64_t size)
{
    panic_if(!file, "Trying to write to a closed file");


    size_t ret = fwrite(buffer, 1, size, file);
    if (ret == 0) {
        // Assume errors are due to invalid file operations (e.g.,
        // writing a read-only stream).
        return -EINVAL;
    } else {
        return ret;
    }
}

int64_t
ArmSemihosting::File::seek(uint64_t _pos)
{
    panic_if(!file, "Trying to seek in a closed file");

    errno = 0;
    if (fseek(file, _pos, SEEK_SET) == 0)
        return 0;
    else
        return -errno;
}

int64_t
ArmSemihosting::File::flen()
{
    errno = 0;
    long pos = ftell(file);
    if (pos < 0)
        return -errno;

    if (fseek(file, 0, SEEK_END) != 0)
        return -errno;

    long len = ftell(file);
    if (len < 0)
        return -errno;

    if (fseek(file, pos, SEEK_SET) != 0)
        return -errno;

    return len;
}


void
ArmSemihosting::File::serialize(CheckpointOut &cp) const
{
    FileBase::serialize(cp);

    if (!isTTY()) {
        long pos = file ? ftell(file) : 0;
        panic_if(pos < 0, "Failed to get file position.");
        SERIALIZE_SCALAR(pos);
    }
}

void
ArmSemihosting::File::unserialize(CheckpointIn &cp)
{
    FileBase::unserialize(cp);

    if (openImpl(true) < 0) {
        fatal("Failed to open file: %s", _name);
    }

    if (!isTTY()) {
        long pos = 0;
        UNSERIALIZE_SCALAR(pos);
        if (fseek(file, pos, SEEK_SET) != 0) {
            fatal("Failed seek to current position (%i) in '%s'", pos, _name);
        }
    }
}

std::ostream &
operator << (std::ostream &os, const ArmSemihosting::InPlaceArg &ipa)
{
    ccprintf(os, "[%#x-%#x)", ipa.addr, ipa.addr + ipa.size - 1);
    return os;
}


ArmSemihosting *
ArmSemihostingParams::create()
{
    return new ArmSemihosting(this);
}
