2 * Lattice Mico32 semihosting syscall interface
6 * Based on target/m68k/m68k-semi.c, which is
7 * Copyright (c) 2005-2007 CodeSourcery.
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
15 #include "exec/helper-proto.h"
17 #include "exec/softmmu-semi.h"
26 TARGET_SYS_fstat = 10,
31 NEWLIB_O_RDONLY = 0x0,
32 NEWLIB_O_WRONLY = 0x1,
34 NEWLIB_O_APPEND = 0x8,
35 NEWLIB_O_CREAT = 0x200,
36 NEWLIB_O_TRUNC = 0x400,
37 NEWLIB_O_EXCL = 0x800,
40 static int translate_openflags(int flags)
44 if (flags & NEWLIB_O_WRONLY) {
46 } else if (flags & NEWLIB_O_RDWR) {
52 if (flags & NEWLIB_O_APPEND) {
56 if (flags & NEWLIB_O_CREAT) {
60 if (flags & NEWLIB_O_TRUNC) {
64 if (flags & NEWLIB_O_EXCL) {
72 int16_t newlib_st_dev; /* device */
73 uint16_t newlib_st_ino; /* inode */
74 uint16_t newlib_st_mode; /* protection */
75 uint16_t newlib_st_nlink; /* number of hard links */
76 uint16_t newlib_st_uid; /* user ID of owner */
77 uint16_t newlib_st_gid; /* group ID of owner */
78 int16_t newlib_st_rdev; /* device type (if inode device) */
79 int32_t newlib_st_size; /* total size, in bytes */
80 int32_t newlib_st_atime; /* time of last access */
81 uint32_t newlib_st_spare1;
82 int32_t newlib_st_mtime; /* time of last modification */
83 uint32_t newlib_st_spare2;
84 int32_t newlib_st_ctime; /* time of last change */
85 uint32_t newlib_st_spare3;
88 static int translate_stat(CPULM32State *env, target_ulong addr,
91 struct newlib_stat *p;
93 p = lock_user(VERIFY_WRITE, addr, sizeof(struct newlib_stat), 0);
97 p->newlib_st_dev = cpu_to_be16(s->st_dev);
98 p->newlib_st_ino = cpu_to_be16(s->st_ino);
99 p->newlib_st_mode = cpu_to_be16(s->st_mode);
100 p->newlib_st_nlink = cpu_to_be16(s->st_nlink);
101 p->newlib_st_uid = cpu_to_be16(s->st_uid);
102 p->newlib_st_gid = cpu_to_be16(s->st_gid);
103 p->newlib_st_rdev = cpu_to_be16(s->st_rdev);
104 p->newlib_st_size = cpu_to_be32(s->st_size);
105 p->newlib_st_atime = cpu_to_be32(s->st_atime);
106 p->newlib_st_mtime = cpu_to_be32(s->st_mtime);
107 p->newlib_st_ctime = cpu_to_be32(s->st_ctime);
108 unlock_user(p, addr, sizeof(struct newlib_stat));
113 bool lm32_cpu_do_semihosting(CPUState *cs)
115 LM32CPU *cpu = LM32_CPU(cs);
116 CPULM32State *env = &cpu->env;
119 target_ulong nr, arg0, arg1, arg2;
123 nr = env->regs[R_R8];
124 arg0 = env->regs[R_R1];
125 arg1 = env->regs[R_R2];
126 arg2 = env->regs[R_R3];
129 case TARGET_SYS_exit:
130 /* void _exit(int rc) */
133 case TARGET_SYS_open:
134 /* int open(const char *pathname, int flags) */
135 p = lock_user_string(arg0);
139 ret = open(p, translate_openflags(arg2));
140 unlock_user(p, arg0, 0);
144 case TARGET_SYS_read:
145 /* ssize_t read(int fd, const void *buf, size_t count) */
146 p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
150 ret = read(arg0, p, arg2);
151 unlock_user(p, arg1, arg2);
155 case TARGET_SYS_write:
156 /* ssize_t write(int fd, const void *buf, size_t count) */
157 p = lock_user(VERIFY_READ, arg1, arg2, 1);
161 ret = write(arg0, p, arg2);
162 unlock_user(p, arg1, 0);
166 case TARGET_SYS_close:
167 /* int close(int fd) */
168 /* don't close stdin/stdout/stderr */
176 case TARGET_SYS_lseek:
177 /* off_t lseek(int fd, off_t offset, int whence */
178 ret = lseek(arg0, arg1, arg2);
181 case TARGET_SYS_stat:
182 /* int stat(const char *path, struct stat *buf) */
183 p = lock_user_string(arg0);
188 unlock_user(p, arg0, 0);
189 if (translate_stat(env, arg1, &s) == 0) {
195 case TARGET_SYS_fstat:
196 /* int stat(int fd, struct stat *buf) */
197 ret = fstat(arg0, &s);
199 if (translate_stat(env, arg1, &s) == 0) {
210 env->regs[R_R1] = ret;