/*
 * Unified Hosting Interface syscalls.
 *
 * Copyright (c) 2015 Imagination Technologies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/helper-proto.h"
#include "exec/softmmu-semi.h"
#include "exec/semihost.h"

typedef enum UHIOp {
    UHI_exit = 1,
    UHI_open = 2,
    UHI_close = 3,
    UHI_read = 4,
    UHI_write = 5,
    UHI_lseek = 6,
    UHI_unlink = 7,
    UHI_fstat = 8,
    UHI_argc = 9,
    UHI_argnlen = 10,
    UHI_argn = 11,
    UHI_plog = 13,
    UHI_assert = 14,
    UHI_pread = 19,
    UHI_pwrite = 20,
    UHI_link = 22
} UHIOp;

typedef struct UHIStat {
    int16_t uhi_st_dev;
    uint16_t uhi_st_ino;
    uint32_t uhi_st_mode;
    uint16_t uhi_st_nlink;
    uint16_t uhi_st_uid;
    uint16_t uhi_st_gid;
    int16_t uhi_st_rdev;
    uint64_t uhi_st_size;
    uint64_t uhi_st_atime;
    uint64_t uhi_st_spare1;
    uint64_t uhi_st_mtime;
    uint64_t uhi_st_spare2;
    uint64_t uhi_st_ctime;
    uint64_t uhi_st_spare3;
    uint64_t uhi_st_blksize;
    uint64_t uhi_st_blocks;
    uint64_t uhi_st_spare4[2];
} UHIStat;

enum UHIOpenFlags {
    UHIOpen_RDONLY = 0x0,
    UHIOpen_WRONLY = 0x1,
    UHIOpen_RDWR   = 0x2,
    UHIOpen_APPEND = 0x8,
    UHIOpen_CREAT  = 0x200,
    UHIOpen_TRUNC  = 0x400,
    UHIOpen_EXCL   = 0x800
};

/* Errno values taken from asm-mips/errno.h */
static uint16_t host_to_mips_errno[] = {
    [ENAMETOOLONG] = 78,
#ifdef EOVERFLOW
    [EOVERFLOW]    = 79,
#endif
#ifdef ELOOP
    [ELOOP]        = 90,
#endif
};

static int errno_mips(int err)
{
    if (err < 0 || err >= ARRAY_SIZE(host_to_mips_errno)) {
        return EINVAL;
    } else if (host_to_mips_errno[err]) {
        return host_to_mips_errno[err];
    } else {
        return err;
    }
}

static int copy_stat_to_target(CPUMIPSState *env, const struct stat *src,
                               target_ulong vaddr)
{
    hwaddr len = sizeof(struct UHIStat);
    UHIStat *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
    if (!dst) {
        errno = EFAULT;
        return -1;
    }

    dst->uhi_st_dev = tswap16(src->st_dev);
    dst->uhi_st_ino = tswap16(src->st_ino);
    dst->uhi_st_mode = tswap32(src->st_mode);
    dst->uhi_st_nlink = tswap16(src->st_nlink);
    dst->uhi_st_uid = tswap16(src->st_uid);
    dst->uhi_st_gid = tswap16(src->st_gid);
    dst->uhi_st_rdev = tswap16(src->st_rdev);
    dst->uhi_st_size = tswap64(src->st_size);
    dst->uhi_st_atime = tswap64(src->st_atime);
    dst->uhi_st_mtime = tswap64(src->st_mtime);
    dst->uhi_st_ctime = tswap64(src->st_ctime);
#ifdef _WIN32
    dst->uhi_st_blksize = 0;
    dst->uhi_st_blocks = 0;
#else
    dst->uhi_st_blksize = tswap64(src->st_blksize);
    dst->uhi_st_blocks = tswap64(src->st_blocks);
#endif
    unlock_user(dst, vaddr, len);
    return 0;
}

static int get_open_flags(target_ulong target_flags)
{
    int open_flags = 0;

    if (target_flags & UHIOpen_RDWR) {
        open_flags |= O_RDWR;
    } else if (target_flags & UHIOpen_WRONLY) {
        open_flags |= O_WRONLY;
    } else {
        open_flags |= O_RDONLY;
    }

    open_flags |= (target_flags & UHIOpen_APPEND) ? O_APPEND : 0;
    open_flags |= (target_flags & UHIOpen_CREAT)  ? O_CREAT  : 0;
    open_flags |= (target_flags & UHIOpen_TRUNC)  ? O_TRUNC  : 0;
    open_flags |= (target_flags & UHIOpen_EXCL)   ? O_EXCL   : 0;

    return open_flags;
}

static int write_to_file(CPUMIPSState *env, target_ulong fd, target_ulong vaddr,
                         target_ulong len, target_ulong offset)
{
    int num_of_bytes;
    void *dst = lock_user(VERIFY_READ, vaddr, len, 1);
    if (!dst) {
        errno = EFAULT;
        return -1;
    }

    if (offset) {
#ifdef _WIN32
        num_of_bytes = 0;
#else
        num_of_bytes = pwrite(fd, dst, len, offset);
#endif
    } else {
        num_of_bytes = write(fd, dst, len);
    }

    unlock_user(dst, vaddr, 0);
    return num_of_bytes;
}

static int read_from_file(CPUMIPSState *env, target_ulong fd,
                          target_ulong vaddr, target_ulong len,
                          target_ulong offset)
{
    int num_of_bytes;
    void *dst = lock_user(VERIFY_WRITE, vaddr, len, 0);
    if (!dst) {
        errno = EFAULT;
        return -1;
    }

    if (offset) {
#ifdef _WIN32
        num_of_bytes = 0;
#else
        num_of_bytes = pread(fd, dst, len, offset);
#endif
    } else {
        num_of_bytes = read(fd, dst, len);
    }

    unlock_user(dst, vaddr, len);
    return num_of_bytes;
}

static int copy_argn_to_target(CPUMIPSState *env, int arg_num,
                               target_ulong vaddr)
{
    int strsize = strlen(semihosting_get_arg(arg_num)) + 1;
    char *dst = lock_user(VERIFY_WRITE, vaddr, strsize, 0);
    if (!dst) {
        return -1;
    }

    strcpy(dst, semihosting_get_arg(arg_num));

    unlock_user(dst, vaddr, strsize);
    return 0;
}

#define GET_TARGET_STRING(p, addr)              \
    do {                                        \
        p = lock_user_string(addr);             \
        if (!p) {                               \
            gpr[2] = -1;                        \
            gpr[3] = EFAULT;                    \
            goto uhi_done;                      \
        }                                       \
    } while (0)

#define GET_TARGET_STRINGS_2(p, addr, p2, addr2)        \
    do {                                                \
        p = lock_user_string(addr);                     \
        if (!p) {                                       \
            gpr[2] = -1;                                \
            gpr[3] = EFAULT;                            \
            goto uhi_done;                              \
        }                                               \
        p2 = lock_user_string(addr2);                   \
        if (!p2) {                                      \
            unlock_user(p, addr, 0);                    \
            gpr[2] = -1;                                \
            gpr[3] = EFAULT;                            \
            goto uhi_done;                              \
        }                                               \
    } while (0)

#define FREE_TARGET_STRING(p, gpr)              \
    do {                                        \
        unlock_user(p, gpr, 0);                 \
    } while (0)

void helper_do_semihosting(CPUMIPSState *env)
{
    target_ulong *gpr = env->active_tc.gpr;
    const UHIOp op = gpr[25];
    char *p, *p2;

    switch (op) {
    case UHI_exit:
        qemu_log("UHI(%d): exit(%d)\n", op, (int)gpr[4]);
        exit(gpr[4]);
    case UHI_open:
        GET_TARGET_STRING(p, gpr[4]);
        if (!strcmp("/dev/stdin", p)) {
            gpr[2] = 0;
        } else if (!strcmp("/dev/stdout", p)) {
            gpr[2] = 1;
        } else if (!strcmp("/dev/stderr", p)) {
            gpr[2] = 2;
        } else {
            gpr[2] = open(p, get_open_flags(gpr[5]), gpr[6]);
            gpr[3] = errno_mips(errno);
        }
        FREE_TARGET_STRING(p, gpr[4]);
        break;
    case UHI_close:
        if (gpr[4] < 3) {
            /* ignore closing stdin/stdout/stderr */
            gpr[2] = 0;
            goto uhi_done;
        }
        gpr[2] = close(gpr[4]);
        gpr[3] = errno_mips(errno);
        break;
    case UHI_read:
        gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6], 0);
        gpr[3] = errno_mips(errno);
        break;
    case UHI_write:
        gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6], 0);
        gpr[3] = errno_mips(errno);
        break;
    case UHI_lseek:
        gpr[2] = lseek(gpr[4], gpr[5], gpr[6]);
        gpr[3] = errno_mips(errno);
        break;
    case UHI_unlink:
        GET_TARGET_STRING(p, gpr[4]);
        gpr[2] = remove(p);
        gpr[3] = errno_mips(errno);
        FREE_TARGET_STRING(p, gpr[4]);
        break;
    case UHI_fstat:
        {
            struct stat sbuf;
            memset(&sbuf, 0, sizeof(sbuf));
            gpr[2] = fstat(gpr[4], &sbuf);
            gpr[3] = errno_mips(errno);
            if (gpr[2]) {
                goto uhi_done;
            }
            gpr[2] = copy_stat_to_target(env, &sbuf, gpr[5]);
            gpr[3] = errno_mips(errno);
        }
        break;
    case UHI_argc:
        gpr[2] = semihosting_get_argc();
        break;
    case UHI_argnlen:
        if (gpr[4] >= semihosting_get_argc()) {
            gpr[2] = -1;
            goto uhi_done;
        }
        gpr[2] = strlen(semihosting_get_arg(gpr[4]));
        break;
    case UHI_argn:
        if (gpr[4] >= semihosting_get_argc()) {
            gpr[2] = -1;
            goto uhi_done;
        }
        gpr[2] = copy_argn_to_target(env, gpr[4], gpr[5]);
        break;
    case UHI_plog:
        GET_TARGET_STRING(p, gpr[4]);
        p2 = strstr(p, "%d");
        if (p2) {
            int char_num = p2 - p;
            char *buf = g_malloc(char_num + 1);
            strncpy(buf, p, char_num);
            buf[char_num] = '\0';
            gpr[2] = printf("%s%d%s", buf, (int)gpr[5], p2 + 2);
            g_free(buf);
        } else {
            gpr[2] = printf("%s", p);
        }
        FREE_TARGET_STRING(p, gpr[4]);
        break;
    case UHI_assert:
        GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
        printf("assertion '");
        printf("\"%s\"", p);
        printf("': file \"%s\", line %d\n", p2, (int)gpr[6]);
        FREE_TARGET_STRING(p2, gpr[5]);
        FREE_TARGET_STRING(p, gpr[4]);
        abort();
        break;
    case UHI_pread:
        gpr[2] = read_from_file(env, gpr[4], gpr[5], gpr[6], gpr[7]);
        gpr[3] = errno_mips(errno);
        break;
    case UHI_pwrite:
        gpr[2] = write_to_file(env, gpr[4], gpr[5], gpr[6], gpr[7]);
        gpr[3] = errno_mips(errno);
        break;
#ifndef _WIN32
    case UHI_link:
        GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
        gpr[2] = link(p, p2);
        gpr[3] = errno_mips(errno);
        FREE_TARGET_STRING(p2, gpr[5]);
        FREE_TARGET_STRING(p, gpr[4]);
        break;
#endif
    default:
        fprintf(stderr, "Unknown UHI operation %d\n", op);
        abort();
    }
uhi_done:
    return;
}
