/*
 *  m68k simulator syscall interface
 *
 *  Copyright (c) 2005 CodeSourcery, LLC. Written by Paul Brook.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#include "qemu.h"

#define SYS_EXIT        1
#define SYS_READ        3
#define SYS_WRITE       4
#define SYS_OPEN        5
#define SYS_CLOSE       6
#define SYS_BRK         17
#define SYS_FSTAT       28
#define SYS_ISATTY      29
#define SYS_LSEEK       199

struct m68k_sim_stat {
    uint16_t sim_st_dev;
    uint16_t sim_st_ino;
    uint32_t sim_st_mode;
    uint16_t sim_st_nlink;
    uint16_t sim_st_uid;
    uint16_t sim_st_gid;
    uint16_t sim_st_rdev;
    uint32_t sim_st_size;
    uint32_t sim_st_atime;
    uint32_t sim_st_mtime;
    uint32_t sim_st_ctime;
    uint32_t sim_st_blksize;
    uint32_t sim_st_blocks;
};

static inline uint32_t check_err(CPUM68KState *env, uint32_t code)
{
  env->dregs[0] = code;
  if (code == (uint32_t)-1) {
      env->dregs[1] = errno;
  } else {
      env->dregs[1] = 0;
  }
  return code;
}

#define SIM_O_APPEND    0x0008
#define SIM_O_CREAT     0x0200
#define SIM_O_TRUNC     0x0400
#define SIM_O_EXCL      0x0800
#define SIM_O_NONBLOCK  0x4000
#define SIM_O_NOCTTY    0x8000
#define SIM_O_SYNC      0x2000

static int translate_openflags(int flags)
{
    int hf;

    switch (flags & 3) {
    case 0: hf = O_RDONLY; break;
    case 1: hf = O_WRONLY; break;
    case 2: hf = O_RDWR; break;
    default: hf = O_RDWR; break;
    }

    if (flags & SIM_O_APPEND) hf |= O_APPEND;
    if (flags & SIM_O_CREAT) hf |= O_CREAT;
    if (flags & SIM_O_TRUNC) hf |= O_TRUNC;
    if (flags & SIM_O_EXCL) hf |= O_EXCL;
    if (flags & SIM_O_NONBLOCK) hf |= O_NONBLOCK;
    if (flags & SIM_O_NOCTTY) hf |= O_NOCTTY;
    if (flags & SIM_O_SYNC) hf |= O_SYNC;

    return hf;
}

#define ARG(x) tswap32(args[x])
void do_m68k_simcall(CPUM68KState *env, int nr)
{
    M68kCPU *cpu = m68k_env_get_cpu(env);
    uint32_t *args;

    args = (uint32_t *)(unsigned long)(env->aregs[7] + 4);
    switch (nr) {
    case SYS_EXIT:
        exit(ARG(0));
    case SYS_READ:
        check_err(env, read(ARG(0), (void *)(unsigned long)ARG(1), ARG(2)));
        break;
    case SYS_WRITE:
        check_err(env, write(ARG(0), (void *)(unsigned long)ARG(1), ARG(2)));
        break;
    case SYS_OPEN:
        check_err(env, open((char *)(unsigned long)ARG(0),
                            translate_openflags(ARG(1)), ARG(2)));
        break;
    case SYS_CLOSE:
        {
            /* Ignore attempts to close stdin/out/err.  */
            int fd = ARG(0);
            if (fd > 2)
              check_err(env, close(fd));
            else
              check_err(env, 0);
            break;
        }
    case SYS_BRK:
        {
            int32_t ret;

            ret = do_brk((abi_ulong)ARG(0));
            if (ret == -ENOMEM)
                ret = -1;
            check_err(env, ret);
        }
        break;
    case SYS_FSTAT:
        {
            struct stat s;
            int rc;
            struct m68k_sim_stat *p;
            rc = check_err(env, fstat(ARG(0), &s));
            if (rc == 0) {
                p = (struct m68k_sim_stat *)(unsigned long)ARG(1);
                p->sim_st_dev = tswap16(s.st_dev);
                p->sim_st_ino = tswap16(s.st_ino);
                p->sim_st_mode = tswap32(s.st_mode);
                p->sim_st_nlink = tswap16(s.st_nlink);
                p->sim_st_uid = tswap16(s.st_uid);
                p->sim_st_gid = tswap16(s.st_gid);
                p->sim_st_rdev = tswap16(s.st_rdev);
                p->sim_st_size = tswap32(s.st_size);
                p->sim_st_atime = tswap32(s.st_atime);
                p->sim_st_mtime = tswap32(s.st_mtime);
                p->sim_st_ctime = tswap32(s.st_ctime);
                p->sim_st_blksize = tswap32(s.st_blksize);
                p->sim_st_blocks = tswap32(s.st_blocks);
            }
        }
        break;
    case SYS_ISATTY:
        check_err(env, isatty(ARG(0)));
        break;
    case SYS_LSEEK:
        check_err(env, lseek(ARG(0), (int32_t)ARG(1), ARG(2)));
        break;
    default:
        cpu_abort(CPU(cpu), "Unsupported m68k sim syscall %d\n", nr);
    }
}
