/*
 * 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/secure_port_proxy.hh"
#include "params/ArmSemihosting.hh"
#include "sim/byteswap.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, 3, 3 } },
    { SYS_CLOSE,    { "SYS_CLOSE", &ArmSemihosting::callClose, 1, 1 } },

    // Write(C|0) are special since we want to read the character
    // manually. We therefore declare them as having 0 params.
    { SYS_WRITEC,   { "SYS_WRITEC", &ArmSemihosting::callWriteC, 0, 0 } },
    { SYS_WRITE0,   { "SYS_WRITE0", &ArmSemihosting::callWrite0, 1, 1 } },

    { SYS_WRITE,    { "SYS_WRITE", &ArmSemihosting::callWrite, 3, 3 } },
    { SYS_READ,     { "SYS_READ", &ArmSemihosting::callRead, 3, 3 } },
    { SYS_READC,    { "SYS_READC", &ArmSemihosting::callReadC, 0, 0 } },
    { SYS_ISERROR,  { "SYS_ISERROR", &ArmSemihosting::callIsError, 1, 1 } },
    { SYS_ISTTY,    { "SYS_ISTTY", &ArmSemihosting::callIsTTY, 1, 1 } },
    { SYS_SEEK,     { "SYS_SEEK", &ArmSemihosting::callSeek, 2, 2 } },
    { SYS_FLEN,     { "SYS_FLEN", &ArmSemihosting::callFLen, 1, 1 } },
    { SYS_TMPNAM,   { "SYS_TMPNAM", &ArmSemihosting::callTmpNam, 3, 3 } },
    { SYS_REMOVE,   { "SYS_REMOVE", &ArmSemihosting::callRemove, 2, 2} },
    { SYS_RENAME,   { "SYS_RENAME", &ArmSemihosting::callRename, 4, 4} },
    { SYS_CLOCK,    { "SYS_CLOCK", &ArmSemihosting::callClock, 0, 0} },
    { SYS_TIME,     { "SYS_TIME", &ArmSemihosting::callTime, 0, 0} },
    { SYS_SYSTEM,   { "SYS_SYSTEM", &ArmSemihosting::callSystem, 2, 2} },
    { SYS_ERRNO,    { "SYS_ERRNO", &ArmSemihosting::callErrno, 0, 0 } },
    { SYS_GET_CMDLINE,
        { "SYS_GET_CMDLINE", &ArmSemihosting::callGetCmdLine, 2, 2} },
    { SYS_HEAPINFO, { "SYS_HEAPINFO", &ArmSemihosting::callHeapInfo, 1, 1} },

    // Exit is special and requires custom handling in aarch32.
    { SYS_EXIT,     { "SYS_EXIT", &ArmSemihosting::callExit, 0, 2 } },
    { SYS_EXIT_EXTENDED,
        { "SYS_EXIT_EXTENDED", &ArmSemihosting::callExitExtended, 2, 2 } },

    { SYS_ELAPSED,  { "SYS_ELAPSED", &ArmSemihosting::callElapsed, 0, 0 } },
    { SYS_TICKFREQ, { "SYS_TICKFREQ", &ArmSemihosting::callTickFreq, 0, 0 } },
};

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);
}

uint64_t
ArmSemihosting::call64(ThreadContext *tc, uint32_t op, uint64_t param)
{
    const SemiCall *call = getCall(op, true);
    if (!call) {
        warn("Unknown aarch64 semihosting call: op = 0x%x, param = 0x%x",
             op, param);

        return (uint64_t)-1;
    } else if (!call->implemented64()) {
        warn("Unimplemented aarch64 semihosting call: "
             "%s (op = 0x%x, param = 0x%x)",
             call->name, op, param);

        return (uint64_t)-1;
    }

    std::vector<uint64_t> argv(call->argc64 + 1);
    PortProxy &proxy = physProxy(tc);
    ByteOrder endian = ArmISA::byteOrder(tc);

    DPRINTF(Semihosting, "Semihosting call64: %s(0x%x)\n", call->name, param);
    argv[0] = param;
    for (int i = 0; i < call->argc64; ++i) {
        argv[i + 1] = proxy.read<uint64_t>(param + i * 8, endian);
        DPRINTF(Semihosting, "\t: 0x%x\n", argv[i + 1]);
    }

    auto ret_errno = (this->*call->call)(tc, true, argv);
    semiErrno = ret_errno.second;
    DPRINTF(Semihosting, "\t ->: 0x%x, %i\n",
            ret_errno.first, ret_errno.second);
    return ret_errno.first;
}

uint32_t
ArmSemihosting::call32(ThreadContext *tc, uint32_t op, uint32_t param)
{
    const SemiCall *call = getCall(op, false);
    if (!call) {
        warn("Unknown aarch32 semihosting call: op = 0x%x, param = 0x%x",
             op, param);

        return (uint32_t)-1;
    } else if (!call->implemented32()) {
        warn("Unimplemented aarch32 semihosting call: "
             "%s (op = 0x%x, param = 0x%x)",
             call->name, op, param);

        return (uint32_t)-1;
    }

    std::vector<uint64_t> argv(call->argc32 + 1);
    PortProxy &proxy = physProxy(tc);
    ByteOrder endian = ArmISA::byteOrder(tc);

    DPRINTF(Semihosting, "Semihosting call32: %s(0x%x)\n", call->name, param);
    argv[0] = param;
    for (int i = 0; i < call->argc32; ++i) {
        argv[i + 1] = proxy.read<uint32_t>(param + i * 4, endian);
        DPRINTF(Semihosting, "\t: 0x%x\n", argv[i + 1]);
    }

    auto ret_errno = (this->*call->call)(tc, false, argv);
    semiErrno = ret_errno.second;
    DPRINTF(Semihosting, "\t ->: 0x%x, %i\n",
            ret_errno.first, ret_errno.second);
    return ret_errno.first;
}

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::physProxy(ThreadContext *tc)
{
    if (ArmISA::inSecureState(tc)) {
        if (!physProxyS) {
            System *sys = tc->getSystemPtr();
            physProxyS.reset(new SecurePortProxy(
                                 sys->getSystemPort(),
                                 sys->cacheLineSize()));
        }
        return *physProxyS;
    } else {
        return tc->getPhysProxy();
    }
}


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

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

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

ArmSemihosting::RetErrno
ArmSemihosting::callOpen(ThreadContext *tc, bool aarch64,
                         std::vector<uint64_t> &argv)
{
    const Addr name_base = argv[1];
    const char *mode = argv[2] < fmodes.size() ? fmodes[argv[2]] : nullptr;
    const Addr name_size = argv[3];

    DPRINTF(Semihosting, "Semihosting SYS_OPEN(0x%x, %i[%s], %i)\n",
            name_base, argv[2], 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, argv[2], 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, bool aarch64,
                          std::vector<uint64_t> &argv)
{
    if (argv[1] > files.size()) {
        DPRINTF(Semihosting, "Semihosting SYS_CLOSE(%i): Illegal file\n");
        return retError(EBADF);
    }

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

ArmSemihosting::RetErrno
ArmSemihosting::callWriteC(ThreadContext *tc, bool aarch64,
                           std::vector<uint64_t> &argv)
{
    const char c = physProxy(tc).read<char>(argv[0]);

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

    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callWrite0(ThreadContext *tc, bool aarch64,
                           std::vector<uint64_t> &argv)
{
    DPRINTF(Semihosting, "Semihosting SYS_WRITE0(...)\n");
    PortProxy &proxy = physProxy(tc);
    for (Addr addr = (Addr)argv[0]; ; ++addr) {
        char data = proxy.read<char>(addr);
        if (data == 0)
            break;

        std::cout.put(data);
    }

    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callWrite(ThreadContext *tc, bool aarch64,
                          std::vector<uint64_t> &argv)
{
    if (argv[1] > files.size() || !files[argv[1]])
        return RetErrno(argv[3], EBADF);

    std::vector<uint8_t> buffer(argv[3]);
    physProxy(tc).readBlob(argv[2], buffer.data(), buffer.size());

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

ArmSemihosting::RetErrno
ArmSemihosting::callRead(ThreadContext *tc, bool aarch64,
                         std::vector<uint64_t> &argv)
{
    if (argv[1] > files.size() || !files[argv[1]])
        return RetErrno(argv[3], EBADF);

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

        physProxy(tc).writeBlob(argv[2], buffer.data(), ret);

        // Return the number of bytes not written
        return retOK(argv[3] - ret);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callReadC(ThreadContext *tc, bool aarch64,
                           std::vector<uint64_t> &argv)
{
    return retOK((char)std::cin.get());
}

ArmSemihosting::RetErrno
ArmSemihosting::callIsError(ThreadContext *tc, bool aarch64,
                            std::vector<uint64_t> &argv)
{
    // Sign extend from a 32 bit integer in aarch32 since the argument
    // reader zero extends to a uint64_t.
    const int64_t status = (int64_t)(aarch64 ? argv[1] :sext<32>(argv[1]));
    // Assume there was an error if the status value is negative.
    return retOK(status < 0 ? 1 : 0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callIsTTY(ThreadContext *tc, bool aarch64,
                          std::vector<uint64_t> &argv)
{
    if (argv[1] > files.size() || !files[argv[1]])
        return retError(EBADF);

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

ArmSemihosting::RetErrno
ArmSemihosting::callSeek(ThreadContext *tc, bool aarch64,
                          std::vector<uint64_t> &argv)
{
    if (argv[1] > files.size() || !files[argv[1]])
        return retError(EBADF);

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

ArmSemihosting::RetErrno
ArmSemihosting::callFLen(ThreadContext *tc, bool aarch64,
                          std::vector<uint64_t> &argv)
{
    if (argv[1] > files.size() || !files[argv[1]])
        return retError(EBADF);

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

ArmSemihosting::RetErrno
ArmSemihosting::callTmpNam(ThreadContext *tc, bool aarch64,
                           std::vector<uint64_t> &argv)
{
    const Addr guest_buf = argv[1];
    //const uint64_t id = argv[2];
    const uint64_t max_len = argv[3];

    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 >= max_len)
        return retError(ENOSPC);

    physProxy(tc).writeBlob(guest_buf, path, path_len + 1);
    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callRemove(ThreadContext *tc, bool aarch64,
                           std::vector<uint64_t> &argv)
{
    std::string fname = readString(tc, argv[1], argv[2]);

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

ArmSemihosting::RetErrno
ArmSemihosting::callRename(ThreadContext *tc, bool aarch64,
                           std::vector<uint64_t> &argv)
{
    std::string from = readString(tc, argv[1], argv[2]);
    std::string to = readString(tc, argv[3], argv[4]);

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

ArmSemihosting::RetErrno
ArmSemihosting::callClock(ThreadContext *tc, bool aarch64,
                          std::vector<uint64_t> &argv)
{
    return retOK(curTick() / (SimClock::Int::s / 100));
}

ArmSemihosting::RetErrno
ArmSemihosting::callTime(ThreadContext *tc, bool aarch64,
                         std::vector<uint64_t> &argv)
{
    return retOK(timeBase + round(curTick() / SimClock::Float::s));
}

ArmSemihosting::RetErrno
ArmSemihosting::callSystem(ThreadContext *tc, bool aarch64,
                         std::vector<uint64_t> &argv)
{
    const std::string cmd = readString(tc, argv[1], argv[2]);
    warn("Semihosting: SYS_SYSTEM not implemented. Guest tried to run: %s\n",
         cmd);
    return retError(EINVAL);

}

ArmSemihosting::RetErrno
ArmSemihosting::callErrno(ThreadContext *tc, bool aarch64,
                          std::vector<uint64_t> &argv)
{
    // Preserve errno by returning it in errno as well.
    return RetErrno(semiErrno, semiErrno);
}

ArmSemihosting::RetErrno
ArmSemihosting::callGetCmdLine(ThreadContext *tc, bool aarch64,
                               std::vector<uint64_t> &argv)
{
    if (cmdLine.size() + 1 < argv[2]) {
        PortProxy &proxy = physProxy(tc);
        ByteOrder endian = ArmISA::byteOrder(tc);
        proxy.writeBlob((Addr)argv[1], cmdLine.c_str(), cmdLine.size() + 1);

        if (aarch64)
            proxy.write<uint64_t>(argv[0] + 1 * 8, cmdLine.size(), endian);
        else
            proxy.write<uint32_t>(argv[0] + 1 * 4, cmdLine.size(), endian);
        return retOK(0);
    } else {
        return retError(0);
    }
}

ArmSemihosting::RetErrno
ArmSemihosting::callHeapInfo(ThreadContext *tc, bool aarch64,
                             std::vector<uint64_t> &argv)
{
    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.");

    const Addr heap_base = mem_start;
    const Addr heap_limit = mem_end - stackSize + 1;
    const Addr stack_base = (mem_end + 1) & ~0x7ULL; // 8 byte stack alignment
    const Addr 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);

    Addr base = argv[1];
    PortProxy &proxy = physProxy(tc);
    ByteOrder endian = ArmISA::byteOrder(tc);
    if (aarch64) {
        proxy.write<uint64_t>(base + 0 * 8, heap_base, endian);
        proxy.write<uint64_t>(base + 1 * 8, heap_limit, endian);
        proxy.write<uint64_t>(base + 2 * 8, stack_base, endian);
        proxy.write<uint64_t>(base + 3 * 8, stack_limit, endian);
    } else {
        proxy.write<uint32_t>(base + 0 * 4, heap_base, endian);
        proxy.write<uint32_t>(base + 1 * 4, heap_limit, endian);
        proxy.write<uint32_t>(base + 2 * 4, stack_base, endian);
        proxy.write<uint32_t>(base + 3 * 4, stack_limit, endian);
    }

    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callExit(ThreadContext *tc, bool aarch64,
                         std::vector<uint64_t> &argv)
{
    if (aarch64) {
        semiExit(argv[1], argv[2]);
    } else {
        semiExit(argv[0], 0);
    }

    return retOK(0);
}

ArmSemihosting::RetErrno
ArmSemihosting::callExitExtended(ThreadContext *tc, bool aarch64,
                                 std::vector<uint64_t> &argv)
{
    semiExit(argv[1], argv[2]);

    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::callElapsed(ThreadContext *tc, bool aarch64,
                            std::vector<uint64_t> &argv)
{
    PortProxy &proxy = physProxy(tc);
    ByteOrder endian = ArmISA::byteOrder(tc);
    const uint64_t tick = semiTick(curTick());

    if (aarch64) {
        proxy.write<uint64_t>(argv[0], tick, endian);
    } else {
        proxy.write<uint32_t>(argv[0] + 0 * 4, tick, endian);
        proxy.write<uint32_t>(argv[0] + 1 * 4, tick >> 32, endian);
    }

    return retOK(0);
}


ArmSemihosting::RetErrno
ArmSemihosting::callTickFreq(ThreadContext *tc, bool aarch64,
                             std::vector<uint64_t> &argv)
{
    return retOK(semiTick(SimClock::Frequency));
}

const ArmSemihosting::SemiCall *
ArmSemihosting::getCall(uint32_t op, bool aarch64)
{
    auto it = calls.find(op);
    if (it == calls.end())
        return nullptr;
    else {
        return &it->second;
    }
}

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);
        }
    }
}


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