Statistics
| Branch: | Revision:

root / linux-user / arm-semi.c @ 0986ac3b

History | View | Annotate | Download (5.9 kB)

1 a4f81979 bellard
/*
2 a4f81979 bellard
 *  Arm "Angel" semihosting syscalls
3 a4f81979 bellard
 * 
4 a4f81979 bellard
 *  Copyright (c) 2005 CodeSourcery, LLC. Written by Paul Brook.
5 a4f81979 bellard
 *
6 a4f81979 bellard
 *  This program is free software; you can redistribute it and/or modify
7 a4f81979 bellard
 *  it under the terms of the GNU General Public License as published by
8 a4f81979 bellard
 *  the Free Software Foundation; either version 2 of the License, or
9 a4f81979 bellard
 *  (at your option) any later version.
10 a4f81979 bellard
 *
11 a4f81979 bellard
 *  This program is distributed in the hope that it will be useful,
12 a4f81979 bellard
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 a4f81979 bellard
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 a4f81979 bellard
 *  GNU General Public License for more details.
15 a4f81979 bellard
 *
16 a4f81979 bellard
 *  You should have received a copy of the GNU General Public License
17 a4f81979 bellard
 *  along with this program; if not, write to the Free Software
18 a4f81979 bellard
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 a4f81979 bellard
 */
20 a4f81979 bellard
21 a4f81979 bellard
#include <sys/types.h>
22 a4f81979 bellard
#include <sys/stat.h>
23 a4f81979 bellard
#include <fcntl.h>
24 a4f81979 bellard
#include <unistd.h>
25 a4f81979 bellard
#include <stdlib.h>
26 a4f81979 bellard
#include <stdio.h>
27 a4f81979 bellard
#include <time.h>
28 a4f81979 bellard
29 a4f81979 bellard
#include "qemu.h"
30 a4f81979 bellard
31 a4f81979 bellard
#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
32 a4f81979 bellard
33 a4f81979 bellard
#define SYS_OPEN        0x01
34 a4f81979 bellard
#define SYS_CLOSE       0x02
35 a4f81979 bellard
#define SYS_WRITEC      0x03
36 a4f81979 bellard
#define SYS_WRITE0      0x04
37 a4f81979 bellard
#define SYS_WRITE       0x05
38 a4f81979 bellard
#define SYS_READ        0x06
39 a4f81979 bellard
#define SYS_READC       0x07
40 a4f81979 bellard
#define SYS_ISTTY       0x09
41 a4f81979 bellard
#define SYS_SEEK        0x0a
42 a4f81979 bellard
#define SYS_FLEN        0x0c
43 a4f81979 bellard
#define SYS_TMPNAM      0x0d
44 a4f81979 bellard
#define SYS_REMOVE      0x0e
45 a4f81979 bellard
#define SYS_RENAME      0x0f
46 a4f81979 bellard
#define SYS_CLOCK       0x10
47 a4f81979 bellard
#define SYS_TIME        0x11
48 a4f81979 bellard
#define SYS_SYSTEM      0x12
49 a4f81979 bellard
#define SYS_ERRNO       0x13
50 a4f81979 bellard
#define SYS_GET_CMDLINE 0x15
51 a4f81979 bellard
#define SYS_HEAPINFO    0x16
52 a4f81979 bellard
#define SYS_EXIT        0x18
53 a4f81979 bellard
54 a4f81979 bellard
#ifndef O_BINARY
55 a4f81979 bellard
#define O_BINARY 0
56 a4f81979 bellard
#endif
57 a4f81979 bellard
58 a4f81979 bellard
int open_modeflags[12] = {
59 a4f81979 bellard
    O_RDONLY,
60 a4f81979 bellard
    O_RDONLY | O_BINARY,
61 a4f81979 bellard
    O_RDWR,
62 a4f81979 bellard
    O_RDWR | O_BINARY,
63 a4f81979 bellard
    O_WRONLY | O_CREAT | O_TRUNC,
64 a4f81979 bellard
    O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
65 a4f81979 bellard
    O_RDWR | O_CREAT | O_TRUNC,
66 a4f81979 bellard
    O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
67 a4f81979 bellard
    O_WRONLY | O_CREAT | O_APPEND,
68 a4f81979 bellard
    O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
69 a4f81979 bellard
    O_RDWR | O_CREAT | O_APPEND,
70 a4f81979 bellard
    O_RDWR | O_CREAT | O_APPEND | O_BINARY
71 a4f81979 bellard
};
72 a4f81979 bellard
73 a4f81979 bellard
static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code)
74 a4f81979 bellard
{
75 a4f81979 bellard
  if (code == (uint32_t)-1)
76 a4f81979 bellard
      ts->swi_errno = errno;
77 a4f81979 bellard
  return code;
78 a4f81979 bellard
}
79 a4f81979 bellard
80 53a5960a pbrook
#define ARG(n) tget32(args + n * 4)
81 a4f81979 bellard
uint32_t do_arm_semihosting(CPUState *env)
82 a4f81979 bellard
{
83 53a5960a pbrook
    target_ulong args;
84 a4f81979 bellard
    char * s;
85 a4f81979 bellard
    int nr;
86 a4f81979 bellard
    uint32_t ret;
87 a4f81979 bellard
    TaskState *ts = env->opaque;
88 a4f81979 bellard
89 a4f81979 bellard
    nr = env->regs[0];
90 53a5960a pbrook
    args = env->regs[1];
91 a4f81979 bellard
    switch (nr) {
92 a4f81979 bellard
    case SYS_OPEN:
93 53a5960a pbrook
        s = (char *)g2h(ARG(0));
94 a4f81979 bellard
        if (ARG(1) >= 12)
95 a4f81979 bellard
          return (uint32_t)-1;
96 a4f81979 bellard
        if (strcmp(s, ":tt") == 0) {
97 a4f81979 bellard
            if (ARG(1) < 4)
98 a4f81979 bellard
                return STDIN_FILENO;
99 a4f81979 bellard
            else
100 a4f81979 bellard
                return STDOUT_FILENO;
101 a4f81979 bellard
        }
102 04d81be8 bellard
        return set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));
103 a4f81979 bellard
    case SYS_CLOSE:
104 a4f81979 bellard
        return set_swi_errno(ts, close(ARG(0)));
105 a4f81979 bellard
    case SYS_WRITEC:
106 53a5960a pbrook
        {
107 53a5960a pbrook
          char c = tget8(args);
108 53a5960a pbrook
          /* Write to debug console.  stderr is near enough.  */
109 53a5960a pbrook
          return write(STDERR_FILENO, &c, 1);
110 53a5960a pbrook
        }
111 a4f81979 bellard
    case SYS_WRITE0:
112 53a5960a pbrook
        s = lock_user_string(args);
113 53a5960a pbrook
        ret = write(STDERR_FILENO, s, strlen(s));
114 53a5960a pbrook
        unlock_user(s, args, 0);
115 53a5960a pbrook
        return ret;
116 a4f81979 bellard
    case SYS_WRITE:
117 53a5960a pbrook
        ret = set_swi_errno(ts, write(ARG(0), g2h(ARG(1)), ARG(2)));
118 a4f81979 bellard
        if (ret == (uint32_t)-1)
119 a4f81979 bellard
            return -1;
120 a4f81979 bellard
        return ARG(2) - ret;
121 a4f81979 bellard
    case SYS_READ:
122 53a5960a pbrook
        ret = set_swi_errno(ts, read(ARG(0), g2h(ARG(1)), ARG(2)));
123 a4f81979 bellard
        if (ret == (uint32_t)-1)
124 a4f81979 bellard
            return -1;
125 a4f81979 bellard
        return ARG(2) - ret;
126 a4f81979 bellard
    case SYS_READC:
127 a4f81979 bellard
       /* XXX: Read from debug cosole. Not implemented.  */
128 a4f81979 bellard
        return 0;
129 a4f81979 bellard
    case SYS_ISTTY:
130 a4f81979 bellard
        return isatty(ARG(0));
131 a4f81979 bellard
    case SYS_SEEK:
132 d0b3e735 bellard
        ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET));
133 d0b3e735 bellard
        if (ret == (uint32_t)-1)
134 d0b3e735 bellard
          return -1;
135 d0b3e735 bellard
        return 0;
136 a4f81979 bellard
    case SYS_FLEN:
137 a4f81979 bellard
        {
138 a4f81979 bellard
            struct stat buf;
139 a4f81979 bellard
            ret = set_swi_errno(ts, fstat(ARG(0), &buf));
140 a4f81979 bellard
            if (ret == (uint32_t)-1)
141 a4f81979 bellard
                return -1;
142 a4f81979 bellard
            return buf.st_size;
143 a4f81979 bellard
        }
144 a4f81979 bellard
    case SYS_TMPNAM:
145 a4f81979 bellard
        /* XXX: Not implemented.  */
146 a4f81979 bellard
        return -1;
147 a4f81979 bellard
    case SYS_REMOVE:
148 53a5960a pbrook
        return set_swi_errno(ts, remove((char *)g2h(ARG(0))));
149 a4f81979 bellard
    case SYS_RENAME:
150 53a5960a pbrook
        return set_swi_errno(ts, rename((char *)g2h(ARG(0)),
151 53a5960a pbrook
                             (char *)g2h(ARG(2))));
152 a4f81979 bellard
    case SYS_CLOCK:
153 a4f81979 bellard
        return clock() / (CLOCKS_PER_SEC / 100);
154 a4f81979 bellard
    case SYS_TIME:
155 a4f81979 bellard
        return set_swi_errno(ts, time(NULL));
156 a4f81979 bellard
    case SYS_SYSTEM:
157 53a5960a pbrook
        return set_swi_errno(ts, system((char *)g2h(ARG(0))));
158 a4f81979 bellard
    case SYS_ERRNO:
159 a4f81979 bellard
        return ts->swi_errno;
160 a4f81979 bellard
    case SYS_GET_CMDLINE:
161 a4f81979 bellard
        /* XXX: Not implemented.  */
162 53a5960a pbrook
        s = (char *)g2h(ARG(0));
163 a4f81979 bellard
        *s = 0;
164 a4f81979 bellard
        return -1;
165 a4f81979 bellard
    case SYS_HEAPINFO:
166 a4f81979 bellard
        {
167 a4f81979 bellard
            uint32_t *ptr;
168 a4f81979 bellard
            uint32_t limit;
169 a4f81979 bellard
170 a4f81979 bellard
            /* Some C llibraries assume the heap immediately follows .bss, so
171 a4f81979 bellard
               allocate it using sbrk.  */
172 a4f81979 bellard
            if (!ts->heap_limit) {
173 a4f81979 bellard
                long ret;
174 a4f81979 bellard
175 53a5960a pbrook
                ts->heap_base = do_brk(0);
176 a4f81979 bellard
                limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
177 a4f81979 bellard
                /* Try a big heap, and reduce the size if that fails.  */
178 a4f81979 bellard
                for (;;) {
179 53a5960a pbrook
                    ret = do_brk(limit);
180 a4f81979 bellard
                    if (ret != -1)
181 a4f81979 bellard
                        break;
182 a4f81979 bellard
                    limit = (ts->heap_base >> 1) + (limit >> 1);
183 a4f81979 bellard
                }
184 a4f81979 bellard
                ts->heap_limit = limit;
185 a4f81979 bellard
            }
186 a4f81979 bellard
              
187 53a5960a pbrook
            page_unprotect_range (ARG(0), 32);
188 53a5960a pbrook
            ptr = (uint32_t *)g2h(ARG(0));
189 a4f81979 bellard
            ptr[0] = tswap32(ts->heap_base);
190 a4f81979 bellard
            ptr[1] = tswap32(ts->heap_limit);
191 a4f81979 bellard
            ptr[2] = tswap32(ts->stack_base);
192 a4f81979 bellard
            ptr[3] = tswap32(0); /* Stack limit.  */
193 a4f81979 bellard
            return 0;
194 a4f81979 bellard
        }
195 a4f81979 bellard
    case SYS_EXIT:
196 a4f81979 bellard
        exit(0);
197 a4f81979 bellard
    default:
198 a4f81979 bellard
        fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
199 a4f81979 bellard
        cpu_dump_state(env, stderr, fprintf, 0);
200 a4f81979 bellard
        abort();
201 a4f81979 bellard
    }
202 a4f81979 bellard
}