This is for full-system only; not implemented in user mode
Written by Derek Hower.
Signed-off-by: Christopher Covington c...@codeaurora.org
---
include/exec/softmmu-semi.h | 21 ++-
target-arm/arm-semi.c | 142
target-arm/cpu.h| 3 +-
target-arm/helper-a64.c | 28 -
target-arm/helper.c | 1 +
target-arm/internals.h | 8 +++
target-arm/translate-a64.c | 2 +-
7 files changed, 174 insertions(+), 31 deletions(-)
diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h
index 8401f7d..9ab8353 100644
--- a/include/exec/softmmu-semi.h
+++ b/include/exec/softmmu-semi.h
@@ -9,6 +9,13 @@
#ifndef SOFTMMU_SEMI_H
#define SOFTMMU_SEMI_H 1
+static inline uint64_t softmmu_tget64(CPUArchState *env, uint64_t addr)
+{
+uint64_t val;
+
+cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)val, 8, 0);
+return tswap64(val);
+}
static inline uint32_t softmmu_tget32(CPUArchState *env, uint32_t addr)
{
uint32_t val;
@@ -24,19 +31,27 @@ static inline uint32_t softmmu_tget8(CPUArchState *env,
uint32_t addr)
return val;
}
+#define get_user_u64(arg, p) ({ arg = softmmu_tget64(env, p) ; 0; })
#define get_user_u32(arg, p) ({ arg = softmmu_tget32(env, p) ; 0; })
#define get_user_u8(arg, p) ({ arg = softmmu_tget8(env, p) ; 0; })
#define get_user_ual(arg, p) get_user_u32(arg, p)
+static inline void softmmu_tput64(CPUArchState *env, uint64_t addr, uint64_t
val)
+{
+val = tswap64(val);
+cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)val, 8, 1);
+}
+
static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t
val)
{
val = tswap32(val);
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)val, 4, 1);
}
+#define put_user_u64(arg, p) ({ softmmu_tput64(env, p, arg) ; 0; })
#define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
#define put_user_ual(arg, p) put_user_u32(arg, p)
-static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
+static void *softmmu_lock_user(CPUArchState *env, target_ulong addr, uint32_t
len,
int copy)
{
uint8_t *p;
@@ -48,11 +63,11 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t
addr, uint32_t len,
return p;
}
#define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
-static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
+static char *softmmu_lock_user_string(CPUArchState *env, target_ulong addr)
{
char *p;
char *s;
-uint8_t c;
+uint8_t c = 0;
/* TODO: Make this something that isn't fixed size. */
s = p = malloc(1024);
if (!s) {
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index bcc70ec..b89ea8f 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -4,6 +4,9 @@
* Copyright (c) 2005, 2007 CodeSourcery.
* Written by Paul Brook.
*
+ * Copyright (c) 2015 the Linux Foundation.
+ * Written by Derek Hower.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -140,19 +143,35 @@ static void arm_semi_cb(CPUState *cs, target_ulong ret,
target_ulong err)
#else
syscall_err = err;
#endif
-env-regs[0] = ret;
+if (env-aarch64) {
+ env-xregs[0] = ret;
+} else {
+ env-regs[0] = ret;
+}
} else {
/* Fixup syscalls that use nonstardard return conventions. */
switch (env-regs[0]) {
case TARGET_SYS_WRITE:
case TARGET_SYS_READ:
+ if (env-aarch64) {
+env-xregs[0] = arm_semi_syscall_len - ret;
+ } else {
env-regs[0] = arm_semi_syscall_len - ret;
+ }
break;
case TARGET_SYS_SEEK:
+ if (env-aarch64) {
+env-xregs[0] = 0;
+ } else {
env-regs[0] = 0;
+ }
break;
default:
+ if (env-aarch64) {
+env-xregs[0] = ret;
+ } else {
env-regs[0] = ret;
+ }
break;
}
}
@@ -165,8 +184,13 @@ static void arm_semi_flen_cb(CPUState *cs, target_ulong
ret, target_ulong err)
/* 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(cs, env-regs[13]-64+32, (uint8_t *)size, 4, 0);
-env-regs[0] = be32_to_cpu(size);
+if (env-aarch64) {
+ cpu_memory_rw_debug(cs, env-pc-64+32, (uint8_t *)size, 4, 0);
+ env-xregs[0] = be32_to_cpu(size);
+} else {
+ 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 *)cs-opaque)-swi_errno = err;
#else