/*
 * 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.
 *
 * Authors: Andreas Sandberg
 */

#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{
    { 0x01, { "SYS_OPEN", &ArmSemihosting::callOpen, 3, 3 } },
    { 0x02, { "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.
    { 0x03, { "SYS_WRITEC", &ArmSemihosting::callWriteC, 0, 0 } },
    { 0x04, { "SYS_WRITE0", &ArmSemihosting::callWrite0, 1, 1 } },

    { 0x05, { "SYS_WRITE", &ArmSemihosting::callWrite, 3, 3 } },
    { 0x06, { "SYS_READ", &ArmSemihosting::callRead, 3, 3 } },
    { 0x07, { "SYS_READC", &ArmSemihosting::callReadC, 0, 0 } },
    { 0x08, { "SYS_ISERROR", &ArmSemihosting::callIsError, 1, 1 } },
    { 0x09, { "SYS_ISTTY", &ArmSemihosting::callIsTTY, 1, 1 } },
    { 0x0A, { "SYS_SEEK", &ArmSemihosting::callSeek, 2, 2 } },
    { 0x0C, { "SYS_FLEN", &ArmSemihosting::callFLen, 1, 1 } },
    { 0x0D, { "SYS_TMPNAM", &ArmSemihosting::callTmpNam, 3, 3 } },
    { 0x0E, { "SYS_REMOVE", &ArmSemihosting::callRemove, 2, 2} },
    { 0x0F, { "SYS_RENAME", &ArmSemihosting::callRename, 4, 4} },
    { 0x10, { "SYS_CLOCK", &ArmSemihosting::callClock, 0, 0} },
    { 0x11, { "SYS_TIME", &ArmSemihosting::callTime, 0, 0} },
    { 0x12, { "SYS_SYSTEM", &ArmSemihosting::callSystem, 2, 2} },
    { 0x13, { "SYS_ERRNO", &ArmSemihosting::callErrno, 0, 0 } },
    { 0x15, { "SYS_GET_CMDLINE", &ArmSemihosting::callGetCmdLine, 2, 2} },
    { 0x16, { "SYS_HEAPINFO", &ArmSemihosting::callHeapInfo, 1, 1} },

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

    { 0x30, { "SYS_ELAPSED", &ArmSemihosting::callElapsed, 0, 0 } },
    { 0x31, { "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);
}
