/*
 *  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 <errno.h>
#include <unistd.h>
#include <string.h>
#include <stddef.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;
}
