#include <time.h>
#include "cpu.h"
+#include "exec/semihost.h"
#ifdef CONFIG_USER_ONLY
#include "qemu.h"
#define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
#else
#include "qemu-common.h"
-#include "gdbstub.h"
-#include "hw/arm-misc.h"
+#include "exec/gdbstub.h"
+#include "hw/arm/arm.h"
#endif
#define TARGET_SYS_OPEN 0x01
#define TARGET_SYS_HEAPINFO 0x16
#define TARGET_SYS_EXIT 0x18
+/* ADP_Stopped_ApplicationExit is used for exit(0),
+ * anything else is implemented as exit(1) */
+#define ADP_Stopped_ApplicationExit (0x20026)
+
#ifndef O_BINARY
#define O_BINARY 0
#endif
return code;
}
-#include "softmmu-semi.h"
+#include "exec/softmmu-semi.h"
#endif
static target_ulong arm_semi_syscall_len;
static target_ulong syscall_err;
#endif
-static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err)
+static void arm_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
#ifdef CONFIG_USER_ONLY
- TaskState *ts = env->opaque;
+ TaskState *ts = cs->opaque;
#endif
if (ret == (target_ulong)-1) {
}
}
-static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong err)
+static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
/* The size is always stored in big-endian order, extract
the value. We assume the size always fit in 32 bits. */
uint32_t size;
- cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
+ cpu_memory_rw_debug(cs, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
env->regs[0] = be32_to_cpu(size);
#ifdef CONFIG_USER_ONLY
- ((TaskState *)env->opaque)->swi_errno = err;
+ ((TaskState *)cs->opaque)->swi_errno = err;
#else
syscall_err = err;
#endif
#define SET_ARG(n, val) put_user_ual(val, args + (n) * 4)
uint32_t do_arm_semihosting(CPUARMState *env)
{
+ ARMCPU *cpu = arm_env_get_cpu(env);
+ CPUState *cs = CPU(cpu);
target_ulong args;
target_ulong arg0, arg1, arg2, arg3;
char * s;
uint32_t ret;
uint32_t len;
#ifdef CONFIG_USER_ONLY
- TaskState *ts = env->opaque;
+ TaskState *ts = cs->opaque;
#else
CPUARMState *ts = env;
#endif
size_t input_size;
size_t output_size;
int status = 0;
+#if !defined(CONFIG_USER_ONLY)
+ const char *cmdline;
+#endif
GET_ARG(0);
GET_ARG(1);
input_size = arg1;
/* Compute the size of the output string. */
#if !defined(CONFIG_USER_ONLY)
- output_size = strlen(ts->boot_info->kernel_filename)
- + 1 /* Separating space. */
- + strlen(ts->boot_info->kernel_cmdline)
- + 1; /* Terminating null byte. */
+ cmdline = semihosting_get_cmdline();
+ if (cmdline == NULL) {
+ cmdline = ""; /* Default to an empty line. */
+ }
+ output_size = strlen(cmdline) + 1; /* Count terminating 0. */
#else
unsigned int i;
/* Copy the command-line arguments. */
#if !defined(CONFIG_USER_ONLY)
- pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename);
- pstrcat(output_buffer, output_size, " ");
- pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline);
+ pstrcpy(output_buffer, output_size, cmdline);
#else
if (output_size == 1) {
/* Empty command-line. */
return 0;
}
case TARGET_SYS_EXIT:
- gdb_exit(env, 0);
- exit(0);
+ /* ARM specifies only Stopped_ApplicationExit as normal
+ * exit, everything else is considered an error */
+ ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1;
+ gdb_exit(env, ret);
+ exit(ret);
default:
fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
- cpu_dump_state(env, stderr, fprintf, 0);
+ cpu_dump_state(cs, stderr, fprintf, 0);
abort();
}
}