/*
 *  Lattice Mico32 semihosting syscall interface
 *
 *  Copyright (c) 2014 Michael Walle <michael@walle.cc>
 *
 * Based on target/m68k/m68k-semi.c, which is
 *  Copyright (c) 2005-2007 CodeSourcery.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

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

enum {
    TARGET_SYS_exit    = 1,
    TARGET_SYS_open    = 2,
    TARGET_SYS_close   = 3,
    TARGET_SYS_read    = 4,
    TARGET_SYS_write   = 5,
    TARGET_SYS_lseek   = 6,
    TARGET_SYS_fstat   = 10,
    TARGET_SYS_stat    = 15,
};

enum {
    NEWLIB_O_RDONLY    =   0x0,
    NEWLIB_O_WRONLY    =   0x1,
    NEWLIB_O_RDWR      =   0x2,
    NEWLIB_O_APPEND    =   0x8,
    NEWLIB_O_CREAT     = 0x200,
    NEWLIB_O_TRUNC     = 0x400,
    NEWLIB_O_EXCL      = 0x800,
};

static int translate_openflags(int flags)
{
    int hf;

    if (flags & NEWLIB_O_WRONLY) {
        hf = O_WRONLY;
    } else if (flags & NEWLIB_O_RDWR) {
        hf = O_RDWR;
    } else {
        hf = O_RDONLY;
    }

    if (flags & NEWLIB_O_APPEND) {
        hf |= O_APPEND;
    }

    if (flags & NEWLIB_O_CREAT) {
        hf |= O_CREAT;
    }

    if (flags & NEWLIB_O_TRUNC) {
        hf |= O_TRUNC;
    }

    if (flags & NEWLIB_O_EXCL) {
        hf |= O_EXCL;
    }

    return hf;
}

struct newlib_stat {
    int16_t     newlib_st_dev;     /* device */
    uint16_t    newlib_st_ino;     /* inode */
    uint16_t    newlib_st_mode;    /* protection */
    uint16_t    newlib_st_nlink;   /* number of hard links */
    uint16_t    newlib_st_uid;     /* user ID of owner */
    uint16_t    newlib_st_gid;     /* group ID of owner */
    int16_t     newlib_st_rdev;    /* device type (if inode device) */
    int32_t     newlib_st_size;    /* total size, in bytes */
    int32_t     newlib_st_atime;   /* time of last access */
    uint32_t    newlib_st_spare1;
    int32_t     newlib_st_mtime;   /* time of last modification */
    uint32_t    newlib_st_spare2;
    int32_t     newlib_st_ctime;   /* time of last change */
    uint32_t    newlib_st_spare3;
} QEMU_PACKED;

static int translate_stat(CPULM32State *env, target_ulong addr,
        struct stat *s)
{
    struct newlib_stat *p;

    p = lock_user(VERIFY_WRITE, addr, sizeof(struct newlib_stat), 0);
    if (!p) {
        return 0;
    }
    p->newlib_st_dev = cpu_to_be16(s->st_dev);
    p->newlib_st_ino = cpu_to_be16(s->st_ino);
    p->newlib_st_mode = cpu_to_be16(s->st_mode);
    p->newlib_st_nlink = cpu_to_be16(s->st_nlink);
    p->newlib_st_uid = cpu_to_be16(s->st_uid);
    p->newlib_st_gid = cpu_to_be16(s->st_gid);
    p->newlib_st_rdev = cpu_to_be16(s->st_rdev);
    p->newlib_st_size = cpu_to_be32(s->st_size);
    p->newlib_st_atime = cpu_to_be32(s->st_atime);
    p->newlib_st_mtime = cpu_to_be32(s->st_mtime);
    p->newlib_st_ctime = cpu_to_be32(s->st_ctime);
    unlock_user(p, addr, sizeof(struct newlib_stat));

    return 1;
}

bool lm32_cpu_do_semihosting(CPUState *cs)
{
    LM32CPU *cpu = LM32_CPU(cs);
    CPULM32State *env = &cpu->env;

    int ret = -1;
    target_ulong nr, arg0, arg1, arg2;
    void *p;
    struct stat s;

    nr = env->regs[R_R8];
    arg0 = env->regs[R_R1];
    arg1 = env->regs[R_R2];
    arg2 = env->regs[R_R3];

    switch (nr) {
    case TARGET_SYS_exit:
        /* void _exit(int rc) */
        exit(arg0);

    case TARGET_SYS_open:
        /* int open(const char *pathname, int flags) */
        p = lock_user_string(arg0);
        if (!p) {
            ret = -1;
        } else {
            ret = open(p, translate_openflags(arg2));
            unlock_user(p, arg0, 0);
        }
        break;

    case TARGET_SYS_read:
        /* ssize_t read(int fd, const void *buf, size_t count) */
        p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
        if (!p) {
            ret = -1;
        } else {
            ret = read(arg0, p, arg2);
            unlock_user(p, arg1, arg2);
        }
        break;

    case TARGET_SYS_write:
        /* ssize_t write(int fd, const void *buf, size_t count) */
        p = lock_user(VERIFY_READ, arg1, arg2, 1);
        if (!p) {
            ret = -1;
        } else {
            ret = write(arg0, p, arg2);
            unlock_user(p, arg1, 0);
        }
        break;

    case TARGET_SYS_close:
        /* int close(int fd) */
        /* don't close stdin/stdout/stderr */
        if (arg0 > 2) {
            ret = close(arg0);
        } else {
            ret = 0;
        }
        break;

    case TARGET_SYS_lseek:
        /* off_t lseek(int fd, off_t offset, int whence */
        ret = lseek(arg0, arg1, arg2);
        break;

    case TARGET_SYS_stat:
        /* int stat(const char *path, struct stat *buf) */
        p = lock_user_string(arg0);
        if (!p) {
            ret = -1;
        } else {
            ret = stat(p, &s);
            unlock_user(p, arg0, 0);
            if (translate_stat(env, arg1, &s) == 0) {
                ret = -1;
            }
        }
        break;

    case TARGET_SYS_fstat:
        /* int stat(int fd, struct stat *buf) */
        ret = fstat(arg0, &s);
        if (ret == 0) {
            if (translate_stat(env, arg1, &s) == 0) {
                ret = -1;
            }
        }
        break;

    default:
        /* unhandled */
        return false;
    }

    env->regs[R_R1] = ret;
    return true;
}
