qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] bsd-user: improve support for sparc syscall flags


From: salvador
Subject: [PATCH] bsd-user: improve support for sparc syscall flags
Date: Fri, 24 Jan 2020 19:31:13 +0100

From: Salvador Fandino <address@hidden>

Under sparc and sparc64, both NetBSD and OpenSSH use two bits of the
syscall number as flags. Until now, those bits where only supported
for sparc64 when emulating OpenBSD.

This patch extends support for syscall flags to the sparc architecture
and NetBSD emulation. It had allowed my to run simple NetBSD sparc
applications with qemu-sparc on a FreeBSD x64 machine.

The code supporting OpenBSD sparc and sparc64 emulation has been
refactored in order to make it simpler and similar to the new one for
NetBSD.

Signed-off-by: Salvador Fandino <address@hidden>
---
 bsd-user/main.c              | 68 ++++++++++++++++++++++++------------
 bsd-user/netbsd/syscall_nr.h | 52 +++++++++++++++++++++++++++
 2 files changed, 98 insertions(+), 22 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 770c2b267a..e249d66e26 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -491,7 +491,7 @@ static void flush_windows(CPUSPARCState *env)
 void cpu_loop(CPUSPARCState *env)
 {
     CPUState *cs = env_cpu(env);
-    int trapnr, ret, syscall_nr;
+    int trapnr, ret, syscall_nr, syscall_flags;
     //target_siginfo_t info;
 
     while (1) {
@@ -511,21 +511,29 @@ void cpu_loop(CPUSPARCState *env)
         case 0x100:
 #endif
             syscall_nr = env->gregs[1];
-            if (bsd_type == target_freebsd)
+            if (bsd_type == target_freebsd) {
                 ret = do_freebsd_syscall(env, syscall_nr,
                                          env->regwptr[0], env->regwptr[1],
                                          env->regwptr[2], env->regwptr[3],
                                          env->regwptr[4], env->regwptr[5], 0, 
0);
-            else if (bsd_type == target_netbsd)
+            }
+            else if (bsd_type == target_netbsd) {
+                syscall_flags = syscall_nr & (TARGET_NETBSD_SYSCALL_G7RFLAG |
+                                              TARGET_NETBSD_SYSCALL_G5RFLAG |
+                                              TARGET_NETBSD_SYSCALL_G2RFLAG);
+                syscall_nr &= ~(TARGET_NETBSD_SYSCALL_G7RFLAG |
+                                TARGET_NETBSD_SYSCALL_G5RFLAG |
+                                TARGET_NETBSD_SYSCALL_G2RFLAG);
                 ret = do_netbsd_syscall(env, syscall_nr,
                                         env->regwptr[0], env->regwptr[1],
                                         env->regwptr[2], env->regwptr[3],
                                         env->regwptr[4], env->regwptr[5]);
+            }
             else { //if (bsd_type == target_openbsd)
-#if defined(TARGET_SPARC64)
-                syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G7RFLAG |
-                                TARGET_OPENBSD_SYSCALL_G2RFLAG);
-#endif
+                syscall_flags = syscall_nr & (TARGET_OPENBSD_SYSCALL_G2RFLAG |
+                                              TARGET_OPENBSD_SYSCALL_G7RFLAG);
+                syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G2RFLAG |
+                                TARGET_OPENBSD_SYSCALL_G7RFLAG);
                 ret = do_openbsd_syscall(env, syscall_nr,
                                          env->regwptr[0], env->regwptr[1],
                                          env->regwptr[2], env->regwptr[3],
@@ -547,23 +555,39 @@ void cpu_loop(CPUSPARCState *env)
             }
             env->regwptr[0] = ret;
             /* next instruction */
-#if defined(TARGET_SPARC64)
-            if (bsd_type == target_openbsd &&
-                env->gregs[1] & TARGET_OPENBSD_SYSCALL_G2RFLAG) {
-                env->pc = env->gregs[2];
-                env->npc = env->pc + 4;
-            } else if (bsd_type == target_openbsd &&
-                       env->gregs[1] & TARGET_OPENBSD_SYSCALL_G7RFLAG) {
-                env->pc = env->gregs[7];
-                env->npc = env->pc + 4;
-            } else {
+            if (bsd_type == target_openbsd) {
+                switch (syscall_flags) {
+                case 0:
+                    env->pc = env->npc;
+                    break;
+                case TARGET_OPENBSD_SYSCALL_G7RFLAG:
+                    env->pc = env->gregs[7];
+                    break;
+                default: /* G2 or G2|G7 */
+                    env->pc = env->gregs[2];
+                    break;
+                }
+            }
+            else if (bsd_type == target_netbsd) {
+                switch (syscall_flags) {
+                case 0:
+                    env->pc = env->npc;
+                    break;
+                case TARGET_NETBSD_SYSCALL_G7RFLAG:
+                    env->pc = env->gregs[7];
+                    break;
+                case TARGET_NETBSD_SYSCALL_G5RFLAG:
+                    env->pc = env->gregs[5];
+                    break;
+                case TARGET_NETBSD_SYSCALL_G2RFLAG:
+                    env->pc = env->gregs[2];
+                    break;
+                }
+            }
+            else  {
                 env->pc = env->npc;
-                env->npc = env->npc + 4;
             }
-#else
-            env->pc = env->npc;
-            env->npc = env->npc + 4;
-#endif
+            env->npc = env->pc + 4;
             break;
         case 0x83: /* flush windows */
 #ifdef TARGET_ABI32
diff --git a/bsd-user/netbsd/syscall_nr.h b/bsd-user/netbsd/syscall_nr.h
index 2e9ab5378e..79022b0b4e 100644
--- a/bsd-user/netbsd/syscall_nr.h
+++ b/bsd-user/netbsd/syscall_nr.h
@@ -371,3 +371,55 @@
 #define TARGET_NETBSD_NR_pset_assign 414
 #define TARGET_NETBSD_NR__pset_bind  415
 #define TARGET_NETBSD_NR___posix_fadvise50   416
+
+/*     $NetBSD: trap.h,v 1.18 2011/03/27 18:47:08 martin Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)trap.h      8.1 (Berkeley) 6/11/93
+ */
+/*
+ * Sun4m support by Aaron Brown, Harvard University.
+ * Changes Copyright (c) 1995 The President and Fellows of Harvard College.
+ * All rights reserved.
+ */
+
+/* flags to system call (flags in %g1 along with syscall number) */
+#define        TARGET_NETBSD_SYSCALL_G2RFLAG   0x400   /* on success, return 
to %g2 rather than npc */
+#define        TARGET_NETBSD_SYSCALL_G7RFLAG   0x800   /* use %g7 as above 
(deprecated) */
+#define        TARGET_NETBSD_SYSCALL_G5RFLAG   0xc00   /* use %g5 as above 
(only ABI compatible way) */
-- 
2.24.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]