|
|
1.1 ! root 1: /* ! 2: * m68k simulator syscall interface ! 3: * ! 4: * Copyright (c) 2005 CodeSourcery, LLC. Written by Paul Brook. ! 5: * ! 6: * This program is free software; you can redistribute it and/or modify ! 7: * it under the terms of the GNU General Public License as published by ! 8: * the Free Software Foundation; either version 2 of the License, or ! 9: * (at your option) any later version. ! 10: * ! 11: * This program is distributed in the hope that it will be useful, ! 12: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: * GNU General Public License for more details. ! 15: * ! 16: * You should have received a copy of the GNU General Public License ! 17: * along with this program; if not, write to the Free Software ! 18: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 19: */ ! 20: ! 21: #include <sys/types.h> ! 22: #include <sys/stat.h> ! 23: #include <errno.h> ! 24: #include <fcntl.h> ! 25: #include <unistd.h> ! 26: #include <stdlib.h> ! 27: #include <stdio.h> ! 28: #include <time.h> ! 29: ! 30: #include "qemu.h" ! 31: ! 32: #define SYS_EXIT 1 ! 33: #define SYS_READ 3 ! 34: #define SYS_WRITE 4 ! 35: #define SYS_OPEN 5 ! 36: #define SYS_CLOSE 6 ! 37: #define SYS_BRK 17 ! 38: #define SYS_FSTAT 28 ! 39: #define SYS_ISATTY 29 ! 40: #define SYS_LSEEK 199 ! 41: ! 42: struct m86k_sim_stat { ! 43: uint16_t sim_st_dev; ! 44: uint16_t sim_st_ino; ! 45: uint32_t sim_st_mode; ! 46: uint16_t sim_st_nlink; ! 47: uint16_t sim_st_uid; ! 48: uint16_t sim_st_gid; ! 49: uint16_t sim_st_rdev; ! 50: uint32_t sim_st_size; ! 51: uint32_t sim_st_atime; ! 52: uint32_t sim_st_mtime; ! 53: uint32_t sim_st_ctime; ! 54: uint32_t sim_st_blksize; ! 55: uint32_t sim_st_blocks; ! 56: }; ! 57: ! 58: static inline uint32_t check_err(CPUM68KState *env, uint32_t code) ! 59: { ! 60: env->dregs[0] = code; ! 61: if (code == (uint32_t)-1) { ! 62: env->dregs[1] = errno; ! 63: } else { ! 64: env->dregs[1] = 0; ! 65: } ! 66: return code; ! 67: } ! 68: ! 69: #define SIM_O_APPEND 0x0008 ! 70: #define SIM_O_CREAT 0x0200 ! 71: #define SIM_O_TRUNC 0x0400 ! 72: #define SIM_O_EXCL 0x0800 ! 73: #define SIM_O_NONBLOCK 0x4000 ! 74: #define SIM_O_NOCTTY 0x8000 ! 75: #define SIM_O_SYNC 0x2000 ! 76: ! 77: static int translate_openflags(int flags) ! 78: { ! 79: int hf; ! 80: ! 81: switch (flags & 3) { ! 82: case 0: hf = O_RDONLY; break; ! 83: case 1: hf = O_WRONLY; break; ! 84: case 2: hf = O_RDWR; break; ! 85: default: hf = O_RDWR; break; ! 86: } ! 87: ! 88: if (flags & SIM_O_APPEND) hf |= O_APPEND; ! 89: if (flags & SIM_O_CREAT) hf |= O_CREAT; ! 90: if (flags & SIM_O_TRUNC) hf |= O_TRUNC; ! 91: if (flags & SIM_O_EXCL) hf |= O_EXCL; ! 92: if (flags & SIM_O_NONBLOCK) hf |= O_NONBLOCK; ! 93: if (flags & SIM_O_NOCTTY) hf |= O_NOCTTY; ! 94: if (flags & SIM_O_SYNC) hf |= O_SYNC; ! 95: ! 96: return hf; ! 97: } ! 98: ! 99: #define ARG(x) tswap32(args[x]) ! 100: void do_m68k_simcall(CPUM68KState *env, int nr) ! 101: { ! 102: uint32_t *args; ! 103: ! 104: args = (uint32_t *)(env->aregs[7] + 4); ! 105: switch (nr) { ! 106: case SYS_EXIT: ! 107: exit(ARG(0)); ! 108: case SYS_READ: ! 109: check_err(env, read(ARG(0), (void *)ARG(1), ARG(2))); ! 110: break; ! 111: case SYS_WRITE: ! 112: check_err(env, write(ARG(0), (void *)ARG(1), ARG(2))); ! 113: break; ! 114: case SYS_OPEN: ! 115: check_err(env, open((char *)ARG(0), translate_openflags(ARG(1)), ! 116: ARG(2))); ! 117: break; ! 118: case SYS_CLOSE: ! 119: { ! 120: /* Ignore attempts to close stdin/out/err. */ ! 121: int fd = ARG(0); ! 122: if (fd > 2) ! 123: check_err(env, close(fd)); ! 124: else ! 125: check_err(env, 0); ! 126: break; ! 127: } ! 128: case SYS_BRK: ! 129: { ! 130: int32_t ret; ! 131: ! 132: ret = do_brk((void *)ARG(0)); ! 133: if (ret == -ENOMEM) ! 134: ret = -1; ! 135: check_err(env, ret); ! 136: } ! 137: break; ! 138: case SYS_FSTAT: ! 139: { ! 140: struct stat s; ! 141: int rc; ! 142: struct m86k_sim_stat *p; ! 143: rc = check_err(env, fstat(ARG(0), &s)); ! 144: if (rc == 0) { ! 145: p = (struct m86k_sim_stat *)ARG(1); ! 146: p->sim_st_dev = tswap16(s.st_dev); ! 147: p->sim_st_ino = tswap16(s.st_ino); ! 148: p->sim_st_mode = tswap32(s.st_mode); ! 149: p->sim_st_nlink = tswap16(s.st_nlink); ! 150: p->sim_st_uid = tswap16(s.st_uid); ! 151: p->sim_st_gid = tswap16(s.st_gid); ! 152: p->sim_st_rdev = tswap16(s.st_rdev); ! 153: p->sim_st_size = tswap32(s.st_size); ! 154: p->sim_st_atime = tswap32(s.st_atime); ! 155: p->sim_st_mtime = tswap32(s.st_mtime); ! 156: p->sim_st_ctime = tswap32(s.st_ctime); ! 157: p->sim_st_blksize = tswap32(s.st_blksize); ! 158: p->sim_st_blocks = tswap32(s.st_blocks); ! 159: } ! 160: } ! 161: break; ! 162: case SYS_ISATTY: ! 163: check_err(env, isatty(ARG(0))); ! 164: break; ! 165: case SYS_LSEEK: ! 166: check_err(env, lseek(ARG(0), (int32_t)ARG(1), ARG(2))); ! 167: break; ! 168: default: ! 169: cpu_abort(env, "Unsupported m68k sim syscall %d\n", nr); ! 170: } ! 171: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.