Revision 8e71621f

b/Makefile.target
397 397
VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl190.o
398 398
VL_OBJS+= versatile_pci.o
399 399
VL_OBJS+= arm_gic.o realview.o arm_sysctl.o
400
VL_OBJS+= arm-semi.o
400 401
endif
401 402
ifeq ($(TARGET_BASE_ARCH), sh4)
402 403
VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
b/arm-semi.c
1
/*
2
 *  Arm "Angel" semihosting syscalls
3
 * 
4
 *  Copyright (c) 2005, 2007 CodeSourcery.
5
 *  Written by Paul Brook.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
 */
21

  
22
#include <sys/types.h>
23
#include <sys/stat.h>
24
#include <fcntl.h>
25
#include <unistd.h>
26
#include <stdlib.h>
27
#include <stdio.h>
28
#include <time.h>
29

  
30
#include "cpu.h"
31
#ifdef CONFIG_USER_ONLY
32
#include "qemu.h"
33

  
34
#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
35
#else
36
#include "vl.h"
37
#endif
38

  
39
#define SYS_OPEN        0x01
40
#define SYS_CLOSE       0x02
41
#define SYS_WRITEC      0x03
42
#define SYS_WRITE0      0x04
43
#define SYS_WRITE       0x05
44
#define SYS_READ        0x06
45
#define SYS_READC       0x07
46
#define SYS_ISTTY       0x09
47
#define SYS_SEEK        0x0a
48
#define SYS_FLEN        0x0c
49
#define SYS_TMPNAM      0x0d
50
#define SYS_REMOVE      0x0e
51
#define SYS_RENAME      0x0f
52
#define SYS_CLOCK       0x10
53
#define SYS_TIME        0x11
54
#define SYS_SYSTEM      0x12
55
#define SYS_ERRNO       0x13
56
#define SYS_GET_CMDLINE 0x15
57
#define SYS_HEAPINFO    0x16
58
#define SYS_EXIT        0x18
59

  
60
#ifndef O_BINARY
61
#define O_BINARY 0
62
#endif
63

  
64
int open_modeflags[12] = {
65
    O_RDONLY,
66
    O_RDONLY | O_BINARY,
67
    O_RDWR,
68
    O_RDWR | O_BINARY,
69
    O_WRONLY | O_CREAT | O_TRUNC,
70
    O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
71
    O_RDWR | O_CREAT | O_TRUNC,
72
    O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
73
    O_WRONLY | O_CREAT | O_APPEND,
74
    O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
75
    O_RDWR | O_CREAT | O_APPEND,
76
    O_RDWR | O_CREAT | O_APPEND | O_BINARY
77
};
78

  
79
#ifdef CONFIG_USER_ONLY
80
static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code)
81
{
82
    if (code == (uint32_t)-1)
83
        ts->swi_errno = errno;
84
    return code;
85
}
86
#else
87
static inline uint32_t set_swi_errno(CPUState *env, uint32_t code)
88
{
89
    return code;
90
}
91

  
92
static uint32_t softmmu_tget32(CPUState *env, uint32_t addr)
93
{
94
    uint32_t val;
95

  
96
    cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 0);
97
    return tswap32(val);
98
}
99
static uint32_t softmmu_tget8(CPUState *env, uint32_t addr)
100
{
101
    uint8_t val;
102

  
103
    cpu_memory_rw_debug(env, addr, &val, 1, 0);
104
    return val;
105
}
106
#define tget32(p) softmmu_tget32(env, p)
107
#define tget8(p) softmmu_tget8(env, p)
108

  
109
static void *softmmu_lock_user(CPUState *env, uint32_t addr, uint32_t len,
110
                               int copy)
111
{
112
    char *p;
113
    /* TODO: Make this something that isn't fixed size.  */
114
    p = malloc(len);
115
    if (copy)
116
        cpu_memory_rw_debug(env, addr, p, len, 0);
117
    return p;
118
}
119
#define lock_user(p, len, copy) softmmu_lock_user(env, p, len, copy)
120
static char *softmmu_lock_user_string(CPUState *env, uint32_t addr)
121
{
122
    char *p;
123
    char *s;
124
    uint8_t c;
125
    /* TODO: Make this something that isn't fixed size.  */
126
    s = p = malloc(1024);
127
    do {
128
        cpu_memory_rw_debug(env, addr, &c, 1, 0);
129
        addr++;
130
        *(p++) = c;
131
    } while (c);
132
    return s;
133
}
134
#define lock_user_string(p) softmmu_lock_user_string(env, p)
135
static void softmmu_unlock_user(CPUState *env, void *p, target_ulong addr,
136
                                target_ulong len)
137
{
138
    if (len)
139
        cpu_memory_rw_debug(env, addr, p, len, 1);
140
    free(p);
141
}
142
#define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len)
143
#endif
144

  
145
#define ARG(n) tget32(args + (n) * 4)
146
#define SET_ARG(n, val) tput32(args + (n) * 4,val)
147
uint32_t do_arm_semihosting(CPUState *env)
148
{
149
    target_ulong args;
150
    char * s;
151
    int nr;
152
    uint32_t ret;
153
    uint32_t len;
154
#ifdef CONFIG_USER_ONLY
155
    TaskState *ts = env->opaque;
156
#else
157
    CPUState *ts = env;
158
#endif
159

  
160
    nr = env->regs[0];
161
    args = env->regs[1];
162
    switch (nr) {
163
    case SYS_OPEN:
164
        s = lock_user_string(ARG(0));
165
        if (ARG(1) >= 12)
166
          return (uint32_t)-1;
167
        if (strcmp(s, ":tt") == 0) {
168
            if (ARG(1) < 4)
169
                return STDIN_FILENO;
170
            else
171
                return STDOUT_FILENO;
172
        }
173
        ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));
174
        unlock_user(s, ARG(0), 0);
175
        return ret;
176
    case SYS_CLOSE:
177
        return set_swi_errno(ts, close(ARG(0)));
178
    case SYS_WRITEC:
179
        {
180
          char c = tget8(args);
181
          /* Write to debug console.  stderr is near enough.  */
182
          return write(STDERR_FILENO, &c, 1);
183
        }
184
    case SYS_WRITE0:
185
        s = lock_user_string(args);
186
        ret = write(STDERR_FILENO, s, strlen(s));
187
        unlock_user(s, args, 0);
188
        return ret;
189
    case SYS_WRITE:
190
        len = ARG(2);
191
        s = lock_user(ARG(1), len, 1);
192
        ret = set_swi_errno(ts, write(ARG(0), s, len));
193
        unlock_user(s, ARG(1), 0);
194
        if (ret == (uint32_t)-1)
195
            return -1;
196
        return ARG(2) - ret;
197
    case SYS_READ:
198
        len = ARG(2);
199
        s = lock_user(ARG(1), len, 0);
200
	do
201
	  ret = set_swi_errno(ts, read(ARG(0), s, len));
202
	while (ret == -1 && errno == EINTR);
203
        unlock_user(s, ARG(1), len);
204
        if (ret == (uint32_t)-1)
205
            return -1;
206
        return ARG(2) - ret;
207
    case SYS_READC:
208
       /* XXX: Read from debug cosole. Not implemented.  */
209
        return 0;
210
    case SYS_ISTTY:
211
        return isatty(ARG(0));
212
    case SYS_SEEK:
213
        ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET));
214
	if (ret == (uint32_t)-1)
215
	  return -1;
216
	return 0;
217
    case SYS_FLEN:
218
        {
219
            struct stat buf;
220
            ret = set_swi_errno(ts, fstat(ARG(0), &buf));
221
            if (ret == (uint32_t)-1)
222
                return -1;
223
            return buf.st_size;
224
        }
225
    case SYS_TMPNAM:
226
        /* XXX: Not implemented.  */
227
        return -1;
228
    case SYS_REMOVE:
229
        s = lock_user_string(ARG(0));
230
        ret =  set_swi_errno(ts, remove(s));
231
        unlock_user(s, ARG(0), 0);
232
        return ret;
233
    case SYS_RENAME:
234
        {
235
            char *s2;
236
            s = lock_user_string(ARG(0));
237
            s2 = lock_user_string(ARG(2));
238
            ret = set_swi_errno(ts, rename(s, s2));
239
            unlock_user(s2, ARG(2), 0);
240
            unlock_user(s, ARG(0), 0);
241
            return ret;
242
        }
243
    case SYS_CLOCK:
244
        return clock() / (CLOCKS_PER_SEC / 100);
245
    case SYS_TIME:
246
        return set_swi_errno(ts, time(NULL));
247
    case SYS_SYSTEM:
248
        s = lock_user_string(ARG(0));
249
        ret = set_swi_errno(ts, system(s));
250
        unlock_user(s, ARG(0), 0);
251
    case SYS_ERRNO:
252
#ifdef CONFIG_USER_ONLY
253
        return ts->swi_errno;
254
#else
255
        return 0;
256
#endif
257
    case SYS_GET_CMDLINE:
258
#ifdef CONFIG_USER_ONLY
259
        /* Build a commandline from the original argv.  */
260
        {
261
            char **arg = ts->info->host_argv;
262
            int len = ARG(1);
263
            /* lock the buffer on the ARM side */
264
            char *cmdline_buffer = (char*)lock_user(ARG(0), len, 0);
265

  
266
            s = cmdline_buffer;
267
            while (*arg && len > 2) {
268
                int n = strlen(*arg);
269

  
270
                if (s != cmdline_buffer) {
271
                    *(s++) = ' ';
272
                    len--;
273
                }
274
                if (n >= len)
275
                    n = len - 1;
276
                memcpy(s, *arg, n);
277
                s += n;
278
                len -= n;
279
                arg++;
280
            }
281
            /* Null terminate the string.  */
282
            *s = 0;
283
            len = s - cmdline_buffer;
284

  
285
            /* Unlock the buffer on the ARM side.  */
286
            unlock_user(cmdline_buffer, ARG(0), len);
287

  
288
            /* Adjust the commandline length argument.  */
289
            SET_ARG(1, len);
290

  
291
            /* Return success if commandline fit into buffer.  */
292
            return *arg ? -1 : 0;
293
        }
294
#else
295
      return -1;
296
#endif
297
    case SYS_HEAPINFO:
298
        {
299
            uint32_t *ptr;
300
            uint32_t limit;
301

  
302
#ifdef CONFIG_USER_ONLY
303
            /* Some C libraries assume the heap immediately follows .bss, so
304
               allocate it using sbrk.  */
305
            if (!ts->heap_limit) {
306
                long ret;
307

  
308
                ts->heap_base = do_brk(0);
309
                limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
310
                /* Try a big heap, and reduce the size if that fails.  */
311
                for (;;) {
312
                    ret = do_brk(limit);
313
                    if (ret != -1)
314
                        break;
315
                    limit = (ts->heap_base >> 1) + (limit >> 1);
316
                }
317
                ts->heap_limit = limit;
318
            }
319
              
320
            ptr = lock_user(ARG(0), 16, 0);
321
            ptr[0] = tswap32(ts->heap_base);
322
            ptr[1] = tswap32(ts->heap_limit);
323
            ptr[2] = tswap32(ts->stack_base);
324
            ptr[3] = tswap32(0); /* Stack limit.  */
325
            unlock_user(ptr, ARG(0), 16);
326
#else
327
            limit = ram_size;
328
            ptr = lock_user(ARG(0), 16, 0);
329
            /* TODO: Make this use the limit of the loaded application.  */
330
            ptr[0] = tswap32(limit / 2);
331
            ptr[1] = tswap32(limit);
332
            ptr[2] = tswap32(limit); /* Stack base */
333
            ptr[3] = tswap32(0); /* Stack limit.  */
334
            unlock_user(ptr, ARG(0), 16);
335
#endif
336
            return 0;
337
        }
338
    case SYS_EXIT:
339
        exit(0);
340
    default:
341
        fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
342
        cpu_dump_state(env, stderr, fprintf, 0);
343
        abort();
344
    }
345
}
/dev/null
1
/*
2
 *  Arm "Angel" semihosting syscalls
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 <fcntl.h>
24
#include <unistd.h>
25
#include <stdlib.h>
26
#include <stdio.h>
27
#include <time.h>
28

  
29
#include "qemu.h"
30

  
31
#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
32

  
33
#define SYS_OPEN        0x01
34
#define SYS_CLOSE       0x02
35
#define SYS_WRITEC      0x03
36
#define SYS_WRITE0      0x04
37
#define SYS_WRITE       0x05
38
#define SYS_READ        0x06
39
#define SYS_READC       0x07
40
#define SYS_ISTTY       0x09
41
#define SYS_SEEK        0x0a
42
#define SYS_FLEN        0x0c
43
#define SYS_TMPNAM      0x0d
44
#define SYS_REMOVE      0x0e
45
#define SYS_RENAME      0x0f
46
#define SYS_CLOCK       0x10
47
#define SYS_TIME        0x11
48
#define SYS_SYSTEM      0x12
49
#define SYS_ERRNO       0x13
50
#define SYS_GET_CMDLINE 0x15
51
#define SYS_HEAPINFO    0x16
52
#define SYS_EXIT        0x18
53

  
54
#ifndef O_BINARY
55
#define O_BINARY 0
56
#endif
57

  
58
int open_modeflags[12] = {
59
    O_RDONLY,
60
    O_RDONLY | O_BINARY,
61
    O_RDWR,
62
    O_RDWR | O_BINARY,
63
    O_WRONLY | O_CREAT | O_TRUNC,
64
    O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
65
    O_RDWR | O_CREAT | O_TRUNC,
66
    O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
67
    O_WRONLY | O_CREAT | O_APPEND,
68
    O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
69
    O_RDWR | O_CREAT | O_APPEND,
70
    O_RDWR | O_CREAT | O_APPEND | O_BINARY
71
};
72

  
73
static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code)
74
{
75
  if (code == (uint32_t)-1)
76
      ts->swi_errno = errno;
77
  return code;
78
}
79

  
80
#define ARG(n) tget32(args + (n) * 4)
81
#define SET_ARG(n, val) tput32(args + (n) * 4,val)
82
uint32_t do_arm_semihosting(CPUState *env)
83
{
84
    target_ulong args;
85
    char * s;
86
    int nr;
87
    uint32_t ret;
88
    TaskState *ts = env->opaque;
89

  
90
    nr = env->regs[0];
91
    args = env->regs[1];
92
    switch (nr) {
93
    case SYS_OPEN:
94
        s = (char *)g2h(ARG(0));
95
        if (ARG(1) >= 12)
96
          return (uint32_t)-1;
97
        if (strcmp(s, ":tt") == 0) {
98
            if (ARG(1) < 4)
99
                return STDIN_FILENO;
100
            else
101
                return STDOUT_FILENO;
102
        }
103
        return set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));
104
    case SYS_CLOSE:
105
        return set_swi_errno(ts, close(ARG(0)));
106
    case SYS_WRITEC:
107
        {
108
          char c = tget8(args);
109
          /* Write to debug console.  stderr is near enough.  */
110
          return write(STDERR_FILENO, &c, 1);
111
        }
112
    case SYS_WRITE0:
113
        s = lock_user_string(args);
114
        ret = write(STDERR_FILENO, s, strlen(s));
115
        unlock_user(s, args, 0);
116
        return ret;
117
    case SYS_WRITE:
118
        ret = set_swi_errno(ts, write(ARG(0), g2h(ARG(1)), ARG(2)));
119
        if (ret == (uint32_t)-1)
120
            return -1;
121
        return ARG(2) - ret;
122
    case SYS_READ:
123
        ret = set_swi_errno(ts, read(ARG(0), g2h(ARG(1)), ARG(2)));
124
        if (ret == (uint32_t)-1)
125
            return -1;
126
        return ARG(2) - ret;
127
    case SYS_READC:
128
       /* XXX: Read from debug cosole. Not implemented.  */
129
        return 0;
130
    case SYS_ISTTY:
131
        return isatty(ARG(0));
132
    case SYS_SEEK:
133
        ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET));
134
	if (ret == (uint32_t)-1)
135
	  return -1;
136
	return 0;
137
    case SYS_FLEN:
138
        {
139
            struct stat buf;
140
            ret = set_swi_errno(ts, fstat(ARG(0), &buf));
141
            if (ret == (uint32_t)-1)
142
                return -1;
143
            return buf.st_size;
144
        }
145
    case SYS_TMPNAM:
146
        /* XXX: Not implemented.  */
147
        return -1;
148
    case SYS_REMOVE:
149
        return set_swi_errno(ts, remove((char *)g2h(ARG(0))));
150
    case SYS_RENAME:
151
        return set_swi_errno(ts, rename((char *)g2h(ARG(0)),
152
                             (char *)g2h(ARG(2))));
153
    case SYS_CLOCK:
154
        return clock() / (CLOCKS_PER_SEC / 100);
155
    case SYS_TIME:
156
        return set_swi_errno(ts, time(NULL));
157
    case SYS_SYSTEM:
158
        return set_swi_errno(ts, system((char *)g2h(ARG(0))));
159
    case SYS_ERRNO:
160
        return ts->swi_errno;
161
    case SYS_GET_CMDLINE:
162
        /* Build a commandline from the original argv.  */
163
        {
164
            char **arg = ts->info->host_argv;
165
            int len = ARG(1);
166
            /* lock the buffer on the ARM side */
167
            char *cmdline_buffer = (char*)lock_user(ARG(0), len, 0);
168

  
169
            s = cmdline_buffer;
170
            while (*arg && len > 2) {
171
                int n = strlen(*arg);
172

  
173
                if (s != cmdline_buffer) {
174
                    *(s++) = ' ';
175
                    len--;
176
                }
177
                if (n >= len)
178
                    n = len - 1;
179
                memcpy(s, *arg, n);
180
                s += n;
181
                len -= n;
182
                arg++;
183
            }
184
            /* Null terminate the string.  */
185
            *s = 0;
186
            len = s - cmdline_buffer;
187

  
188
            /* Unlock the buffer on the ARM side.  */
189
            unlock_user(cmdline_buffer, ARG(0), len);
190

  
191
            /* Adjust the commandline length argument.  */
192
            SET_ARG(1, len);
193

  
194
            /* Return success if commandline fit into buffer.  */
195
            return *arg ? -1 : 0;
196
        }
197
    case SYS_HEAPINFO:
198
        {
199
            uint32_t *ptr;
200
            uint32_t limit;
201

  
202
            /* Some C llibraries assume the heap immediately follows .bss, so
203
               allocate it using sbrk.  */
204
            if (!ts->heap_limit) {
205
                long ret;
206

  
207
                ts->heap_base = do_brk(0);
208
                limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
209
                /* Try a big heap, and reduce the size if that fails.  */
210
                for (;;) {
211
                    ret = do_brk(limit);
212
                    if (ret != -1)
213
                        break;
214
                    limit = (ts->heap_base >> 1) + (limit >> 1);
215
                }
216
                ts->heap_limit = limit;
217
            }
218
              
219
            page_unprotect_range (ARG(0), 32);
220
            ptr = (uint32_t *)g2h(ARG(0));
221
            ptr[0] = tswap32(ts->heap_base);
222
            ptr[1] = tswap32(ts->heap_limit);
223
            ptr[2] = tswap32(ts->stack_base);
224
            ptr[3] = tswap32(0); /* Stack limit.  */
225
            return 0;
226
        }
227
    case SYS_EXIT:
228
        exit(0);
229
    default:
230
        fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
231
        cpu_dump_state(env, stderr, fprintf, 0);
232
        abort();
233
    }
234
}
235

  
b/qemu-doc.texi
661 661

  
662 662
@item -loadvm file
663 663
Start right away with a saved state (@code{loadvm} in monitor)
664

  
665
@item -semihosting
666
Enable "Angel" semihosting interface (ARM target machines only).
667
Note that this allows guest direct access to the host filesystem,
668
so should only be used with trusted guest OS.
664 669
@end table
665 670

  
666 671
@c man end
b/target-arm/helper.c
105 105

  
106 106
#else
107 107

  
108
extern int semihosting_enabled;
109

  
108 110
/* Map CPU modes onto saved register banks.  */
109 111
static inline int bank_number (int mode)
110 112
{
......
175 177
            offset = 4;
176 178
        break;
177 179
    case EXCP_SWI:
180
        if (semihosting_enabled) {
181
            /* Check for semihosting interrupt.  */
182
            if (env->thumb) {
183
                mask = lduw_code(env->regs[15] - 2) & 0xff;
184
            } else {
185
                mask = ldl_code(env->regs[15] - 4) & 0xffffff;
186
            }
187
            /* Only intercept calls from privileged modes, to provide some
188
               semblance of security.  */
189
            if (((mask == 0x123456 && !env->thumb)
190
                    || (mask == 0xab && env->thumb))
191
                  && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
192
                env->regs[0] = do_arm_semihosting(env);
193
                return;
194
            }
195
        }
178 196
        new_mode = ARM_CPU_MODE_SVC;
179 197
        addr = 0x08;
180 198
        mask = CPSR_I;
b/vl.c
171 171
int daemonize = 0;
172 172
const char *option_rom[MAX_OPTION_ROMS];
173 173
int nb_option_roms;
174
int semihosting_enabled = 0;
174 175

  
175 176
/***********************************************************/
176 177
/* x86 ISA bus support */
......
6227 6228
    QEMU_OPTION_no_reboot,
6228 6229
    QEMU_OPTION_daemonize,
6229 6230
    QEMU_OPTION_option_rom,
6231
    QEMU_OPTION_semihosting
6230 6232
};
6231 6233

  
6232 6234
typedef struct QEMUOption {
......
6309 6311
    { "no-reboot", 0, QEMU_OPTION_no_reboot },
6310 6312
    { "daemonize", 0, QEMU_OPTION_daemonize },
6311 6313
    { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
6314
#if defined(TARGET_ARM)
6315
    { "semihosting", 0, QEMU_OPTION_semihosting },
6316
#endif
6312 6317
    { NULL },
6313 6318
};
6314 6319

  
......
6970 6975
		option_rom[nb_option_roms] = optarg;
6971 6976
		nb_option_roms++;
6972 6977
		break;
6978
            case QEMU_OPTION_semihosting:
6979
                semihosting_enabled = 1;
6980
                break;
6973 6981
            }
6974 6982
        }
6975 6983
    }
b/vl.h
159 159
extern int usb_enabled;
160 160
extern int smp_cpus;
161 161
extern int no_quit;
162
extern int semihosting_enabled;
162 163

  
163 164
#define MAX_OPTION_ROMS 16
164 165
extern const char *option_rom[MAX_OPTION_ROMS];

Also available in: Unified diff